int www_authenticate(int sd, rr_data_t request, rr_data_t response, struct auth_s *creds) { char *tmp, *buf, *challenge; rr_data_t auth; int len; int rc = 0; buf = new(BUFSIZE); strcpy(buf, "NTLM "); len = ntlm_request(&tmp, creds); if (len) { to_base64(MEM(buf, unsigned char, 5), MEM(tmp, unsigned char, 0), len, BUFSIZE-5); free(tmp); } auth = dup_rr_data(request); auth->headers = hlist_mod(auth->headers, "Connection", "keep-alive", 1); auth->headers = hlist_mod(auth->headers, "Authorization", buf, 1); auth->headers = hlist_mod(auth->headers, "Content-Length", "0", 1); auth->headers = hlist_del(auth->headers, "Transfer-Encoding"); /* * Drop whatever error page server returned */ if (!http_body_drop(sd, response)) goto bailout; if (debug) { printf("\nSending WWW auth request...\n"); hlist_dump(auth->headers); } if (!headers_send(sd, auth)) goto bailout; if (debug) printf("\nReading WWW auth response...\n"); /* * Get NTLM challenge */ reset_rr_data(auth); if (!headers_recv(sd, auth)) { goto bailout; } if (debug) hlist_dump(auth->headers); /* * Auth required? */ if (auth->code == 401) { if (!http_body_drop(sd, auth)) goto bailout; tmp = hlist_get(auth->headers, "WWW-Authenticate"); if (tmp && strlen(tmp) > 6 + 8) { challenge = new(strlen(tmp) + 5 + 1); len = from_base64(challenge, tmp + 5); if (len > NTLM_CHALLENGE_MIN) { len = ntlm_response(&tmp, challenge, len, creds); if (len > 0) { strcpy(buf, "NTLM "); to_base64(MEM(buf, unsigned char, 5), MEM(tmp, unsigned char, 0), len, BUFSIZE-5); request->headers = hlist_mod(request->headers, "Authorization", buf, 1); free(tmp); } else {
/** * Report NTLM authentication test result * * @v test Authentication test * @v file Test code file * @v line Test code line */ static void ntlm_authenticate_okx ( struct ntlm_authenticate_test *test, const char *file, unsigned int line ) { struct ntlm_authenticate *expected = test->expected; struct ntlm_challenge_info info; struct ntlm_authenticate *auth; struct ntlm_key key; struct ntlm_lm_response lm; struct ntlm_nt_response nt; size_t len; /* Parse Challenge message */ okx ( ntlm_challenge ( test->challenge, test->challenge_len, &info ) == 0, file, line ); /* Generate key */ ntlm_key ( test->domain, test->username, test->password, &key ); /* Generate responses */ ntlm_response ( &info, &key, &test->nonce, &lm, &nt ); /* Allocate buffer for Authenticate message */ len = ntlm_authenticate_len ( &info, test->domain, test->username, test->workstation ); okx ( len >= sizeof ( *auth ), file, line ); auth = malloc ( len ); okx ( auth != NULL, file, line ); /* Construct Authenticate message */ okx ( ntlm_authenticate ( &info, test->domain, test->username, test->workstation, &lm, &nt, auth ) == len, file, line ); /* Verify header */ okx ( memcmp ( &auth->header, &expected->header, sizeof ( auth->header ) ) == 0, file, line ); /* Verify LAN Manager response */ ntlm_data_okx ( &auth->header, len, &auth->lm, &expected->header, &expected->lm, "LM", file, line ); /* Verify NT response */ ntlm_data_okx ( &auth->header, len, &auth->nt, &expected->header, &expected->nt, "NT", file, line ); /* Verify domain name */ ntlm_data_okx ( &auth->header, len, &auth->domain, &expected->header, &expected->domain, "domain", file, line ); /* Verify user name */ ntlm_data_okx ( &auth->header, len, &auth->user, &expected->header, &expected->user, "user", file, line ); /* Verify workstation name */ ntlm_data_okx ( &auth->header, len, &auth->workstation, &expected->header, &expected->workstation, "workstation",file, line ); /* Verify session key */ if ( auth->flags & NTLM_NEGOTIATE_KEY_EXCH ) { ntlm_data_okx ( &auth->header, len, &auth->session, &expected->header, &expected->session, "session", file, line ); } /* Free Authenticate message */ free ( auth ); }