47 #if !defined(HAVE_DECL_XMALLOC) || !HAVE_DECL_XMALLOC
48 #define xmalloc malloc
50 #if !defined(HAVE_DECL_XSTRDUP) || !HAVE_DECL_XSTRDUP
51 #define xstrdup strdup
53 #if !defined(HAVE_DECL_XFREE) || !HAVE_DECL_XFREE
58 #define PROGRAM "negotiate_wrapper"
60 #define VERSION "1.0.1"
62 #ifndef MAX_AUTHTOKEN_LEN
63 #define MAX_AUTHTOKEN_LEN 65535
66 static const unsigned char ntlmProtocol[] = {
'N',
'T',
'L',
'M',
'S',
'S',
'P', 0};
72 static time_t last_t = 0;
75 gettimeofday(&now,
nullptr);
76 if (now.tv_sec != last_t) {
77 time_t *tmp = (time_t *) & now.tv_sec;
78 struct tm *tm = localtime(tmp);
79 strftime(buf, 127,
"%Y/%m/%d %H:%M:%S", tm);
88 fprintf(stderr,
"Usage: \n");
89 fprintf(stderr,
"negotiate_wrapper [-h] [-d] --ntlm ntlm helper + arguments --kerberos kerberos helper + arguments\n");
90 fprintf(stderr,
"-h help\n");
91 fprintf(stderr,
"-d full debug\n");
92 fprintf(stderr,
"--ntlm full ntlm helper path with arguments\n");
93 fprintf(stderr,
"--kerberos full kerberos helper path with arguments\n");
117 uint8_t *token =
nullptr;
120 if (fgets(buf,
sizeof(buf) - 1, stdin) ==
nullptr) {
125 "%s| %s: fgets() failed! dying..... errno=%d (%s)\n",
129 fprintf(stdout,
"BH input error\n");
132 fprintf(stdout,
"BH input error\n");
135 c =
static_cast<char*
>(memchr(buf,
'\n',
sizeof(buf) - 1));
140 fprintf(stderr,
"%s| %s: Got '%s' from squid (length: %zu).\n",
144 fprintf(stderr,
"%s| %s: Oversized message\n",
LogTime(),
146 fprintf(stdout,
"BH Oversized message\n");
150 if (buf[0] ==
'\0') {
152 fprintf(stderr,
"%s| %s: Invalid request\n",
LogTime(),
154 fprintf(stdout,
"BH Invalid request\n");
157 if (strlen(buf) < 2) {
159 fprintf(stderr,
"%s| %s: Invalid request [%s]\n",
LogTime(),
161 fprintf(stdout,
"BH Invalid request\n");
164 if (!strncmp(buf,
"QQ", 2)) {
165 fprintf(stdout,
"BH quit command\n");
169 if (strncmp(buf,
"YR", 2) && strncmp(buf,
"KK", 2)) {
171 fprintf(stderr,
"%s| %s: Invalid request [%s]\n",
LogTime(),
173 fprintf(stdout,
"BH Invalid request\n");
176 if (strlen(buf) <= 3) {
178 fprintf(stderr,
"%s| %s: Invalid negotiate request [%s]\n",
180 fprintf(stdout,
"BH Invalid negotiate request\n");
185 fprintf(stderr,
"%s| %s: Decode '%s' (decoded length: %zu).\n",
189 if (!(token =
static_cast<uint8_t *
>(
xmalloc(length+1)))) {
190 fprintf(stderr,
"%s| %s: Error allocating memory for token\n",
LogTime(),
PROGRAM);
200 fprintf(stderr,
"%s| %s: Invalid base64 token [%s]\n",
LogTime(),
PROGRAM, buf+3);
201 fprintf(stdout,
"BH Invalid negotiate request token\n");
206 token[dstLen] =
'\0';
208 if ((
static_cast<size_t>(length) >=
sizeof(
ntlmProtocol) + 1) &&
211 fprintf(stderr,
"%s| %s: received type %d NTLM token\n",
214 fprintf(FDNIN,
"%s\n",buf);
215 if (fgets(tbuff,
sizeof(tbuff) - 1, FDNOUT) ==
nullptr) {
217 if (ferror(FDNOUT)) {
219 "fgets() failed! dying..... errno=%d (%s)\n",
220 ferror(FDNOUT),
strerror(ferror(FDNOUT)));
223 fprintf(stderr,
"%s| %s: Error reading NTLM helper response\n",
228 if (!memchr(tbuff,
'\n',
sizeof(tbuff) - 1)) {
229 fprintf(stderr,
"%s| %s: Oversized NTLM helper response\n",
240 if (strlen(tbuff) >= 3 && (!strncmp(tbuff,
"AF ",3) || !strncmp(tbuff,
"NA ",3))) {
241 strncpy(buff,tbuff,3);
243 for (
unsigned int i=2; i<=strlen(tbuff); ++i)
244 buff[i+2] = tbuff[i];
250 fprintf(stderr,
"%s| %s: received Kerberos token\n",
253 fprintf(FDKIN,
"%s\n",buf);
254 if (fgets(buff,
sizeof(buff) - 1, FDKOUT) ==
nullptr) {
256 if (ferror(FDKOUT)) {
258 "fgets() failed! dying..... errno=%d (%s)\n",
259 ferror(FDKOUT),
strerror(ferror(FDKOUT)));
262 fprintf(stderr,
"%s| %s: Error reading Kerberos helper response\n",
267 if (!memchr(buff,
'\n',
sizeof(buff) - 1)) {
268 fprintf(stderr,
"%s| %s: Oversized Kerberos helper response\n",
273 buff[
sizeof(buff)-1] =
'\0';
274 fprintf(stdout,
"%s",buff);
276 fprintf(stderr,
"%s| %s: Return '%s'\n",
285 main(
int argc,
char *
const argv[])
287 int nstart = 0, kstart = 0;
288 int nend = 0, kend = 0;
289 char **nargs, **kargs;
296 setbuf(stdout,
nullptr);
297 setbuf(stdin,
nullptr);
299 if (argc ==1 || !strncasecmp(argv[1],
"-h",2)) {
305 if (!strncasecmp(argv[1],
"-d",2)) {
310 for (
int i=j; i<argc; ++i) {
311 if (!strncasecmp(argv[i],
"--ntlm",6))
313 if (!strncasecmp(argv[i],
"--kerberos",10))
316 if (nstart > kstart) {
323 if (nstart == 0 || kstart == 0 || kend-kstart <= 0 || nend-nstart <= 0 ) {
329 fprintf(stderr,
"%s| %s: Starting version %s\n",
LogTime(),
PROGRAM,
332 if ((nargs = (
char **)
xmalloc((nend-nstart+1)*
sizeof(
char *))) ==
nullptr) {
333 fprintf(stderr,
"%s| %s: Error allocating memory for ntlm helper\n",
LogTime(),
PROGRAM);
336 memcpy(nargs,argv+nstart+1,(nend-nstart)*
sizeof(
char *));
337 nargs[nend-nstart]=
nullptr;
340 for (
int i=0; i<nend-nstart; ++i)
341 fprintf(stderr,
"%s ", nargs[i]);
342 fprintf(stderr,
"\n");
344 if ((kargs = (
char **)
xmalloc((kend-kstart+1)*
sizeof(
char *))) ==
nullptr) {
345 fprintf(stderr,
"%s| %s: Error allocating memory for kerberos helper\n",
LogTime(),
PROGRAM);
348 memcpy(kargs,argv+kstart+1,(kend-kstart)*
sizeof(
char *));
349 kargs[kend-kstart]=
nullptr;
351 fprintf(stderr,
"%s| %s: Kerberos command: ",
LogTime(),
PROGRAM);
352 for (
int i=0; i<kend-kstart; ++i)
353 fprintf(stderr,
"%s ", kargs[i]);
354 fprintf(stderr,
"\n");
361 if (pipe(pkin) < 0) {
362 fprintf(stderr,
"%s| %s: Could not assign streams for pkin\n",
LogTime(),
PROGRAM);
365 if (pipe(pkout) < 0) {
366 fprintf(stderr,
"%s| %s: Could not assign streams for pkout\n",
LogTime(),
PROGRAM);
370 if (( fpid = fork()) < 0 ) {
371 fprintf(stderr,
"%s| %s: Failed first fork\n",
LogTime(),
PROGRAM);
379 dup2(pkin[0],STDIN_FILENO);
383 dup2(pkout[1],STDOUT_FILENO);
386 setbuf(stdin,
nullptr);
387 setbuf(stdout,
nullptr);
389 execv(kargs[0], kargs);
397 if (pipe(pnin) < 0) {
398 fprintf(stderr,
"%s| %s: Could not assign streams for pnin\n",
LogTime(),
PROGRAM);
401 if (pipe(pnout) < 0) {
402 fprintf(stderr,
"%s| %s: Could not assign streams for pnout\n",
LogTime(),
PROGRAM);
406 if (( fpid = fork()) < 0 ) {
407 fprintf(stderr,
"%s| %s: Failed second fork\n",
LogTime(),
PROGRAM);
415 dup2(pnin[0],STDIN_FILENO);
419 dup2(pnout[1],STDOUT_FILENO);
422 setbuf(stdin,
nullptr);
423 setbuf(stdout,
nullptr);
425 execv(nargs[0], nargs);
433 FILE *FDKIN=fdopen(pkin[1],
"w");
434 FILE *FDKOUT=fdopen(pkout[0],
"r");
436 FILE *FDNIN=fdopen(pnin[1],
"w");
437 FILE *FDNOUT=fdopen(pnout[0],
"r");
439 if (!FDKIN || !FDKOUT || !FDNIN || !FDNOUT) {
440 fprintf(stderr,
"%s| %s: Could not assign streams for FDKIN/FDKOUT/FDNIN/FDNOUT\n",
LogTime(),
PROGRAM);
441 closeFds(FDKIN, FDKOUT, FDNIN, FDNOUT);
445 setbuf(FDKIN,
nullptr);
446 setbuf(FDKOUT,
nullptr);
447 setbuf(FDNIN,
nullptr);
448 setbuf(FDNOUT,
nullptr);
451 closeFds(FDKIN, FDKOUT, FDNIN, FDNOUT);