void helperfail(const char *reason) { #if FAIL_DEBUG fail_debug_enabled = 1; #endif SEND2("BH %s", reason); }
void authfail(char *domain, char *user, char *reason) { /* TODO: -move away from SEND-type gcc-isms * -prepare for protocol extension as soon as rbcollins is ready */ SEND2("NA %s\\%s auth failure because: %s", domain, user, reason); }
void send_bh_or_ld(char const *bhmessage, ntlm_authenticate * failedauth, int authlen) { #ifdef NTLM_FAIL_OPEN char *creds = NULL; if (last_ditch_enabled) { creds = fetch_credentials(failedauth, authlen); if (creds) { lc(creds); SEND2("LD %s", creds); } else { SEND("NA last-ditch on, but no credentials"); } } else { #endif SEND2("BH %s", bhmessage); #ifdef NTLM_FAIL_OPEN } #endif }
void manage_request() { ntlmhdr *fast_header; char buf[BUFFER_SIZE]; const char *ch; char *ch2, *decoded, *cred = NULL; int plen; if (fgets(buf, BUFFER_SIZE, stdin) == NULL) { fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno, strerror(errno)); exit(1); /* BIIG buffer */ } debug("managing request\n"); ch2 = memchr(buf, '\n', BUFFER_SIZE); /* safer against overrun than strchr */ if (ch2) { *ch2 = '\0'; /* terminate the string at newline. */ ch = ch2; } debug("ntlm authenticator. Got '%s' from Squid\n", buf); if (memcmp(buf, "KK ", 3) == 0) { /* authenticate-request */ /* figure out what we got */ decoded = base64_decode(buf + 3); /* Note: we don't need to manage memory at this point, since * base64_decode returns a pointer to static storage. */ if (!decoded) { /* decoding failure, return error */ SEND("NA Packet format error, couldn't base64-decode"); return; } /* fast-track-decode request type. */ fast_header = (struct _ntlmhdr *) decoded; /* sanity-check: it IS a NTLMSSP packet, isn't it? */ if (memcmp(fast_header->signature, "NTLMSSP", 8) != 0) { SEND("NA Broken authentication packet"); return; } switch (le32toh(fast_header->type)) { case NTLM_NEGOTIATE: SEND("NA Invalid negotiation request received"); return; /* notreached */ case NTLM_CHALLENGE: SEND("NA Got a challenge. We refuse to have our authority disputed"); return; /* notreached */ case NTLM_AUTHENTICATE: /* check against the DC */ plen = strlen(buf) * 3 / 4; /* we only need it here. Optimization */ signal(SIGALRM, timeout_during_auth); alarm(30); cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen); alarm(0); signal(SIGALRM, SIG_DFL); if (got_timeout != 0) { fprintf(stderr, "ntlm-auth[%ld]: Timeout during authentication.\n", (long)getpid()); SEND("BH Timeout during authentication"); got_timeout = 0; return; } if (cred == NULL) { int smblib_err, smb_errorclass, smb_errorcode, nb_error; if (ntlm_errno == NTLM_LOGON_ERROR) { /* hackish */ SEND("NA Logon Failure"); return; } /* there was an error. We have two errno's to look at. * libntlmssp's erno is insufficient, we'll have to look at * the actual SMB library error codes, to acually figure * out what's happening. The thing has braindamaged interfacess..*/ smblib_err = SMB_Get_Last_Error(); smb_errorclass = SMBlib_Error_Class(SMB_Get_Last_SMB_Err()); smb_errorcode = SMBlib_Error_Code(SMB_Get_Last_SMB_Err()); nb_error = RFCNB_Get_Last_Error(); debug("No creds. SMBlib error %d, SMB error class %d, SMB error code %d, NB error %d\n", smblib_err, smb_errorclass, smb_errorcode, nb_error); /* Should I use smblib_err? Actually it seems I can do as well * without it.. */ if (nb_error != 0) { /* netbios-level error */ send_bh_or_ld("NetBios error!", (ntlm_authenticate *) decoded, plen); fprintf(stderr, "NetBios error code %d (%s)\n", nb_error, RFCNB_Error_Strings[abs(nb_error)]); return; } switch (smb_errorclass) { case SMBC_SUCCESS: debug("Huh? Got a SMB success code but could check auth.."); SEND("NA Authentication failed"); /* * send_bh_or_ld("SMB success, but no creds. Internal error?", * (ntlm_authenticate *) decoded, plen); */ return; case SMBC_ERRDOS: /*this is the most important one for errors */ debug("DOS error\n"); switch (smb_errorcode) { /* two categories matter to us: those which could be * server errors, and those which are auth errors */ case SMBD_noaccess: /* 5 */ SEND("NA Access denied"); return; case SMBD_badformat: SEND("NA bad format in authentication packet"); return; case SMBD_badaccess: SEND("NA Bad access request"); return; case SMBD_baddata: SEND("NA Bad Data"); return; default: send_bh_or_ld("DOS Error", (ntlm_authenticate *) decoded, plen); return; } case SMBC_ERRSRV: /* server errors */ debug("Server error"); switch (smb_errorcode) { /* mostly same as above */ case SMBV_badpw: SEND("NA Bad password"); return; case SMBV_access: SEND("NA Server access error"); return; default: send_bh_or_ld("Server Error", (ntlm_authenticate *) decoded, plen); return; } case SMBC_ERRHRD: /* hardware errors don't really matter */ send_bh_or_ld("Domain Controller Hardware error", (ntlm_authenticate *) decoded, plen); return; case SMBC_ERRCMD: send_bh_or_ld("Domain Controller Command Error", (ntlm_authenticate *) decoded, plen); return; } SEND("BH unknown internal error."); return; } lc(cred); /* let's lowercase them for our convenience */ SEND2("AF %s", cred); return; default: SEND("BH unknown authentication packet type"); return; } return; } if (memcmp(buf, "YR", 2) == 0) { /* refresh-request */ dc_disconnect(); ch = obtain_challenge(); /* Robert says we can afford to wait forever. I'll trust him on this * one */ while (ch == NULL) { sleep(30); ch = obtain_challenge(); } SEND2("TT %s", ch); return; } SEND("BH Helper detected protocol error"); return; /********* END ********/ }
int manage_request() { char buf[BUFFER_SIZE]; char helper_command[3]; char *c, *decoded; int plen, status; int oversized = 0; char *ErrorMessage; static char cred[SSP_MAX_CRED_LEN + 1]; BOOL Done = FALSE; try_again: if (fgets(buf, BUFFER_SIZE, stdin) == NULL) return 0; c = memchr(buf, '\n', BUFFER_SIZE); /* safer against overrun than strchr */ if (c) { if (oversized) { helperfail("illegal request received"); fprintf(stderr, "Illegal request received: '%s'\n", buf); return 1; } *c = '\0'; } else { fprintf(stderr, "No newline in '%s'\n", buf); oversized = 1; goto try_again; } if ((strlen(buf) > 3) && Negotiate_packet_debug_enabled) { decoded = base64_decode(buf + 3); strncpy(helper_command, buf, 2); debug("Got '%s' from Squid with data:\n", helper_command); hex_dump(decoded, ((strlen(buf) - 3) * 3) / 4); } else debug("Got '%s' from Squid\n", buf); if (memcmp(buf, "YR ", 3) == 0) { /* refresh-request */ /* figure out what we got */ decoded = base64_decode(buf + 3); /* Note: we don't need to manage memory at this point, since * base64_decode returns a pointer to static storage. */ if (!decoded) { /* decoding failure, return error */ SEND("NA * Packet format error, couldn't base64-decode"); return 1; } /* Obtain server blob against SSPI */ plen = (strlen(buf) - 3) * 3 / 4; /* we only need it here. Optimization */ c = (char *) SSP_MakeNegotiateBlob(decoded, plen, &Done, &status, cred); if (status == SSP_OK) { if (Done) { lc(cred); /* let's lowercase them for our convenience */ have_serverblob = 0; Done = FALSE; if (Negotiate_packet_debug_enabled) { decoded = base64_decode(c); debug("sending 'AF' %s to squid with data:\n", cred); if (c != NULL) hex_dump(decoded, (strlen(c) * 3) / 4); else fprintf(stderr, "No data available.\n"); printf("AF %s %s\n", c, cred); } else SEND3("AF %s %s", c, cred); } else { if (Negotiate_packet_debug_enabled) { decoded = base64_decode(c); debug("sending 'TT' to squid with data:\n"); hex_dump(decoded, (strlen(c) * 3) / 4); printf("TT %s\n", c); } else { SEND2("TT %s", c); } have_serverblob = 1; } } else helperfail("can't obtain server blob"); return 1; } if (memcmp(buf, "KK ", 3) == 0) { /* authenticate-request */ if (!have_serverblob) { helperfail("invalid server blob"); return 1; } /* figure out what we got */ decoded = base64_decode(buf + 3); /* Note: we don't need to manage memory at this point, since * base64_decode returns a pointer to static storage. */ if (!decoded) { /* decoding failure, return error */ SEND("NA * Packet format error, couldn't base64-decode"); return 1; } /* check against SSPI */ plen = (strlen(buf) - 3) * 3 / 4; /* we only need it here. Optimization */ c = (char *) SSP_ValidateNegotiateCredentials(decoded, plen, &Done, &status, cred); if (status == SSP_ERROR) { #if FAIL_DEBUG fail_debug_enabled = 1; #endif FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ (LPTSTR) & ErrorMessage, 0, NULL); if (ErrorMessage[strlen(ErrorMessage) - 1] == '\n') ErrorMessage[strlen(ErrorMessage) - 1] = '\0'; if (ErrorMessage[strlen(ErrorMessage) - 1] == '\r') ErrorMessage[strlen(ErrorMessage) - 1] = '\0'; SEND2("NA * %s", ErrorMessage); LocalFree(ErrorMessage); return 1; } if (Done) { lc(cred); /* let's lowercase them for our convenience */ have_serverblob = 0; Done = FALSE; if (Negotiate_packet_debug_enabled) { decoded = base64_decode(c); debug("sending 'AF' %s to squid with data:\n", cred); if (c != NULL) hex_dump(decoded, (strlen(c) * 3) / 4); else fprintf(stderr, "No data available.\n"); printf("AF %s %s\n", c, cred); } else { SEND3("AF %s %s", c, cred); } return 1; } else { if (Negotiate_packet_debug_enabled) { decoded = base64_decode(c); debug("sending 'TT' to squid with data:\n"); hex_dump(decoded, (strlen(c) * 3) / 4); printf("TT %s\n", c); } else SEND2("TT %s", c); return 1; } } else { /* not an auth-request */ helperfail("illegal request received"); fprintf(stderr, "Illegal request received: '%s'\n", buf); return 1; } helperfail("detected protocol error"); return 1; /********* END ********/ }
void helperfail(const char *reason) { SEND2("BH %s", reason); }
void sendchallenge(const char *challenge) { SEND2("TT %s", challenge); }
void authok(const char *domain, const char *user) { SEND2("AF %s\\%s", domain, user); }