📄 ntlm_auth.c
字号:
DEBUG(1, ("Need username and domain for NTLMSSP\n")); return NT_STATUS_INVALID_PARAMETER; } status = ntlmssp_client_start(client_ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not start NTLMSSP client: %s\n", nt_errstr(status))); ntlmssp_end(client_ntlmssp_state); return status; } status = ntlmssp_set_username(*client_ntlmssp_state, opt_username); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set username: %s\n", nt_errstr(status))); ntlmssp_end(client_ntlmssp_state); return status; } status = ntlmssp_set_domain(*client_ntlmssp_state, opt_domain); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set domain: %s\n", nt_errstr(status))); ntlmssp_end(client_ntlmssp_state); return status; } status = ntlmssp_set_password(*client_ntlmssp_state, opt_password); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not set password: %s\n", nt_errstr(status))); ntlmssp_end(client_ntlmssp_state); return status; } return NT_STATUS_OK;}static NTSTATUS ntlm_auth_start_ntlmssp_server(NTLMSSP_STATE **ntlmssp_state) { NTSTATUS status = ntlmssp_server_start(ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Could not start NTLMSSP client: %s\n", nt_errstr(status))); return status; } /* Have we been given a local password, or should we ask winbind? */ if (opt_password) { (*ntlmssp_state)->check_password = local_pw_check; (*ntlmssp_state)->get_domain = lp_workgroup; (*ntlmssp_state)->get_global_myname = global_myname; } else { (*ntlmssp_state)->check_password = winbind_pw_check; (*ntlmssp_state)->get_domain = get_winbind_domain; (*ntlmssp_state)->get_global_myname = get_winbind_netbios_name; } return NT_STATUS_OK;}static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; DATA_BLOB request, reply; NTSTATUS nt_status; if (strlen(buf) < 2) { DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); return; } if (strlen(buf) > 3) { request = base64_decode_data_blob(buf + 3); } else { request = data_blob(NULL, 0); } if ((strncmp(buf, "PW ", 3) == 0)) { /* The calling application wants us to use a local password (rather than winbindd) */ opt_password = SMB_STRNDUP((const char *)request.data, request.length); if (opt_password == NULL) { DEBUG(1, ("Out of memory\n")); x_fprintf(x_stdout, "BH\n"); data_blob_free(&request); return; } x_fprintf(x_stdout, "OK\n"); data_blob_free(&request); return; } if (strncmp(buf, "YR", 2) == 0) { if (ntlmssp_state) ntlmssp_end(&ntlmssp_state); } else if (strncmp(buf, "KK", 2) == 0) { } else { DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); return; } if (!ntlmssp_state) { if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); return; } } DEBUG(10, ("got NTLMSSP packet:\n")); dump_data(10, (const char *)request.data, request.length); nt_status = ntlmssp_update(ntlmssp_state, request, &reply); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { char *reply_base64 = base64_encode_data_blob(reply); x_fprintf(x_stdout, "TT %s\n", reply_base64); SAFE_FREE(reply_base64); data_blob_free(&reply); DEBUG(10, ("NTLMSSP challenge\n")); } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); ntlmssp_end(&ntlmssp_state); } else if (!NT_STATUS_IS_OK(nt_status)) { x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); } else { x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context); DEBUG(10, ("NTLMSSP OK!\n")); } data_blob_free(&request);}static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; DATA_BLOB request, reply; NTSTATUS nt_status; BOOL first = False; if (strlen(buf) < 2) { DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); return; } if (strlen(buf) > 3) { request = base64_decode_data_blob(buf + 3); } else { request = data_blob(NULL, 0); } if (strncmp(buf, "PW ", 3) == 0) { /* We asked for a password and obviously got it :-) */ opt_password = SMB_STRNDUP((const char *)request.data, request.length); if (opt_password == NULL) { DEBUG(1, ("Out of memory\n")); x_fprintf(x_stdout, "BH\n"); data_blob_free(&request); return; } x_fprintf(x_stdout, "OK\n"); data_blob_free(&request); return; } if (opt_password == NULL) { /* Request a password from the calling process. After sending it, the calling process should retry asking for the negotiate. */ DEBUG(10, ("Requesting password\n")); x_fprintf(x_stdout, "PW\n"); return; } if (strncmp(buf, "YR", 2) == 0) { if (ntlmssp_state) ntlmssp_end(&ntlmssp_state); } else if (strncmp(buf, "TT", 2) == 0) { } else { DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); return; } if (!ntlmssp_state) { if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_client(&ntlmssp_state))) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); return; } first = True; } DEBUG(10, ("got NTLMSSP packet:\n")); dump_data(10, (const char *)request.data, request.length); nt_status = ntlmssp_update(ntlmssp_state, request, &reply); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { char *reply_base64 = base64_encode_data_blob(reply); if (first) { x_fprintf(x_stdout, "YR %s\n", reply_base64); } else { x_fprintf(x_stdout, "KK %s\n", reply_base64); } SAFE_FREE(reply_base64); data_blob_free(&reply); DEBUG(10, ("NTLMSSP challenge\n")); } else if (NT_STATUS_IS_OK(nt_status)) { char *reply_base64 = base64_encode_data_blob(reply); x_fprintf(x_stdout, "AF %s\n", reply_base64); DEBUG(10, ("NTLMSSP OK!\n")); if (ntlmssp_state) ntlmssp_end(&ntlmssp_state); } else { x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); if (ntlmssp_state) ntlmssp_end(&ntlmssp_state); } data_blob_free(&request);}static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { char *user, *pass; user=buf; pass=memchr(buf,' ',length); if (!pass) { DEBUG(2, ("Password not found. Denying access\n")); x_fprintf(x_stdout, "ERR\n"); return; } *pass='\0'; pass++; if (stdio_helper_mode == SQUID_2_5_BASIC) { rfc1738_unescape(user); rfc1738_unescape(pass); } if (check_plaintext_auth(user, pass, False)) { x_fprintf(x_stdout, "OK\n"); } else { x_fprintf(x_stdout, "ERR\n"); }}static void offer_gss_spnego_mechs(void) { DATA_BLOB token; SPNEGO_DATA spnego; ssize_t len; char *reply_base64; pstring principal; pstring myname_lower; ZERO_STRUCT(spnego); pstrcpy(myname_lower, global_myname()); strlower_m(myname_lower); pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm()); /* Server negTokenInit (mech offerings) */ spnego.type = SPNEGO_NEG_TOKEN_INIT; spnego.negTokenInit.mechTypes = SMB_XMALLOC_ARRAY(const char *, 2);#ifdef HAVE_KRB5 spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD); spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP); spnego.negTokenInit.mechTypes[2] = NULL;#else spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_NTLMSSP); spnego.negTokenInit.mechTypes[1] = NULL;#endif spnego.negTokenInit.mechListMIC = data_blob(principal, strlen(principal)); len = write_spnego_data(&token, &spnego); free_spnego_data(&spnego); if (len == -1) { DEBUG(1, ("Could not write SPNEGO data blob\n")); x_fprintf(x_stdout, "BH\n"); return; } reply_base64 = base64_encode_data_blob(token); x_fprintf(x_stdout, "TT %s *\n", reply_base64); SAFE_FREE(reply_base64); data_blob_free(&token); DEBUG(10, ("sent SPNEGO negTokenInit\n")); return;}static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; SPNEGO_DATA request, response; DATA_BLOB token; NTSTATUS status; ssize_t len; char *user = NULL; char *domain = NULL; const char *reply_code; char *reply_base64; pstring reply_argument; if (strlen(buf) < 2) { DEBUG(1, ("SPENGO query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); return; } if (strncmp(buf, "YR", 2) == 0) { if (ntlmssp_state) ntlmssp_end(&ntlmssp_state); } else if (strncmp(buf, "KK", 2) == 0) { } else { DEBUG(1, ("SPENGO query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); return; } if ( (strlen(buf) == 2)) { /* no client data, get the negTokenInit offering mechanisms */ offer_gss_spnego_mechs(); return; } /* All subsequent requests have a blob. This might be negTokenInit or negTokenTarg */ if (strlen(buf) <= 3) { DEBUG(1, ("GSS-SPNEGO query [%s] invalid\n", buf)); x_fprintf(x_stdout, "BH\n"); return; } token = base64_decode_data_blob(buf + 3); len = read_spnego_data(token, &request); data_blob_free(&token); if (len == -1) { DEBUG(1, ("GSS-SPNEGO query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); return; } if (request.type == SPNEGO_NEG_TOKEN_INIT) { /* Second request from Client. This is where the client offers its mechanism to use. */ if ( (request.negTokenInit.mechTypes == NULL) || (request.negTokenInit.mechTypes[0] == NULL) ) { DEBUG(1, ("Client did not offer any mechanism")); x_fprintf(x_stdout, "BH\n"); return; } status = NT_STATUS_UNSUCCESSFUL; if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) { if ( request.negTokenInit.mechToken.data == NULL ) { DEBUG(1, ("Client did not provide NTLMSSP data\n")); x_fprintf(x_stdout, "BH\n"); return; } if ( ntlmssp_state != NULL ) { DEBUG(1, ("Client wants a new NTLMSSP challenge, but " "already got one\n")); x_fprintf(x_stdout, "BH\n"); ntlmssp_end(&ntlmssp_state); return; } if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) { x_fprintf(x_stdout, "BH %s\n", nt_errstr(status)); return; } DEBUG(10, ("got NTLMSSP packet:\n")); dump_data(10, (const char *)request.negTokenInit.mechToken.data, request.negTokenInit.mechToken.length); response.type = SPNEGO_NEG_TOKEN_TARG; response.negTokenTarg.supportedMech = SMB_STRDUP(OID_NTLMSSP); response.negTokenTarg.mechListMIC = data_blob(NULL, 0); status = ntlmssp_update(ntlmssp_state, request.negTokenInit.mechToken, &response.negTokenTarg.responseToken); }#ifdef HAVE_KRB5 if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) { TALLOC_CTX *mem_ctx = talloc_init("manage_gss_spnego_request"); char *principal; DATA_BLOB ap_rep; DATA_BLOB session_key; if ( request.negTokenInit.mechToken.data == NULL ) { DEBUG(1, ("Client did not provide Kerberos data\n")); x_fprintf(x_stdout, "BH\n"); return; } response.type = SPNEGO_NEG_TOKEN_TARG; response.negTokenTarg.supportedMech = SMB_STRDUP(OID_KERBEROS5_OLD); response.negTokenTarg.mechListMIC = data_blob(NULL, 0); response.negTokenTarg.responseToken = data_blob(NULL, 0); status = ads_verify_ticket(mem_ctx, lp_realm(), &request.negTokenInit.mechToken, &principal, NULL, &ap_rep, &session_key); talloc_destroy(mem_ctx); /* Now in "principal" we have the name we are authenticated as. */ if (NT_STATUS_IS_OK(status)) { domain = strchr_m(principal, '@'); if (domain == NULL) { DEBUG(1, ("Did not get a valid principal " "from ads_verify_ticket\n")); x_fprintf(x_stdout, "BH\n"); return; } *domain++ = '\0'; domain = SMB_STRDUP(domain);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -