52#define DEAD_DC_RETRY_INTERVAL 30
57#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
59#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
60#define SEND3(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
71int is_dc_ok(
char *domain,
char *domain_controller);
87#define ENCODED_PASS_LEN 24
88#define MAX_USERNAME_LEN 255
89#define MAX_DOMAIN_LEN 255
90#define MAX_PASSWD_LEN 31
145 debug(
"Connecting to server %s domain %s\n", domain_controller, domain);
151 debug(
"Couldn't connect to SMB Server. Error:%s\n",
errstr);
155 debug(
"Error negotiating protocol with SMB Server\n");
161 debug(
"SMB Server uses share-level security .. we need user security.\n");
200 debug(
"base64 encoding of the token challenge will exceed %zu bytes",
sizeof(b64buf));
206 size_t blen =
base64_encode_update(&ctx, b64buf, len,
reinterpret_cast<const uint8_t *
>(&chal));
228 debug(
"Weird, we've been disconnected\n");
235 if (tmp.
str ==
NULL || tmp.
l == 0) {
236 debug(
"No domain supplied. Returning no-auth\n");
245 memcpy(domain, tmp.
str, tmp.
l);
246 user = domain + tmp.
l;
252 if (tmp.
str ==
NULL || tmp.
l == 0) {
253 debug(
"No username supplied. Returning no-auth\n");
262 memcpy(user, tmp.
str, tmp.
l);
263 *(user + tmp.
l) =
'\0';
274 debug(
"LM response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset);
278 tmp.
str = (
char *)packet + offset;
288 memcpy(pass, tmp.
str, tmp.
l);
291 debug(
"Empty LM pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n",
294 fprintf(stderr,
"Empty LM password supplied for user %s\\%s. "
295 "No-auth\n",domain,user);
309 debug(
"NT response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset);
313 tmp.
str = (
char *)packet + offset;
316 debug(
"Empty NT pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n",
319 fprintf(stderr,
"ERROR: Empty NT password supplied for user %s\\%s. No-auth\n", domain, user);
326 debug(
"checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass);
329 debug(
"Login attempt had result %d\n", rv);
366 "%s usage:\n%s [-b] [-f] [-d] [-l] domain\\controller [domain\\controller ...]\n"
367 "-b enables load-balancing among controllers\n"
368 "-f enables failover among controllers (DEPRECATED and always active)\n"
369 "-d enables debugging statements if DEBUG was defined at build-time.\n\n"
370 "You MUST specify at least one Domain Controller.\n"
371 "You can use either \\ or / as separator between the domain name \n"
372 "and the controller name\n",
381 int opt, j, had_error = 0;
382 dc *new_dc =
nullptr, *last_dc =
nullptr;
383 while (-1 != (opt =
getopt(argc, argv,
"bfld"))) {
390 "WARNING. The -f flag is DEPRECATED and always active.\n");
396 fprintf(stderr,
"unknown option: -%c. Exiting\n", opt);
405 for (j =
optind; j < argc; ++j) {
409 d =
static_cast<char*
>(
xmalloc(strlen(argv[j]) + 1));
411 debug(
"Adding domain-controller %s\n", d);
412 if (
NULL == (c = strchr(d,
'\\')) &&
NULL == (c = strchr(d,
'/'))) {
413 fprintf(stderr,
"Couldn't grok domain-controller %s\n", d);
418 if (
NULL != strchr(c + 1,
'\\') ||
NULL != strchr(c + 1,
'/')) {
419 fprintf(stderr,
"Broken domain-controller %s\n", d);
427 fprintf(stderr,
"Malloc error while parsing DC options\n");
442 last_dc->
next = new_dc;
447 fprintf(stderr,
"You must specify at least one domain-controller!\n");
462 const char *ch =
nullptr;
464 debug(
"obtain_challenge: selecting %s\\%s (attempt #%d)\n",
469 debug(
"Reviving DC\n");
472 debug(
"Skipping it\n");
477 debug(
"attempting challenge retrieval\n");
479 debug(
"make_challenge retuned %p\n", ch);
485 debug(
"Marking DC as DEAD\n");
488 debug(
"moving on to next controller\n");
501 char *ch2, *cred =
nullptr;
504 fprintf(stderr,
"fgets() failed! dying..... errno=%d (%s)\n", errno,
508 debug(
"managing request\n");
513 debug(
"ntlm authenticator. Got '%s' from Squid\n", buf);
515 if (memcmp(buf,
"KK ", 3) == 0) {
521 if (!
base64_decode_update(&ctx, &dstLen,
reinterpret_cast<uint8_t*
>(decoded), strlen(buf)-3, buf+3) ||
523 SEND(
"NA Packet format error, couldn't base64-decode");
528 if ((
size_t)decodedLen <
sizeof(
ntlmhdr)) {
529 SEND(
"NA Packet format error, truncated packet header.");
533 fast_header = (
ntlmhdr *) decoded;
537 SEND(
"NA Broken authentication packet");
542 SEND(
"NA Invalid negotiation request received");
546 SEND(
"NA Got a challenge. We refuse to have our authority disputed");
555 signal(SIGALRM, SIG_DFL);
557 fprintf(stderr,
"ntlm-auth[%ld]: Timeout during authentication.\n", (
long)getpid());
558 SEND(
"BH Timeout during authentication");
563 int smblib_err, smb_errorclass, smb_errorcode, nb_error;
565 SEND(
"NA Logon Failure");
576 debug(
"No creds. SMBlib error %d, SMB error class %d, SMB error code %d, NB error %d\n",
577 smblib_err, smb_errorclass, smb_errorcode, nb_error);
581 SEND(
"BH NetBios error!");
582 fprintf(stderr,
"NetBios error code %d (%s)\n", nb_error,
586 switch (smb_errorclass) {
588 debug(
"Huh? Got a SMB success code but could check auth..");
589 SEND(
"NA Authentication failed");
593 debug(
"DOS error\n");
594 switch (smb_errorcode) {
598 SEND(
"NA Access denied");
601 SEND(
"NA bad format in authentication packet");
604 SEND(
"NA Bad access request");
610 SEND(
"BH DOS Error");
614 debug(
"Server error");
615 switch (smb_errorcode) {
618 SEND(
"NA Bad password");
621 SEND(
"NA Server access error");
624 SEND(
"BH Server Error");
628 SEND(
"BH Domain Controller Hardware error");
631 SEND(
"BH Domain Controller Command Error");
634 SEND(
"BH unknown internal error.");
639 SEND2(
"AF %s", cred);
642 SEND(
"BH unknown authentication packet type");
648 if (memcmp(buf,
"YR", 2) == 0) {
660 SEND(
"BH Helper detected protocol error");
669 debug(
"%s " VERSION " " SQUID_BUILD_INFO
" starting up...\n", argv[0]);
674 debug(
"options processed OK\n");
677 setbuf(stdout,
nullptr);
678 setbuf(stderr,
nullptr);
684 pid_t
pid = getpid();
686 debug(
"load balancing. Selected controller #%d\n", n);
void base64_encode_init(struct base64_encode_ctx *ctx)
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
void base64_decode_init(struct base64_decode_ctx *ctx)
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
#define base64_encode_len(length)
int base64_decode_update(struct base64_decode_ctx *ctx, size_t *dst_length, uint8_t *dst, size_t src_length, const char *src)
int base64_decode_final(struct base64_decode_ctx *ctx)
#define HELPER_INPUT_BUFFER
void debug(const char *format,...)
A const & min(A const &lhs, A const &rhs)
int getopt(int nargc, char *const *nargv, const char *ostr)
const char * make_challenge(char *domain, char *controller)
int main(int argc, char *argv[])
static char my_domain_controller[100]
static char credentials[MAX_USERNAME_LEN+MAX_DOMAIN_LEN+2]
static char my_domain[100]
static unsigned char challenge[NTLM_NONCE_LEN]
static unsigned char lmencoded_empty_pass[ENCODED_PASS_LEN]
void timeout_during_auth(int signum)
static int init_challenge(char *domain, char *domain_controller)
void process_options(int argc, char *argv[])
static unsigned char ntencoded_empty_pass[ENCODED_PASS_LEN]
char * ntlm_check_auth(ntlm_authenticate *auth, int auth_length)
void manage_request(void)
int is_dc_ok(char *domain, char *domain_controller)
#define DEAD_DC_RETRY_INTERVAL
const char * obtain_challenge(void)
char smb_error_buffer[1000]
int ntlm_validate_packet(const ntlmhdr *hdr, const int32_t type)
void ntlm_make_challenge(ntlm_challenge *ch, const char *domain, const char *, const char *challenge_nonce, const int challenge_nonce_len, const uint32_t flags)
lstring ntlm_fetch_string(const ntlmhdr *packet, const int32_t packet_size, const strhdr *str, const uint32_t flags)
#define NTLM_REQUEST_NON_NT_SESSION_KEY
#define NTLM_AUTHENTICATE
#define NTLM_ERR_NOT_CONNECTED
#define NTLM_NEGOTIATE_USE_NTLM
#define NTLM_NEGOTIATE_USE_LM
#define NTLM_NEGOTIATE_ASCII
#define NTLM_BLOB_BUFFER_SIZE
#define NTLM_CHALLENGE_TARGET_IS_DOMAIN
#define NTLM_NEGOTIATE_ALWAYS_SIGN
const char * RFCNB_Error_Strings[]
int RFCNB_Get_Last_Error(void)
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
#define SMBlib_Error_Class(p)
#define SMBlib_Error_Code(p)
int SMB_Negotiate(SMB_Handle_Type Con_Handle, const char *Prots[])
int SMB_Get_Last_SMB_Err()
void SMB_Get_Error_Msg(int msg, char *msgbuf, int len)
int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle)
int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, char *PassWord, const char *NtDomain, int PreCrypted)
SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, const char *server, const char *NTdomain)