os400sys.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at https://curl.haxx.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. *
  22. ***************************************************************************/
  23. /* OS/400 additional support. */
  24. #include <curl/curl.h>
  25. #include "config-os400.h" /* Not curl_setup.h: we only need some defines. */
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28. #include <sys/un.h>
  29. #include <stdlib.h>
  30. #include <stddef.h>
  31. #include <string.h>
  32. #include <pthread.h>
  33. #include <netdb.h>
  34. #include <qadrt.h>
  35. #include <errno.h>
  36. #ifdef HAVE_ZLIB_H
  37. #include <zlib.h>
  38. #endif
  39. #ifdef USE_GSKIT
  40. #include <gskssl.h>
  41. #include <qsoasync.h>
  42. #endif
  43. #ifdef HAVE_GSSAPI
  44. #include <gssapi.h>
  45. #endif
  46. #ifndef CURL_DISABLE_LDAP
  47. #include <ldap.h>
  48. #endif
  49. #include <netinet/in.h>
  50. #include <arpa/inet.h>
  51. #include "os400sys.h"
  52. /**
  53. *** QADRT OS/400 ASCII runtime defines only the most used procedures, but
  54. *** but a lot of them are not supported. This module implements
  55. *** ASCII wrappers for those that are used by libcurl, but not
  56. *** defined by QADRT.
  57. **/
  58. #pragma convert(0) /* Restore EBCDIC. */
  59. #define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */
  60. typedef struct {
  61. unsigned long size; /* Buffer size. */
  62. char * buf; /* Buffer address. */
  63. } buffer_t;
  64. static char * buffer_undef(localkey_t key, long size);
  65. static char * buffer_threaded(localkey_t key, long size);
  66. static char * buffer_unthreaded(localkey_t key, long size);
  67. static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  68. static pthread_key_t thdkey;
  69. static buffer_t * locbufs;
  70. char * (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;
  71. static void
  72. thdbufdestroy(void * private)
  73. {
  74. if(private) {
  75. buffer_t * p = (buffer_t *) private;
  76. localkey_t i;
  77. for(i = (localkey_t) 0; i < LK_LAST; i++) {
  78. free(p->buf);
  79. p++;
  80. }
  81. free(private);
  82. }
  83. }
  84. static void
  85. terminate(void)
  86. {
  87. if(Curl_thread_buffer == buffer_threaded) {
  88. locbufs = pthread_getspecific(thdkey);
  89. pthread_setspecific(thdkey, (void *) NULL);
  90. pthread_key_delete(thdkey);
  91. }
  92. if(Curl_thread_buffer != buffer_undef) {
  93. thdbufdestroy((void *) locbufs);
  94. locbufs = (buffer_t *) NULL;
  95. }
  96. Curl_thread_buffer = buffer_undef;
  97. }
  98. static char *
  99. get_buffer(buffer_t * buf, long size)
  100. {
  101. char * cp;
  102. /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long.
  103. Return the buffer address. */
  104. if(size < 0)
  105. return buf->buf;
  106. if(!buf->buf) {
  107. buf->buf = malloc(size);
  108. if(buf->buf)
  109. buf->size = size;
  110. return buf->buf;
  111. }
  112. if((unsigned long) size <= buf->size) {
  113. /* Shorten the buffer only if it frees a significant byte count. This
  114. avoids some realloc() overhead. */
  115. if(buf->size - size < MIN_BYTE_GAIN)
  116. return buf->buf;
  117. }
  118. /* Resize the buffer. */
  119. cp = realloc(buf->buf, size);
  120. if(cp) {
  121. buf->buf = cp;
  122. buf->size = size;
  123. }
  124. else if(size <= buf->size)
  125. cp = buf->buf;
  126. return cp;
  127. }
  128. static char *
  129. buffer_unthreaded(localkey_t key, long size)
  130. {
  131. return get_buffer(locbufs + key, size);
  132. }
  133. static char *
  134. buffer_threaded(localkey_t key, long size)
  135. {
  136. buffer_t * bufs;
  137. /* Get the buffer for the given local key in the current thread, and
  138. make sure it is at least `size'-byte long. Set `size' to < 0 to get
  139. its address only. */
  140. bufs = (buffer_t *) pthread_getspecific(thdkey);
  141. if(!bufs) {
  142. if(size < 0)
  143. return (char *) NULL; /* No buffer yet. */
  144. /* Allocate buffer descriptors for the current thread. */
  145. bufs = calloc((size_t) LK_LAST, sizeof *bufs);
  146. if(!bufs)
  147. return (char *) NULL;
  148. if(pthread_setspecific(thdkey, (void *) bufs)) {
  149. free(bufs);
  150. return (char *) NULL;
  151. }
  152. }
  153. return get_buffer(bufs + key, size);
  154. }
  155. static char *
  156. buffer_undef(localkey_t key, long size)
  157. {
  158. /* Define the buffer system, get the buffer for the given local key in
  159. the current thread, and make sure it is at least `size'-byte long.
  160. Set `size' to < 0 to get its address only. */
  161. pthread_mutex_lock(&mutex);
  162. /* Determine if we can use pthread-specific data. */
  163. if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
  164. if(!pthread_key_create(&thdkey, thdbufdestroy))
  165. Curl_thread_buffer = buffer_threaded;
  166. else if(!(locbufs = calloc((size_t) LK_LAST, sizeof *locbufs))) {
  167. pthread_mutex_unlock(&mutex);
  168. return (char *) NULL;
  169. }
  170. else
  171. Curl_thread_buffer = buffer_unthreaded;
  172. atexit(terminate);
  173. }
  174. pthread_mutex_unlock(&mutex);
  175. return Curl_thread_buffer(key, size);
  176. }
  177. static char *
  178. set_thread_string(localkey_t key, const char * s)
  179. {
  180. int i;
  181. char * cp;
  182. if(!s)
  183. return (char *) NULL;
  184. i = strlen(s) + 1;
  185. cp = Curl_thread_buffer(key, MAX_CONV_EXPANSION * i + 1);
  186. if(cp) {
  187. i = QadrtConvertE2A(cp, s, MAX_CONV_EXPANSION * i, i);
  188. cp[i] = '\0';
  189. }
  190. return cp;
  191. }
  192. int
  193. Curl_getnameinfo_a(const struct sockaddr * sa, curl_socklen_t salen,
  194. char * nodename, curl_socklen_t nodenamelen,
  195. char * servname, curl_socklen_t servnamelen,
  196. int flags)
  197. {
  198. char * enodename;
  199. char * eservname;
  200. int status;
  201. int i;
  202. enodename = (char *) NULL;
  203. eservname = (char *) NULL;
  204. if(nodename && nodenamelen) {
  205. enodename = malloc(nodenamelen);
  206. if(!enodename)
  207. return EAI_MEMORY;
  208. }
  209. if(servname && servnamelen) {
  210. eservname = malloc(servnamelen);
  211. if(!eservname) {
  212. free(enodename);
  213. return EAI_MEMORY;
  214. }
  215. }
  216. status = getnameinfo(sa, salen, enodename, nodenamelen,
  217. eservname, servnamelen, flags);
  218. if(!status) {
  219. if(enodename) {
  220. i = QadrtConvertE2A(nodename, enodename,
  221. nodenamelen - 1, strlen(enodename));
  222. nodename[i] = '\0';
  223. }
  224. if(eservname) {
  225. i = QadrtConvertE2A(servname, eservname,
  226. servnamelen - 1, strlen(eservname));
  227. servname[i] = '\0';
  228. }
  229. }
  230. free(enodename);
  231. free(eservname);
  232. return status;
  233. }
  234. int
  235. Curl_getaddrinfo_a(const char * nodename, const char * servname,
  236. const struct addrinfo * hints,
  237. struct addrinfo * * res)
  238. {
  239. char * enodename;
  240. char * eservname;
  241. int status;
  242. int i;
  243. enodename = (char *) NULL;
  244. eservname = (char *) NULL;
  245. if(nodename) {
  246. i = strlen(nodename);
  247. enodename = malloc(i + 1);
  248. if(!enodename)
  249. return EAI_MEMORY;
  250. i = QadrtConvertA2E(enodename, nodename, i, i);
  251. enodename[i] = '\0';
  252. }
  253. if(servname) {
  254. i = strlen(servname);
  255. eservname = malloc(i + 1);
  256. if(!eservname) {
  257. free(enodename);
  258. return EAI_MEMORY;
  259. }
  260. QadrtConvertA2E(eservname, servname, i, i);
  261. eservname[i] = '\0';
  262. }
  263. status = getaddrinfo(enodename, eservname, hints, res);
  264. free(enodename);
  265. free(eservname);
  266. return status;
  267. }
  268. #ifdef USE_GSKIT
  269. /* ASCII wrappers for the GSKit procedures. */
  270. /*
  271. * EBCDIC --> ASCII string mapping table.
  272. * Some strings returned by GSKit are dynamically allocated and automatically
  273. * released when closing the handle.
  274. * To provide the same functionality, we use a "private" handle that
  275. * holds the GSKit handle and a list of string mappings. This will allow
  276. * avoid conversion of already converted strings and releasing them upon
  277. * close time.
  278. */
  279. struct gskstrlist {
  280. struct gskstrlist * next;
  281. const char * ebcdicstr;
  282. const char * asciistr;
  283. };
  284. struct Curl_gsk_descriptor {
  285. gsk_handle h;
  286. struct gskstrlist * strlist;
  287. };
  288. int
  289. Curl_gsk_environment_open(gsk_handle * my_env_handle)
  290. {
  291. struct Curl_gsk_descriptor * p;
  292. gsk_handle h;
  293. int rc;
  294. if(!my_env_handle)
  295. return GSK_OS400_ERROR_INVALID_POINTER;
  296. p = (struct Curl_gsk_descriptor *) malloc(sizeof *p);
  297. if(!p)
  298. return GSK_INSUFFICIENT_STORAGE;
  299. p->strlist = (struct gskstrlist *) NULL;
  300. rc = gsk_environment_open(&p->h);
  301. if(rc != GSK_OK)
  302. free(p);
  303. else
  304. *my_env_handle = (gsk_handle) p;
  305. return rc;
  306. }
  307. int
  308. Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
  309. gsk_handle * my_session_handle)
  310. {
  311. struct Curl_gsk_descriptor * p;
  312. gsk_handle h;
  313. int rc;
  314. if(!my_env_handle)
  315. return GSK_INVALID_HANDLE;
  316. if(!my_session_handle)
  317. return GSK_OS400_ERROR_INVALID_POINTER;
  318. h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
  319. p = (struct Curl_gsk_descriptor *) malloc(sizeof *p);
  320. if(!p)
  321. return GSK_INSUFFICIENT_STORAGE;
  322. p->strlist = (struct gskstrlist *) NULL;
  323. rc = gsk_secure_soc_open(h, &p->h);
  324. if(rc != GSK_OK)
  325. free(p);
  326. else
  327. *my_session_handle = (gsk_handle) p;
  328. return rc;
  329. }
  330. static void
  331. gsk_free_handle(struct Curl_gsk_descriptor * p)
  332. {
  333. struct gskstrlist * q;
  334. while((q = p->strlist)) {
  335. p->strlist = q;
  336. free((void *) q->asciistr);
  337. free(q);
  338. }
  339. free(p);
  340. }
  341. int
  342. Curl_gsk_environment_close(gsk_handle * my_env_handle)
  343. {
  344. struct Curl_gsk_descriptor * p;
  345. int rc;
  346. if(!my_env_handle)
  347. return GSK_OS400_ERROR_INVALID_POINTER;
  348. if(!*my_env_handle)
  349. return GSK_INVALID_HANDLE;
  350. p = (struct Curl_gsk_descriptor *) *my_env_handle;
  351. rc = gsk_environment_close(&p->h);
  352. if(rc == GSK_OK) {
  353. gsk_free_handle(p);
  354. *my_env_handle = (gsk_handle) NULL;
  355. }
  356. return rc;
  357. }
  358. int
  359. Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
  360. {
  361. struct Curl_gsk_descriptor * p;
  362. int rc;
  363. if(!my_session_handle)
  364. return GSK_OS400_ERROR_INVALID_POINTER;
  365. if(!*my_session_handle)
  366. return GSK_INVALID_HANDLE;
  367. p = (struct Curl_gsk_descriptor *) *my_session_handle;
  368. rc = gsk_secure_soc_close(&p->h);
  369. if(rc == GSK_OK) {
  370. gsk_free_handle(p);
  371. *my_session_handle = (gsk_handle) NULL;
  372. }
  373. return rc;
  374. }
  375. int
  376. Curl_gsk_environment_init(gsk_handle my_env_handle)
  377. {
  378. struct Curl_gsk_descriptor * p;
  379. if(!my_env_handle)
  380. return GSK_INVALID_HANDLE;
  381. p = (struct Curl_gsk_descriptor *) my_env_handle;
  382. return gsk_environment_init(p->h);
  383. }
  384. int
  385. Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
  386. {
  387. struct Curl_gsk_descriptor * p;
  388. if(!my_session_handle)
  389. return GSK_INVALID_HANDLE;
  390. p = (struct Curl_gsk_descriptor *) my_session_handle;
  391. return gsk_secure_soc_init(p->h);
  392. }
  393. int
  394. Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
  395. const char * buffer, int bufSize)
  396. {
  397. struct Curl_gsk_descriptor * p;
  398. char * ebcdicbuf;
  399. int rc;
  400. if(!my_gsk_handle)
  401. return GSK_INVALID_HANDLE;
  402. if(!buffer)
  403. return GSK_OS400_ERROR_INVALID_POINTER;
  404. if(bufSize < 0)
  405. return GSK_ATTRIBUTE_INVALID_LENGTH;
  406. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  407. if(!bufSize)
  408. bufSize = strlen(buffer);
  409. ebcdicbuf = malloc(bufSize + 1);
  410. if(!ebcdicbuf)
  411. return GSK_INSUFFICIENT_STORAGE;
  412. QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
  413. ebcdicbuf[bufSize] = '\0';
  414. rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
  415. free(ebcdicbuf);
  416. return rc;
  417. }
  418. int
  419. Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
  420. GSK_ENUM_VALUE enumValue)
  421. {
  422. struct Curl_gsk_descriptor * p;
  423. if(!my_gsk_handle)
  424. return GSK_INVALID_HANDLE;
  425. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  426. return gsk_attribute_set_enum(p->h, enumID, enumValue);
  427. }
  428. int
  429. Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
  430. GSK_NUM_ID numID, int numValue)
  431. {
  432. struct Curl_gsk_descriptor * p;
  433. if(!my_gsk_handle)
  434. return GSK_INVALID_HANDLE;
  435. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  436. return gsk_attribute_set_numeric_value(p->h, numID, numValue);
  437. }
  438. int
  439. Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
  440. GSK_CALLBACK_ID callBackID,
  441. void * callBackAreaPtr)
  442. {
  443. struct Curl_gsk_descriptor * p;
  444. if(!my_gsk_handle)
  445. return GSK_INVALID_HANDLE;
  446. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  447. return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
  448. }
  449. static int
  450. cachestring(struct Curl_gsk_descriptor * p,
  451. const char * ebcdicbuf, int bufsize, const char * * buffer)
  452. {
  453. int rc;
  454. char * asciibuf;
  455. struct gskstrlist * sp;
  456. for(sp = p->strlist; sp; sp = sp->next)
  457. if(sp->ebcdicstr == ebcdicbuf)
  458. break;
  459. if(!sp) {
  460. sp = (struct gskstrlist *) malloc(sizeof *sp);
  461. if(!sp)
  462. return GSK_INSUFFICIENT_STORAGE;
  463. asciibuf = malloc(bufsize + 1);
  464. if(!asciibuf) {
  465. free(sp);
  466. return GSK_INSUFFICIENT_STORAGE;
  467. }
  468. QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
  469. asciibuf[bufsize] = '\0';
  470. sp->ebcdicstr = ebcdicbuf;
  471. sp->asciistr = asciibuf;
  472. sp->next = p->strlist;
  473. p->strlist = sp;
  474. }
  475. *buffer = sp->asciistr;
  476. return GSK_OK;
  477. }
  478. int
  479. Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
  480. const char * * buffer, int * bufSize)
  481. {
  482. struct Curl_gsk_descriptor * p;
  483. int rc;
  484. const char * mybuf;
  485. int mylen;
  486. if(!my_gsk_handle)
  487. return GSK_INVALID_HANDLE;
  488. if(!buffer || !bufSize)
  489. return GSK_OS400_ERROR_INVALID_POINTER;
  490. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  491. rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen);
  492. if(rc != GSK_OK)
  493. return rc;
  494. rc = cachestring(p, mybuf, mylen, buffer);
  495. if(rc == GSK_OK)
  496. *bufSize = mylen;
  497. return rc;
  498. }
  499. int
  500. Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
  501. GSK_ENUM_VALUE * enumValue)
  502. {
  503. struct Curl_gsk_descriptor * p;
  504. if(!my_gsk_handle)
  505. return GSK_INVALID_HANDLE;
  506. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  507. return gsk_attribute_get_enum(p->h, enumID, enumValue);
  508. }
  509. int
  510. Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
  511. GSK_NUM_ID numID, int * numValue)
  512. {
  513. struct Curl_gsk_descriptor * p;
  514. if(!my_gsk_handle)
  515. return GSK_INVALID_HANDLE;
  516. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  517. return gsk_attribute_get_numeric_value(p->h, numID, numValue);
  518. }
  519. int
  520. Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
  521. GSK_CERT_ID certID,
  522. const gsk_cert_data_elem * * certDataElem,
  523. int * certDataElementCount)
  524. {
  525. struct Curl_gsk_descriptor * p;
  526. if(!my_gsk_handle)
  527. return GSK_INVALID_HANDLE;
  528. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  529. /* No need to convert code: text results are already in ASCII. */
  530. return gsk_attribute_get_cert_info(p->h, certID,
  531. certDataElem, certDataElementCount);
  532. }
  533. int
  534. Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
  535. {
  536. struct Curl_gsk_descriptor * p;
  537. if(!my_session_handle)
  538. return GSK_INVALID_HANDLE;
  539. p = (struct Curl_gsk_descriptor *) my_session_handle;
  540. return gsk_secure_soc_misc(p->h, miscID);
  541. }
  542. int
  543. Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
  544. int readBufSize, int * amtRead)
  545. {
  546. struct Curl_gsk_descriptor * p;
  547. if(!my_session_handle)
  548. return GSK_INVALID_HANDLE;
  549. p = (struct Curl_gsk_descriptor *) my_session_handle;
  550. return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
  551. }
  552. int
  553. Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
  554. int writeBufSize, int * amtWritten)
  555. {
  556. struct Curl_gsk_descriptor * p;
  557. if(!my_session_handle)
  558. return GSK_INVALID_HANDLE;
  559. p = (struct Curl_gsk_descriptor *) my_session_handle;
  560. return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
  561. }
  562. const char *
  563. Curl_gsk_strerror_a(int gsk_return_value)
  564. {
  565. return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
  566. }
  567. int
  568. Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
  569. int IOCompletionPort,
  570. Qso_OverlappedIO_t * communicationsArea)
  571. {
  572. struct Curl_gsk_descriptor * p;
  573. if(!my_session_handle)
  574. return GSK_INVALID_HANDLE;
  575. p = (struct Curl_gsk_descriptor *) my_session_handle;
  576. return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
  577. }
  578. #endif /* USE_GSKIT */
  579. #ifdef HAVE_GSSAPI
  580. /* ASCII wrappers for the GSSAPI procedures. */
  581. static int
  582. Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
  583. {
  584. unsigned int i;
  585. char * t;
  586. /* Convert `buf' in place, from EBCDIC to ASCII.
  587. If error, release the buffer and return -1. Else return 0. */
  588. i = buf->length;
  589. if(i) {
  590. t = malloc(i);
  591. if(!t) {
  592. gss_release_buffer(minor_status, buf);
  593. if(minor_status)
  594. *minor_status = ENOMEM;
  595. return -1;
  596. }
  597. QadrtConvertE2A(t, buf->value, i, i);
  598. memcpy(buf->value, t, i);
  599. free(t);
  600. }
  601. return 0;
  602. }
  603. OM_uint32
  604. Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
  605. gss_OID in_name_type, gss_name_t * out_name)
  606. {
  607. int rc;
  608. unsigned int i;
  609. gss_buffer_desc in;
  610. if(!in_name || !in_name->value || !in_name->length)
  611. return gss_import_name(minor_status, in_name, in_name_type, out_name);
  612. memcpy((char *) &in, (char *) in_name, sizeof in);
  613. i = in.length;
  614. in.value = malloc(i + 1);
  615. if(!in.value) {
  616. if(minor_status)
  617. *minor_status = ENOMEM;
  618. return GSS_S_FAILURE;
  619. }
  620. QadrtConvertA2E(in.value, in_name->value, i, i);
  621. ((char *) in.value)[i] = '\0';
  622. rc = gss_import_name(minor_status, &in, in_name_type, out_name);
  623. free(in.value);
  624. return rc;
  625. }
  626. OM_uint32
  627. Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
  628. int status_type, gss_OID mech_type,
  629. gss_msg_ctx_t * message_context, gss_buffer_t status_string)
  630. {
  631. int rc;
  632. rc = gss_display_status(minor_status, status_value, status_type,
  633. mech_type, message_context, status_string);
  634. if(rc != GSS_S_COMPLETE || !status_string ||
  635. !status_string->length || !status_string->value)
  636. return rc;
  637. /* No way to allocate a buffer here, because it will be released by
  638. gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
  639. with ASCII to return it. */
  640. if(Curl_gss_convert_in_place(minor_status, status_string))
  641. return GSS_S_FAILURE;
  642. return rc;
  643. }
  644. OM_uint32
  645. Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
  646. gss_cred_id_t cred_handle,
  647. gss_ctx_id_t * context_handle,
  648. gss_name_t target_name, gss_OID mech_type,
  649. gss_flags_t req_flags, OM_uint32 time_req,
  650. gss_channel_bindings_t input_chan_bindings,
  651. gss_buffer_t input_token,
  652. gss_OID * actual_mech_type,
  653. gss_buffer_t output_token, gss_flags_t * ret_flags,
  654. OM_uint32 * time_rec)
  655. {
  656. int rc;
  657. unsigned int i;
  658. gss_buffer_desc in;
  659. gss_buffer_t inp;
  660. in.value = NULL;
  661. inp = input_token;
  662. if(inp) {
  663. if(inp->length && inp->value) {
  664. i = inp->length;
  665. in.value = malloc(i + 1);
  666. if(!in.value) {
  667. if(minor_status)
  668. *minor_status = ENOMEM;
  669. return GSS_S_FAILURE;
  670. }
  671. QadrtConvertA2E(in.value, input_token->value, i, i);
  672. ((char *) in.value)[i] = '\0';
  673. in.length = i;
  674. inp = &in;
  675. }
  676. }
  677. rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
  678. target_name, mech_type, req_flags, time_req,
  679. input_chan_bindings, inp, actual_mech_type,
  680. output_token, ret_flags, time_rec);
  681. free(in.value);
  682. if(rc != GSS_S_COMPLETE || !output_token ||
  683. !output_token->length || !output_token->value)
  684. return rc;
  685. /* No way to allocate a buffer here, because it will be released by
  686. gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
  687. with ASCII to return it. */
  688. if(Curl_gss_convert_in_place(minor_status, output_token))
  689. return GSS_S_FAILURE;
  690. return rc;
  691. }
  692. OM_uint32
  693. Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
  694. gss_ctx_id_t * context_handle,
  695. gss_buffer_t output_token)
  696. {
  697. int rc;
  698. rc = gss_delete_sec_context(minor_status, context_handle, output_token);
  699. if(rc != GSS_S_COMPLETE || !output_token ||
  700. !output_token->length || !output_token->value)
  701. return rc;
  702. /* No way to allocate a buffer here, because it will be released by
  703. gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
  704. with ASCII to return it. */
  705. if(Curl_gss_convert_in_place(minor_status, output_token))
  706. return GSS_S_FAILURE;
  707. return rc;
  708. }
  709. #endif /* HAVE_GSSAPI */
  710. #ifndef CURL_DISABLE_LDAP
  711. /* ASCII wrappers for the LDAP procedures. */
  712. void *
  713. Curl_ldap_init_a(char * host, int port)
  714. {
  715. unsigned int i;
  716. char * ehost;
  717. void * result;
  718. if(!host)
  719. return (void *) ldap_init(host, port);
  720. i = strlen(host);
  721. ehost = malloc(i + 1);
  722. if(!ehost)
  723. return (void *) NULL;
  724. QadrtConvertA2E(ehost, host, i, i);
  725. ehost[i] = '\0';
  726. result = (void *) ldap_init(ehost, port);
  727. free(ehost);
  728. return result;
  729. }
  730. int
  731. Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
  732. {
  733. int i;
  734. char * edn;
  735. char * epasswd;
  736. edn = (char *) NULL;
  737. epasswd = (char *) NULL;
  738. if(dn) {
  739. i = strlen(dn);
  740. edn = malloc(i + 1);
  741. if(!edn)
  742. return LDAP_NO_MEMORY;
  743. QadrtConvertA2E(edn, dn, i, i);
  744. edn[i] = '\0';
  745. }
  746. if(passwd) {
  747. i = strlen(passwd);
  748. epasswd = malloc(i + 1);
  749. if(!epasswd) {
  750. free(edn);
  751. return LDAP_NO_MEMORY;
  752. }
  753. QadrtConvertA2E(epasswd, passwd, i, i);
  754. epasswd[i] = '\0';
  755. }
  756. i = ldap_simple_bind_s(ld, edn, epasswd);
  757. free(epasswd);
  758. free(edn);
  759. return i;
  760. }
  761. int
  762. Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
  763. char * * attrs, int attrsonly, LDAPMessage * * res)
  764. {
  765. int i;
  766. int j;
  767. char * ebase;
  768. char * efilter;
  769. char * * eattrs;
  770. int status;
  771. ebase = (char *) NULL;
  772. efilter = (char *) NULL;
  773. eattrs = (char * *) NULL;
  774. status = LDAP_SUCCESS;
  775. if(base) {
  776. i = strlen(base);
  777. ebase = malloc(i + 1);
  778. if(!ebase)
  779. status = LDAP_NO_MEMORY;
  780. else {
  781. QadrtConvertA2E(ebase, base, i, i);
  782. ebase[i] = '\0';
  783. }
  784. }
  785. if(filter && status == LDAP_SUCCESS) {
  786. i = strlen(filter);
  787. efilter = malloc(i + 1);
  788. if(!efilter)
  789. status = LDAP_NO_MEMORY;
  790. else {
  791. QadrtConvertA2E(efilter, filter, i, i);
  792. efilter[i] = '\0';
  793. }
  794. }
  795. if(attrs && status == LDAP_SUCCESS) {
  796. for(i = 0; attrs[i++];)
  797. ;
  798. eattrs = calloc(i, sizeof *eattrs);
  799. if(!eattrs)
  800. status = LDAP_NO_MEMORY;
  801. else {
  802. for(j = 0; attrs[j]; j++) {
  803. i = strlen(attrs[j]);
  804. eattrs[j] = malloc(i + 1);
  805. if(!eattrs[j]) {
  806. status = LDAP_NO_MEMORY;
  807. break;
  808. }
  809. QadrtConvertA2E(eattrs[j], attrs[j], i, i);
  810. eattrs[j][i] = '\0';
  811. }
  812. }
  813. }
  814. if(status == LDAP_SUCCESS)
  815. status = ldap_search_s(ld, ebase? ebase: "", scope,
  816. efilter? efilter: "(objectclass=*)",
  817. eattrs, attrsonly, res);
  818. if(eattrs) {
  819. for(j = 0; eattrs[j]; j++)
  820. free(eattrs[j]);
  821. free(eattrs);
  822. }
  823. free(efilter);
  824. free(ebase);
  825. return status;
  826. }
  827. struct berval * *
  828. Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
  829. {
  830. char * cp;
  831. struct berval * * result;
  832. cp = (char *) NULL;
  833. if(attr) {
  834. int i = strlen(attr);
  835. cp = malloc(i + 1);
  836. if(!cp) {
  837. ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
  838. ldap_err2string(LDAP_NO_MEMORY));
  839. return (struct berval * *) NULL;
  840. }
  841. QadrtConvertA2E(cp, attr, i, i);
  842. cp[i] = '\0';
  843. }
  844. result = ldap_get_values_len(ld, entry, cp);
  845. free(cp);
  846. /* Result data are binary in nature, so they haven't been
  847. converted to EBCDIC. Therefore do not convert. */
  848. return result;
  849. }
  850. char *
  851. Curl_ldap_err2string_a(int error)
  852. {
  853. return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
  854. }
  855. char *
  856. Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
  857. {
  858. int i;
  859. char * cp;
  860. char * cp2;
  861. cp = ldap_get_dn(ld, entry);
  862. if(!cp)
  863. return cp;
  864. i = strlen(cp);
  865. cp2 = malloc(i + 1);
  866. if(!cp2)
  867. return cp2;
  868. QadrtConvertE2A(cp2, cp, i, i);
  869. cp2[i] = '\0';
  870. /* No way to allocate a buffer here, because it will be released by
  871. ldap_memfree() and ldap_memalloc() does not exist. The solution is to
  872. overwrite the EBCDIC buffer with ASCII to return it. */
  873. strcpy(cp, cp2);
  874. free(cp2);
  875. return cp;
  876. }
  877. char *
  878. Curl_ldap_first_attribute_a(void * ld,
  879. LDAPMessage * entry, BerElement * * berptr)
  880. {
  881. int i;
  882. char * cp;
  883. char * cp2;
  884. cp = ldap_first_attribute(ld, entry, berptr);
  885. if(!cp)
  886. return cp;
  887. i = strlen(cp);
  888. cp2 = malloc(i + 1);
  889. if(!cp2)
  890. return cp2;
  891. QadrtConvertE2A(cp2, cp, i, i);
  892. cp2[i] = '\0';
  893. /* No way to allocate a buffer here, because it will be released by
  894. ldap_memfree() and ldap_memalloc() does not exist. The solution is to
  895. overwrite the EBCDIC buffer with ASCII to return it. */
  896. strcpy(cp, cp2);
  897. free(cp2);
  898. return cp;
  899. }
  900. char *
  901. Curl_ldap_next_attribute_a(void * ld,
  902. LDAPMessage * entry, BerElement * berptr)
  903. {
  904. int i;
  905. char * cp;
  906. char * cp2;
  907. cp = ldap_next_attribute(ld, entry, berptr);
  908. if(!cp)
  909. return cp;
  910. i = strlen(cp);
  911. cp2 = malloc(i + 1);
  912. if(!cp2)
  913. return cp2;
  914. QadrtConvertE2A(cp2, cp, i, i);
  915. cp2[i] = '\0';
  916. /* No way to allocate a buffer here, because it will be released by
  917. ldap_memfree() and ldap_memalloc() does not exist. The solution is to
  918. overwrite the EBCDIC buffer with ASCII to return it. */
  919. strcpy(cp, cp2);
  920. free(cp2);
  921. return cp;
  922. }
  923. #endif /* CURL_DISABLE_LDAP */
  924. static int
  925. convert_sockaddr(struct sockaddr_storage * dstaddr,
  926. const struct sockaddr * srcaddr, int srclen)
  927. {
  928. const struct sockaddr_un * srcu;
  929. struct sockaddr_un * dstu;
  930. unsigned int i;
  931. unsigned int dstsize;
  932. /* Convert a socket address into job CCSID, if needed. */
  933. if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
  934. sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
  935. errno = EINVAL;
  936. return -1;
  937. }
  938. memcpy((char *) dstaddr, (char *) srcaddr, srclen);
  939. switch (srcaddr->sa_family) {
  940. case AF_UNIX:
  941. srcu = (const struct sockaddr_un *) srcaddr;
  942. dstu = (struct sockaddr_un *) dstaddr;
  943. dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
  944. srclen -= offsetof(struct sockaddr_un, sun_path);
  945. i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
  946. dstu->sun_path[i] = '\0';
  947. i += offsetof(struct sockaddr_un, sun_path);
  948. srclen = i;
  949. }
  950. return srclen;
  951. }
  952. int
  953. Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
  954. {
  955. int i;
  956. struct sockaddr_storage laddr;
  957. i = convert_sockaddr(&laddr, destaddr, addrlen);
  958. if(i < 0)
  959. return -1;
  960. return connect(sd, (struct sockaddr *) &laddr, i);
  961. }
  962. int
  963. Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
  964. {
  965. int i;
  966. struct sockaddr_storage laddr;
  967. i = convert_sockaddr(&laddr, localaddr, addrlen);
  968. if(i < 0)
  969. return -1;
  970. return bind(sd, (struct sockaddr *) &laddr, i);
  971. }
  972. int
  973. Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
  974. struct sockaddr * dstaddr, int addrlen)
  975. {
  976. int i;
  977. struct sockaddr_storage laddr;
  978. i = convert_sockaddr(&laddr, dstaddr, addrlen);
  979. if(i < 0)
  980. return -1;
  981. return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
  982. }
  983. int
  984. Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
  985. struct sockaddr * fromaddr, int * addrlen)
  986. {
  987. int i;
  988. int rcvlen;
  989. int laddrlen;
  990. const struct sockaddr_un * srcu;
  991. struct sockaddr_un * dstu;
  992. struct sockaddr_storage laddr;
  993. if(!fromaddr || !addrlen || *addrlen <= 0)
  994. return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
  995. laddrlen = sizeof laddr;
  996. laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
  997. rcvlen = recvfrom(sd, buffer, buflen, flags,
  998. (struct sockaddr *) &laddr, &laddrlen);
  999. if(rcvlen < 0)
  1000. return rcvlen;
  1001. switch (laddr.ss_family) {
  1002. case AF_UNIX:
  1003. srcu = (const struct sockaddr_un *) &laddr;
  1004. dstu = (struct sockaddr_un *) fromaddr;
  1005. i = *addrlen - offsetof(struct sockaddr_un, sun_path);
  1006. laddrlen -= offsetof(struct sockaddr_un, sun_path);
  1007. i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
  1008. laddrlen = i + offsetof(struct sockaddr_un, sun_path);
  1009. if(laddrlen < *addrlen)
  1010. dstu->sun_path[i] = '\0';
  1011. break;
  1012. case AF_UNSPEC:
  1013. break;
  1014. default:
  1015. if(laddrlen > *addrlen)
  1016. laddrlen = *addrlen;
  1017. if(laddrlen)
  1018. memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
  1019. break;
  1020. }
  1021. *addrlen = laddrlen;
  1022. return rcvlen;
  1023. }
  1024. #ifdef HAVE_LIBZ
  1025. const char *
  1026. Curl_os400_zlibVersion(void)
  1027. {
  1028. return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
  1029. }
  1030. int
  1031. Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
  1032. {
  1033. z_const char * msgb4 = strm->msg;
  1034. int ret;
  1035. ret = inflateInit(strm);
  1036. if(strm->msg != msgb4)
  1037. strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
  1038. return ret;
  1039. }
  1040. int
  1041. Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
  1042. const char * version, int stream_size)
  1043. {
  1044. z_const char * msgb4 = strm->msg;
  1045. int ret;
  1046. ret = inflateInit2(strm, windowBits);
  1047. if(strm->msg != msgb4)
  1048. strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
  1049. return ret;
  1050. }
  1051. int
  1052. Curl_os400_inflate(z_streamp strm, int flush)
  1053. {
  1054. z_const char * msgb4 = strm->msg;
  1055. int ret;
  1056. ret = inflate(strm, flush);
  1057. if(strm->msg != msgb4)
  1058. strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
  1059. return ret;
  1060. }
  1061. int
  1062. Curl_os400_inflateEnd(z_streamp strm)
  1063. {
  1064. z_const char * msgb4 = strm->msg;
  1065. int ret;
  1066. ret = inflateEnd(strm);
  1067. if(strm->msg != msgb4)
  1068. strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
  1069. return ret;
  1070. }
  1071. #endif