dso_lib.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:11k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* dso_lib.c -*- mode:C; c-file-style: "eay" -*- */
  2. /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
  3.  * project 2000.
  4.  */
  5. /* ====================================================================
  6.  * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  *
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer. 
  14.  *
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in
  17.  *    the documentation and/or other materials provided with the
  18.  *    distribution.
  19.  *
  20.  * 3. All advertising materials mentioning features or use of this
  21.  *    software must display the following acknowledgment:
  22.  *    "This product includes software developed by the OpenSSL Project
  23.  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24.  *
  25.  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26.  *    endorse or promote products derived from this software without
  27.  *    prior written permission. For written permission, please contact
  28.  *    licensing@OpenSSL.org.
  29.  *
  30.  * 5. Products derived from this software may not be called "OpenSSL"
  31.  *    nor may "OpenSSL" appear in their names without prior written
  32.  *    permission of the OpenSSL Project.
  33.  *
  34.  * 6. Redistributions of any form whatsoever must retain the following
  35.  *    acknowledgment:
  36.  *    "This product includes software developed by the OpenSSL Project
  37.  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38.  *
  39.  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  51.  * ====================================================================
  52.  *
  53.  * This product includes cryptographic software written by Eric Young
  54.  * (eay@cryptsoft.com).  This product includes software written by Tim
  55.  * Hudson (tjh@cryptsoft.com).
  56.  *
  57.  */
  58. #include <stdio.h>
  59. #include <openssl/crypto.h>
  60. #include "cryptlib.h"
  61. #include <openssl/dso.h>
  62. static DSO_METHOD *default_DSO_meth = NULL;
  63. DSO *DSO_new(void)
  64. {
  65. return(DSO_new_method(NULL));
  66. }
  67. void DSO_set_default_method(DSO_METHOD *meth)
  68. {
  69. default_DSO_meth = meth;
  70. }
  71. DSO_METHOD *DSO_get_default_method(void)
  72. {
  73. return(default_DSO_meth);
  74. }
  75. DSO_METHOD *DSO_get_method(DSO *dso)
  76. {
  77. return(dso->meth);
  78. }
  79. DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth)
  80. {
  81. DSO_METHOD *mtmp;
  82. mtmp = dso->meth;
  83. dso->meth = meth;
  84. return(mtmp);
  85. }
  86. DSO *DSO_new_method(DSO_METHOD *meth)
  87. {
  88. DSO *ret;
  89. if(default_DSO_meth == NULL)
  90. /* We default to DSO_METH_openssl() which in turn defaults
  91.  * to stealing the "best available" method. Will fallback
  92.  * to DSO_METH_null() in the worst case. */
  93. default_DSO_meth = DSO_METHOD_openssl();
  94. ret = (DSO *)OPENSSL_malloc(sizeof(DSO));
  95. if(ret == NULL)
  96. {
  97. DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE);
  98. return(NULL);
  99. }
  100. memset(ret, 0, sizeof(DSO));
  101. ret->meth_data = sk_new_null();
  102. if(ret->meth_data == NULL)
  103. {
  104. /* sk_new doesn't generate any errors so we do */
  105. DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE);
  106. OPENSSL_free(ret);
  107. return(NULL);
  108. }
  109. if(meth == NULL)
  110. ret->meth = default_DSO_meth;
  111. else
  112. ret->meth = meth;
  113. ret->references = 1;
  114. if((ret->meth->init != NULL) && !ret->meth->init(ret))
  115. {
  116. OPENSSL_free(ret);
  117. ret=NULL;
  118. }
  119. return(ret);
  120. }
  121. int DSO_free(DSO *dso)
  122. {
  123.         int i;
  124.  
  125. if(dso == NULL)
  126. {
  127. DSOerr(DSO_F_DSO_FREE,ERR_R_PASSED_NULL_PARAMETER);
  128. return(0);
  129. }
  130.  
  131. i=CRYPTO_add(&dso->references,-1,CRYPTO_LOCK_DSO);
  132. #ifdef REF_PRINT
  133. REF_PRINT("DSO",dso);
  134. #endif
  135. if(i > 0) return(1);
  136. #ifdef REF_CHECK
  137. if(i < 0)
  138. {
  139. fprintf(stderr,"DSO_free, bad reference countn");
  140. abort();
  141. }
  142. #endif
  143. if((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso))
  144. {
  145. DSOerr(DSO_F_DSO_FREE,DSO_R_UNLOAD_FAILED);
  146. return(0);
  147. }
  148.  
  149. if((dso->meth->finish != NULL) && !dso->meth->finish(dso))
  150. {
  151. DSOerr(DSO_F_DSO_FREE,DSO_R_FINISH_FAILED);
  152. return(0);
  153. }
  154. sk_free(dso->meth_data);
  155. if(dso->filename != NULL)
  156. OPENSSL_free(dso->filename);
  157. if(dso->loaded_filename != NULL)
  158. OPENSSL_free(dso->loaded_filename);
  159.  
  160. OPENSSL_free(dso);
  161. return(1);
  162. }
  163. int DSO_flags(DSO *dso)
  164. {
  165. return((dso == NULL) ? 0 : dso->flags);
  166. }
  167. int DSO_up_ref(DSO *dso)
  168. {
  169. if (dso == NULL)
  170. {
  171. DSOerr(DSO_F_DSO_UP_REF,ERR_R_PASSED_NULL_PARAMETER);
  172. return(0);
  173. }
  174. CRYPTO_add(&dso->references,1,CRYPTO_LOCK_DSO);
  175. return(1);
  176. }
  177. DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
  178. {
  179. DSO *ret;
  180. int allocated = 0;
  181. if(dso == NULL)
  182. {
  183. ret = DSO_new_method(meth);
  184. if(ret == NULL)
  185. {
  186. DSOerr(DSO_F_DSO_LOAD,ERR_R_MALLOC_FAILURE);
  187. goto err;
  188. }
  189. allocated = 1;
  190. /* Pass the provided flags to the new DSO object */
  191. if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0)
  192. {
  193. DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED);
  194. goto err;
  195. }
  196. }
  197. else
  198. ret = dso;
  199. /* Don't load if we're currently already loaded */
  200. if(ret->filename != NULL)
  201. {
  202. DSOerr(DSO_F_DSO_LOAD,DSO_R_DSO_ALREADY_LOADED);
  203. goto err;
  204. }
  205. /* filename can only be NULL if we were passed a dso that already has
  206.  * one set. */
  207. if(filename != NULL)
  208. if(!DSO_set_filename(ret, filename))
  209. {
  210. DSOerr(DSO_F_DSO_LOAD,DSO_R_SET_FILENAME_FAILED);
  211. goto err;
  212. }
  213. filename = ret->filename;
  214. if(filename == NULL)
  215. {
  216. DSOerr(DSO_F_DSO_LOAD,DSO_R_NO_FILENAME);
  217. goto err;
  218. }
  219. if(ret->meth->dso_load == NULL)
  220. {
  221. DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED);
  222. goto err;
  223. }
  224. if(!ret->meth->dso_load(ret))
  225. {
  226. DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED);
  227. goto err;
  228. }
  229. /* Load succeeded */
  230. return(ret);
  231. err:
  232. if(allocated)
  233. DSO_free(ret);
  234. return(NULL);
  235. }
  236. void *DSO_bind_var(DSO *dso, const char *symname)
  237. {
  238. void *ret = NULL;
  239. if((dso == NULL) || (symname == NULL))
  240. {
  241. DSOerr(DSO_F_DSO_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
  242. return(NULL);
  243. }
  244. if(dso->meth->dso_bind_var == NULL)
  245. {
  246. DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_UNSUPPORTED);
  247. return(NULL);
  248. }
  249. if((ret = dso->meth->dso_bind_var(dso, symname)) == NULL)
  250. {
  251. DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_SYM_FAILURE);
  252. return(NULL);
  253. }
  254. /* Success */
  255. return(ret);
  256. }
  257. DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
  258. {
  259. DSO_FUNC_TYPE ret = NULL;
  260. if((dso == NULL) || (symname == NULL))
  261. {
  262. DSOerr(DSO_F_DSO_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
  263. return(NULL);
  264. }
  265. if(dso->meth->dso_bind_func == NULL)
  266. {
  267. DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED);
  268. return(NULL);
  269. }
  270. if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL)
  271. {
  272. DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE);
  273. return(NULL);
  274. }
  275. /* Success */
  276. return(ret);
  277. }
  278. /* I don't really like these *_ctrl functions very much to be perfectly
  279.  * honest. For one thing, I think I have to return a negative value for
  280.  * any error because possible DSO_ctrl() commands may return values
  281.  * such as "size"s that can legitimately be zero (making the standard
  282.  * "if(DSO_cmd(...))" form that works almost everywhere else fail at
  283.  * odd times. I'd prefer "output" values to be passed by reference and
  284.  * the return value as success/failure like usual ... but we conform
  285.  * when we must... :-) */
  286. long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
  287. {
  288. if(dso == NULL)
  289. {
  290. DSOerr(DSO_F_DSO_CTRL,ERR_R_PASSED_NULL_PARAMETER);
  291. return(-1);
  292. }
  293. /* We should intercept certain generic commands and only pass control
  294.  * to the method-specific ctrl() function if it's something we don't
  295.  * handle. */
  296. switch(cmd)
  297. {
  298. case DSO_CTRL_GET_FLAGS:
  299. return dso->flags;
  300. case DSO_CTRL_SET_FLAGS:
  301. dso->flags = (int)larg;
  302. return(0);
  303. case DSO_CTRL_OR_FLAGS:
  304. dso->flags |= (int)larg;
  305. return(0);
  306. default:
  307. break;
  308. }
  309. if((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL))
  310. {
  311. DSOerr(DSO_F_DSO_CTRL,DSO_R_UNSUPPORTED);
  312. return(-1);
  313. }
  314. return(dso->meth->dso_ctrl(dso,cmd,larg,parg));
  315. }
  316. int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
  317. DSO_NAME_CONVERTER_FUNC *oldcb)
  318. {
  319. if(dso == NULL)
  320. {
  321. DSOerr(DSO_F_DSO_SET_NAME_CONVERTER,
  322. ERR_R_PASSED_NULL_PARAMETER);
  323. return(0);
  324. }
  325. if(oldcb)
  326. *oldcb = dso->name_converter;
  327. dso->name_converter = cb;
  328. return(1);
  329. }
  330. const char *DSO_get_filename(DSO *dso)
  331. {
  332. if(dso == NULL)
  333. {
  334. DSOerr(DSO_F_DSO_GET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
  335. return(NULL);
  336. }
  337. return(dso->filename);
  338. }
  339. int DSO_set_filename(DSO *dso, const char *filename)
  340. {
  341. char *copied;
  342. if((dso == NULL) || (filename == NULL))
  343. {
  344. DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
  345. return(0);
  346. }
  347. if(dso->loaded_filename)
  348. {
  349. DSOerr(DSO_F_DSO_SET_FILENAME,DSO_R_DSO_ALREADY_LOADED);
  350. return(0);
  351. }
  352. /* We'll duplicate filename */
  353. copied = OPENSSL_malloc(strlen(filename) + 1);
  354. if(copied == NULL)
  355. {
  356. DSOerr(DSO_F_DSO_SET_FILENAME,ERR_R_MALLOC_FAILURE);
  357. return(0);
  358. }
  359. BUF_strlcpy(copied, filename, strlen(filename) + 1);
  360. if(dso->filename)
  361. OPENSSL_free(dso->filename);
  362. dso->filename = copied;
  363. return(1);
  364. }
  365. char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
  366. {
  367. char *result = NULL;
  368. if(dso == NULL || filespec1 == NULL)
  369. {
  370. DSOerr(DSO_F_DSO_MERGE,ERR_R_PASSED_NULL_PARAMETER);
  371. return(NULL);
  372. }
  373. if(filespec1 == NULL)
  374. filespec1 = dso->filename;
  375. if(filespec1 == NULL)
  376. {
  377. DSOerr(DSO_F_DSO_MERGE,DSO_R_NO_FILE_SPECIFICATION);
  378. return(NULL);
  379. }
  380. if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
  381. {
  382. if(dso->merger != NULL)
  383. result = dso->merger(dso, filespec1, filespec2);
  384. else if(dso->meth->dso_merger != NULL)
  385. result = dso->meth->dso_merger(dso,
  386. filespec1, filespec2);
  387. }
  388. return(result);
  389. }
  390. char *DSO_convert_filename(DSO *dso, const char *filename)
  391. {
  392. char *result = NULL;
  393. if(dso == NULL)
  394. {
  395. DSOerr(DSO_F_DSO_CONVERT_FILENAME,ERR_R_PASSED_NULL_PARAMETER);
  396. return(NULL);
  397. }
  398. if(filename == NULL)
  399. filename = dso->filename;
  400. if(filename == NULL)
  401. {
  402. DSOerr(DSO_F_DSO_CONVERT_FILENAME,DSO_R_NO_FILENAME);
  403. return(NULL);
  404. }
  405. if((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0)
  406. {
  407. if(dso->name_converter != NULL)
  408. result = dso->name_converter(dso, filename);
  409. else if(dso->meth->dso_name_converter != NULL)
  410. result = dso->meth->dso_name_converter(dso, filename);
  411. }
  412. if(result == NULL)
  413. {
  414. result = OPENSSL_malloc(strlen(filename) + 1);
  415. if(result == NULL)
  416. {
  417. DSOerr(DSO_F_DSO_CONVERT_FILENAME,
  418. ERR_R_MALLOC_FAILURE);
  419. return(NULL);
  420. }
  421. BUF_strlcpy(result, filename, strlen(filename) + 1);
  422. }
  423. return(result);
  424. }
  425. const char *DSO_get_loaded_filename(DSO *dso)
  426. {
  427. if(dso == NULL)
  428. {
  429. DSOerr(DSO_F_DSO_GET_LOADED_FILENAME,
  430. ERR_R_PASSED_NULL_PARAMETER);
  431. return(NULL);
  432. }
  433. return(dso->loaded_filename);
  434. }