48 #if !defined(HAVE_DECL_XMALLOC) || !HAVE_DECL_XMALLOC
49 #define xmalloc malloc
51 #if !defined(HAVE_DECL_XSTRDUP) || !HAVE_DECL_XSTRDUP
52 #define xstrdup strdup
54 #if !defined(HAVE_DECL_XFREE) || !HAVE_DECL_XFREE
59 #define PROGRAM "negotiate_wrapper"
61 #define VERSION "1.0.1"
63 #ifndef MAX_AUTHTOKEN_LEN
64 #define MAX_AUTHTOKEN_LEN 65535
67 static const unsigned char ntlmProtocol[] = {
'N',
'T',
'L',
'M',
'S',
'S',
'P', 0};
73 static time_t last_t = 0;
76 gettimeofday(&now,
nullptr);
77 if (now.tv_sec != last_t) {
78 time_t *tmp = (time_t *) & now.tv_sec;
79 struct tm *tm = localtime(tmp);
80 strftime(buf, 127,
"%Y/%m/%d %H:%M:%S", tm);
89 fprintf(stderr,
"Usage: \n");
90 fprintf(stderr,
"negotiate_wrapper [-h] [-d] --ntlm ntlm helper + arguments --kerberos kerberos helper + arguments\n");
91 fprintf(stderr,
"-h help\n");
92 fprintf(stderr,
"-d full debug\n");
93 fprintf(stderr,
"--ntlm full ntlm helper path with arguments\n");
94 fprintf(stderr,
"--kerberos full kerberos helper path with arguments\n");
118 uint8_t *token =
nullptr;
121 if (fgets(buf,
sizeof(buf) - 1, stdin) ==
nullptr) {
126 "%s| %s: fgets() failed! dying..... errno=%d (%s)\n",
130 fprintf(stdout,
"BH input error\n");
133 fprintf(stdout,
"BH input error\n");
136 c =
static_cast<char*
>(memchr(buf,
'\n',
sizeof(buf) - 1));
141 fprintf(stderr,
"%s| %s: Got '%s' from squid (length: %zu).\n",
145 fprintf(stderr,
"%s| %s: Oversized message\n",
LogTime(),
147 fprintf(stdout,
"BH Oversized message\n");
151 if (buf[0] ==
'\0') {
153 fprintf(stderr,
"%s| %s: Invalid request\n",
LogTime(),
155 fprintf(stdout,
"BH Invalid request\n");
158 if (strlen(buf) < 2) {
160 fprintf(stderr,
"%s| %s: Invalid request [%s]\n",
LogTime(),
162 fprintf(stdout,
"BH Invalid request\n");
165 if (!strncmp(buf,
"QQ", 2)) {
166 fprintf(stdout,
"BH quit command\n");
170 if (strncmp(buf,
"YR", 2) && strncmp(buf,
"KK", 2)) {
172 fprintf(stderr,
"%s| %s: Invalid request [%s]\n",
LogTime(),
174 fprintf(stdout,
"BH Invalid request\n");
177 if (strlen(buf) <= 3) {
179 fprintf(stderr,
"%s| %s: Invalid negotiate request [%s]\n",
181 fprintf(stdout,
"BH Invalid negotiate request\n");
186 fprintf(stderr,
"%s| %s: Decode '%s' (decoded length: %zu).\n",
190 if (!(token =
static_cast<uint8_t *
>(
xmalloc(length+1)))) {
191 fprintf(stderr,
"%s| %s: Error allocating memory for token\n",
LogTime(),
PROGRAM);
201 fprintf(stderr,
"%s| %s: Invalid base64 token [%s]\n",
LogTime(),
PROGRAM, buf+3);
202 fprintf(stdout,
"BH Invalid negotiate request token\n");
207 token[dstLen] =
'\0';
209 if ((
static_cast<size_t>(length) >=
sizeof(
ntlmProtocol) + 1) &&
212 fprintf(stderr,
"%s| %s: received type %d NTLM token\n",
215 fprintf(FDNIN,
"%s\n",buf);
216 if (fgets(tbuff,
sizeof(tbuff) - 1, FDNOUT) ==
nullptr) {
218 if (ferror(FDNOUT)) {
220 "fgets() failed! dying..... errno=%d (%s)\n",
221 ferror(FDNOUT),
strerror(ferror(FDNOUT)));
224 fprintf(stderr,
"%s| %s: Error reading NTLM helper response\n",
229 if (!memchr(tbuff,
'\n',
sizeof(tbuff) - 1)) {
230 fprintf(stderr,
"%s| %s: Oversized NTLM helper response\n",
241 if (strlen(tbuff) >= 3 && (!strncmp(tbuff,
"AF ",3) || !strncmp(tbuff,
"NA ",3))) {
242 strncpy(buff,tbuff,3);
244 for (
unsigned int i=2; i<=strlen(tbuff); ++i)
245 buff[i+2] = tbuff[i];
251 fprintf(stderr,
"%s| %s: received Kerberos token\n",
254 fprintf(FDKIN,
"%s\n",buf);
255 if (fgets(buff,
sizeof(buff) - 1, FDKOUT) ==
nullptr) {
257 if (ferror(FDKOUT)) {
259 "fgets() failed! dying..... errno=%d (%s)\n",
260 ferror(FDKOUT),
strerror(ferror(FDKOUT)));
263 fprintf(stderr,
"%s| %s: Error reading Kerberos helper response\n",
268 if (!memchr(buff,
'\n',
sizeof(buff) - 1)) {
269 fprintf(stderr,
"%s| %s: Oversized Kerberos helper response\n",
274 buff[
sizeof(buff)-1] =
'\0';
275 fprintf(stdout,
"%s",buff);
277 fprintf(stderr,
"%s| %s: Return '%s'\n",
286 main(
int argc,
char *
const argv[])
288 int nstart = 0, kstart = 0;
289 int nend = 0, kend = 0;
290 char **nargs, **kargs;
297 setbuf(stdout,
nullptr);
298 setbuf(stdin,
nullptr);
300 if (argc ==1 || !strncasecmp(argv[1],
"-h",2)) {
306 if (!strncasecmp(argv[1],
"-d",2)) {
311 for (
int i=j; i<argc; ++i) {
312 if (!strncasecmp(argv[i],
"--ntlm",6))
314 if (!strncasecmp(argv[i],
"--kerberos",10))
317 if (nstart > kstart) {
324 if (nstart == 0 || kstart == 0 || kend-kstart <= 0 || nend-nstart <= 0 ) {
330 fprintf(stderr,
"%s| %s: Starting version %s\n",
LogTime(),
PROGRAM,
333 if ((nargs = (
char **)
xmalloc((nend-nstart+1)*
sizeof(
char *))) ==
nullptr) {
334 fprintf(stderr,
"%s| %s: Error allocating memory for ntlm helper\n",
LogTime(),
PROGRAM);
337 memcpy(nargs,argv+nstart+1,(nend-nstart)*
sizeof(
char *));
338 nargs[nend-nstart]=
nullptr;
341 for (
int i=0; i<nend-nstart; ++i)
342 fprintf(stderr,
"%s ", nargs[i]);
343 fprintf(stderr,
"\n");
345 if ((kargs = (
char **)
xmalloc((kend-kstart+1)*
sizeof(
char *))) ==
nullptr) {
346 fprintf(stderr,
"%s| %s: Error allocating memory for kerberos helper\n",
LogTime(),
PROGRAM);
349 memcpy(kargs,argv+kstart+1,(kend-kstart)*
sizeof(
char *));
350 kargs[kend-kstart]=
nullptr;
352 fprintf(stderr,
"%s| %s: Kerberos command: ",
LogTime(),
PROGRAM);
353 for (
int i=0; i<kend-kstart; ++i)
354 fprintf(stderr,
"%s ", kargs[i]);
355 fprintf(stderr,
"\n");
362 if (pipe(pkin) < 0) {
363 fprintf(stderr,
"%s| %s: Could not assign streams for pkin\n",
LogTime(),
PROGRAM);
366 if (pipe(pkout) < 0) {
367 fprintf(stderr,
"%s| %s: Could not assign streams for pkout\n",
LogTime(),
PROGRAM);
371 if (( fpid = fork()) < 0 ) {
372 fprintf(stderr,
"%s| %s: Failed first fork\n",
LogTime(),
PROGRAM);
380 dup2(pkin[0],STDIN_FILENO);
384 dup2(pkout[1],STDOUT_FILENO);
387 setbuf(stdin,
nullptr);
388 setbuf(stdout,
nullptr);
390 execv(kargs[0], kargs);
398 if (pipe(pnin) < 0) {
399 fprintf(stderr,
"%s| %s: Could not assign streams for pnin\n",
LogTime(),
PROGRAM);
402 if (pipe(pnout) < 0) {
403 fprintf(stderr,
"%s| %s: Could not assign streams for pnout\n",
LogTime(),
PROGRAM);
407 if (( fpid = fork()) < 0 ) {
408 fprintf(stderr,
"%s| %s: Failed second fork\n",
LogTime(),
PROGRAM);
416 dup2(pnin[0],STDIN_FILENO);
420 dup2(pnout[1],STDOUT_FILENO);
423 setbuf(stdin,
nullptr);
424 setbuf(stdout,
nullptr);
426 execv(nargs[0], nargs);
434 FILE *FDKIN=fdopen(pkin[1],
"w");
435 FILE *FDKOUT=fdopen(pkout[0],
"r");
437 FILE *FDNIN=fdopen(pnin[1],
"w");
438 FILE *FDNOUT=fdopen(pnout[0],
"r");
440 if (!FDKIN || !FDKOUT || !FDNIN || !FDNOUT) {
441 fprintf(stderr,
"%s| %s: Could not assign streams for FDKIN/FDKOUT/FDNIN/FDNOUT\n",
LogTime(),
PROGRAM);
442 closeFds(FDKIN, FDKOUT, FDNIN, FDNOUT);
446 setbuf(FDKIN,
nullptr);
447 setbuf(FDKOUT,
nullptr);
448 setbuf(FDNIN,
nullptr);
449 setbuf(FDNOUT,
nullptr);
452 closeFds(FDKIN, FDKOUT, FDNIN, FDNOUT);