From: Amos Jeffries Date: Fri, 11 Sep 2015 02:16:06 +0000 (-0700) Subject: Bug 4292: negotiate_wrapper: Unreleased Resources X-Git-Tag: SQUID_4_0_1~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=af845cee67e3dc2a58f93a9ac7d9ce091ea4fa00;p=thirdparty%2Fsquid.git Bug 4292: negotiate_wrapper: Unreleased Resources FILE* handles need to be closed on exit. Shuffle the processing loop logics to a static function to avoid code duplication from all the requires close points. Also, use the available global flag debug_enabled instead of local variable to avoid having to pass it down explicitly. --- diff --git a/helpers/negotiate_auth/wrapper/negotiate_wrapper.cc b/helpers/negotiate_auth/wrapper/negotiate_wrapper.cc index 0d90701cea..1561d1b737 100644 --- a/helpers/negotiate_auth/wrapper/negotiate_wrapper.cc +++ b/helpers/negotiate_auth/wrapper/negotiate_wrapper.cc @@ -92,22 +92,182 @@ void usage(void) fprintf(stderr, "--kerberos full kerberos helper path with arguments\n"); } -int -main(int argc, char *const argv[]) +static void +closeFds(FILE *a, FILE *b, FILE *c, FILE *d) +{ + if (a >= 0) + fclose(a); + if (b >= 0) + fclose(b); + if (c >= 0) + fclose(c); + if (d >= 0) + fclose(d); +} + +static int +processingLoop(FILE *FDKIN, FILE *FDKOUT, FILE *FDNIN, FILE *FDNOUT) { char buf[MAX_AUTHTOKEN_LEN]; char tbuff[MAX_AUTHTOKEN_LEN]; char buff[MAX_AUTHTOKEN_LEN+2]; char *c; - int debug = 0; int length; + uint8_t *token; + + while (1) { + if (fgets(buf, sizeof(buf) - 1, stdin) == NULL) { + if (ferror(stdin)) { + if (debug_enabled) + fprintf(stderr, + "%s| %s: fgets() failed! dying..... errno=%d (%s)\n", + LogTime(), PROGRAM, ferror(stdin), + strerror(ferror(stdin))); + + fprintf(stdout, "BH input error\n"); + return 1; /* BIIG buffer */ + } + fprintf(stdout, "BH input error\n"); + return 0; + } + c = static_cast(memchr(buf, '\n', sizeof(buf) - 1)); + if (c) { + *c = '\0'; + length = c - buf; + if (debug_enabled) + fprintf(stderr, "%s| %s: Got '%s' from squid (length: %d).\n", + LogTime(), PROGRAM, buf, length); + } else { + if (debug_enabled) + fprintf(stderr, "%s| %s: Oversized message\n", LogTime(), + PROGRAM); + fprintf(stdout, "BH Oversized message\n"); + continue; + } + + if (buf[0] == '\0') { + if (debug_enabled) + fprintf(stderr, "%s| %s: Invalid request\n", LogTime(), + PROGRAM); + fprintf(stdout, "BH Invalid request\n"); + continue; + } + if (strlen(buf) < 2) { + if (debug_enabled) + fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(), + PROGRAM, buf); + fprintf(stdout, "BH Invalid request\n"); + continue; + } + if (!strncmp(buf, "QQ", 2)) { + fprintf(stdout, "BH quit command\n"); + return 0; + } + if (strncmp(buf, "YR", 2) && strncmp(buf, "KK", 2)) { + if (debug_enabled) + fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(), + PROGRAM, buf); + fprintf(stdout, "BH Invalid request\n"); + continue; + } + if (strlen(buf) <= 3) { + if (debug_enabled) + fprintf(stderr, "%s| %s: Invalid negotiate request [%s]\n", + LogTime(), PROGRAM, buf); + fprintf(stdout, "BH Invalid negotiate request\n"); + continue; + } + length = BASE64_DECODE_LENGTH(strlen(buf+3)); + if (debug_enabled) + fprintf(stderr, "%s| %s: Decode '%s' (decoded length: %d).\n", + LogTime(), PROGRAM, buf + 3, (int) length); + + if ((token = static_cast(xmalloc(length))) == NULL) { + fprintf(stderr, "%s| %s: Error allocating memory for token\n", LogTime(), PROGRAM); + return 1; + } + + struct base64_decode_ctx ctx; + base64_decode_init(&ctx); + size_t dstLen = 0; + if (!base64_decode_update(&ctx, &dstLen, token, strlen(buf+3), reinterpret_cast(buf+3)) || + !base64_decode_final(&ctx)) { + if (debug_enabled) + fprintf(stderr, "%s| %s: Invalid base64 token [%s]\n", LogTime(), PROGRAM, buf+3); + fprintf(stdout, "BH Invalid negotiate request token\n"); + continue; + } + length = dstLen; + token[dstLen] = '\0'; + + if ((static_cast(length) >= sizeof(ntlmProtocol) + 1) && + (!memcmp(token, ntlmProtocol, sizeof ntlmProtocol))) { + free(token); + if (debug_enabled) + fprintf(stderr, "%s| %s: received type %d NTLM token\n", + LogTime(), PROGRAM, (int) *((unsigned char *) token + + sizeof ntlmProtocol)); + fprintf(FDNIN, "%s\n",buf); + if (fgets(tbuff, sizeof(tbuff) - 1, FDNOUT) == NULL) { + if (ferror(FDNOUT)) { + fprintf(stderr, + "fgets() failed! dying..... errno=%d (%s)\n", + ferror(FDNOUT), strerror(ferror(FDNOUT))); + return 1; + } + fprintf(stderr, "%s| %s: Error reading NTLM helper response\n", + LogTime(), PROGRAM); + return 0; + } + /* + Need to translate NTLM reply to Negotiate reply + AF user => AF blob user + NA reason => NA blob reason + Set blob to '=' + */ + if (strlen(tbuff) >= 3 && (!strncmp(tbuff,"AF ",3) || !strncmp(tbuff,"NA ",3))) { + strncpy(buff,tbuff,3); + buff[3]='='; + for (unsigned int i=2; i<=strlen(tbuff); ++i) + buff[i+2] = tbuff[i]; + } else { + strcpy(buff,tbuff); + } + } else { + xfree(token); + if (debug_enabled) + fprintf(stderr, "%s| %s: received Kerberos token\n", + LogTime(), PROGRAM); + + fprintf(FDKIN, "%s\n",buf); + if (fgets(buff, sizeof(buff) - 1, FDKOUT) == NULL) { + if (ferror(FDKOUT)) { + fprintf(stderr, + "fgets() failed! dying..... errno=%d (%s)\n", + ferror(FDKOUT), strerror(ferror(FDKOUT))); + return 1; + } + fprintf(stderr, "%s| %s: Error reading Kerberos helper response\n", + LogTime(), PROGRAM); + return 0; + } + } + fprintf(stdout,"%s",buff); + if (debug_enabled) + fprintf(stderr, "%s| %s: Return '%s'\n", + LogTime(), PROGRAM, buff); + } + + return 1; +} + +int +main(int argc, char *const argv[]) +{ int nstart = 0, kstart = 0; int nend = 0, kend = 0; - uint8_t *token; char **nargs, **kargs; int fpid; - FILE *FDKIN,*FDKOUT; - FILE *FDNIN,*FDNOUT; int pkin[2]; int pkout[2]; int pnin[2]; @@ -123,7 +283,7 @@ main(int argc, char *const argv[]) int j = 1; if (!strncasecmp(argv[1],"-d",2)) { - debug = 1; + debug_enabled = 1; j = 2; } @@ -145,7 +305,7 @@ main(int argc, char *const argv[]) return 0; } - if (debug) + if (debug_enabled) fprintf(stderr, "%s| %s: Starting version %s\n", LogTime(), PROGRAM, VERSION); @@ -155,7 +315,7 @@ main(int argc, char *const argv[]) } memcpy(nargs,argv+nstart+1,(nend-nstart)*sizeof(char *)); nargs[nend-nstart]=NULL; - if (debug) { + if (debug_enabled) { fprintf(stderr, "%s| %s: NTLM command: ", LogTime(), PROGRAM); for (int i=0; i(memchr(buf, '\n', sizeof(buf) - 1)); - if (c) { - *c = '\0'; - length = c - buf; - if (debug) - fprintf(stderr, "%s| %s: Got '%s' from squid (length: %d).\n", - LogTime(), PROGRAM, buf, length); - } else { - if (debug) - fprintf(stderr, "%s| %s: Oversized message\n", LogTime(), - PROGRAM); - fprintf(stdout, "BH Oversized message\n"); - continue; - } - - if (buf[0] == '\0') { - if (debug) - fprintf(stderr, "%s| %s: Invalid request\n", LogTime(), - PROGRAM); - fprintf(stdout, "BH Invalid request\n"); - continue; - } - if (strlen(buf) < 2) { - if (debug) - fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(), - PROGRAM, buf); - fprintf(stdout, "BH Invalid request\n"); - continue; - } - if (!strncmp(buf, "QQ", 2)) { - fprintf(stdout, "BH quit command\n"); - return 0; - } - if (strncmp(buf, "YR", 2) && strncmp(buf, "KK", 2)) { - if (debug) - fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(), - PROGRAM, buf); - fprintf(stdout, "BH Invalid request\n"); - continue; - } - if (strlen(buf) <= 3) { - if (debug) - fprintf(stderr, "%s| %s: Invalid negotiate request [%s]\n", - LogTime(), PROGRAM, buf); - fprintf(stdout, "BH Invalid negotiate request\n"); - continue; - } - length = BASE64_DECODE_LENGTH(strlen(buf+3)); - if (debug) - fprintf(stderr, "%s| %s: Decode '%s' (decoded length: %d).\n", - LogTime(), PROGRAM, buf + 3, (int) length); - - if ((token = static_cast(xmalloc(length))) == NULL) { - fprintf(stderr, "%s| %s: Error allocating memory for token\n", LogTime(), PROGRAM); - return 1; - } - - struct base64_decode_ctx ctx; - base64_decode_init(&ctx); - size_t dstLen = 0; - if (!base64_decode_update(&ctx, &dstLen, token, strlen(buf+3), reinterpret_cast(buf+3)) || - !base64_decode_final(&ctx)) { - if (debug) - fprintf(stderr, "%s| %s: Invalid base64 token [%s]\n", LogTime(), PROGRAM, buf+3); - fprintf(stdout, "BH Invalid negotiate request token\n"); - continue; - } - length = dstLen; - token[dstLen] = '\0'; - - if ((static_cast(length) >= sizeof(ntlmProtocol) + 1) && - (!memcmp(token, ntlmProtocol, sizeof ntlmProtocol))) { - free(token); - if (debug) - fprintf(stderr, "%s| %s: received type %d NTLM token\n", - LogTime(), PROGRAM, (int) *((unsigned char *) token + - sizeof ntlmProtocol)); - fprintf(FDNIN, "%s\n",buf); - if (fgets(tbuff, sizeof(tbuff) - 1, FDNOUT) == NULL) { - if (ferror(FDNOUT)) { - fprintf(stderr, - "fgets() failed! dying..... errno=%d (%s)\n", - ferror(FDNOUT), strerror(ferror(FDNOUT))); - return 1; - } - fprintf(stderr, "%s| %s: Error reading NTLM helper response\n", - LogTime(), PROGRAM); - return 0; - } - /* - Need to translate NTLM reply to Negotiate reply - AF user => AF blob user - NA reason => NA blob reason - Set blob to '=' - */ - if (strlen(tbuff) >= 3 && (!strncmp(tbuff,"AF ",3) || !strncmp(tbuff,"NA ",3))) { - strncpy(buff,tbuff,3); - buff[3]='='; - for (unsigned int i=2; i<=strlen(tbuff); ++i) - buff[i+2] = tbuff[i]; - } else { - strcpy(buff,tbuff); - } - } else { - xfree(token); - if (debug) - fprintf(stderr, "%s| %s: received Kerberos token\n", - LogTime(), PROGRAM); - - fprintf(FDKIN, "%s\n",buf); - if (fgets(buff, sizeof(buff) - 1, FDKOUT) == NULL) { - if (ferror(FDKOUT)) { - fprintf(stderr, - "fgets() failed! dying..... errno=%d (%s)\n", - ferror(FDKOUT), strerror(ferror(FDKOUT))); - return 1; - } - fprintf(stderr, "%s| %s: Error reading Kerberos helper response\n", - LogTime(), PROGRAM); - return 0; - } - } - fprintf(stdout,"%s",buff); - if (debug) - fprintf(stderr, "%s| %s: Return '%s'\n", - LogTime(), PROGRAM, buff); - } - - return 1; + int result = processingLoop(FDKIN, FDKOUT, FDNIN, FDNOUT); + closeFds(FDKIN, FDKOUT, FDNIN, FDNOUT); + return result; }