http_ntlm.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2009, 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 http://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. * $Id$
  22. ***************************************************************************/
  23. #include "setup.h"
  24. /* NTLM details:
  25. http://davenport.sourceforge.net/ntlm.html
  26. http://www.innovation.ch/java/ntlm.html
  27. Another implementation:
  28. http://lxr.mozilla.org/mozilla/source/security/manager/ssl/src/nsNTLMAuthModule.cpp
  29. */
  30. #ifndef CURL_DISABLE_HTTP
  31. #ifdef USE_NTLM
  32. #define DEBUG_ME 0
  33. /* -- WIN32 approved -- */
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <stdarg.h>
  37. #include <stdlib.h>
  38. #include <ctype.h>
  39. #ifdef HAVE_UNISTD_H
  40. #include <unistd.h>
  41. #endif
  42. #if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
  43. #include <netdb.h>
  44. #endif
  45. #include "urldata.h"
  46. #include "easyif.h" /* for Curl_convert_... prototypes */
  47. #include "sendf.h"
  48. #include "rawstr.h"
  49. #include "curl_base64.h"
  50. #include "http_ntlm.h"
  51. #include "url.h"
  52. #include "curl_memory.h"
  53. #define _MPRINTF_REPLACE /* use our functions only */
  54. #include <curl/mprintf.h>
  55. /* "NTLMSSP" signature is always in ASCII regardless of the platform */
  56. #define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
  57. #ifdef USE_SSLEAY
  58. #include "ssluse.h"
  59. # ifdef USE_OPENSSL
  60. # include <openssl/des.h>
  61. # include <openssl/md4.h>
  62. # include <openssl/md5.h>
  63. # include <openssl/ssl.h>
  64. # include <openssl/rand.h>
  65. # else
  66. # include <des.h>
  67. # include <md4.h>
  68. # include <md5.h>
  69. # include <ssl.h>
  70. # include <rand.h>
  71. # endif
  72. #if OPENSSL_VERSION_NUMBER < 0x00907001L
  73. #define DES_key_schedule des_key_schedule
  74. #define DES_cblock des_cblock
  75. #define DES_set_odd_parity des_set_odd_parity
  76. #define DES_set_key des_set_key
  77. #define DES_ecb_encrypt des_ecb_encrypt
  78. /* This is how things were done in the old days */
  79. #define DESKEY(x) x
  80. #define DESKEYARG(x) x
  81. #else
  82. /* Modern version */
  83. #define DESKEYARG(x) *x
  84. #define DESKEY(x) &x
  85. #endif
  86. #elif defined(USE_GNUTLS)
  87. #include "gtls.h"
  88. #include <gcrypt.h>
  89. #define MD5_DIGEST_LENGTH 16
  90. #define MD4_DIGEST_LENGTH 16
  91. #elif defined(USE_WINDOWS_SSPI)
  92. #include "curl_sspi.h"
  93. #else
  94. # error "Can't compile NTLM support without a crypto library."
  95. #endif
  96. /* The last #include file should be: */
  97. #include "memdebug.h"
  98. /* Define this to make the type-3 message include the NT response message */
  99. #define USE_NTRESPONSES 1
  100. /* Define this to make the type-3 message include the NTLM2Session response
  101. message, requires USE_NTRESPONSES. */
  102. #define USE_NTLM2SESSION 1
  103. #ifndef USE_WINDOWS_SSPI
  104. /* this function converts from the little endian format used in the incoming
  105. package to whatever endian format we're using natively */
  106. static unsigned int readint_le(unsigned char *buf) /* must point to a
  107. 4 bytes buffer*/
  108. {
  109. return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
  110. ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
  111. }
  112. #endif
  113. #if DEBUG_ME
  114. # define DEBUG_OUT(x) x
  115. static void print_flags(FILE *handle, unsigned long flags)
  116. {
  117. if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
  118. fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
  119. if(flags & NTLMFLAG_NEGOTIATE_OEM)
  120. fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
  121. if(flags & NTLMFLAG_REQUEST_TARGET)
  122. fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
  123. if(flags & (1<<3))
  124. fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
  125. if(flags & NTLMFLAG_NEGOTIATE_SIGN)
  126. fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
  127. if(flags & NTLMFLAG_NEGOTIATE_SEAL)
  128. fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
  129. if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
  130. fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
  131. if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
  132. fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
  133. if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
  134. fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE ");
  135. if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
  136. fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
  137. if(flags & (1<<10))
  138. fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
  139. if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS)
  140. fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS ");
  141. if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
  142. fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
  143. if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
  144. fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
  145. if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
  146. fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
  147. if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
  148. fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
  149. if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
  150. fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
  151. if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
  152. fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
  153. if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
  154. fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
  155. if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
  156. fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
  157. if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
  158. fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
  159. if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
  160. fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
  161. if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
  162. fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
  163. if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
  164. fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
  165. if(flags & (1<<24))
  166. fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
  167. if(flags & (1<<25))
  168. fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
  169. if(flags & (1<<26))
  170. fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
  171. if(flags & (1<<27))
  172. fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
  173. if(flags & (1<<28))
  174. fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
  175. if(flags & NTLMFLAG_NEGOTIATE_128)
  176. fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
  177. if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
  178. fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
  179. if(flags & NTLMFLAG_NEGOTIATE_56)
  180. fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
  181. }
  182. static void print_hex(FILE *handle, const char *buf, size_t len)
  183. {
  184. const char *p = buf;
  185. fprintf(stderr, "0x");
  186. while(len-- > 0)
  187. fprintf(stderr, "%02.2x", (unsigned int)*p++);
  188. }
  189. #else
  190. # define DEBUG_OUT(x)
  191. #endif
  192. /*
  193. (*) = A "security buffer" is a triplet consisting of two shorts and one
  194. long:
  195. 1. a 'short' containing the length of the buffer in bytes
  196. 2. a 'short' containing the allocated space for the buffer in bytes
  197. 3. a 'long' containing the offset to the start of the buffer from the
  198. beginning of the NTLM message, in bytes.
  199. */
  200. CURLntlm Curl_input_ntlm(struct connectdata *conn,
  201. bool proxy, /* if proxy or not */
  202. const char *header) /* rest of the www-authenticate:
  203. header */
  204. {
  205. /* point to the correct struct with this */
  206. struct ntlmdata *ntlm;
  207. #ifndef USE_WINDOWS_SSPI
  208. static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
  209. #endif
  210. ntlm = proxy?&conn->proxyntlm:&conn->ntlm;
  211. /* skip initial whitespaces */
  212. while(*header && ISSPACE(*header))
  213. header++;
  214. if(checkprefix("NTLM", header)) {
  215. header += strlen("NTLM");
  216. while(*header && ISSPACE(*header))
  217. header++;
  218. if(*header) {
  219. /* We got a type-2 message here:
  220. Index Description Content
  221. 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
  222. (0x4e544c4d53535000)
  223. 8 NTLM Message Type long (0x02000000)
  224. 12 Target Name security buffer(*)
  225. 20 Flags long
  226. 24 Challenge 8 bytes
  227. (32) Context (optional) 8 bytes (two consecutive longs)
  228. (40) Target Information (optional) security buffer(*)
  229. 32 (48) start of data block
  230. */
  231. size_t size;
  232. unsigned char *buffer;
  233. size = Curl_base64_decode(header, &buffer);
  234. if(!buffer)
  235. return CURLNTLM_BAD;
  236. ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
  237. #ifdef USE_WINDOWS_SSPI
  238. ntlm->type_2 = malloc(size+1);
  239. if(ntlm->type_2 == NULL) {
  240. free(buffer);
  241. return CURLE_OUT_OF_MEMORY;
  242. }
  243. ntlm->n_type_2 = size;
  244. memcpy(ntlm->type_2, buffer, size);
  245. #else
  246. ntlm->flags = 0;
  247. if((size < 32) ||
  248. (memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) ||
  249. (memcmp(buffer+8, type2_marker, sizeof(type2_marker)) != 0)) {
  250. /* This was not a good enough type-2 message */
  251. free(buffer);
  252. return CURLNTLM_BAD;
  253. }
  254. ntlm->flags = readint_le(&buffer[20]);
  255. memcpy(ntlm->nonce, &buffer[24], 8);
  256. DEBUG_OUT({
  257. fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
  258. print_flags(stderr, ntlm->flags);
  259. fprintf(stderr, "\n nonce=");
  260. print_hex(stderr, (char *)ntlm->nonce, 8);
  261. fprintf(stderr, "\n****\n");
  262. fprintf(stderr, "**** Header %s\n ", header);
  263. });
  264. #endif
  265. free(buffer);
  266. }
  267. else {
  268. if(ntlm->state >= NTLMSTATE_TYPE1)
  269. return CURLNTLM_BAD;
  270. ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
  271. }
  272. }
  273. return CURLNTLM_FINE;
  274. }
  275. #ifndef USE_WINDOWS_SSPI
  276. #ifdef USE_SSLEAY
  277. /*
  278. * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
  279. * key schedule ks is also set.
  280. */
  281. static void setup_des_key(const unsigned char *key_56,
  282. DES_key_schedule DESKEYARG(ks))
  283. {
  284. DES_cblock key;
  285. key[0] = key_56[0];
  286. key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
  287. key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
  288. key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
  289. key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
  290. key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
  291. key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
  292. key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
  293. DES_set_odd_parity(&key);
  294. DES_set_key(&key, ks);
  295. }
  296. #elif defined(USE_GNUTLS)
  297. /*
  298. * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
  299. */
  300. static void setup_des_key(const unsigned char *key_56,
  301. gcry_cipher_hd_t *des)
  302. {
  303. char key[8];
  304. key[0] = key_56[0];
  305. key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
  306. key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
  307. key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
  308. key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
  309. key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
  310. key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
  311. key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
  312. gcry_cipher_setkey(*des, key, 8);
  313. }
  314. #endif
  315. /*
  316. * takes a 21 byte array and treats it as 3 56-bit DES keys. The
  317. * 8 byte plaintext is encrypted with each key and the resulting 24
  318. * bytes are stored in the results array.
  319. */
  320. static void lm_resp(const unsigned char *keys,
  321. const unsigned char *plaintext,
  322. unsigned char *results)
  323. {
  324. #ifdef USE_SSLEAY
  325. DES_key_schedule ks;
  326. setup_des_key(keys, DESKEY(ks));
  327. DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
  328. DESKEY(ks), DES_ENCRYPT);
  329. setup_des_key(keys+7, DESKEY(ks));
  330. DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
  331. DESKEY(ks), DES_ENCRYPT);
  332. setup_des_key(keys+14, DESKEY(ks));
  333. DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
  334. DESKEY(ks), DES_ENCRYPT);
  335. #elif defined(USE_GNUTLS)
  336. gcry_cipher_hd_t des;
  337. gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
  338. setup_des_key(keys, &des);
  339. gcry_cipher_encrypt(des, results, 8, plaintext, 8);
  340. gcry_cipher_close(des);
  341. gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
  342. setup_des_key(keys+7, &des);
  343. gcry_cipher_encrypt(des, results+8, 8, plaintext, 8);
  344. gcry_cipher_close(des);
  345. gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
  346. setup_des_key(keys+14, &des);
  347. gcry_cipher_encrypt(des, results+16, 8, plaintext, 8);
  348. gcry_cipher_close(des);
  349. #endif
  350. }
  351. /*
  352. * Set up lanmanager hashed password
  353. */
  354. static void mk_lm_hash(struct SessionHandle *data,
  355. const char *password,
  356. unsigned char *lmbuffer /* 21 bytes */)
  357. {
  358. unsigned char pw[14];
  359. static const unsigned char magic[] = {
  360. 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
  361. };
  362. size_t len = CURLMIN(strlen(password), 14);
  363. Curl_strntoupper((char *)pw, password, len);
  364. memset(&pw[len], 0, 14-len);
  365. #ifdef CURL_DOES_CONVERSIONS
  366. /*
  367. * The LanManager hashed password needs to be created using the
  368. * password in the network encoding not the host encoding.
  369. */
  370. if(data)
  371. Curl_convert_to_network(data, (char *)pw, 14);
  372. #else
  373. (void)data;
  374. #endif
  375. {
  376. /* Create LanManager hashed password. */
  377. #ifdef USE_SSLEAY
  378. DES_key_schedule ks;
  379. setup_des_key(pw, DESKEY(ks));
  380. DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
  381. DESKEY(ks), DES_ENCRYPT);
  382. setup_des_key(pw+7, DESKEY(ks));
  383. DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
  384. DESKEY(ks), DES_ENCRYPT);
  385. #elif defined(USE_GNUTLS)
  386. gcry_cipher_hd_t des;
  387. gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
  388. setup_des_key(pw, &des);
  389. gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
  390. gcry_cipher_close(des);
  391. gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
  392. setup_des_key(pw+7, &des);
  393. gcry_cipher_encrypt(des, lmbuffer+8, 8, magic, 8);
  394. gcry_cipher_close(des);
  395. #endif
  396. memset(lmbuffer + 16, 0, 21 - 16);
  397. }
  398. }
  399. #if USE_NTRESPONSES
  400. static void ascii_to_unicode_le(unsigned char *dest, const char *src,
  401. size_t srclen)
  402. {
  403. size_t i;
  404. for (i=0; i<srclen; i++) {
  405. dest[2*i] = (unsigned char)src[i];
  406. dest[2*i+1] = '\0';
  407. }
  408. }
  409. /*
  410. * Set up nt hashed passwords
  411. */
  412. static CURLcode mk_nt_hash(struct SessionHandle *data,
  413. const char *password,
  414. unsigned char *ntbuffer /* 21 bytes */)
  415. {
  416. size_t len = strlen(password);
  417. unsigned char *pw = malloc(len*2);
  418. if(!pw)
  419. return CURLE_OUT_OF_MEMORY;
  420. ascii_to_unicode_le(pw, password, len);
  421. #ifdef CURL_DOES_CONVERSIONS
  422. /*
  423. * The NT hashed password needs to be created using the
  424. * password in the network encoding not the host encoding.
  425. */
  426. if(data)
  427. Curl_convert_to_network(data, (char *)pw, len*2);
  428. #else
  429. (void)data;
  430. #endif
  431. {
  432. /* Create NT hashed password. */
  433. #ifdef USE_SSLEAY
  434. MD4_CTX MD4pw;
  435. MD4_Init(&MD4pw);
  436. MD4_Update(&MD4pw, pw, 2*len);
  437. MD4_Final(ntbuffer, &MD4pw);
  438. #elif defined(USE_GNUTLS)
  439. gcry_md_hd_t MD4pw;
  440. gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
  441. gcry_md_write(MD4pw, pw, 2*len);
  442. memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
  443. gcry_md_close(MD4pw);
  444. #endif
  445. memset(ntbuffer + 16, 0, 21 - 16);
  446. }
  447. free(pw);
  448. return CURLE_OK;
  449. }
  450. #endif
  451. #endif
  452. #ifdef USE_WINDOWS_SSPI
  453. static void
  454. ntlm_sspi_cleanup(struct ntlmdata *ntlm)
  455. {
  456. if(ntlm->type_2) {
  457. free(ntlm->type_2);
  458. ntlm->type_2 = NULL;
  459. }
  460. if(ntlm->has_handles) {
  461. s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
  462. s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
  463. ntlm->has_handles = 0;
  464. }
  465. if(ntlm->p_identity) {
  466. if(ntlm->identity.User) free(ntlm->identity.User);
  467. if(ntlm->identity.Password) free(ntlm->identity.Password);
  468. if(ntlm->identity.Domain) free(ntlm->identity.Domain);
  469. ntlm->p_identity = NULL;
  470. }
  471. }
  472. #endif
  473. #define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
  474. #define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
  475. (((x) >>16)&0xff), (((x)>>24) & 0xff)
  476. #define HOSTNAME_MAX 1024
  477. /* this is for creating ntlm header output */
  478. CURLcode Curl_output_ntlm(struct connectdata *conn,
  479. bool proxy)
  480. {
  481. const char *domain=""; /* empty */
  482. char host [HOSTNAME_MAX+ 1] = ""; /* empty */
  483. #ifndef USE_WINDOWS_SSPI
  484. size_t domlen = strlen(domain);
  485. size_t hostlen = strlen(host);
  486. size_t hostoff; /* host name offset */
  487. size_t domoff; /* domain name offset */
  488. #endif
  489. size_t size;
  490. char *base64=NULL;
  491. unsigned char ntlmbuf[1024]; /* enough, unless the user+host+domain is very
  492. long */
  493. /* point to the address of the pointer that holds the string to sent to the
  494. server, which is for a plain host or for a HTTP proxy */
  495. char **allocuserpwd;
  496. /* point to the name and password for this */
  497. const char *userp;
  498. const char *passwdp;
  499. /* point to the correct struct with this */
  500. struct ntlmdata *ntlm;
  501. struct auth *authp;
  502. DEBUGASSERT(conn);
  503. DEBUGASSERT(conn->data);
  504. if(proxy) {
  505. allocuserpwd = &conn->allocptr.proxyuserpwd;
  506. userp = conn->proxyuser;
  507. passwdp = conn->proxypasswd;
  508. ntlm = &conn->proxyntlm;
  509. authp = &conn->data->state.authproxy;
  510. }
  511. else {
  512. allocuserpwd = &conn->allocptr.userpwd;
  513. userp = conn->user;
  514. passwdp = conn->passwd;
  515. ntlm = &conn->ntlm;
  516. authp = &conn->data->state.authhost;
  517. }
  518. authp->done = FALSE;
  519. /* not set means empty */
  520. if(!userp)
  521. userp="";
  522. if(!passwdp)
  523. passwdp="";
  524. #ifdef USE_WINDOWS_SSPI
  525. if (s_hSecDll == NULL) {
  526. /* not thread safe and leaks - use curl_global_init() to avoid */
  527. CURLcode err = Curl_sspi_global_init();
  528. if (s_hSecDll == NULL)
  529. return err;
  530. }
  531. #endif
  532. switch(ntlm->state) {
  533. case NTLMSTATE_TYPE1:
  534. default: /* for the weird cases we (re)start here */
  535. #ifdef USE_WINDOWS_SSPI
  536. {
  537. SecBuffer buf;
  538. SecBufferDesc desc;
  539. SECURITY_STATUS status;
  540. ULONG attrs;
  541. const char *user;
  542. int domlen;
  543. TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
  544. ntlm_sspi_cleanup(ntlm);
  545. user = strchr(userp, '\\');
  546. if(!user)
  547. user = strchr(userp, '/');
  548. if(user) {
  549. domain = userp;
  550. domlen = user - userp;
  551. user++;
  552. }
  553. else {
  554. user = userp;
  555. domain = "";
  556. domlen = 0;
  557. }
  558. if(user && *user) {
  559. /* note: initialize all of this before doing the mallocs so that
  560. * it can be cleaned up later without leaking memory.
  561. */
  562. ntlm->p_identity = &ntlm->identity;
  563. memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity));
  564. if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL)
  565. return CURLE_OUT_OF_MEMORY;
  566. ntlm->identity.UserLength = strlen(user);
  567. if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL)
  568. return CURLE_OUT_OF_MEMORY;
  569. ntlm->identity.PasswordLength = strlen(passwdp);
  570. if((ntlm->identity.Domain = malloc(domlen+1)) == NULL)
  571. return CURLE_OUT_OF_MEMORY;
  572. strncpy((char *)ntlm->identity.Domain, domain, domlen);
  573. ntlm->identity.Domain[domlen] = '\0';
  574. ntlm->identity.DomainLength = domlen;
  575. ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  576. }
  577. else {
  578. ntlm->p_identity = NULL;
  579. }
  580. if(s_pSecFn->AcquireCredentialsHandleA(
  581. NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity,
  582. NULL, NULL, &ntlm->handle, &tsDummy
  583. ) != SEC_E_OK) {
  584. return CURLE_OUT_OF_MEMORY;
  585. }
  586. desc.ulVersion = SECBUFFER_VERSION;
  587. desc.cBuffers = 1;
  588. desc.pBuffers = &buf;
  589. buf.cbBuffer = sizeof(ntlmbuf);
  590. buf.BufferType = SECBUFFER_TOKEN;
  591. buf.pvBuffer = ntlmbuf;
  592. status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, NULL,
  593. (char *) host,
  594. ISC_REQ_CONFIDENTIALITY |
  595. ISC_REQ_REPLAY_DETECT |
  596. ISC_REQ_CONNECTION,
  597. 0, SECURITY_NETWORK_DREP,
  598. NULL, 0,
  599. &ntlm->c_handle, &desc,
  600. &attrs, &tsDummy);
  601. if(status == SEC_I_COMPLETE_AND_CONTINUE ||
  602. status == SEC_I_CONTINUE_NEEDED) {
  603. s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &desc);
  604. }
  605. else if(status != SEC_E_OK) {
  606. s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
  607. return CURLE_RECV_ERROR;
  608. }
  609. ntlm->has_handles = 1;
  610. size = buf.cbBuffer;
  611. }
  612. #else
  613. hostoff = 0;
  614. domoff = hostoff + hostlen; /* This is 0: remember that host and domain
  615. are empty */
  616. /* Create and send a type-1 message:
  617. Index Description Content
  618. 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
  619. (0x4e544c4d53535000)
  620. 8 NTLM Message Type long (0x01000000)
  621. 12 Flags long
  622. 16 Supplied Domain security buffer(*)
  623. 24 Supplied Workstation security buffer(*)
  624. 32 start of data block
  625. */
  626. #if USE_NTLM2SESSION
  627. #define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
  628. #else
  629. #define NTLM2FLAG 0
  630. #endif
  631. snprintf((char *)ntlmbuf, sizeof(ntlmbuf), NTLMSSP_SIGNATURE "%c"
  632. "\x01%c%c%c" /* 32-bit type = 1 */
  633. "%c%c%c%c" /* 32-bit NTLM flag field */
  634. "%c%c" /* domain length */
  635. "%c%c" /* domain allocated space */
  636. "%c%c" /* domain name offset */
  637. "%c%c" /* 2 zeroes */
  638. "%c%c" /* host length */
  639. "%c%c" /* host allocated space */
  640. "%c%c" /* host name offset */
  641. "%c%c" /* 2 zeroes */
  642. "%s" /* host name */
  643. "%s", /* domain string */
  644. 0, /* trailing zero */
  645. 0,0,0, /* part of type-1 long */
  646. LONGQUARTET(
  647. NTLMFLAG_NEGOTIATE_OEM|
  648. NTLMFLAG_REQUEST_TARGET|
  649. NTLMFLAG_NEGOTIATE_NTLM_KEY|
  650. NTLM2FLAG|
  651. NTLMFLAG_NEGOTIATE_ALWAYS_SIGN
  652. ),
  653. SHORTPAIR(domlen),
  654. SHORTPAIR(domlen),
  655. SHORTPAIR(domoff),
  656. 0,0,
  657. SHORTPAIR(hostlen),
  658. SHORTPAIR(hostlen),
  659. SHORTPAIR(hostoff),
  660. 0,0,
  661. host /* this is empty */, domain /* this is empty */);
  662. /* initial packet length */
  663. size = 32 + hostlen + domlen;
  664. #endif
  665. DEBUG_OUT({
  666. fprintf(stderr, "**** TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
  667. LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
  668. NTLMFLAG_REQUEST_TARGET|
  669. NTLMFLAG_NEGOTIATE_NTLM_KEY|
  670. NTLM2FLAG|
  671. NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
  672. NTLMFLAG_NEGOTIATE_OEM|
  673. NTLMFLAG_REQUEST_TARGET|
  674. NTLMFLAG_NEGOTIATE_NTLM_KEY|
  675. NTLM2FLAG|
  676. NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
  677. print_flags(stderr,
  678. NTLMFLAG_NEGOTIATE_OEM|
  679. NTLMFLAG_REQUEST_TARGET|
  680. NTLMFLAG_NEGOTIATE_NTLM_KEY|
  681. NTLM2FLAG|
  682. NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
  683. fprintf(stderr, "\n****\n");
  684. });
  685. /* now size is the size of the base64 encoded package size */
  686. size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
  687. if(size >0 ) {
  688. Curl_safefree(*allocuserpwd);
  689. *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
  690. proxy?"Proxy-":"",
  691. base64);
  692. DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
  693. free(base64);
  694. }
  695. else
  696. return CURLE_OUT_OF_MEMORY; /* FIX TODO */
  697. break;
  698. case NTLMSTATE_TYPE2:
  699. /* We received the type-2 message already, create a type-3 message:
  700. Index Description Content
  701. 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
  702. (0x4e544c4d53535000)
  703. 8 NTLM Message Type long (0x03000000)
  704. 12 LM/LMv2 Response security buffer(*)
  705. 20 NTLM/NTLMv2 Response security buffer(*)
  706. 28 Domain Name security buffer(*)
  707. 36 User Name security buffer(*)
  708. 44 Workstation Name security buffer(*)
  709. (52) Session Key (optional) security buffer(*)
  710. (60) Flags (optional) long
  711. 52 (64) start of data block
  712. */
  713. {
  714. #ifdef USE_WINDOWS_SSPI
  715. SecBuffer type_2, type_3;
  716. SecBufferDesc type_2_desc, type_3_desc;
  717. SECURITY_STATUS status;
  718. ULONG attrs;
  719. TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
  720. type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION;
  721. type_2_desc.cBuffers = type_3_desc.cBuffers = 1;
  722. type_2_desc.pBuffers = &type_2;
  723. type_3_desc.pBuffers = &type_3;
  724. type_2.BufferType = SECBUFFER_TOKEN;
  725. type_2.pvBuffer = ntlm->type_2;
  726. type_2.cbBuffer = ntlm->n_type_2;
  727. type_3.BufferType = SECBUFFER_TOKEN;
  728. type_3.pvBuffer = ntlmbuf;
  729. type_3.cbBuffer = sizeof(ntlmbuf);
  730. status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, &ntlm->c_handle,
  731. (char *) host,
  732. ISC_REQ_CONFIDENTIALITY |
  733. ISC_REQ_REPLAY_DETECT |
  734. ISC_REQ_CONNECTION,
  735. 0, SECURITY_NETWORK_DREP, &type_2_desc,
  736. 0, &ntlm->c_handle, &type_3_desc,
  737. &attrs, &tsDummy);
  738. if(status != SEC_E_OK)
  739. return CURLE_RECV_ERROR;
  740. size = type_3.cbBuffer;
  741. ntlm_sspi_cleanup(ntlm);
  742. #else
  743. int lmrespoff;
  744. unsigned char lmresp[24]; /* fixed-size */
  745. #if USE_NTRESPONSES
  746. int ntrespoff;
  747. unsigned char ntresp[24]; /* fixed-size */
  748. #endif
  749. size_t useroff;
  750. const char *user;
  751. size_t userlen;
  752. user = strchr(userp, '\\');
  753. if(!user)
  754. user = strchr(userp, '/');
  755. if(user) {
  756. domain = userp;
  757. domlen = (user - domain);
  758. user++;
  759. }
  760. else
  761. user = userp;
  762. userlen = strlen(user);
  763. if(gethostname(host, HOSTNAME_MAX)) {
  764. infof(conn->data, "gethostname() failed, continuing without!");
  765. hostlen = 0;
  766. }
  767. else {
  768. /* If the workstation if configured with a full DNS name (i.e.
  769. * workstation.somewhere.net) gethostname() returns the fully qualified
  770. * name, which NTLM doesn't like.
  771. */
  772. char *dot = strchr(host, '.');
  773. if(dot)
  774. *dot = '\0';
  775. hostlen = strlen(host);
  776. }
  777. #if USE_NTLM2SESSION
  778. /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
  779. if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
  780. unsigned char ntbuffer[0x18];
  781. unsigned char tmp[0x18];
  782. unsigned char md5sum[MD5_DIGEST_LENGTH];
  783. unsigned char entropy[8];
  784. /* Need to create 8 bytes random data */
  785. #ifdef USE_SSLEAY
  786. MD5_CTX MD5pw;
  787. Curl_ossl_seed(conn->data); /* Initiate the seed if not already done */
  788. RAND_bytes(entropy,8);
  789. #elif defined(USE_GNUTLS)
  790. gcry_md_hd_t MD5pw;
  791. Curl_gtls_seed(conn->data); /* Initiate the seed if not already done */
  792. gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM);
  793. #endif
  794. /* 8 bytes random data as challenge in lmresp */
  795. memcpy(lmresp,entropy,8);
  796. /* Pad with zeros */
  797. memset(lmresp+8,0,0x10);
  798. /* Fill tmp with challenge(nonce?) + entropy */
  799. memcpy(tmp,&ntlm->nonce[0],8);
  800. memcpy(tmp+8,entropy,8);
  801. #ifdef USE_SSLEAY
  802. MD5_Init(&MD5pw);
  803. MD5_Update(&MD5pw, tmp, 16);
  804. MD5_Final(md5sum, &MD5pw);
  805. #elif defined(USE_GNUTLS)
  806. gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
  807. gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH);
  808. memcpy(md5sum, gcry_md_read (MD5pw, 0), MD5_DIGEST_LENGTH);
  809. gcry_md_close(MD5pw);
  810. #endif
  811. /* We shall only use the first 8 bytes of md5sum,
  812. but the des code in lm_resp only encrypt the first 8 bytes */
  813. if(mk_nt_hash(conn->data, passwdp, ntbuffer) == CURLE_OUT_OF_MEMORY)
  814. return CURLE_OUT_OF_MEMORY;
  815. lm_resp(ntbuffer, md5sum, ntresp);
  816. /* End of NTLM2 Session code */
  817. }
  818. else {
  819. #endif
  820. #if USE_NTRESPONSES
  821. unsigned char ntbuffer[0x18];
  822. #endif
  823. unsigned char lmbuffer[0x18];
  824. #if USE_NTRESPONSES
  825. if(mk_nt_hash(conn->data, passwdp, ntbuffer) == CURLE_OUT_OF_MEMORY)
  826. return CURLE_OUT_OF_MEMORY;
  827. lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
  828. #endif
  829. mk_lm_hash(conn->data, passwdp, lmbuffer);
  830. lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
  831. /* A safer but less compatible alternative is:
  832. * lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
  833. * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
  834. #if USE_NTLM2SESSION
  835. }
  836. #endif
  837. lmrespoff = 64; /* size of the message header */
  838. #if USE_NTRESPONSES
  839. ntrespoff = lmrespoff + 0x18;
  840. domoff = ntrespoff + 0x18;
  841. #else
  842. domoff = lmrespoff + 0x18;
  843. #endif
  844. useroff = domoff + domlen;
  845. hostoff = useroff + userlen;
  846. /*
  847. * In the case the server sets the flag NTLMFLAG_NEGOTIATE_UNICODE, we
  848. * need to filter it off because libcurl doesn't UNICODE encode the
  849. * strings it packs into the NTLM authenticate packet.
  850. */
  851. ntlm->flags &= ~NTLMFLAG_NEGOTIATE_UNICODE;
  852. /* Create the big type-3 message binary blob */
  853. size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
  854. NTLMSSP_SIGNATURE "%c"
  855. "\x03%c%c%c" /* type-3, 32 bits */
  856. "%c%c" /* LanManager length */
  857. "%c%c" /* LanManager allocated space */
  858. "%c%c" /* LanManager offset */
  859. "%c%c" /* 2 zeroes */
  860. "%c%c" /* NT-response length */
  861. "%c%c" /* NT-response allocated space */
  862. "%c%c" /* NT-response offset */
  863. "%c%c" /* 2 zeroes */
  864. "%c%c" /* domain length */
  865. "%c%c" /* domain allocated space */
  866. "%c%c" /* domain name offset */
  867. "%c%c" /* 2 zeroes */
  868. "%c%c" /* user length */
  869. "%c%c" /* user allocated space */
  870. "%c%c" /* user offset */
  871. "%c%c" /* 2 zeroes */
  872. "%c%c" /* host length */
  873. "%c%c" /* host allocated space */
  874. "%c%c" /* host offset */
  875. "%c%c" /* 2 zeroes */
  876. "%c%c" /* session key length (unknown purpose) */
  877. "%c%c" /* session key allocated space (unknown purpose) */
  878. "%c%c" /* session key offset (unknown purpose) */
  879. "%c%c" /* 2 zeroes */
  880. "%c%c%c%c" /* flags */
  881. /* domain string */
  882. /* user string */
  883. /* host string */
  884. /* LanManager response */
  885. /* NT response */
  886. ,
  887. 0, /* zero termination */
  888. 0,0,0, /* type-3 long, the 24 upper bits */
  889. SHORTPAIR(0x18), /* LanManager response length, twice */
  890. SHORTPAIR(0x18),
  891. SHORTPAIR(lmrespoff),
  892. 0x0, 0x0,
  893. #if USE_NTRESPONSES
  894. SHORTPAIR(0x18), /* NT-response length, twice */
  895. SHORTPAIR(0x18),
  896. SHORTPAIR(ntrespoff),
  897. 0x0, 0x0,
  898. #else
  899. 0x0, 0x0,
  900. 0x0, 0x0,
  901. 0x0, 0x0,
  902. 0x0, 0x0,
  903. #endif
  904. SHORTPAIR(domlen),
  905. SHORTPAIR(domlen),
  906. SHORTPAIR(domoff),
  907. 0x0, 0x0,
  908. SHORTPAIR(userlen),
  909. SHORTPAIR(userlen),
  910. SHORTPAIR(useroff),
  911. 0x0, 0x0,
  912. SHORTPAIR(hostlen),
  913. SHORTPAIR(hostlen),
  914. SHORTPAIR(hostoff),
  915. 0x0, 0x0,
  916. 0x0, 0x0,
  917. 0x0, 0x0,
  918. 0x0, 0x0,
  919. 0x0, 0x0,
  920. LONGQUARTET(ntlm->flags));
  921. DEBUGASSERT(size==64);
  922. DEBUGASSERT(size == (size_t)lmrespoff);
  923. /* We append the binary hashes */
  924. if(size < (sizeof(ntlmbuf) - 0x18)) {
  925. memcpy(&ntlmbuf[size], lmresp, 0x18);
  926. size += 0x18;
  927. }
  928. DEBUG_OUT({
  929. fprintf(stderr, "**** TYPE3 header lmresp=");
  930. print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
  931. });
  932. #if USE_NTRESPONSES
  933. if(size < (sizeof(ntlmbuf) - 0x18)) {
  934. DEBUGASSERT(size == (size_t)ntrespoff);
  935. memcpy(&ntlmbuf[size], ntresp, 0x18);
  936. size += 0x18;
  937. }
  938. DEBUG_OUT({
  939. fprintf(stderr, "\n ntresp=");
  940. print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
  941. });
  942. #endif
  943. DEBUG_OUT({
  944. fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
  945. LONGQUARTET(ntlm->flags), ntlm->flags);
  946. print_flags(stderr, ntlm->flags);
  947. fprintf(stderr, "\n****\n");
  948. });
  949. /* Make sure that the domain, user and host strings fit in the target
  950. buffer before we copy them there. */
  951. if(size + userlen + domlen + hostlen >= sizeof(ntlmbuf)) {
  952. failf(conn->data, "user + domain + host name too big");
  953. return CURLE_OUT_OF_MEMORY;
  954. }
  955. DEBUGASSERT(size == domoff);
  956. memcpy(&ntlmbuf[size], domain, domlen);
  957. size += domlen;
  958. DEBUGASSERT(size == useroff);
  959. memcpy(&ntlmbuf[size], user, userlen);
  960. size += userlen;
  961. DEBUGASSERT(size == hostoff);
  962. memcpy(&ntlmbuf[size], host, hostlen);
  963. size += hostlen;
  964. #ifdef CURL_DOES_CONVERSIONS
  965. /* convert domain, user, and host to ASCII but leave the rest as-is */
  966. if(CURLE_OK != Curl_convert_to_network(conn->data,
  967. (char *)&ntlmbuf[domoff],
  968. size-domoff)) {
  969. return CURLE_CONV_FAILED;
  970. }
  971. #endif /* CURL_DOES_CONVERSIONS */
  972. #endif
  973. /* convert the binary blob into base64 */
  974. size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
  975. if(size >0 ) {
  976. Curl_safefree(*allocuserpwd);
  977. *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
  978. proxy?"Proxy-":"",
  979. base64);
  980. DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
  981. free(base64);
  982. }
  983. else
  984. return CURLE_OUT_OF_MEMORY; /* FIX TODO */
  985. ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
  986. authp->done = TRUE;
  987. }
  988. break;
  989. case NTLMSTATE_TYPE3:
  990. /* connection is already authenticated,
  991. * don't send a header in future requests */
  992. if(*allocuserpwd) {
  993. free(*allocuserpwd);
  994. *allocuserpwd=NULL;
  995. }
  996. authp->done = TRUE;
  997. break;
  998. }
  999. return CURLE_OK;
  1000. }
  1001. void
  1002. Curl_ntlm_cleanup(struct connectdata *conn)
  1003. {
  1004. #ifdef USE_WINDOWS_SSPI
  1005. ntlm_sspi_cleanup(&conn->ntlm);
  1006. ntlm_sspi_cleanup(&conn->proxyntlm);
  1007. #else
  1008. (void)conn;
  1009. #endif
  1010. }
  1011. #endif /* USE_NTLM */
  1012. #endif /* !CURL_DISABLE_HTTP */