1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2010, Mandy Wu, <mandy.wu@intel.com> 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at http://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 23/* 24 * This is a fake ntlm_auth, which is used for testing NTLM single-sign-on. 25 * When DEBUGBUILD is defined, libcurl invoke this tool instead of real winbind 26 * daemon helper /usr/bin/ntlm_auth. This tool will accept commands and 27 * responses with a pre-written string saved in test case test2005. 28 */ 29 30#define CURL_NO_OLDIES 31 32#include "setup.h" 33 34#ifdef HAVE_UNISTD_H 35#include <unistd.h> 36#endif 37 38#define ENABLE_CURLX_PRINTF 39#include "curlx.h" /* from the private lib dir */ 40#include "getpart.h" 41#include "util.h" 42 43/* include memdebug.h last */ 44#include "memdebug.h" 45 46#ifndef DEFAULT_LOGFILE 47#define DEFAULT_LOGFILE "log/fake_ntlm.log" 48#endif 49 50const char *serverlogfile = DEFAULT_LOGFILE; 51 52/* 53 * Returns an allocated buffer with printable representation of input 54 * buffer contents or returns NULL on out of memory condition. 55 */ 56static char *printable(char *inbuf, size_t inlength) 57{ 58 char *outbuf; 59 char *newbuf; 60 size_t newsize; 61 size_t outsize; 62 size_t outincr = 0; 63 size_t i, o = 0; 64 65#define HEX_FMT_STR "[0x%02X]" 66#define HEX_STR_LEN 6 67#define NOTHING_STR "[NOTHING]" 68#define NOTHING_LEN 9 69 70 if(!inlength) 71 inlength = strlen(inbuf); 72 73 if(inlength) { 74 outincr = ((inlength/2) < (HEX_STR_LEN+1)) ? HEX_STR_LEN+1 : inlength/2; 75 outsize = inlength + outincr; 76 } 77 else 78 outsize = NOTHING_LEN + 1; 79 80 outbuf = malloc(outsize); 81 if(!outbuf) 82 return NULL; 83 84 if(!inlength) { 85 sprintf(&outbuf[0], "%s", NOTHING_STR); 86 return outbuf; 87 } 88 89 for(i=0; i<inlength; i++) { 90 91 if(o > outsize - (HEX_STR_LEN + 1)) { 92 newsize = outsize + outincr; 93 newbuf = realloc(outbuf, newsize); 94 if(!newbuf) { 95 free(outbuf); 96 return NULL; 97 } 98 outbuf = newbuf; 99 outsize = newsize; 100 } 101 102 if((inbuf[i] > 0x20) && (inbuf[i] < 0x7F)) { 103 outbuf[o] = inbuf[i]; 104 o++; 105 } 106 else { 107 sprintf(&outbuf[o], HEX_FMT_STR, inbuf[i]); 108 o += HEX_STR_LEN; 109 } 110 111 } 112 outbuf[o] = '\0'; 113 114 return outbuf; 115} 116 117int main(int argc, char *argv[]) 118{ 119 char buf[1024]; 120 FILE *stream; 121 char *filename; 122 int error; 123 char *type1_input = NULL, *type3_input = NULL; 124 char *type1_output = NULL, *type3_output = NULL; 125 size_t size = 0; 126 long testnum; 127 const char *env; 128 int arg = 1; 129 char *helper_user = (char *)"unknown"; 130 char *helper_proto = (char *)"unknown"; 131 char *helper_domain = (char *)"unknown"; 132 bool use_cached_creds = FALSE; 133 char *msgbuf; 134 135 buf[0] = '\0'; 136 137 while(argc > arg) { 138 if(!strcmp("--use-cached-creds", argv[arg])) { 139 use_cached_creds = TRUE; 140 arg++; 141 } 142 else if(!strcmp("--helper-protocol", argv[arg])) { 143 arg++; 144 if(argc > arg) 145 helper_proto = argv[arg++]; 146 } 147 else if(!strcmp("--username", argv[arg])) { 148 arg++; 149 if(argc > arg) 150 helper_user = argv[arg++]; 151 } 152 else if(!strcmp("--domain", argv[arg])) { 153 arg++; 154 if(argc > arg) 155 helper_domain = argv[arg++]; 156 } 157 else { 158 puts("Usage: fake_ntlm [option]\n" 159 " --use-cached-creds\n" 160 " --helper-protocol [protocol]\n" 161 " --username [username]\n" 162 " --domain [domain]"); 163 exit(1); 164 } 165 } 166 167 logmsg("fake_ntlm (user: %s) (proto: %s) (domain: %s) (cached creds: %s)", 168 helper_user, helper_proto, helper_domain, 169 (use_cached_creds) ? "yes" : "no"); 170 171 env = getenv("CURL_NTLM_AUTH_TESTNUM"); 172 if (env) { 173 char *endptr; 174 long lnum = strtol(env, &endptr, 10); 175 if((endptr != env + strlen(env)) || (lnum < 1L)) { 176 logmsg("Test number not valid in CURL_NTLM_AUTH_TESTNUM"); 177 exit(1); 178 } 179 testnum = lnum; 180 } else { 181 logmsg("Test number not specified in CURL_NTLM_AUTH_TESTNUM"); 182 exit(1); 183 } 184 185 env = getenv("CURL_NTLM_AUTH_SRCDIR"); 186 if (env) { 187 path = env; 188 } 189 190 filename = test2file(testnum); 191 stream=fopen(filename, "rb"); 192 if(!stream) { 193 error = ERRNO; 194 logmsg("fopen() failed with error: %d %s", error, strerror(error)); 195 logmsg("Error opening file: %s", filename); 196 logmsg("Couldn't open test file %ld", testnum); 197 exit(1); 198 } 199 else { 200 /* get the ntlm_auth input/output */ 201 error = getpart(&type1_input, &size, "ntlm_auth_type1", "input", stream); 202 fclose(stream); 203 if(error || size == 0) { 204 logmsg("getpart() type 1 input failed with error: %d", error); 205 exit(1); 206 } 207 } 208 209 stream=fopen(filename, "rb"); 210 if(!stream) { 211 error = ERRNO; 212 logmsg("fopen() failed with error: %d %s", error, strerror(error)); 213 logmsg("Error opening file: %s", filename); 214 logmsg("Couldn't open test file %ld", testnum); 215 exit(1); 216 } 217 else { 218 size = 0; 219 error = getpart(&type3_input, &size, "ntlm_auth_type3", "input", stream); 220 fclose(stream); 221 if(error || size == 0) { 222 logmsg("getpart() type 3 input failed with error: %d", error); 223 exit(1); 224 } 225 } 226 227 while(fgets(buf, sizeof(buf), stdin)) { 228 if(strcmp(buf, type1_input) == 0) { 229 stream=fopen(filename, "rb"); 230 if(!stream) { 231 error = ERRNO; 232 logmsg("fopen() failed with error: %d %s", error, strerror(error)); 233 logmsg("Error opening file: %s", filename); 234 logmsg("Couldn't open test file %ld", testnum); 235 exit(1); 236 } 237 else { 238 size = 0; 239 error = getpart(&type1_output, &size, "ntlm_auth_type1", "output", stream); 240 fclose(stream); 241 if(error || size == 0) { 242 logmsg("getpart() type 1 output failed with error: %d", error); 243 exit(1); 244 } 245 } 246 printf("%s", type1_output); 247 fflush(stdout); 248 } 249 else if(strncmp(buf, type3_input, strlen(type3_input)) == 0) { 250 stream=fopen(filename, "rb"); 251 if(!stream) { 252 error = ERRNO; 253 logmsg("fopen() failed with error: %d %s", error, strerror(error)); 254 logmsg("Error opening file: %s", filename); 255 logmsg("Couldn't open test file %ld", testnum); 256 exit(1); 257 } 258 else { 259 size = 0; 260 error = getpart(&type3_output, &size, "ntlm_auth_type3", "output", stream); 261 fclose(stream); 262 if(error || size == 0) { 263 logmsg("getpart() type 3 output failed with error: %d", error); 264 exit(1); 265 } 266 } 267 printf("%s", type3_output); 268 fflush(stdout); 269 } 270 else { 271 printf("Unknown request\n"); 272 msgbuf = printable(buf, 0); 273 if(msgbuf) { 274 logmsg("invalid input: '%s'\n", msgbuf); 275 free(msgbuf); 276 } 277 else 278 logmsg("OOM formatting invalid input: '%s'\n", buf); 279 exit(1); 280 } 281 } 282 return 1; 283} 284