ntlm.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. /*
  2. * OpenConnect (SSL + DTLS) VPN client
  3. *
  4. * Copyright © 2008-2015 Intel Corporation.
  5. *
  6. * Author: David Woodhouse <dwmw2@infradead.org>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * version 2.1, as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. */
  17. #include <config.h>
  18. #include "openconnect-internal.h"
  19. #include <unistd.h>
  20. #include <fcntl.h>
  21. #include <sys/stat.h>
  22. #include <sys/types.h>
  23. #ifdef HAVE_ALLOCA_H
  24. #include <alloca.h>
  25. #endif
  26. #ifndef _WIN32
  27. #include <sys/wait.h>
  28. #endif
  29. #include <time.h>
  30. #include <string.h>
  31. #include <errno.h>
  32. #include <stdlib.h>
  33. #include <stdio.h>
  34. #include <stdarg.h>
  35. #include <ctype.h>
  36. #define NTLM_SSO_REQ 2 /* SSO type1 packet sent */
  37. #define NTLM_MANUAL 3 /* SSO challenge/response sent or skipped; manual next */
  38. #define NTLM_MANUAL_REQ 4 /* manual type1 packet sent */
  39. #ifdef _WIN32
  40. static int ntlm_sspi(struct openconnect_info *vpninfo, int proxy,
  41. struct http_auth_state *auth_state,
  42. struct oc_text_buf *buf, const char *challenge)
  43. {
  44. SECURITY_STATUS status;
  45. SecBufferDesc input_desc, output_desc;
  46. SecBuffer in_token, out_token;
  47. ULONG ret_flags;
  48. if (challenge) {
  49. int token_len = -EINVAL;
  50. input_desc.cBuffers = 1;
  51. input_desc.pBuffers = &in_token;
  52. input_desc.ulVersion = SECBUFFER_VERSION;
  53. in_token.BufferType = SECBUFFER_TOKEN;
  54. in_token.pvBuffer = openconnect_base64_decode(&token_len, challenge);
  55. if (!in_token.pvBuffer)
  56. return token_len;
  57. in_token.cbBuffer = token_len;
  58. }
  59. output_desc.cBuffers = 1;
  60. output_desc.pBuffers = &out_token;
  61. output_desc.ulVersion = SECBUFFER_VERSION;
  62. out_token.BufferType = SECBUFFER_TOKEN;
  63. out_token.cbBuffer = 0;
  64. out_token.pvBuffer = NULL;
  65. status = InitializeSecurityContextW(&auth_state->ntlm_sspi_cred,
  66. challenge ? &auth_state->ntlm_sspi_ctx : NULL,
  67. (SEC_WCHAR *)L"",
  68. ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
  69. 0, SECURITY_NETWORK_DREP,
  70. challenge ? &input_desc : NULL,
  71. 0, &auth_state->ntlm_sspi_ctx,
  72. &output_desc, &ret_flags, NULL);
  73. if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) {
  74. vpn_progress(vpninfo, PRG_ERR,
  75. _("InitializeSecurityContext() failed: %lx\n"), status);
  76. return -EIO;
  77. }
  78. buf_append(buf, "%sAuthorization: NTLM ", proxy ? "Proxy-" : "");
  79. buf_append_base64(buf, out_token.pvBuffer, out_token.cbBuffer, 0);
  80. buf_append(buf, "\r\n");
  81. FreeContextBuffer(out_token.pvBuffer);
  82. return 0;
  83. }
  84. static int ntlm_helper_spawn(struct openconnect_info *vpninfo, int proxy,
  85. struct http_auth_state *auth_state,
  86. struct oc_text_buf *buf)
  87. {
  88. SECURITY_STATUS status;
  89. int ret;
  90. status = AcquireCredentialsHandleW(NULL, (SEC_WCHAR *)L"NTLM",
  91. SECPKG_CRED_OUTBOUND, NULL, NULL,
  92. NULL, NULL,
  93. &auth_state->ntlm_sspi_cred, NULL);
  94. if (status != SEC_E_OK) {
  95. vpn_progress(vpninfo, PRG_ERR,
  96. _("AcquireCredentialsHandle() failed: %lx\n"), status);
  97. return -EIO;
  98. }
  99. ret = ntlm_sspi(vpninfo, proxy, auth_state, buf, NULL);
  100. if (ret)
  101. FreeCredentialsHandle(&auth_state->ntlm_sspi_cred);
  102. return ret;
  103. }
  104. static int ntlm_helper_challenge(struct openconnect_info *vpninfo, int proxy,
  105. struct http_auth_state *auth_state,
  106. struct oc_text_buf *buf)
  107. {
  108. return ntlm_sspi(vpninfo, proxy, auth_state, buf, auth_state->challenge);
  109. }
  110. void cleanup_ntlm_auth(struct openconnect_info *vpninfo,
  111. struct http_auth_state *auth_state)
  112. {
  113. if (auth_state->state == NTLM_SSO_REQ) {
  114. FreeCredentialsHandle(&auth_state->ntlm_sspi_cred);
  115. DeleteSecurityContext(&auth_state->ntlm_sspi_ctx);
  116. }
  117. }
  118. #else /* !_WIN32 */
  119. static int ntlm_helper_spawn(struct openconnect_info *vpninfo, int proxy,
  120. struct http_auth_state *auth_state,
  121. struct oc_text_buf *buf)
  122. {
  123. char *username;
  124. int pipefd[2];
  125. pid_t pid;
  126. char helperbuf[4096];
  127. int len;
  128. if (access("/usr/bin/ntlm_auth", X_OK))
  129. return -errno;
  130. username = vpninfo->proxy_user;
  131. if (!username)
  132. username = getenv("NTLMUSER");
  133. if (!username)
  134. username = getenv("USER");
  135. if (!username)
  136. return -EINVAL;
  137. #ifdef SOCK_CLOEXEC
  138. if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, pipefd))
  139. #endif
  140. {
  141. if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd))
  142. return -errno;
  143. set_fd_cloexec(pipefd[0]);
  144. set_fd_cloexec(pipefd[1]);
  145. }
  146. pid = fork();
  147. if (pid == -1)
  148. return -errno;
  149. if (!pid) {
  150. int i;
  151. char *p;
  152. const char *argv[9];
  153. /* Fork again to detach grandchild */
  154. if (fork())
  155. exit(1);
  156. close(pipefd[1]);
  157. /* The duplicated fd does not have O_CLOEXEC */
  158. dup2(pipefd[0], 0);
  159. dup2(pipefd[0], 1);
  160. /* Should we leave stderr open? */
  161. for (i = 3; i < 1024 ; i++)
  162. close(i);
  163. i = 0;
  164. argv[i++] = "/usr/bin/ntlm_auth";
  165. argv[i++] = "--helper-protocol";
  166. argv[i++] = "ntlmssp-client-1";
  167. argv[i++] = "--use-cached-creds";
  168. argv[i++] = "--username";
  169. p = strchr(username, '\\');
  170. if (p) {
  171. argv[i++] = p+1;
  172. argv[i++] = "--domain";
  173. argv[i++] = strndup(username, p - username);
  174. } else
  175. argv[i++] = username;
  176. argv[i++] = NULL;
  177. execv(argv[0], (char **)argv);
  178. exit(1);
  179. }
  180. waitpid(pid, NULL, 0);
  181. close(pipefd[0]);
  182. if (write(pipefd[1], "YR\n", 3) != 3) {
  183. close(pipefd[1]);
  184. return -EIO;
  185. }
  186. len = read(pipefd[1], helperbuf, sizeof(helperbuf));
  187. if (len < 4 || helperbuf[0] != 'Y' || helperbuf[1] != 'R' ||
  188. helperbuf[2] != ' ' || helperbuf[len - 1] != '\n') {
  189. close(pipefd[1]);
  190. return -EIO;
  191. }
  192. helperbuf[len - 1] = 0;
  193. buf_append(buf, "%sAuthorization: NTLM %s\r\n", proxy ? "Proxy-" : "",
  194. helperbuf + 3);
  195. auth_state->ntlm_helper_fd = pipefd[1];
  196. return 0;
  197. }
  198. static int ntlm_helper_challenge(struct openconnect_info *vpninfo, int proxy,
  199. struct http_auth_state *auth_state,
  200. struct oc_text_buf *buf)
  201. {
  202. char helperbuf[4096];
  203. int len;
  204. if (!auth_state->challenge ||
  205. write(auth_state->ntlm_helper_fd, "TT ", 3) != 3 ||
  206. write(auth_state->ntlm_helper_fd, auth_state->challenge,
  207. strlen(auth_state->challenge)) != strlen(auth_state->challenge) ||
  208. write(auth_state->ntlm_helper_fd, "\n", 1) != 1) {
  209. err:
  210. vpn_progress(vpninfo, PRG_ERR, _("Error communicating with ntlm_auth helper\n"));
  211. close(auth_state->ntlm_helper_fd);
  212. auth_state->ntlm_helper_fd = -1;
  213. return -EAGAIN;
  214. }
  215. len = read(auth_state->ntlm_helper_fd, helperbuf, sizeof(helperbuf));
  216. /* Accept both 'KK' and 'AF'. It should be the latter but see
  217. https://bugzilla.samba.org/show_bug.cgi?id=10691 */
  218. if (len < 4 || (!(helperbuf[0] == 'K' && helperbuf[1] == 'K') &&
  219. !(helperbuf[0] == 'A' && helperbuf[1] == 'F')) ||
  220. helperbuf[2] != ' ' || helperbuf[len - 1] != '\n') {
  221. goto err;
  222. }
  223. helperbuf[len - 1] = 0;
  224. buf_append(buf, "%sAuthorization: NTLM %s\r\n", proxy ? "Proxy-" : "",
  225. helperbuf + 3);
  226. if (proxy)
  227. vpn_progress(vpninfo, PRG_INFO,
  228. _("Attempting HTTP NTLM authentication to proxy (single-sign-on)\n"));
  229. else
  230. vpn_progress(vpninfo, PRG_INFO,
  231. _("Attempting HTTP NTLM authentication to server '%s' (single-sign-on)\n"),
  232. vpninfo->hostname);
  233. return 0;
  234. }
  235. void cleanup_ntlm_auth(struct openconnect_info *vpninfo,
  236. struct http_auth_state *auth_state)
  237. {
  238. if (auth_state->state == NTLM_SSO_REQ) {
  239. close(auth_state->ntlm_helper_fd);
  240. auth_state->ntlm_helper_fd = -1;
  241. }
  242. }
  243. #endif /* !_WIN32 */
  244. /*
  245. * NTLM implementation taken from libsoup / Evolution Data Server
  246. * Copyright (C) 2007 Red Hat, Inc.
  247. * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  248. */
  249. /* DES */
  250. typedef uint32_t DES_KS[16][2]; /* Single-key DES key schedule */
  251. /*
  252. * MD4 encoder. (The one everyone else uses is not GPL-compatible;
  253. * this is a reimplementation from spec.) This doesn't need to be
  254. * efficient for our purposes, although it would be nice to fix
  255. * it to not malloc()...
  256. */
  257. #define F(X,Y,Z) ( ((X)&(Y)) | ((~(X))&(Z)) )
  258. #define G(X,Y,Z) ( ((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)) )
  259. #define H(X,Y,Z) ( (X)^(Y)^(Z) )
  260. #define ROT(val, n) ( ((val) << (n)) | ((val) >> (32 - (n))) )
  261. static int md4sum (struct oc_text_buf *buf, unsigned char digest[16])
  262. {
  263. int nbytes = buf->pos;
  264. unsigned char *M;
  265. uint32_t A, B, C, D, AA, BB, CC, DD, X[16];
  266. int pbytes, nbits = nbytes * 8, i, j;
  267. /* There is *always* padding of at least one bit. */
  268. pbytes = ((119 - (nbytes % 64)) % 64) + 1;
  269. if (buf_ensure_space (buf, pbytes + 8))
  270. return -ENOMEM;
  271. M = (void *)buf->data;
  272. memset (M + nbytes, 0, pbytes + 8);
  273. M[nbytes] = 0x80;
  274. store_le32(&M[nbytes + pbytes], nbits);
  275. A = 0x67452301;
  276. B = 0xEFCDAB89;
  277. C = 0x98BADCFE;
  278. D = 0x10325476;
  279. for (i = 0; i < nbytes + pbytes + 8; i += 64) {
  280. for (j = 0; j < 16; j++)
  281. X[j] = load_le32(&M[i + j * 4]);
  282. AA = A;
  283. BB = B;
  284. CC = C;
  285. DD = D;
  286. A = ROT (A + F (B, C, D) + X[0], 3);
  287. D = ROT (D + F (A, B, C) + X[1], 7);
  288. C = ROT (C + F (D, A, B) + X[2], 11);
  289. B = ROT (B + F (C, D, A) + X[3], 19);
  290. A = ROT (A + F (B, C, D) + X[4], 3);
  291. D = ROT (D + F (A, B, C) + X[5], 7);
  292. C = ROT (C + F (D, A, B) + X[6], 11);
  293. B = ROT (B + F (C, D, A) + X[7], 19);
  294. A = ROT (A + F (B, C, D) + X[8], 3);
  295. D = ROT (D + F (A, B, C) + X[9], 7);
  296. C = ROT (C + F (D, A, B) + X[10], 11);
  297. B = ROT (B + F (C, D, A) + X[11], 19);
  298. A = ROT (A + F (B, C, D) + X[12], 3);
  299. D = ROT (D + F (A, B, C) + X[13], 7);
  300. C = ROT (C + F (D, A, B) + X[14], 11);
  301. B = ROT (B + F (C, D, A) + X[15], 19);
  302. A = ROT (A + G (B, C, D) + X[0] + 0x5A827999, 3);
  303. D = ROT (D + G (A, B, C) + X[4] + 0x5A827999, 5);
  304. C = ROT (C + G (D, A, B) + X[8] + 0x5A827999, 9);
  305. B = ROT (B + G (C, D, A) + X[12] + 0x5A827999, 13);
  306. A = ROT (A + G (B, C, D) + X[1] + 0x5A827999, 3);
  307. D = ROT (D + G (A, B, C) + X[5] + 0x5A827999, 5);
  308. C = ROT (C + G (D, A, B) + X[9] + 0x5A827999, 9);
  309. B = ROT (B + G (C, D, A) + X[13] + 0x5A827999, 13);
  310. A = ROT (A + G (B, C, D) + X[2] + 0x5A827999, 3);
  311. D = ROT (D + G (A, B, C) + X[6] + 0x5A827999, 5);
  312. C = ROT (C + G (D, A, B) + X[10] + 0x5A827999, 9);
  313. B = ROT (B + G (C, D, A) + X[14] + 0x5A827999, 13);
  314. A = ROT (A + G (B, C, D) + X[3] + 0x5A827999, 3);
  315. D = ROT (D + G (A, B, C) + X[7] + 0x5A827999, 5);
  316. C = ROT (C + G (D, A, B) + X[11] + 0x5A827999, 9);
  317. B = ROT (B + G (C, D, A) + X[15] + 0x5A827999, 13);
  318. A = ROT (A + H (B, C, D) + X[0] + 0x6ED9EBA1, 3);
  319. D = ROT (D + H (A, B, C) + X[8] + 0x6ED9EBA1, 9);
  320. C = ROT (C + H (D, A, B) + X[4] + 0x6ED9EBA1, 11);
  321. B = ROT (B + H (C, D, A) + X[12] + 0x6ED9EBA1, 15);
  322. A = ROT (A + H (B, C, D) + X[2] + 0x6ED9EBA1, 3);
  323. D = ROT (D + H (A, B, C) + X[10] + 0x6ED9EBA1, 9);
  324. C = ROT (C + H (D, A, B) + X[6] + 0x6ED9EBA1, 11);
  325. B = ROT (B + H (C, D, A) + X[14] + 0x6ED9EBA1, 15);
  326. A = ROT (A + H (B, C, D) + X[1] + 0x6ED9EBA1, 3);
  327. D = ROT (D + H (A, B, C) + X[9] + 0x6ED9EBA1, 9);
  328. C = ROT (C + H (D, A, B) + X[5] + 0x6ED9EBA1, 11);
  329. B = ROT (B + H (C, D, A) + X[13] + 0x6ED9EBA1, 15);
  330. A = ROT (A + H (B, C, D) + X[3] + 0x6ED9EBA1, 3);
  331. D = ROT (D + H (A, B, C) + X[11] + 0x6ED9EBA1, 9);
  332. C = ROT (C + H (D, A, B) + X[7] + 0x6ED9EBA1, 11);
  333. B = ROT (B + H (C, D, A) + X[15] + 0x6ED9EBA1, 15);
  334. A += AA;
  335. B += BB;
  336. C += CC;
  337. D += DD;
  338. }
  339. store_le32(digest, A);
  340. store_le32(digest + 4, B);
  341. store_le32(digest + 8, C);
  342. store_le32(digest + 12, D);
  343. return 0;
  344. }
  345. /* Public domain DES implementation from Phil Karn */
  346. static const uint32_t Spbox[8][64] = {
  347. { 0x01010400, 0x00000000, 0x00010000, 0x01010404,
  348. 0x01010004, 0x00010404, 0x00000004, 0x00010000,
  349. 0x00000400, 0x01010400, 0x01010404, 0x00000400,
  350. 0x01000404, 0x01010004, 0x01000000, 0x00000004,
  351. 0x00000404, 0x01000400, 0x01000400, 0x00010400,
  352. 0x00010400, 0x01010000, 0x01010000, 0x01000404,
  353. 0x00010004, 0x01000004, 0x01000004, 0x00010004,
  354. 0x00000000, 0x00000404, 0x00010404, 0x01000000,
  355. 0x00010000, 0x01010404, 0x00000004, 0x01010000,
  356. 0x01010400, 0x01000000, 0x01000000, 0x00000400,
  357. 0x01010004, 0x00010000, 0x00010400, 0x01000004,
  358. 0x00000400, 0x00000004, 0x01000404, 0x00010404,
  359. 0x01010404, 0x00010004, 0x01010000, 0x01000404,
  360. 0x01000004, 0x00000404, 0x00010404, 0x01010400,
  361. 0x00000404, 0x01000400, 0x01000400, 0x00000000,
  362. 0x00010004, 0x00010400, 0x00000000, 0x01010004 },
  363. { 0x80108020, 0x80008000, 0x00008000, 0x00108020,
  364. 0x00100000, 0x00000020, 0x80100020, 0x80008020,
  365. 0x80000020, 0x80108020, 0x80108000, 0x80000000,
  366. 0x80008000, 0x00100000, 0x00000020, 0x80100020,
  367. 0x00108000, 0x00100020, 0x80008020, 0x00000000,
  368. 0x80000000, 0x00008000, 0x00108020, 0x80100000,
  369. 0x00100020, 0x80000020, 0x00000000, 0x00108000,
  370. 0x00008020, 0x80108000, 0x80100000, 0x00008020,
  371. 0x00000000, 0x00108020, 0x80100020, 0x00100000,
  372. 0x80008020, 0x80100000, 0x80108000, 0x00008000,
  373. 0x80100000, 0x80008000, 0x00000020, 0x80108020,
  374. 0x00108020, 0x00000020, 0x00008000, 0x80000000,
  375. 0x00008020, 0x80108000, 0x00100000, 0x80000020,
  376. 0x00100020, 0x80008020, 0x80000020, 0x00100020,
  377. 0x00108000, 0x00000000, 0x80008000, 0x00008020,
  378. 0x80000000, 0x80100020, 0x80108020, 0x00108000 },
  379. { 0x00000208, 0x08020200, 0x00000000, 0x08020008,
  380. 0x08000200, 0x00000000, 0x00020208, 0x08000200,
  381. 0x00020008, 0x08000008, 0x08000008, 0x00020000,
  382. 0x08020208, 0x00020008, 0x08020000, 0x00000208,
  383. 0x08000000, 0x00000008, 0x08020200, 0x00000200,
  384. 0x00020200, 0x08020000, 0x08020008, 0x00020208,
  385. 0x08000208, 0x00020200, 0x00020000, 0x08000208,
  386. 0x00000008, 0x08020208, 0x00000200, 0x08000000,
  387. 0x08020200, 0x08000000, 0x00020008, 0x00000208,
  388. 0x00020000, 0x08020200, 0x08000200, 0x00000000,
  389. 0x00000200, 0x00020008, 0x08020208, 0x08000200,
  390. 0x08000008, 0x00000200, 0x00000000, 0x08020008,
  391. 0x08000208, 0x00020000, 0x08000000, 0x08020208,
  392. 0x00000008, 0x00020208, 0x00020200, 0x08000008,
  393. 0x08020000, 0x08000208, 0x00000208, 0x08020000,
  394. 0x00020208, 0x00000008, 0x08020008, 0x00020200 },
  395. { 0x00802001, 0x00002081, 0x00002081, 0x00000080,
  396. 0x00802080, 0x00800081, 0x00800001, 0x00002001,
  397. 0x00000000, 0x00802000, 0x00802000, 0x00802081,
  398. 0x00000081, 0x00000000, 0x00800080, 0x00800001,
  399. 0x00000001, 0x00002000, 0x00800000, 0x00802001,
  400. 0x00000080, 0x00800000, 0x00002001, 0x00002080,
  401. 0x00800081, 0x00000001, 0x00002080, 0x00800080,
  402. 0x00002000, 0x00802080, 0x00802081, 0x00000081,
  403. 0x00800080, 0x00800001, 0x00802000, 0x00802081,
  404. 0x00000081, 0x00000000, 0x00000000, 0x00802000,
  405. 0x00002080, 0x00800080, 0x00800081, 0x00000001,
  406. 0x00802001, 0x00002081, 0x00002081, 0x00000080,
  407. 0x00802081, 0x00000081, 0x00000001, 0x00002000,
  408. 0x00800001, 0x00002001, 0x00802080, 0x00800081,
  409. 0x00002001, 0x00002080, 0x00800000, 0x00802001,
  410. 0x00000080, 0x00800000, 0x00002000, 0x00802080 },
  411. { 0x00000100, 0x02080100, 0x02080000, 0x42000100,
  412. 0x00080000, 0x00000100, 0x40000000, 0x02080000,
  413. 0x40080100, 0x00080000, 0x02000100, 0x40080100,
  414. 0x42000100, 0x42080000, 0x00080100, 0x40000000,
  415. 0x02000000, 0x40080000, 0x40080000, 0x00000000,
  416. 0x40000100, 0x42080100, 0x42080100, 0x02000100,
  417. 0x42080000, 0x40000100, 0x00000000, 0x42000000,
  418. 0x02080100, 0x02000000, 0x42000000, 0x00080100,
  419. 0x00080000, 0x42000100, 0x00000100, 0x02000000,
  420. 0x40000000, 0x02080000, 0x42000100, 0x40080100,
  421. 0x02000100, 0x40000000, 0x42080000, 0x02080100,
  422. 0x40080100, 0x00000100, 0x02000000, 0x42080000,
  423. 0x42080100, 0x00080100, 0x42000000, 0x42080100,
  424. 0x02080000, 0x00000000, 0x40080000, 0x42000000,
  425. 0x00080100, 0x02000100, 0x40000100, 0x00080000,
  426. 0x00000000, 0x40080000, 0x02080100, 0x40000100 },
  427. { 0x20000010, 0x20400000, 0x00004000, 0x20404010,
  428. 0x20400000, 0x00000010, 0x20404010, 0x00400000,
  429. 0x20004000, 0x00404010, 0x00400000, 0x20000010,
  430. 0x00400010, 0x20004000, 0x20000000, 0x00004010,
  431. 0x00000000, 0x00400010, 0x20004010, 0x00004000,
  432. 0x00404000, 0x20004010, 0x00000010, 0x20400010,
  433. 0x20400010, 0x00000000, 0x00404010, 0x20404000,
  434. 0x00004010, 0x00404000, 0x20404000, 0x20000000,
  435. 0x20004000, 0x00000010, 0x20400010, 0x00404000,
  436. 0x20404010, 0x00400000, 0x00004010, 0x20000010,
  437. 0x00400000, 0x20004000, 0x20000000, 0x00004010,
  438. 0x20000010, 0x20404010, 0x00404000, 0x20400000,
  439. 0x00404010, 0x20404000, 0x00000000, 0x20400010,
  440. 0x00000010, 0x00004000, 0x20400000, 0x00404010,
  441. 0x00004000, 0x00400010, 0x20004010, 0x00000000,
  442. 0x20404000, 0x20000000, 0x00400010, 0x20004010 },
  443. { 0x00200000, 0x04200002, 0x04000802, 0x00000000,
  444. 0x00000800, 0x04000802, 0x00200802, 0x04200800,
  445. 0x04200802, 0x00200000, 0x00000000, 0x04000002,
  446. 0x00000002, 0x04000000, 0x04200002, 0x00000802,
  447. 0x04000800, 0x00200802, 0x00200002, 0x04000800,
  448. 0x04000002, 0x04200000, 0x04200800, 0x00200002,
  449. 0x04200000, 0x00000800, 0x00000802, 0x04200802,
  450. 0x00200800, 0x00000002, 0x04000000, 0x00200800,
  451. 0x04000000, 0x00200800, 0x00200000, 0x04000802,
  452. 0x04000802, 0x04200002, 0x04200002, 0x00000002,
  453. 0x00200002, 0x04000000, 0x04000800, 0x00200000,
  454. 0x04200800, 0x00000802, 0x00200802, 0x04200800,
  455. 0x00000802, 0x04000002, 0x04200802, 0x04200000,
  456. 0x00200800, 0x00000000, 0x00000002, 0x04200802,
  457. 0x00000000, 0x00200802, 0x04200000, 0x00000800,
  458. 0x04000002, 0x04000800, 0x00000800, 0x00200002 },
  459. { 0x10001040, 0x00001000, 0x00040000, 0x10041040,
  460. 0x10000000, 0x10001040, 0x00000040, 0x10000000,
  461. 0x00040040, 0x10040000, 0x10041040, 0x00041000,
  462. 0x10041000, 0x00041040, 0x00001000, 0x00000040,
  463. 0x10040000, 0x10000040, 0x10001000, 0x00001040,
  464. 0x00041000, 0x00040040, 0x10040040, 0x10041000,
  465. 0x00001040, 0x00000000, 0x00000000, 0x10040040,
  466. 0x10000040, 0x10001000, 0x00041040, 0x00040000,
  467. 0x00041040, 0x00040000, 0x10041000, 0x00001000,
  468. 0x00000040, 0x10040040, 0x00001000, 0x00041040,
  469. 0x10001000, 0x00000040, 0x10000040, 0x10040000,
  470. 0x10040040, 0x10000000, 0x00040000, 0x10001040,
  471. 0x00000000, 0x10041040, 0x00040040, 0x10000040,
  472. 0x10040000, 0x10001000, 0x10001040, 0x00000000,
  473. 0x10041040, 0x00041000, 0x00041000, 0x00001040,
  474. 0x00001040, 0x00040040, 0x10000000, 0x10041000 }
  475. };
  476. #undef F
  477. #define F(l,r,key){\
  478. work = ((r >> 4) | (r << 28)) ^ key[0];\
  479. l ^= Spbox[6][work & 0x3f];\
  480. l ^= Spbox[4][(work >> 8) & 0x3f];\
  481. l ^= Spbox[2][(work >> 16) & 0x3f];\
  482. l ^= Spbox[0][(work >> 24) & 0x3f];\
  483. work = r ^ key[1];\
  484. l ^= Spbox[7][work & 0x3f];\
  485. l ^= Spbox[5][(work >> 8) & 0x3f];\
  486. l ^= Spbox[3][(work >> 16) & 0x3f];\
  487. l ^= Spbox[1][(work >> 24) & 0x3f];\
  488. }
  489. /* Encrypt or decrypt a block of data in ECB mode */
  490. static void des (uint32_t ks[16][2], unsigned char block[8])
  491. {
  492. uint32_t left, right, work;
  493. /* Read input block and place in left/right in big-endian order */
  494. left = load_be32(block);
  495. right = load_be32(block + 4);
  496. /* Hoey's clever initial permutation algorithm, from Outerbridge
  497. * (see Schneier p 478)
  498. *
  499. * The convention here is the same as Outerbridge: rotate each
  500. * register left by 1 bit, i.e., so that "left" contains permuted
  501. * input bits 2, 3, 4, ... 1 and "right" contains 33, 34, 35, ... 32
  502. * (using origin-1 numbering as in the FIPS). This allows us to avoid
  503. * one of the two rotates that would otherwise be required in each of
  504. * the 16 rounds.
  505. */
  506. work = ((left >> 4) ^ right) & 0x0f0f0f0f;
  507. right ^= work;
  508. left ^= work << 4;
  509. work = ((left >> 16) ^ right) & 0xffff;
  510. right ^= work;
  511. left ^= work << 16;
  512. work = ((right >> 2) ^ left) & 0x33333333;
  513. left ^= work;
  514. right ^= (work << 2);
  515. work = ((right >> 8) ^ left) & 0xff00ff;
  516. left ^= work;
  517. right ^= (work << 8);
  518. right = (right << 1) | (right >> 31);
  519. work = (left ^ right) & 0xaaaaaaaa;
  520. left ^= work;
  521. right ^= work;
  522. left = (left << 1) | (left >> 31);
  523. /* Now do the 16 rounds */
  524. F (left,right,ks[0]);
  525. F (right,left,ks[1]);
  526. F (left,right,ks[2]);
  527. F (right,left,ks[3]);
  528. F (left,right,ks[4]);
  529. F (right,left,ks[5]);
  530. F (left,right,ks[6]);
  531. F (right,left,ks[7]);
  532. F (left,right,ks[8]);
  533. F (right,left,ks[9]);
  534. F (left,right,ks[10]);
  535. F (right,left,ks[11]);
  536. F (left,right,ks[12]);
  537. F (right,left,ks[13]);
  538. F (left,right,ks[14]);
  539. F (right,left,ks[15]);
  540. /* Inverse permutation, also from Hoey via Outerbridge and Schneier */
  541. right = (right << 31) | (right >> 1);
  542. work = (left ^ right) & 0xaaaaaaaa;
  543. left ^= work;
  544. right ^= work;
  545. left = (left >> 1) | (left << 31);
  546. work = ((left >> 8) ^ right) & 0xff00ff;
  547. right ^= work;
  548. left ^= work << 8;
  549. work = ((left >> 2) ^ right) & 0x33333333;
  550. right ^= work;
  551. left ^= work << 2;
  552. work = ((right >> 16) ^ left) & 0xffff;
  553. left ^= work;
  554. right ^= work << 16;
  555. work = ((right >> 4) ^ left) & 0x0f0f0f0f;
  556. left ^= work;
  557. right ^= work << 4;
  558. /* Put the block back into the user's buffer with final swap */
  559. store_be32(block, right);
  560. store_be32(block + 4, left);
  561. }
  562. /* Key schedule-related tables from FIPS-46 */
  563. /* permuted choice table (key) */
  564. static const unsigned char pc1[] = {
  565. 57, 49, 41, 33, 25, 17, 9,
  566. 1, 58, 50, 42, 34, 26, 18,
  567. 10, 2, 59, 51, 43, 35, 27,
  568. 19, 11, 3, 60, 52, 44, 36,
  569. 63, 55, 47, 39, 31, 23, 15,
  570. 7, 62, 54, 46, 38, 30, 22,
  571. 14, 6, 61, 53, 45, 37, 29,
  572. 21, 13, 5, 28, 20, 12, 4
  573. };
  574. /* number left rotations of pc1 */
  575. static const unsigned char totrot[] = {
  576. 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
  577. };
  578. /* permuted choice key (table) */
  579. static const unsigned char pc2[] = {
  580. 14, 17, 11, 24, 1, 5,
  581. 3, 28, 15, 6, 21, 10,
  582. 23, 19, 12, 4, 26, 8,
  583. 16, 7, 27, 20, 13, 2,
  584. 41, 52, 31, 37, 47, 55,
  585. 30, 40, 51, 45, 33, 48,
  586. 44, 49, 39, 56, 34, 53,
  587. 46, 42, 50, 36, 29, 32
  588. };
  589. /* End of DES-defined tables */
  590. /* bit 0 is left-most in byte */
  591. static const int bytebit[] = {
  592. 0200,0100,040,020,010,04,02,01
  593. };
  594. /* Generate key schedule for encryption or decryption
  595. * depending on the value of "decrypt"
  596. */
  597. static void deskey (DES_KS k, unsigned char *key, int decrypt)
  598. {
  599. unsigned char pc1m[56]; /* place to modify pc1 into */
  600. unsigned char pcr[56]; /* place to rotate pc1 into */
  601. register int i,j,l;
  602. int m;
  603. unsigned char ks[8];
  604. for (j=0; j<56; j++) { /* convert pc1 to bits of key */
  605. l=pc1[j]-1; /* integer bit location */
  606. m = l & 07; /* find bit */
  607. pc1m[j]=(key[l>>3] & /* find which key byte l is in */
  608. bytebit[m]) /* and which bit of that byte */
  609. ? 1 : 0; /* and store 1-bit result */
  610. }
  611. for (i=0; i<16; i++) { /* key chunk for each iteration */
  612. memset (ks,0,sizeof (ks)); /* Clear key schedule */
  613. for (j=0; j<56; j++) /* rotate pc1 the right amount */
  614. pcr[j] = pc1m[(l = j + totrot[decrypt? 15 - i : i]) < (j < 28? 28 : 56) ? l: l - 28];
  615. /* rotate left and right halves independently */
  616. for (j=0; j<48; j++){ /* select bits individually */
  617. /* check bit that goes to ks[j] */
  618. if (pcr[pc2[j]-1]) {
  619. /* mask it in if it's there */
  620. l= j % 6;
  621. ks[j / 6] |= bytebit[l] >> 2;
  622. }
  623. }
  624. /* Now convert to packed odd/even interleaved form */
  625. k[i][0] = ((uint32_t) ks[0] << 24)
  626. | ((uint32_t) ks[2] << 16)
  627. | ((uint32_t) ks[4] << 8)
  628. | ((uint32_t) ks[6]);
  629. k[i][1] = ((uint32_t) ks[1] << 24)
  630. | ((uint32_t) ks[3] << 16)
  631. | ((uint32_t) ks[5] << 8)
  632. | ((uint32_t) ks[7]);
  633. }
  634. }
  635. #define HIKEYBITS(k,s) ((k[(s) / 8] << ((s) % 8)) & 0xFF)
  636. #define LOKEYBITS(k,s) (k[(s) / 8 + 1] >> (8 - (s) % 8))
  637. /* DES utils */
  638. /* Set up a key schedule based on a 56bit key */
  639. static void setup_schedule (const unsigned char *key_56, DES_KS ks)
  640. {
  641. unsigned char key[8];
  642. int i, c, bit;
  643. for (i = 0; i < 8; i++) {
  644. key[i] = HIKEYBITS (key_56, i * 7);
  645. /* Mask in the low bits only if they're used. It doesn't
  646. * matter if we get an unwanted bit 0; it's going to be
  647. * overwritten with parity anyway. */
  648. if (i && i < 7)
  649. key[i] |= LOKEYBITS(key_56, i * 7);
  650. /* Fix parity */
  651. for (c = bit = 0; bit < 8; bit++)
  652. if (key[i] & (1 << bit))
  653. c++;
  654. if (!(c & 1))
  655. key[i] ^= 0x01;
  656. }
  657. deskey (ks, key, 0);
  658. }
  659. #define LM_PASSWORD_MAGIC "\x4B\x47\x53\x21\x40\x23\x24\x25" \
  660. "\x4B\x47\x53\x21\x40\x23\x24\x25" \
  661. "\x00\x00\x00\x00\x00"
  662. static void ntlm_lanmanager_hash (const char *password, char hash[21])
  663. {
  664. unsigned char lm_password[15];
  665. DES_KS ks;
  666. int i;
  667. for (i = 0; i < 14 && password[i]; i++)
  668. lm_password[i] = toupper ((unsigned char) password[i]);
  669. for (; i < 15; i++)
  670. lm_password[i] = '\0';
  671. memcpy (hash, LM_PASSWORD_MAGIC, 21);
  672. setup_schedule (lm_password, ks);
  673. des (ks, (unsigned char *) hash);
  674. setup_schedule (lm_password + 7, ks);
  675. des (ks, (unsigned char *) hash + 8);
  676. memset(lm_password, 0, sizeof(lm_password));
  677. }
  678. static int ntlm_nt_hash (const char *pass, char hash[21])
  679. {
  680. struct oc_text_buf *utf16pass = buf_alloc();
  681. int ret;
  682. /* Preallocate just to ensure md4sum() doesn't have to realloc, which
  683. would leave a copy of the password lying around. There is always
  684. at least one byte of padding, then 8 bytes of length, and round up
  685. to the next multiple of 64. */
  686. ret = buf_ensure_space(utf16pass, ((strlen(pass) * 2) + 1 + 8 + 63) & ~63);
  687. if (ret)
  688. goto out;
  689. ret = buf_append_utf16le(utf16pass, pass);
  690. if (ret < 0)
  691. goto wipe;
  692. ret = buf_error(utf16pass);
  693. if (ret)
  694. goto wipe;
  695. ret = md4sum(utf16pass, (unsigned char *) hash);
  696. if (ret)
  697. goto wipe;
  698. memset(hash + 16, 0, 5);
  699. wipe:
  700. memset(utf16pass->data, 0, utf16pass->pos);
  701. out:
  702. buf_free(utf16pass);
  703. return 0;
  704. }
  705. static void ntlm_calc_response (const unsigned char key[21],
  706. const unsigned char plaintext[8],
  707. unsigned char results[24])
  708. {
  709. DES_KS ks;
  710. memcpy (results, plaintext, 8);
  711. memcpy (results + 8, plaintext, 8);
  712. memcpy (results + 16, plaintext, 8);
  713. setup_schedule (key, ks);
  714. des (ks, results);
  715. setup_schedule (key + 7, ks);
  716. des (ks, results + 8);
  717. setup_schedule (key + 14, ks);
  718. des (ks, results + 16);
  719. }
  720. #define NTLM_CHALLENGE_DOMAIN_OFFSET 12
  721. #define NTLM_CHALLENGE_FLAGS_OFFSET 20
  722. #define NTLM_CHALLENGE_NONCE_OFFSET 24
  723. #define NTLM_RESPONSE_BASE_SIZE 64
  724. #define NTLM_RESPONSE_LM_RESP_OFFSET 12
  725. #define NTLM_RESPONSE_NT_RESP_OFFSET 20
  726. #define NTLM_RESPONSE_DOMAIN_OFFSET 28
  727. #define NTLM_RESPONSE_USER_OFFSET 36
  728. #define NTLM_RESPONSE_HOST_OFFSET 44
  729. #define NTLM_RESPONSE_FLAGS_OFFSET 60
  730. static const char ntlm_response_base[NTLM_RESPONSE_BASE_SIZE] = {
  731. 'N', 'T', 'L', 'M', 'S', 'S', 'P', 0x00,
  732. 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  733. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  734. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  735. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  736. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  737. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  738. 0x00, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00
  739. };
  740. static void ntlm_set_string_utf8(struct oc_text_buf *buf, int offset,
  741. const char *data)
  742. {
  743. int oldpos = buf->pos;
  744. int len = buf_append_utf16le(buf, data);
  745. /* Fill in the SecurityBuffer pointing to the string */
  746. store_le16(buf->data + offset, len); /* len */
  747. store_le16(buf->data + offset + 2, len); /* allocated */
  748. store_le32(buf->data + offset + 4, oldpos); /* offset */
  749. }
  750. static void ntlm_set_string_binary(struct oc_text_buf *buf, int offset,
  751. const void *data, int len)
  752. {
  753. /* Fill in the SecurityBuffer pointing to the string */
  754. store_le16(buf->data + offset, len); /* len */
  755. store_le16(buf->data + offset + 2, len); /* allocated */
  756. store_le32(buf->data + offset + 4, buf->pos); /* offset */
  757. buf_append_bytes(buf, data, len);
  758. }
  759. static int ntlm_manual_challenge(struct openconnect_info *vpninfo, int proxy,
  760. struct http_auth_state *auth_state,
  761. struct oc_text_buf *hdrbuf,
  762. const char *domuser, const char *pass)
  763. {
  764. struct oc_text_buf *resp;
  765. char *user;
  766. unsigned char nonce[8], hash[21], lm_resp[24], nt_resp[24];
  767. unsigned char *token;
  768. int token_len = -EINVAL;
  769. int ntlmver;
  770. memset(hash, 0, sizeof(hash));
  771. if (!auth_state->challenge)
  772. return -EINVAL;
  773. if (ntlm_nt_hash (pass, (char *) hash))
  774. return -EINVAL;
  775. token = openconnect_base64_decode(&token_len,
  776. auth_state->challenge);
  777. if (!token)
  778. return token_len;
  779. if (token_len < NTLM_CHALLENGE_NONCE_OFFSET + 8 || token[0] != 'N' ||
  780. token[1] != 'T' || token[2] != 'L' || token[3] != 'M' ||
  781. token[4] != 'S' || token[5] != 'S' || token[6] != 'P' ||
  782. token[7] || token[8] != 2 || token[9] || token[10] || token[11]) {
  783. free(token);
  784. return -EINVAL;
  785. }
  786. /* 0x00080000: Negotiate NTLM2 Key */
  787. if (token[NTLM_CHALLENGE_FLAGS_OFFSET + 2] & 8) {
  788. /* NTLM2 session response */
  789. struct {
  790. uint32_t srv[2];
  791. uint32_t clnt[2];
  792. } sess_nonce;
  793. unsigned char digest[16];
  794. ntlmver = 2;
  795. if (openconnect_random(sess_nonce.clnt, sizeof(sess_nonce.clnt))) {
  796. free(token);
  797. return -EIO;
  798. }
  799. /* LM response is 8-byte client nonce, NUL-padded to 24 */
  800. memcpy (lm_resp, sess_nonce.clnt, 8);
  801. memset (lm_resp + 8, 0, 16);
  802. /* Session nonce is client nonce + server nonce */
  803. memcpy (sess_nonce.srv,
  804. token + NTLM_CHALLENGE_NONCE_OFFSET, 8);
  805. /* Take MD5 of session nonce */
  806. if (openconnect_md5(digest, &sess_nonce, sizeof(sess_nonce))) {
  807. free(token);
  808. return -EIO;
  809. }
  810. ntlm_calc_response (hash, digest, nt_resp);
  811. } else {
  812. /* NTLM1 */
  813. ntlmver = 1;
  814. memcpy (nonce, token + NTLM_CHALLENGE_NONCE_OFFSET, 8);
  815. ntlm_calc_response (hash, nonce, nt_resp);
  816. ntlm_lanmanager_hash (pass, (char *) hash);
  817. ntlm_calc_response (hash, nonce, lm_resp);
  818. }
  819. resp = buf_alloc();
  820. buf_append_bytes(resp, ntlm_response_base, sizeof(ntlm_response_base));
  821. if (buf_error(resp)) {
  822. free(token);
  823. return buf_free(resp);
  824. }
  825. /* Mask in the NTLM2SESSION flag */
  826. resp->data[NTLM_RESPONSE_FLAGS_OFFSET + 2] = token[NTLM_CHALLENGE_FLAGS_OFFSET + 2] & 8;
  827. user = strchr(domuser, '\\');
  828. if (user) {
  829. *user = 0;
  830. ntlm_set_string_utf8(resp, NTLM_RESPONSE_DOMAIN_OFFSET, domuser);
  831. *user = '\\';
  832. user++;
  833. } else {
  834. int offset = load_le32(token + NTLM_CHALLENGE_DOMAIN_OFFSET + 4);
  835. int len = load_le16(token + NTLM_CHALLENGE_DOMAIN_OFFSET);
  836. if (!len || offset + len >= token_len) {
  837. free(token);
  838. buf_free(resp);
  839. return -EINVAL;
  840. }
  841. ntlm_set_string_binary(resp, NTLM_RESPONSE_DOMAIN_OFFSET, token + offset, len);
  842. user = (char *)domuser;
  843. }
  844. ntlm_set_string_utf8(resp, NTLM_RESPONSE_USER_OFFSET, user);
  845. ntlm_set_string_utf8(resp, NTLM_RESPONSE_HOST_OFFSET, "UNKNOWN");
  846. ntlm_set_string_binary(resp, NTLM_RESPONSE_LM_RESP_OFFSET, lm_resp, sizeof(lm_resp));
  847. ntlm_set_string_binary(resp, NTLM_RESPONSE_NT_RESP_OFFSET, nt_resp, sizeof(nt_resp));
  848. free(token);
  849. if (buf_error(resp))
  850. return buf_free(resp);
  851. buf_append(hdrbuf, "%sAuthorization: NTLM ", proxy ? "Proxy-" : "");
  852. buf_append_base64(hdrbuf, resp->data, resp->pos, 0);
  853. buf_append(hdrbuf, "\r\n");
  854. buf_free(resp);
  855. if (proxy)
  856. vpn_progress(vpninfo, PRG_INFO,
  857. _("Attempting HTTP NTLMv%d authentication to proxy\n"),
  858. ntlmver);
  859. else
  860. vpn_progress(vpninfo, PRG_INFO,
  861. _("Attempting HTTP NTLMv%d authentication to server '%s'\n"),
  862. ntlmver, vpninfo->hostname);
  863. return 0;
  864. }
  865. int ntlm_authorization(struct openconnect_info *vpninfo, int proxy,
  866. struct http_auth_state *auth_state, struct oc_text_buf *buf)
  867. {
  868. const char *user, *pass;
  869. if (proxy) {
  870. user = vpninfo->proxy_user;
  871. pass = vpninfo->proxy_pass;
  872. } else {
  873. user = pass = NULL;
  874. }
  875. if (auth_state->state == AUTH_AVAILABLE) {
  876. auth_state->state = NTLM_MANUAL;
  877. /* Don't attempt automatic NTLM auth if we were given a password */
  878. if (!pass && !ntlm_helper_spawn(vpninfo, proxy, auth_state, buf)) {
  879. auth_state->state = NTLM_SSO_REQ;
  880. return 0;
  881. }
  882. }
  883. if (auth_state->state == NTLM_SSO_REQ) {
  884. int ret;
  885. ret = ntlm_helper_challenge(vpninfo, proxy, auth_state, buf);
  886. /* Clean up after it. We're done here, whether it worked or not */
  887. cleanup_ntlm_auth(vpninfo, auth_state);
  888. auth_state->state = NTLM_MANUAL;
  889. if (ret == -EAGAIN) {
  890. /* Don't let it reset our state when it reconnects */
  891. if (proxy)
  892. vpninfo->proxy_close_during_auth = 1;
  893. return ret;
  894. }
  895. if (!ret)
  896. return ret;
  897. }
  898. if (auth_state->state == NTLM_MANUAL && user && pass) {
  899. buf_append(buf, "%sAuthorization: NTLM %s\r\n", proxy ? "Proxy-" : "",
  900. "TlRMTVNTUAABAAAABYIIAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAA");
  901. auth_state->state = NTLM_MANUAL_REQ;
  902. return 0;
  903. }
  904. if (auth_state->state == NTLM_MANUAL_REQ && user && pass &&
  905. !ntlm_manual_challenge(vpninfo, proxy, auth_state, buf, user, pass)) {
  906. /* Leave the state as it is. If we come back there'll be no
  907. challenge string and we'll fail then. */
  908. return 0;
  909. }
  910. auth_state->state = AUTH_FAILED;
  911. return -EAGAIN;
  912. }