os400sys.c 30 KB

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