📄 ntlm_auth.c
字号:
dlen = strlen(domain); hlen = strlen(host); ulen = strlen(user); lm_len = 0x18; nt_len = 0x18; dofs = 64; uofs = dofs + dlen; hofs = uofs + ulen; lm_ofs = hofs + hlen; nt_ofs = lm_ofs + lm_len; msgtk_size = 64 + dlen + ulen + hlen + lm_len + nt_len; memset(&msg, '\0', sizeof(msg));#ifndef NTLM_UNPACKED_STRUCT strcpy(msg.protocol, "NTLMSSP"); msg.type = 0x03; msg.flags = 0x8201; msg.dom_len = msg.dom_len2 = ntlm_do_litle_endian_short(dlen); msg.dom_off = ntlm_do_litle_endian_short(dofs); msg.user_len = msg.user_len2 = ntlm_do_litle_endian_short(ulen); msg.user_off = ntlm_do_litle_endian_short(uofs); msg.host_len = msg.host_len2 = ntlm_do_litle_endian_short(hlen); msg.host_off = ntlm_do_litle_endian_short(hofs); msg.lm_resp_len = msg.lm_resp_len2 = ntlm_do_litle_endian_short(lm_len); msg.lm_resp_off = ntlm_do_litle_endian_short(lm_ofs); msg.nt_resp_len = msg.nt_resp_len2 = ntlm_do_litle_endian_short(nt_len); msg.nt_resp_off = ntlm_do_litle_endian_short(nt_ofs); msg.msg_len = ntlm_do_litle_endian_short(msgtk_size);#else strcpy(msg, "NTLMSSP"); msg[8] = 0x3; msg[12] = msg[14] = _LB(lm_len); msg[13] = msg[15] = _HB(lm_len); msg[16] = _LB(lm_ofs); msg[17] = _HB(lm_ofs); msg[20] = msg[22] = _LB(nt_len); msg[21] = msg[23] = _HB(nt_len); msg[24] = _LB(nt_ofs); msg[25] = _HB(nt_ofs); msg[28] = msg[30] = _LB(dlen); msg[29] = msg[31] = _HB(dlen); msg[32] = _LB(dofs); msg[33] = _HB(dofs); msg[36] = msg[38] = _LB(ulen); msg[37] = msg[39] = _HB(ulen); msg[40] = _LB(uofs); msg[41] = _HB(uofs); msg[44] = msg[46] = _LB(hlen); msg[45] = msg[47] = _HB(hlen); msg[48] = _LB(hofs); msg[49] = _HB(hofs); msg[56] = _LB(msgtk_size); msg[57] = _HB(msgtk_size); msg[60] = 0x1; msg[61] = 0x82;#endif strcpy(((char *) &msg) + dofs, domain); upperstr(((char *) &msg) + dofs); strcpy(((char *) &msg) + uofs, user); strcpy(((char *) &msg) + hofs, host); upperstr(((char *) &msg) + hofs); ntlm_gen_lm_resp(pass, nonce, ((char *) &msg) + lm_ofs); ntlm_gen_nt_resp(pass, nonce, ((char *) &msg) + nt_ofs); return base64_encode_data((char *) &msg, msgtk_size);}char *ntlm_get_t3msg_str(char *domain, char *host, char *user, char *pass, char *nonce, unsigned short t2flags){ return (t2flags & 0x01) ? ntlm_get_t3msg_wcstr(domain, host, user, pass, nonce) : ntlm_get_t3msg_asciistr(domain, host, user, pass, nonce);}/* * -1 - failure before sending auth data - http_process_response() can * continue safely * 0 - OK - http_process_response() must return immediately * 1 - failure after sending auth data - http_process_response() must * return immediately */int ntlm_negotiate_connection(doc * docp, char *authtag){ char *ntlm_msg, *nonce; unsigned short t2_flags; http_response *resp; char *user, *pass, *domain, *host; authinfo *ai; char shost[128]; int l; if(docp->num_auth) return -1; docp->num_auth++; xprintf(1, gettext("Trying to do NTLM authorization\n")); /*** it seems we should allow the first response ***/ /*** to be sent via non persistent connection ***/#if 0 /*** supported only when persistant connections are ***/ /*** supported by server and we are talking HTTP/1.1 ***/ if(!docp->is_persistent) { xprintf(1, gettext ("NTLM authorization supported only on persistent connections!\n")); docp->errcode = ERR_HTTP_AUTH_NTLM; return -1; }#endif /*** get authorization infos (all mandatory) ***/ ai = authinfo_match_entry(docp->doc_url->type, url_get_site(docp->doc_url), url_get_port(docp->doc_url), url_get_path(docp->doc_url), NULL); domain = (ai && ai->ntlm_domain) ? ai->ntlm_domain : priv_cfg.auth_ntlm_domain; l = strcspn(cfg.local_host, "."); if (l > 127) { l = 127; } strncpy(shost, cfg.local_host, l); shost[l] = '\0'; host = shost; user = url_get_user(docp->doc_url, NULL); pass = url_get_pass(docp->doc_url, NULL); if(!domain || !user || !pass || !host) { xprintf(1, gettext("Not enough data for NTLM authorization!\n")); xprintf(1, gettext("Missing:\n")); if(!domain) xprintf(1, gettext(" domain\n")); if(!user) xprintf(1, gettext(" username\n")); if(!pass) xprintf(1, gettext(" password\n")); if(!host) xprintf(1, gettext(" local hostname\n")); return -1; } /*** read body of 401 response ***/ if(http_throw_message_body(docp)) { docp->is_persistent = FALSE; abs_close_socket(docp, FALSE); return 1; } abs_close_socket(docp, FALSE); /*** prepare and send NTLM msg type 1 to ***/ /*** start NTLM negotiation with server ***/ ntlm_msg = ntlm_get_t1msg_str(domain, host); docp->additional_headers = tl_str_concat(NULL, "Authorization: NTLM ", ntlm_msg, "\r\n", NULL); _free(ntlm_msg); _free(docp->mime); _free(docp->type_str); l = http_repeat_request(docp); _free(docp->additional_headers); if(l) return -1; /*** now we expect 401 server response with ***/ /*** NTLM msg type 2 which contains nonce ***/ resp = http_get_response_info(docp->mime); if(!resp) { xprintf(1, gettext("Got unexpected response\n")); if(!docp->errcode) docp->errcode = ERR_HTTP_AUTH_NTLM; return -1; } if(resp->ret_code != 401) { xprintf(1, gettext("Got unexpected response\n")); docp->errcode = ERR_HTTP_AUTH_NTLM; http_response_free(resp); return -1; } http_response_free(resp); if(!docp->is_persistent) { xprintf(1, gettext ("NTLM authorization supported only on persistent connections!\n")); docp->errcode = ERR_HTTP_AUTH_NTLM; return -1; } if(http_throw_message_body(docp)) { docp->is_persistent = FALSE; abs_close_socket(docp, FALSE); return 1; } authtag = get_mime_param_val_str("WWW-Authenticate: NTLM ", docp->mime); if(!authtag) { xprintf(1, gettext("Got unexpected response\n")); docp->errcode = ERR_HTTP_AUTH_NTLM; return -1; } nonce = ntlm_get_nonce(authtag, &t2_flags); _free(authtag); if(!nonce) { xprintf(1, gettext("Failed NTLM nonce negotiation\n")); docp->errcode = ERR_HTTP_AUTH_NTLM; return -1; } /*** final step of NTLM authorization - prepare ***/ /*** and send NTLM msg type 3 with all auth. infos ***/ ntlm_msg = ntlm_get_t3msg_str(domain, host, user, pass, nonce, t2_flags); docp->additional_headers = tl_str_concat(NULL, "Authorization: NTLM ", ntlm_msg, "\r\n", NULL); _free(ntlm_msg); _free(nonce); _free(docp->mime); _free(docp->type_str); l = http_repeat_request(docp); _free(docp->additional_headers); if(l) return -1; return 0;}int ntlm_negotiate_proxy_connection(doc * docp, char *authtag){ char *ntlm_msg, *nonce; unsigned short t2_flags; http_response *resp; char *user, *pass, *domain, *host; authinfo *ai; char shost[128]; int l; if(docp->num_proxy_auth) return -1; if(!docp->http_proxy) return -1; xprintf(1, gettext("Trying to do proxy NTLM authorization\n")); docp->num_proxy_auth++; docp->errcode = ERR_HTTP_PROAUTH_NTLM; /*** it seems we should allow the first response ***/ /*** to be sent via non persistent connection ***/#if 0 /*** supported only when persistant connections are ***/ /*** supported by server and we are talking HTTP/1.1 ***/ if(!docp->is_persistent) { xprintf(1, gettext ("NTLM authorization supported only on persistent connections!\n")); return -1; }#endif /*** get authorization infos (all mandatory) ***/ ai = authinfo_match_entry(docp->doc_url->type, docp->http_proxy, docp->http_proxy_port, NULL, NULL); domain = (ai && ai->ntlm_domain) ? ai->ntlm_domain : priv_cfg.auth_proxy_ntlm_domain; l = strcspn(cfg.local_host, "."); if (l > 127) { l = 127; } strncpy(shost, cfg.local_host, l); shost[l] = '\0'; host = shost; user = priv_cfg.http_proxy_user; pass = priv_cfg.http_proxy_pass; if(!domain || !user || !pass || !host) { xprintf(1, gettext("Not enough data for NTLM authorization!\n")); xprintf(1, gettext("Missing:\n")); if(!domain) xprintf(1, gettext(" domain\n")); if(!user) xprintf(1, gettext(" username\n")); if(!pass) xprintf(1, gettext(" password\n")); if(!host) xprintf(1, gettext(" local hostname\n")); return -1; } /*** read body of 407 response ***/ if(http_throw_message_body(docp)) { docp->is_persistent = FALSE; abs_close_socket(docp, FALSE); return 1; } abs_close_socket(docp, FALSE); /*** prepare and send NTLM msg type 1 to ***/ /*** start NTLM negotiation with server ***/ ntlm_msg = ntlm_get_t1msg_str(domain, host); docp->additional_headers = tl_str_concat(NULL, "Proxy-Authorization: NTLM ", ntlm_msg, "\r\n", NULL); _free(ntlm_msg); _free(docp->mime); _free(docp->type_str); l = http_repeat_request(docp); _free(docp->additional_headers); if(l) return -1; /*** now we expect 407 server response with ***/ /*** NTLM msg type 2 which contains nonce ***/ resp = http_get_response_info(docp->mime); if(!resp) { xprintf(1, gettext("Got unexpected response\n")); if(!docp->errcode) docp->errcode = ERR_HTTP_PROAUTH_NTLM; return -1; } if(resp->ret_code != 407) { xprintf(1, gettext("Got unexpected response\n")); docp->errcode = ERR_HTTP_PROAUTH_NTLM; http_response_free(resp); return -1; } http_response_free(resp); if(!docp->is_persistent) { xprintf(1, gettext ("NTLM authorization supported only on persistent connections!\n")); docp->errcode = ERR_HTTP_PROAUTH_NTLM; return -1; } if(http_throw_message_body(docp)) { docp->is_persistent = FALSE; abs_close_socket(docp, FALSE); return 1; } authtag = get_mime_param_val_str("Proxy-Authenticate: NTLM ", docp->mime); if(!authtag) { xprintf(1, gettext("Got unexpected response\n")); docp->errcode = ERR_HTTP_PROAUTH_NTLM; return -1; } nonce = ntlm_get_nonce(authtag, &t2_flags); _free(authtag); if(!nonce) { xprintf(1, gettext("Failed NTLM proxy nonce negotiation\n")); docp->errcode = ERR_HTTP_PROAUTH_NTLM; return -1; } /*** final step of NTLM authorization - prepare ***/ /*** and send NTLM msg type 3 with all auth. infos ***/ ntlm_msg = ntlm_get_t3msg_str(domain, host, user, pass, nonce, t2_flags); docp->additional_headers = tl_str_concat(NULL, "Proxy-Authorization: NTLM ", ntlm_msg, "\r\n", NULL); _free(ntlm_msg); _free(nonce); _free(docp->mime); _free(docp->type_str); l = http_repeat_request(docp); if(l) return -1; return 0;}#endif /* ENABLE_NTLM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -