os400sys.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451
  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. int rc;
  293. if(!my_env_handle)
  294. return GSK_OS400_ERROR_INVALID_POINTER;
  295. p = (struct Curl_gsk_descriptor *) malloc(sizeof *p);
  296. if(!p)
  297. return GSK_INSUFFICIENT_STORAGE;
  298. p->strlist = (struct gskstrlist *) NULL;
  299. rc = gsk_environment_open(&p->h);
  300. if(rc != GSK_OK)
  301. free(p);
  302. else
  303. *my_env_handle = (gsk_handle) p;
  304. return rc;
  305. }
  306. int
  307. Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
  308. gsk_handle * my_session_handle)
  309. {
  310. struct Curl_gsk_descriptor * p;
  311. gsk_handle h;
  312. int rc;
  313. if(!my_env_handle)
  314. return GSK_INVALID_HANDLE;
  315. if(!my_session_handle)
  316. return GSK_OS400_ERROR_INVALID_POINTER;
  317. h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
  318. p = (struct Curl_gsk_descriptor *) malloc(sizeof *p);
  319. if(!p)
  320. return GSK_INSUFFICIENT_STORAGE;
  321. p->strlist = (struct gskstrlist *) NULL;
  322. rc = gsk_secure_soc_open(h, &p->h);
  323. if(rc != GSK_OK)
  324. free(p);
  325. else
  326. *my_session_handle = (gsk_handle) p;
  327. return rc;
  328. }
  329. static void
  330. gsk_free_handle(struct Curl_gsk_descriptor * p)
  331. {
  332. struct gskstrlist * q;
  333. while((q = p->strlist)) {
  334. p->strlist = q;
  335. free((void *) q->asciistr);
  336. free(q);
  337. }
  338. free(p);
  339. }
  340. int
  341. Curl_gsk_environment_close(gsk_handle * my_env_handle)
  342. {
  343. struct Curl_gsk_descriptor * p;
  344. int rc;
  345. if(!my_env_handle)
  346. return GSK_OS400_ERROR_INVALID_POINTER;
  347. if(!*my_env_handle)
  348. return GSK_INVALID_HANDLE;
  349. p = (struct Curl_gsk_descriptor *) *my_env_handle;
  350. rc = gsk_environment_close(&p->h);
  351. if(rc == GSK_OK) {
  352. gsk_free_handle(p);
  353. *my_env_handle = (gsk_handle) NULL;
  354. }
  355. return rc;
  356. }
  357. int
  358. Curl_gsk_secure_soc_close(gsk_handle * my_session_handle)
  359. {
  360. struct Curl_gsk_descriptor * p;
  361. int rc;
  362. if(!my_session_handle)
  363. return GSK_OS400_ERROR_INVALID_POINTER;
  364. if(!*my_session_handle)
  365. return GSK_INVALID_HANDLE;
  366. p = (struct Curl_gsk_descriptor *) *my_session_handle;
  367. rc = gsk_secure_soc_close(&p->h);
  368. if(rc == GSK_OK) {
  369. gsk_free_handle(p);
  370. *my_session_handle = (gsk_handle) NULL;
  371. }
  372. return rc;
  373. }
  374. int
  375. Curl_gsk_environment_init(gsk_handle my_env_handle)
  376. {
  377. struct Curl_gsk_descriptor * p;
  378. if(!my_env_handle)
  379. return GSK_INVALID_HANDLE;
  380. p = (struct Curl_gsk_descriptor *) my_env_handle;
  381. return gsk_environment_init(p->h);
  382. }
  383. int
  384. Curl_gsk_secure_soc_init(gsk_handle my_session_handle)
  385. {
  386. struct Curl_gsk_descriptor * p;
  387. if(!my_session_handle)
  388. return GSK_INVALID_HANDLE;
  389. p = (struct Curl_gsk_descriptor *) my_session_handle;
  390. return gsk_secure_soc_init(p->h);
  391. }
  392. int
  393. Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
  394. const char * buffer, int bufSize)
  395. {
  396. struct Curl_gsk_descriptor * p;
  397. char * ebcdicbuf;
  398. int rc;
  399. if(!my_gsk_handle)
  400. return GSK_INVALID_HANDLE;
  401. if(!buffer)
  402. return GSK_OS400_ERROR_INVALID_POINTER;
  403. if(bufSize < 0)
  404. return GSK_ATTRIBUTE_INVALID_LENGTH;
  405. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  406. if(!bufSize)
  407. bufSize = strlen(buffer);
  408. ebcdicbuf = malloc(bufSize + 1);
  409. if(!ebcdicbuf)
  410. return GSK_INSUFFICIENT_STORAGE;
  411. QadrtConvertA2E(ebcdicbuf, buffer, bufSize, bufSize);
  412. ebcdicbuf[bufSize] = '\0';
  413. rc = gsk_attribute_set_buffer(p->h, bufID, ebcdicbuf, bufSize);
  414. free(ebcdicbuf);
  415. return rc;
  416. }
  417. int
  418. Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
  419. GSK_ENUM_VALUE enumValue)
  420. {
  421. struct Curl_gsk_descriptor * p;
  422. if(!my_gsk_handle)
  423. return GSK_INVALID_HANDLE;
  424. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  425. return gsk_attribute_set_enum(p->h, enumID, enumValue);
  426. }
  427. int
  428. Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
  429. GSK_NUM_ID numID, int numValue)
  430. {
  431. struct Curl_gsk_descriptor * p;
  432. if(!my_gsk_handle)
  433. return GSK_INVALID_HANDLE;
  434. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  435. return gsk_attribute_set_numeric_value(p->h, numID, numValue);
  436. }
  437. int
  438. Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
  439. GSK_CALLBACK_ID callBackID,
  440. void * callBackAreaPtr)
  441. {
  442. struct Curl_gsk_descriptor * p;
  443. if(!my_gsk_handle)
  444. return GSK_INVALID_HANDLE;
  445. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  446. return gsk_attribute_set_callback(p->h, callBackID, callBackAreaPtr);
  447. }
  448. static int
  449. cachestring(struct Curl_gsk_descriptor * p,
  450. const char * ebcdicbuf, int bufsize, const char * * buffer)
  451. {
  452. int rc;
  453. char * asciibuf;
  454. struct gskstrlist * sp;
  455. for(sp = p->strlist; sp; sp = sp->next)
  456. if(sp->ebcdicstr == ebcdicbuf)
  457. break;
  458. if(!sp) {
  459. sp = (struct gskstrlist *) malloc(sizeof *sp);
  460. if(!sp)
  461. return GSK_INSUFFICIENT_STORAGE;
  462. asciibuf = malloc(bufsize + 1);
  463. if(!asciibuf) {
  464. free(sp);
  465. return GSK_INSUFFICIENT_STORAGE;
  466. }
  467. QadrtConvertE2A(asciibuf, ebcdicbuf, bufsize, bufsize);
  468. asciibuf[bufsize] = '\0';
  469. sp->ebcdicstr = ebcdicbuf;
  470. sp->asciistr = asciibuf;
  471. sp->next = p->strlist;
  472. p->strlist = sp;
  473. }
  474. *buffer = sp->asciistr;
  475. return GSK_OK;
  476. }
  477. int
  478. Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, GSK_BUF_ID bufID,
  479. const char * * buffer, int * bufSize)
  480. {
  481. struct Curl_gsk_descriptor * p;
  482. int rc;
  483. const char * mybuf;
  484. int mylen;
  485. if(!my_gsk_handle)
  486. return GSK_INVALID_HANDLE;
  487. if(!buffer || !bufSize)
  488. return GSK_OS400_ERROR_INVALID_POINTER;
  489. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  490. rc = gsk_attribute_get_buffer(p->h, bufID, &mybuf, &mylen);
  491. if(rc != GSK_OK)
  492. return rc;
  493. rc = cachestring(p, mybuf, mylen, buffer);
  494. if(rc == GSK_OK)
  495. *bufSize = mylen;
  496. return rc;
  497. }
  498. int
  499. Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, GSK_ENUM_ID enumID,
  500. GSK_ENUM_VALUE * enumValue)
  501. {
  502. struct Curl_gsk_descriptor * p;
  503. if(!my_gsk_handle)
  504. return GSK_INVALID_HANDLE;
  505. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  506. return gsk_attribute_get_enum(p->h, enumID, enumValue);
  507. }
  508. int
  509. Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
  510. GSK_NUM_ID numID, int * numValue)
  511. {
  512. struct Curl_gsk_descriptor * p;
  513. if(!my_gsk_handle)
  514. return GSK_INVALID_HANDLE;
  515. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  516. return gsk_attribute_get_numeric_value(p->h, numID, numValue);
  517. }
  518. int
  519. Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
  520. GSK_CERT_ID certID,
  521. const gsk_cert_data_elem * * certDataElem,
  522. int * certDataElementCount)
  523. {
  524. struct Curl_gsk_descriptor * p;
  525. if(!my_gsk_handle)
  526. return GSK_INVALID_HANDLE;
  527. p = (struct Curl_gsk_descriptor *) my_gsk_handle;
  528. /* No need to convert code: text results are already in ASCII. */
  529. return gsk_attribute_get_cert_info(p->h, certID,
  530. certDataElem, certDataElementCount);
  531. }
  532. int
  533. Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, GSK_MISC_ID miscID)
  534. {
  535. struct Curl_gsk_descriptor * p;
  536. if(!my_session_handle)
  537. return GSK_INVALID_HANDLE;
  538. p = (struct Curl_gsk_descriptor *) my_session_handle;
  539. return gsk_secure_soc_misc(p->h, miscID);
  540. }
  541. int
  542. Curl_gsk_secure_soc_read(gsk_handle my_session_handle, char * readBuffer,
  543. int readBufSize, int * amtRead)
  544. {
  545. struct Curl_gsk_descriptor * p;
  546. if(!my_session_handle)
  547. return GSK_INVALID_HANDLE;
  548. p = (struct Curl_gsk_descriptor *) my_session_handle;
  549. return gsk_secure_soc_read(p->h, readBuffer, readBufSize, amtRead);
  550. }
  551. int
  552. Curl_gsk_secure_soc_write(gsk_handle my_session_handle, char * writeBuffer,
  553. int writeBufSize, int * amtWritten)
  554. {
  555. struct Curl_gsk_descriptor * p;
  556. if(!my_session_handle)
  557. return GSK_INVALID_HANDLE;
  558. p = (struct Curl_gsk_descriptor *) my_session_handle;
  559. return gsk_secure_soc_write(p->h, writeBuffer, writeBufSize, amtWritten);
  560. }
  561. const char *
  562. Curl_gsk_strerror_a(int gsk_return_value)
  563. {
  564. return set_thread_string(LK_GSK_ERROR, gsk_strerror(gsk_return_value));
  565. }
  566. int
  567. Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
  568. int IOCompletionPort,
  569. Qso_OverlappedIO_t * communicationsArea)
  570. {
  571. struct Curl_gsk_descriptor * p;
  572. if(!my_session_handle)
  573. return GSK_INVALID_HANDLE;
  574. p = (struct Curl_gsk_descriptor *) my_session_handle;
  575. return gsk_secure_soc_startInit(p->h, IOCompletionPort, communicationsArea);
  576. }
  577. #endif /* USE_GSKIT */
  578. #ifdef HAVE_GSSAPI
  579. /* ASCII wrappers for the GSSAPI procedures. */
  580. static int
  581. Curl_gss_convert_in_place(OM_uint32 * minor_status, gss_buffer_t buf)
  582. {
  583. unsigned int i;
  584. char * t;
  585. /* Convert `buf' in place, from EBCDIC to ASCII.
  586. If error, release the buffer and return -1. Else return 0. */
  587. i = buf->length;
  588. if(i) {
  589. t = malloc(i);
  590. if(!t) {
  591. gss_release_buffer(minor_status, buf);
  592. if(minor_status)
  593. *minor_status = ENOMEM;
  594. return -1;
  595. }
  596. QadrtConvertE2A(t, buf->value, i, i);
  597. memcpy(buf->value, t, i);
  598. free(t);
  599. }
  600. return 0;
  601. }
  602. OM_uint32
  603. Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
  604. gss_OID in_name_type, gss_name_t * out_name)
  605. {
  606. int rc;
  607. unsigned int i;
  608. gss_buffer_desc in;
  609. if(!in_name || !in_name->value || !in_name->length)
  610. return gss_import_name(minor_status, in_name, in_name_type, out_name);
  611. memcpy((char *) &in, (char *) in_name, sizeof in);
  612. i = in.length;
  613. in.value = malloc(i + 1);
  614. if(!in.value) {
  615. if(minor_status)
  616. *minor_status = ENOMEM;
  617. return GSS_S_FAILURE;
  618. }
  619. QadrtConvertA2E(in.value, in_name->value, i, i);
  620. ((char *) in.value)[i] = '\0';
  621. rc = gss_import_name(minor_status, &in, in_name_type, out_name);
  622. free(in.value);
  623. return rc;
  624. }
  625. OM_uint32
  626. Curl_gss_display_status_a(OM_uint32 * minor_status, OM_uint32 status_value,
  627. int status_type, gss_OID mech_type,
  628. gss_msg_ctx_t * message_context, gss_buffer_t status_string)
  629. {
  630. int rc;
  631. rc = gss_display_status(minor_status, status_value, status_type,
  632. mech_type, message_context, status_string);
  633. if(rc != GSS_S_COMPLETE || !status_string ||
  634. !status_string->length || !status_string->value)
  635. return rc;
  636. /* No way to allocate a buffer here, because it will be released by
  637. gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
  638. with ASCII to return it. */
  639. if(Curl_gss_convert_in_place(minor_status, status_string))
  640. return GSS_S_FAILURE;
  641. return rc;
  642. }
  643. OM_uint32
  644. Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
  645. gss_cred_id_t cred_handle,
  646. gss_ctx_id_t * context_handle,
  647. gss_name_t target_name, gss_OID mech_type,
  648. gss_flags_t req_flags, OM_uint32 time_req,
  649. gss_channel_bindings_t input_chan_bindings,
  650. gss_buffer_t input_token,
  651. gss_OID * actual_mech_type,
  652. gss_buffer_t output_token, gss_flags_t * ret_flags,
  653. OM_uint32 * time_rec)
  654. {
  655. int rc;
  656. unsigned int i;
  657. gss_buffer_desc in;
  658. gss_buffer_t inp;
  659. in.value = NULL;
  660. inp = input_token;
  661. if(inp) {
  662. if(inp->length && inp->value) {
  663. i = inp->length;
  664. in.value = malloc(i + 1);
  665. if(!in.value) {
  666. if(minor_status)
  667. *minor_status = ENOMEM;
  668. return GSS_S_FAILURE;
  669. }
  670. QadrtConvertA2E(in.value, input_token->value, i, i);
  671. ((char *) in.value)[i] = '\0';
  672. in.length = i;
  673. inp = &in;
  674. }
  675. }
  676. rc = gss_init_sec_context(minor_status, cred_handle, context_handle,
  677. target_name, mech_type, req_flags, time_req,
  678. input_chan_bindings, inp, actual_mech_type,
  679. output_token, ret_flags, time_rec);
  680. free(in.value);
  681. if(rc != GSS_S_COMPLETE || !output_token ||
  682. !output_token->length || !output_token->value)
  683. return rc;
  684. /* No way to allocate a buffer here, because it will be released by
  685. gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
  686. with ASCII to return it. */
  687. if(Curl_gss_convert_in_place(minor_status, output_token))
  688. return GSS_S_FAILURE;
  689. return rc;
  690. }
  691. OM_uint32
  692. Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
  693. gss_ctx_id_t * context_handle,
  694. gss_buffer_t output_token)
  695. {
  696. int rc;
  697. rc = gss_delete_sec_context(minor_status, context_handle, output_token);
  698. if(rc != GSS_S_COMPLETE || !output_token ||
  699. !output_token->length || !output_token->value)
  700. return rc;
  701. /* No way to allocate a buffer here, because it will be released by
  702. gss_release_buffer(). The solution is to overwrite the EBCDIC buffer
  703. with ASCII to return it. */
  704. if(Curl_gss_convert_in_place(minor_status, output_token))
  705. return GSS_S_FAILURE;
  706. return rc;
  707. }
  708. #endif /* HAVE_GSSAPI */
  709. #ifndef CURL_DISABLE_LDAP
  710. /* ASCII wrappers for the LDAP procedures. */
  711. void *
  712. Curl_ldap_init_a(char * host, int port)
  713. {
  714. unsigned int i;
  715. char * ehost;
  716. void * result;
  717. if(!host)
  718. return (void *) ldap_init(host, port);
  719. i = strlen(host);
  720. ehost = malloc(i + 1);
  721. if(!ehost)
  722. return (void *) NULL;
  723. QadrtConvertA2E(ehost, host, i, i);
  724. ehost[i] = '\0';
  725. result = (void *) ldap_init(ehost, port);
  726. free(ehost);
  727. return result;
  728. }
  729. int
  730. Curl_ldap_simple_bind_s_a(void * ld, char * dn, char * passwd)
  731. {
  732. int i;
  733. char * edn;
  734. char * epasswd;
  735. edn = (char *) NULL;
  736. epasswd = (char *) NULL;
  737. if(dn) {
  738. i = strlen(dn);
  739. edn = malloc(i + 1);
  740. if(!edn)
  741. return LDAP_NO_MEMORY;
  742. QadrtConvertA2E(edn, dn, i, i);
  743. edn[i] = '\0';
  744. }
  745. if(passwd) {
  746. i = strlen(passwd);
  747. epasswd = malloc(i + 1);
  748. if(!epasswd) {
  749. free(edn);
  750. return LDAP_NO_MEMORY;
  751. }
  752. QadrtConvertA2E(epasswd, passwd, i, i);
  753. epasswd[i] = '\0';
  754. }
  755. i = ldap_simple_bind_s(ld, edn, epasswd);
  756. free(epasswd);
  757. free(edn);
  758. return i;
  759. }
  760. int
  761. Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
  762. char * * attrs, int attrsonly, LDAPMessage * * res)
  763. {
  764. int i;
  765. int j;
  766. char * ebase;
  767. char * efilter;
  768. char * * eattrs;
  769. int status;
  770. ebase = (char *) NULL;
  771. efilter = (char *) NULL;
  772. eattrs = (char * *) NULL;
  773. status = LDAP_SUCCESS;
  774. if(base) {
  775. i = strlen(base);
  776. ebase = malloc(i + 1);
  777. if(!ebase)
  778. status = LDAP_NO_MEMORY;
  779. else {
  780. QadrtConvertA2E(ebase, base, i, i);
  781. ebase[i] = '\0';
  782. }
  783. }
  784. if(filter && status == LDAP_SUCCESS) {
  785. i = strlen(filter);
  786. efilter = malloc(i + 1);
  787. if(!efilter)
  788. status = LDAP_NO_MEMORY;
  789. else {
  790. QadrtConvertA2E(efilter, filter, i, i);
  791. efilter[i] = '\0';
  792. }
  793. }
  794. if(attrs && status == LDAP_SUCCESS) {
  795. for(i = 0; attrs[i++];)
  796. ;
  797. eattrs = calloc(i, sizeof *eattrs);
  798. if(!eattrs)
  799. status = LDAP_NO_MEMORY;
  800. else {
  801. for(j = 0; attrs[j]; j++) {
  802. i = strlen(attrs[j]);
  803. eattrs[j] = malloc(i + 1);
  804. if(!eattrs[j]) {
  805. status = LDAP_NO_MEMORY;
  806. break;
  807. }
  808. QadrtConvertA2E(eattrs[j], attrs[j], i, i);
  809. eattrs[j][i] = '\0';
  810. }
  811. }
  812. }
  813. if(status == LDAP_SUCCESS)
  814. status = ldap_search_s(ld, ebase? ebase: "", scope,
  815. efilter? efilter: "(objectclass=*)",
  816. eattrs, attrsonly, res);
  817. if(eattrs) {
  818. for(j = 0; eattrs[j]; j++)
  819. free(eattrs[j]);
  820. free(eattrs);
  821. }
  822. free(efilter);
  823. free(ebase);
  824. return status;
  825. }
  826. struct berval * *
  827. Curl_ldap_get_values_len_a(void * ld, LDAPMessage * entry, const char * attr)
  828. {
  829. char * cp;
  830. struct berval * * result;
  831. cp = (char *) NULL;
  832. if(attr) {
  833. int i = strlen(attr);
  834. cp = malloc(i + 1);
  835. if(!cp) {
  836. ldap_set_lderrno(ld, LDAP_NO_MEMORY, NULL,
  837. ldap_err2string(LDAP_NO_MEMORY));
  838. return (struct berval * *) NULL;
  839. }
  840. QadrtConvertA2E(cp, attr, i, i);
  841. cp[i] = '\0';
  842. }
  843. result = ldap_get_values_len(ld, entry, cp);
  844. free(cp);
  845. /* Result data are binary in nature, so they haven't been
  846. converted to EBCDIC. Therefore do not convert. */
  847. return result;
  848. }
  849. char *
  850. Curl_ldap_err2string_a(int error)
  851. {
  852. return set_thread_string(LK_LDAP_ERROR, ldap_err2string(error));
  853. }
  854. char *
  855. Curl_ldap_get_dn_a(void * ld, LDAPMessage * entry)
  856. {
  857. int i;
  858. char * cp;
  859. char * cp2;
  860. cp = ldap_get_dn(ld, entry);
  861. if(!cp)
  862. return cp;
  863. i = strlen(cp);
  864. cp2 = malloc(i + 1);
  865. if(!cp2)
  866. return cp2;
  867. QadrtConvertE2A(cp2, cp, i, i);
  868. cp2[i] = '\0';
  869. /* No way to allocate a buffer here, because it will be released by
  870. ldap_memfree() and ldap_memalloc() does not exist. The solution is to
  871. overwrite the EBCDIC buffer with ASCII to return it. */
  872. strcpy(cp, cp2);
  873. free(cp2);
  874. return cp;
  875. }
  876. char *
  877. Curl_ldap_first_attribute_a(void * ld,
  878. LDAPMessage * entry, BerElement * * berptr)
  879. {
  880. int i;
  881. char * cp;
  882. char * cp2;
  883. cp = ldap_first_attribute(ld, entry, berptr);
  884. if(!cp)
  885. return cp;
  886. i = strlen(cp);
  887. cp2 = malloc(i + 1);
  888. if(!cp2)
  889. return cp2;
  890. QadrtConvertE2A(cp2, cp, i, i);
  891. cp2[i] = '\0';
  892. /* No way to allocate a buffer here, because it will be released by
  893. ldap_memfree() and ldap_memalloc() does not exist. The solution is to
  894. overwrite the EBCDIC buffer with ASCII to return it. */
  895. strcpy(cp, cp2);
  896. free(cp2);
  897. return cp;
  898. }
  899. char *
  900. Curl_ldap_next_attribute_a(void * ld,
  901. LDAPMessage * entry, BerElement * berptr)
  902. {
  903. int i;
  904. char * cp;
  905. char * cp2;
  906. cp = ldap_next_attribute(ld, entry, berptr);
  907. if(!cp)
  908. return cp;
  909. i = strlen(cp);
  910. cp2 = malloc(i + 1);
  911. if(!cp2)
  912. return cp2;
  913. QadrtConvertE2A(cp2, cp, i, i);
  914. cp2[i] = '\0';
  915. /* No way to allocate a buffer here, because it will be released by
  916. ldap_memfree() and ldap_memalloc() does not exist. The solution is to
  917. overwrite the EBCDIC buffer with ASCII to return it. */
  918. strcpy(cp, cp2);
  919. free(cp2);
  920. return cp;
  921. }
  922. #endif /* CURL_DISABLE_LDAP */
  923. static int
  924. convert_sockaddr(struct sockaddr_storage * dstaddr,
  925. const struct sockaddr * srcaddr, int srclen)
  926. {
  927. const struct sockaddr_un * srcu;
  928. struct sockaddr_un * dstu;
  929. unsigned int i;
  930. unsigned int dstsize;
  931. /* Convert a socket address into job CCSID, if needed. */
  932. if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
  933. sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
  934. errno = EINVAL;
  935. return -1;
  936. }
  937. memcpy((char *) dstaddr, (char *) srcaddr, srclen);
  938. switch (srcaddr->sa_family) {
  939. case AF_UNIX:
  940. srcu = (const struct sockaddr_un *) srcaddr;
  941. dstu = (struct sockaddr_un *) dstaddr;
  942. dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
  943. srclen -= offsetof(struct sockaddr_un, sun_path);
  944. i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
  945. dstu->sun_path[i] = '\0';
  946. i += offsetof(struct sockaddr_un, sun_path);
  947. srclen = i;
  948. }
  949. return srclen;
  950. }
  951. int
  952. Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
  953. {
  954. int i;
  955. struct sockaddr_storage laddr;
  956. i = convert_sockaddr(&laddr, destaddr, addrlen);
  957. if(i < 0)
  958. return -1;
  959. return connect(sd, (struct sockaddr *) &laddr, i);
  960. }
  961. int
  962. Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
  963. {
  964. int i;
  965. struct sockaddr_storage laddr;
  966. i = convert_sockaddr(&laddr, localaddr, addrlen);
  967. if(i < 0)
  968. return -1;
  969. return bind(sd, (struct sockaddr *) &laddr, i);
  970. }
  971. int
  972. Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
  973. struct sockaddr * dstaddr, int addrlen)
  974. {
  975. int i;
  976. struct sockaddr_storage laddr;
  977. i = convert_sockaddr(&laddr, dstaddr, addrlen);
  978. if(i < 0)
  979. return -1;
  980. return sendto(sd, buffer, buflen, flags, (struct sockaddr *) &laddr, i);
  981. }
  982. int
  983. Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
  984. struct sockaddr * fromaddr, int * addrlen)
  985. {
  986. int i;
  987. int rcvlen;
  988. int laddrlen;
  989. const struct sockaddr_un * srcu;
  990. struct sockaddr_un * dstu;
  991. struct sockaddr_storage laddr;
  992. if(!fromaddr || !addrlen || *addrlen <= 0)
  993. return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
  994. laddrlen = sizeof laddr;
  995. laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
  996. rcvlen = recvfrom(sd, buffer, buflen, flags,
  997. (struct sockaddr *) &laddr, &laddrlen);
  998. if(rcvlen < 0)
  999. return rcvlen;
  1000. switch (laddr.ss_family) {
  1001. case AF_UNIX:
  1002. srcu = (const struct sockaddr_un *) &laddr;
  1003. dstu = (struct sockaddr_un *) fromaddr;
  1004. i = *addrlen - offsetof(struct sockaddr_un, sun_path);
  1005. laddrlen -= offsetof(struct sockaddr_un, sun_path);
  1006. i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
  1007. laddrlen = i + offsetof(struct sockaddr_un, sun_path);
  1008. if(laddrlen < *addrlen)
  1009. dstu->sun_path[i] = '\0';
  1010. break;
  1011. case AF_UNSPEC:
  1012. break;
  1013. default:
  1014. if(laddrlen > *addrlen)
  1015. laddrlen = *addrlen;
  1016. if(laddrlen)
  1017. memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
  1018. break;
  1019. }
  1020. *addrlen = laddrlen;
  1021. return rcvlen;
  1022. }
  1023. #ifdef HAVE_LIBZ
  1024. const char *
  1025. Curl_os400_zlibVersion(void)
  1026. {
  1027. return set_thread_string(LK_ZLIB_VERSION, zlibVersion());
  1028. }
  1029. int
  1030. Curl_os400_inflateInit_(z_streamp strm, const char * version, int stream_size)
  1031. {
  1032. z_const char * msgb4 = strm->msg;
  1033. int ret;
  1034. ret = inflateInit(strm);
  1035. if(strm->msg != msgb4)
  1036. strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
  1037. return ret;
  1038. }
  1039. int
  1040. Curl_os400_inflateInit2_(z_streamp strm, int windowBits,
  1041. const char * version, int stream_size)
  1042. {
  1043. z_const char * msgb4 = strm->msg;
  1044. int ret;
  1045. ret = inflateInit2(strm, windowBits);
  1046. if(strm->msg != msgb4)
  1047. strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
  1048. return ret;
  1049. }
  1050. int
  1051. Curl_os400_inflate(z_streamp strm, int flush)
  1052. {
  1053. z_const char * msgb4 = strm->msg;
  1054. int ret;
  1055. ret = inflate(strm, flush);
  1056. if(strm->msg != msgb4)
  1057. strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
  1058. return ret;
  1059. }
  1060. int
  1061. Curl_os400_inflateEnd(z_streamp strm)
  1062. {
  1063. z_const char * msgb4 = strm->msg;
  1064. int ret;
  1065. ret = inflateEnd(strm);
  1066. if(strm->msg != msgb4)
  1067. strm->msg = set_thread_string(LK_ZLIB_MSG, strm->msg);
  1068. return ret;
  1069. }
  1070. #endif