]> git.ipfire.org Git - thirdparty/squid.git/blame - helpers/ntlm_auth/fake/ntlm_fake_auth.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / helpers / ntlm_auth / fake / ntlm_fake_auth.cc
CommitLineData
75aa769b
AJ
1/*
2 * $Id$
3 *
4 * AUTHOR: Andrew Doran <ad@interlude.eu.org>
5 * AUTHOR: Robert Collins <rbtcollins@hotmail.com>
6 * AUTHOR: Guido Serassio: <guido.serassio@acmeconsulting.it>
7 *
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
33 *
34 */
35/*
36 * Example ntlm authentication program for Squid, based on the
37 * original proxy_auth code from client_side.c, written by
38 * Jon Thackray <jrmt@uk.gdscorp.com>. Initial ntlm code by
39 * Andrew Doran <ad@interlude.eu.org>.
40 *
41 * This code gets the username and returns it. No validation is done.
42 * and by the way: it is a complete patch-up. Use the "real thing" NTLMSSP
43 * if you can.
44 *
45 * Revised by Guido Serassio: <guido.serassio@acmeconsulting.it>
46 *
47 * - Added negotiation of UNICODE char support
48 * - More detailed debugging info
49 *
50 */
51
52/* undefine this to have strict protocol adherence. You don't really need
53 * that though */
54#define IGNORANCE_IS_BLISS
55
f7f3304a 56#include "squid.h"
25f98340 57#include "base64.h"
dcb9c96c 58#include "helpers/defines.h"
7c16470c
AJ
59#include "ntlmauth/ntlmauth.h"
60#include "ntlmauth/support_bits.cci"
25f98340 61//#include "util.h"
75aa769b 62
75aa769b
AJ
63#if HAVE_STRING_H
64#include <string.h>
65#endif
5dc2526c
FC
66#if HAVE_CTYPE_H
67#include <ctype.h>
68#endif
75aa769b
AJ
69#if HAVE_CRYPT_H
70#include <crypt.h>
71#endif
72#if HAVE_PWD_H
73#include <pwd.h>
74#endif
75#if HAVE_GETOPT_H
76#include <getopt.h>
77#endif
5dc2526c
FC
78#if HAVE_STDIO_H
79#include <stdio.h>
80#endif
81#if HAVE_STDINT_H
82#include <stdint.h>
83#endif
84#if HAVE_INTTYPES_H
85#include <inttypes.h>
86#endif
75aa769b 87
75aa769b
AJ
88/* A couple of harmless helper macros */
89#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n");
90#ifdef __GNUC__
91#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
59a09b98 92#define SEND4(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
75aa769b
AJ
93#else
94/* no gcc, no debugging. varargs macros are a gcc extension */
95#define SEND2(X,Y) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y);
079c2dd4 96#define SEND4(X,Y,Z,W) debug("sending '" X "' to squid\n",Y,Z,W); printf(X "\n",Y,Z,W);
75aa769b
AJ
97#endif
98
75aa769b
AJ
99const char *authenticate_ntlm_domain = "WORKGROUP";
100int strip_domain_enabled = 0;
101int NTLM_packet_debug_enabled = 0;
102
75aa769b
AJ
103/*
104 * options:
105 * -d enable debugging.
106 * -v enable verbose NTLM packet debugging.
107 * -l if specified, changes behavior on failures to last-ditch.
108 */
109char *my_program_name = NULL;
110
111static void
112usage(void)
113{
114 fprintf(stderr,
115 "Usage: %s [-d] [-v] [-h]\n"
116 " -d enable debugging.\n"
117 " -S strip domain from username.\n"
118 " -v enable verbose NTLM packet debugging.\n"
119 " -h this message\n\n",
120 my_program_name);
121}
122
123static void
124process_options(int argc, char *argv[])
125{
126 int opt, had_error = 0;
127
128 opterr = 0;
129 while (-1 != (opt = getopt(argc, argv, "hdvS"))) {
130 switch (opt) {
131 case 'd':
132 debug_enabled = 1;
133 break;
134 case 'v':
135 debug_enabled = 1;
136 NTLM_packet_debug_enabled = 1;
137 break;
138 case 'S':
139 strip_domain_enabled = 1;
140 break;
141 case 'h':
142 usage();
143 exit(0);
144 case '?':
145 opt = optopt;
146 /* fall thru to default */
147 default:
148 fprintf(stderr, "unknown option: -%c. Exiting\n", opt);
149 usage();
150 had_error = 1;
151 }
152 }
153 if (had_error)
154 exit(1);
155}
156
157int
158main(int argc, char *argv[])
159{
4c4ca9c2 160 char buf[HELPER_INPUT_BUFFER];
75aa769b 161 int buflen = 0;
8bdd0cec
AJ
162 char decodedBuf[HELPER_INPUT_BUFFER];
163 int decodedLen;
75aa769b 164 char user[NTLM_MAX_FIELD_LENGTH], domain[NTLM_MAX_FIELD_LENGTH];
350f6838 165 char *p;
75aa769b
AJ
166 ntlmhdr *packet = NULL;
167 char helper_command[3];
168 int len;
169 char *data = NULL;
170
171 setbuf(stdout, NULL);
172 setbuf(stderr, NULL);
173
174 my_program_name = argv[0];
175
176 process_options(argc, argv);
177
178 debug("%s build " __DATE__ ", " __TIME__ " starting up...\n", my_program_name);
179
dcb9c96c 180 while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL) {
75aa769b
AJ
181 user[0] = '\0'; /*no user code */
182 domain[0] = '\0'; /*no domain code */
183
184 if ((p = strchr(buf, '\n')) != NULL)
185 *p = '\0'; /* strip \n */
186 buflen = strlen(buf); /* keep this so we only scan the buffer for \0 once per loop */
8bdd0cec
AJ
187 if (buflen > 3) {
188 decodedLen = base64_decode(decodedBuf, sizeof(decodedBuf), buf+3);
189 packet = (ntlmhdr*)decodedBuf;
190 } else {
191 packet = NULL;
fb599974 192 decodedLen = 0;
8bdd0cec 193 }
75aa769b
AJ
194 if (buflen > 3 && NTLM_packet_debug_enabled) {
195 strncpy(helper_command, buf, 2);
196 helper_command[2] = '\0';
197 debug("Got '%s' from Squid with data:\n", helper_command);
8bdd0cec 198 hex_dump((unsigned char *)decodedBuf, decodedLen);
75aa769b
AJ
199 } else
200 debug("Got '%s' from Squid\n", buf);
201
5dc2526c 202 if (strncmp(buf, "YR", 2) == 0) {
75aa769b
AJ
203 char nonce[NTLM_NONCE_LEN];
204 ntlm_challenge chal;
205 ntlm_make_nonce(nonce);
206 if (buflen > 3) {
207 ntlm_negotiate *nego = (ntlm_negotiate *)packet;
208 ntlm_make_challenge(&chal, authenticate_ntlm_domain, NULL, nonce, NTLM_NONCE_LEN, nego->flags);
209 } else {
1dcf61eb 210 ntlm_make_challenge(&chal, authenticate_ntlm_domain, NULL, nonce, NTLM_NONCE_LEN, NTLM_NEGOTIATE_ASCII);
75aa769b
AJ
211 }
212 // TODO: find out what this context means, and why only the fake auth helper contains it.
213 chal.context_high = htole32(0x003a<<16);
214
215 len = sizeof(chal) - sizeof(chal.payload) + le16toh(chal.target.maxlen);
216 data = (char *) base64_encode_bin((char *) &chal, len);
217 if (NTLM_packet_debug_enabled) {
218 printf("TT %s\n", data);
219 debug("sending 'TT' to squid with data:\n");
220 hex_dump((unsigned char *)&chal, len);
221 } else
222 SEND2("TT %s", data);
5dc2526c 223 } else if (strncmp(buf, "KK ", 3) == 0) {
75aa769b
AJ
224 if (!packet) {
225 SEND("BH received KK with no data! user=");
1dcf61eb 226 } else if (ntlm_validate_packet(packet, NTLM_AUTHENTICATE) == NTLM_ERR_NONE) {
8bdd0cec 227 if (ntlm_unpack_auth((ntlm_authenticate *)packet, user, domain, decodedLen) == NTLM_ERR_NONE) {
75aa769b
AJ
228 lc(user);
229 lc(domain);
230 if (strip_domain_enabled) {
231 SEND2("AF %s", user);
232 } else {
59a09b98 233 SEND4("AF %s%s%s", domain, (*domain?"\\":""), user);
75aa769b
AJ
234 }
235 } else {
236 lc(user);
237 lc(domain);
59a09b98 238 SEND4("NA invalid credentials, user=%s%s%s", domain, (*domain?"\\":""), user);
75aa769b
AJ
239 }
240 } else {
241 SEND("BH wrong packet type! user=");
242 }
243 }
244 }
245 exit(0);
246}