47#if !defined(HAVE_DECL_XMALLOC) || !HAVE_DECL_XMALLOC
50#if !defined(HAVE_DECL_XSTRDUP) || !HAVE_DECL_XSTRDUP
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
66static 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",
233 if (strlen(tbuff) >= 3 && (!strncmp(tbuff,
"AF ",3) || !strncmp(tbuff,
"NA ",3))) {
234 strncpy(buff,tbuff,3);
236 for (
unsigned int i=2; i<=strlen(tbuff); ++i)
237 buff[i+2] = tbuff[i];
243 fprintf(stderr,
"%s| %s: received Kerberos token\n",
246 fprintf(FDKIN,
"%s\n",buf);
247 if (fgets(buff,
sizeof(buff) - 1, FDKOUT) ==
nullptr) {
249 if (ferror(FDKOUT)) {
251 "fgets() failed! dying..... errno=%d (%s)\n",
252 ferror(FDKOUT),
strerror(ferror(FDKOUT)));
255 fprintf(stderr,
"%s| %s: Error reading Kerberos helper response\n",
260 buff[
sizeof(buff)-1] =
'\0';
261 fprintf(stdout,
"%s",buff);
263 fprintf(stderr,
"%s| %s: Return '%s'\n",
272main(
int argc,
char *
const argv[])
274 int nstart = 0, kstart = 0;
275 int nend = 0, kend = 0;
276 char **nargs, **kargs;
283 setbuf(stdout,
nullptr);
284 setbuf(stdin,
nullptr);
286 if (argc ==1 || !strncasecmp(argv[1],
"-h",2)) {
292 if (!strncasecmp(argv[1],
"-d",2)) {
297 for (
int i=j; i<argc; ++i) {
298 if (!strncasecmp(argv[i],
"--ntlm",6))
300 if (!strncasecmp(argv[i],
"--kerberos",10))
303 if (nstart > kstart) {
310 if (nstart == 0 || kstart == 0 || kend-kstart <= 0 || nend-nstart <= 0 ) {
316 fprintf(stderr,
"%s| %s: Starting version %s\n",
LogTime(),
PROGRAM,
319 if ((nargs = (
char **)
xmalloc((nend-nstart+1)*
sizeof(
char *))) ==
nullptr) {
320 fprintf(stderr,
"%s| %s: Error allocating memory for ntlm helper\n",
LogTime(),
PROGRAM);
323 memcpy(nargs,argv+nstart+1,(nend-nstart)*
sizeof(
char *));
324 nargs[nend-nstart]=
nullptr;
327 for (
int i=0; i<nend-nstart; ++i)
328 fprintf(stderr,
"%s ", nargs[i]);
329 fprintf(stderr,
"\n");
331 if ((kargs = (
char **)
xmalloc((kend-kstart+1)*
sizeof(
char *))) ==
nullptr) {
332 fprintf(stderr,
"%s| %s: Error allocating memory for kerberos helper\n",
LogTime(),
PROGRAM);
335 memcpy(kargs,argv+kstart+1,(kend-kstart)*
sizeof(
char *));
336 kargs[kend-kstart]=
nullptr;
338 fprintf(stderr,
"%s| %s: Kerberos command: ",
LogTime(),
PROGRAM);
339 for (
int i=0; i<kend-kstart; ++i)
340 fprintf(stderr,
"%s ", kargs[i]);
341 fprintf(stderr,
"\n");
348 if (pipe(pkin) < 0) {
349 fprintf(stderr,
"%s| %s: Could not assign streams for pkin\n",
LogTime(),
PROGRAM);
352 if (pipe(pkout) < 0) {
353 fprintf(stderr,
"%s| %s: Could not assign streams for pkout\n",
LogTime(),
PROGRAM);
357 if (( fpid = vfork()) < 0 ) {
358 fprintf(stderr,
"%s| %s: Failed first fork\n",
LogTime(),
PROGRAM);
366 dup2(pkin[0],STDIN_FILENO);
370 dup2(pkout[1],STDOUT_FILENO);
373 setbuf(stdin,
nullptr);
374 setbuf(stdout,
nullptr);
376 execv(kargs[0], kargs);
384 if (pipe(pnin) < 0) {
385 fprintf(stderr,
"%s| %s: Could not assign streams for pnin\n",
LogTime(),
PROGRAM);
388 if (pipe(pnout) < 0) {
389 fprintf(stderr,
"%s| %s: Could not assign streams for pnout\n",
LogTime(),
PROGRAM);
393 if (( fpid = vfork()) < 0 ) {
394 fprintf(stderr,
"%s| %s: Failed second fork\n",
LogTime(),
PROGRAM);
402 dup2(pnin[0],STDIN_FILENO);
406 dup2(pnout[1],STDOUT_FILENO);
409 setbuf(stdin,
nullptr);
410 setbuf(stdout,
nullptr);
412 execv(nargs[0], nargs);
420 FILE *FDKIN=fdopen(pkin[1],
"w");
421 FILE *FDKOUT=fdopen(pkout[0],
"r");
423 FILE *FDNIN=fdopen(pnin[1],
"w");
424 FILE *FDNOUT=fdopen(pnout[0],
"r");
426 if (!FDKIN || !FDKOUT || !FDNIN || !FDNOUT) {
427 fprintf(stderr,
"%s| %s: Could not assign streams for FDKIN/FDKOUT/FDNIN/FDNOUT\n",
LogTime(),
PROGRAM);
428 closeFds(FDKIN, FDKOUT, FDNIN, FDNOUT);
432 setbuf(FDKIN,
nullptr);
433 setbuf(FDKOUT,
nullptr);
434 setbuf(FDNIN,
nullptr);
435 setbuf(FDNOUT,
nullptr);
438 closeFds(FDKIN, FDKOUT, FDNIN, FDNOUT);
void base64_decode_init(struct base64_decode_ctx *ctx)
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 BASE64_DECODE_LENGTH(length)
static void closeFds(FILE *a, FILE *b, FILE *c, FILE *d)
#define MAX_AUTHTOKEN_LEN
static int processingLoop(FILE *FDKIN, FILE *FDKOUT, FILE *FDNIN, FILE *FDNOUT)
static const char * LogTime()
static const unsigned char ntlmProtocol[]
int main(int argc, char *const argv[])