43 #if !defined(HAVE_DECL_XMALLOC) || !HAVE_DECL_XMALLOC
44 #define xmalloc malloc
46 #if !defined(HAVE_DECL_XSTRDUP) || !HAVE_DECL_XSTRDUP
47 #define xstrdup strdup
49 #if !defined(HAVE_DECL_XFREE) || !HAVE_DECL_XFREE
54 #define PROGRAM "negotiate_wrapper"
56 #define VERSION "1.0.1"
58 #ifndef MAX_AUTHTOKEN_LEN
59 #define MAX_AUTHTOKEN_LEN 65535
62 static const unsigned char ntlmProtocol[] = {
'N',
'T',
'L',
'M',
'S',
'S',
'P', 0};
68 static time_t last_t = 0;
71 gettimeofday(&now,
nullptr);
72 if (now.tv_sec != last_t) {
73 time_t *tmp = (time_t *) & now.tv_sec;
74 struct tm *tm = localtime(tmp);
75 strftime(buf, 127,
"%Y/%m/%d %H:%M:%S", tm);
84 fprintf(stderr,
"Usage: \n");
85 fprintf(stderr,
"negotiate_wrapper [-h] [-d] --ntlm ntlm helper + arguments --kerberos kerberos helper + arguments\n");
86 fprintf(stderr,
"-h help\n");
87 fprintf(stderr,
"-d full debug\n");
88 fprintf(stderr,
"--ntlm full ntlm helper path with arguments\n");
89 fprintf(stderr,
"--kerberos full kerberos helper path with arguments\n");
113 uint8_t *token =
nullptr;
116 if (fgets(buf,
sizeof(buf) - 1, stdin) ==
nullptr) {
121 "%s| %s: fgets() failed! dying..... errno=%d (%s)\n",
125 fprintf(stdout,
"BH input error\n");
128 fprintf(stdout,
"BH input error\n");
131 c =
static_cast<char*
>(memchr(buf,
'\n',
sizeof(buf) - 1));
136 fprintf(stderr,
"%s| %s: Got '%s' from squid (length: %zu).\n",
140 fprintf(stderr,
"%s| %s: Oversized message\n",
LogTime(),
142 fprintf(stdout,
"BH Oversized message\n");
146 if (buf[0] ==
'\0') {
148 fprintf(stderr,
"%s| %s: Invalid request\n",
LogTime(),
150 fprintf(stdout,
"BH Invalid request\n");
153 if (strlen(buf) < 2) {
155 fprintf(stderr,
"%s| %s: Invalid request [%s]\n",
LogTime(),
157 fprintf(stdout,
"BH Invalid request\n");
160 if (!strncmp(buf,
"QQ", 2)) {
161 fprintf(stdout,
"BH quit command\n");
165 if (strncmp(buf,
"YR", 2) && strncmp(buf,
"KK", 2)) {
167 fprintf(stderr,
"%s| %s: Invalid request [%s]\n",
LogTime(),
169 fprintf(stdout,
"BH Invalid request\n");
172 if (strlen(buf) <= 3) {
174 fprintf(stderr,
"%s| %s: Invalid negotiate request [%s]\n",
176 fprintf(stdout,
"BH Invalid negotiate request\n");
181 fprintf(stderr,
"%s| %s: Decode '%s' (decoded length: %zu).\n",
185 if (!(token =
static_cast<uint8_t *
>(
xmalloc(length+1)))) {
186 fprintf(stderr,
"%s| %s: Error allocating memory for token\n",
LogTime(),
PROGRAM);
196 fprintf(stderr,
"%s| %s: Invalid base64 token [%s]\n",
LogTime(),
PROGRAM, buf+3);
197 fprintf(stdout,
"BH Invalid negotiate request token\n");
202 token[dstLen] =
'\0';
204 if ((
static_cast<size_t>(length) >=
sizeof(
ntlmProtocol) + 1) &&
207 fprintf(stderr,
"%s| %s: received type %d NTLM token\n",
210 fprintf(FDNIN,
"%s\n",buf);
211 if (fgets(tbuff,
sizeof(tbuff) - 1, FDNOUT) ==
nullptr) {
213 if (ferror(FDNOUT)) {
215 "fgets() failed! dying..... errno=%d (%s)\n",
216 ferror(FDNOUT),
strerror(ferror(FDNOUT)));
219 fprintf(stderr,
"%s| %s: Error reading NTLM helper response\n",
224 if (!memchr(tbuff,
'\n',
sizeof(tbuff) - 1)) {
225 fprintf(stderr,
"%s| %s: Oversized NTLM helper response\n",
236 if (strlen(tbuff) >= 3 && (!strncmp(tbuff,
"AF ",3) || !strncmp(tbuff,
"NA ",3))) {
237 strncpy(buff,tbuff,3);
239 for (
unsigned int i=2; i<=strlen(tbuff); ++i)
240 buff[i+2] = tbuff[i];
246 fprintf(stderr,
"%s| %s: received Kerberos token\n",
249 fprintf(FDKIN,
"%s\n",buf);
250 if (fgets(buff,
sizeof(buff) - 1, FDKOUT) ==
nullptr) {
252 if (ferror(FDKOUT)) {
254 "fgets() failed! dying..... errno=%d (%s)\n",
255 ferror(FDKOUT),
strerror(ferror(FDKOUT)));
258 fprintf(stderr,
"%s| %s: Error reading Kerberos helper response\n",
263 if (!memchr(buff,
'\n',
sizeof(buff) - 1)) {
264 fprintf(stderr,
"%s| %s: Oversized Kerberos helper response\n",
269 buff[
sizeof(buff)-1] =
'\0';
270 fprintf(stdout,
"%s",buff);
272 fprintf(stderr,
"%s| %s: Return '%s'\n",
281 main(
int argc,
char *
const argv[])
283 int nstart = 0, kstart = 0;
284 int nend = 0, kend = 0;
285 char **nargs, **kargs;
292 setbuf(stdout,
nullptr);
293 setbuf(stdin,
nullptr);
295 if (argc ==1 || !strncasecmp(argv[1],
"-h",2)) {
301 if (!strncasecmp(argv[1],
"-d",2)) {
306 for (
int i=j; i<argc; ++i) {
307 if (!strncasecmp(argv[i],
"--ntlm",6))
309 if (!strncasecmp(argv[i],
"--kerberos",10))
312 if (nstart > kstart) {
319 if (nstart == 0 || kstart == 0 || kend-kstart <= 0 || nend-nstart <= 0 ) {
325 fprintf(stderr,
"%s| %s: Starting version %s\n",
LogTime(),
PROGRAM,
328 if ((nargs = (
char **)
xmalloc((nend-nstart+1)*
sizeof(
char *))) ==
nullptr) {
329 fprintf(stderr,
"%s| %s: Error allocating memory for ntlm helper\n",
LogTime(),
PROGRAM);
332 memcpy(nargs,argv+nstart+1,(nend-nstart)*
sizeof(
char *));
333 nargs[nend-nstart]=
nullptr;
336 for (
int i=0; i<nend-nstart; ++i)
337 fprintf(stderr,
"%s ", nargs[i]);
338 fprintf(stderr,
"\n");
340 if ((kargs = (
char **)
xmalloc((kend-kstart+1)*
sizeof(
char *))) ==
nullptr) {
341 fprintf(stderr,
"%s| %s: Error allocating memory for kerberos helper\n",
LogTime(),
PROGRAM);
344 memcpy(kargs,argv+kstart+1,(kend-kstart)*
sizeof(
char *));
345 kargs[kend-kstart]=
nullptr;
347 fprintf(stderr,
"%s| %s: Kerberos command: ",
LogTime(),
PROGRAM);
348 for (
int i=0; i<kend-kstart; ++i)
349 fprintf(stderr,
"%s ", kargs[i]);
350 fprintf(stderr,
"\n");
357 if (pipe(pkin) < 0) {
358 fprintf(stderr,
"%s| %s: Could not assign streams for pkin\n",
LogTime(),
PROGRAM);
361 if (pipe(pkout) < 0) {
362 fprintf(stderr,
"%s| %s: Could not assign streams for pkout\n",
LogTime(),
PROGRAM);
366 if (( fpid = fork()) < 0 ) {
367 fprintf(stderr,
"%s| %s: Failed first fork\n",
LogTime(),
PROGRAM);
375 dup2(pkin[0],STDIN_FILENO);
379 dup2(pkout[1],STDOUT_FILENO);
382 setbuf(stdin,
nullptr);
383 setbuf(stdout,
nullptr);
385 execv(kargs[0], kargs);
393 if (pipe(pnin) < 0) {
394 fprintf(stderr,
"%s| %s: Could not assign streams for pnin\n",
LogTime(),
PROGRAM);
397 if (pipe(pnout) < 0) {
398 fprintf(stderr,
"%s| %s: Could not assign streams for pnout\n",
LogTime(),
PROGRAM);
402 if (( fpid = fork()) < 0 ) {
403 fprintf(stderr,
"%s| %s: Failed second fork\n",
LogTime(),
PROGRAM);
411 dup2(pnin[0],STDIN_FILENO);
415 dup2(pnout[1],STDOUT_FILENO);
418 setbuf(stdin,
nullptr);
419 setbuf(stdout,
nullptr);
421 execv(nargs[0], nargs);
429 FILE *FDKIN=fdopen(pkin[1],
"w");
430 FILE *FDKOUT=fdopen(pkout[0],
"r");
432 FILE *FDNIN=fdopen(pnin[1],
"w");
433 FILE *FDNOUT=fdopen(pnout[0],
"r");
435 if (!FDKIN || !FDKOUT || !FDNIN || !FDNOUT) {
436 fprintf(stderr,
"%s| %s: Could not assign streams for FDKIN/FDKOUT/FDNIN/FDNOUT\n",
LogTime(),
PROGRAM);
437 closeFds(FDKIN, FDKOUT, FDNIN, FDNOUT);
441 setbuf(FDKIN,
nullptr);
442 setbuf(FDKOUT,
nullptr);
443 setbuf(FDNIN,
nullptr);
444 setbuf(FDNOUT,
nullptr);
447 closeFds(FDKIN, FDKOUT, FDNIN, FDNOUT);