8 #include "smbencrypt.h"
9 #include "smbbyteorder.h"
10 #include "fetchmail.h"
12 char versionString[] ="libntlm version 0.21";
14 /* Utility routines that handle NTLM auth structures. */
16 /* The [IS]VAL macros are to take care of byte order for non-Intel
17 * Machines -- I think this file is OK, but it hasn't been tested.
18 * The other files (the ones stolen from Samba) should be OK.
22 /* I am not crazy about these macros -- they seem to have gotten
23 * a bit complex. A new scheme for handling string/buffer fields
24 * in the structures probably needs to be designed
27 #define AddBytes(ptr, header, buf, count) \
29 if (buf != NULL && count != 0) \
31 SSVAL(&ptr->header.len,0,count); \
32 SSVAL(&ptr->header.maxlen,0,count); \
33 SIVAL(&ptr->header.offset,0,((ptr->buffer - ((uint8*)ptr)) + ptr->bufIndex)); \
34 memcpy(ptr->buffer+ptr->bufIndex, buf, count); \
35 ptr->bufIndex += count; \
40 ptr->header.maxlen = 0; \
41 SIVAL(&ptr->header.offset,0,ptr->bufIndex); \
45 #define AddString(ptr, header, string) \
49 if (p_) len_ = strlen(p_); \
50 AddBytes(ptr, header, ((unsigned char*)p_), len_); \
53 #define AddUnicodeString(ptr, header, string) \
56 unsigned char *b_ = NULL; \
61 b_ = strToUnicode(p_); \
63 AddBytes(ptr, header, b_, len_*2); \
67 #define GetUnicodeString(structPtr, header) \
68 unicodeToString(((char*)structPtr) + IVAL(&structPtr->header.offset,0) , SVAL(&structPtr->header.len,0)/2)
69 #define GetString(structPtr, header) \
70 toString((((char *)structPtr) + IVAL(&structPtr->header.offset,0)), SVAL(&structPtr->header.len,0))
71 #define DumpBuffer(fp, structPtr, header) \
72 dumpRaw(fp,((unsigned char*)structPtr)+IVAL(&structPtr->header.offset,0),SVAL(&structPtr->header.len,0))
75 static void dumpRaw(FILE *fp, unsigned char *buf, size_t len)
80 fprintf(fp,"%02x ",buf[i]);
85 /* helper macro to destructively resize buffers; assumes that bufsiz
86 * is initialized to 0 if buf is unallocated! */
87 #define allocbuf(buf, bufsiz, need, type) do { \
88 if (!buf || (need) > (bufsiz)) \
90 (bufsiz) = ((need) < 1024) ? 1024 : (need); \
92 (buf) = (type)xmalloc(bufsiz); \
96 /* this is a brute-force conversion from UCS-2LE to US-ASCII, discarding
98 static char *unicodeToString(char *p, size_t len)
102 static size_t bufsiz;
104 allocbuf(buf, bufsiz, len + 1, char *);
106 for (i=0; i<len; ++i)
116 /* This is a brute-force conversion from US-ASCII to UCS-2LE */
117 static unsigned char *strToUnicode(char *p)
119 static unsigned char *buf;
120 static size_t bufsiz;
121 size_t l = strlen(p);
124 allocbuf(buf, bufsiz, l * 2, unsigned char *);
135 static unsigned char *toString(char *p, size_t len)
137 static unsigned char *buf;
138 static size_t bufsiz;
140 allocbuf(buf, bufsiz, len + 1, unsigned char *);
147 void dumpSmbNtlmAuthRequest(FILE *fp, tSmbNtlmAuthRequest *request)
149 fprintf(fp,"NTLM Request:\n");
150 fprintf(fp," Ident = %s\n",request->ident);
151 fprintf(fp," mType = %ld\n",(long int)IVAL(&request->msgType,0));
152 fprintf(fp," Flags = %08x\n",IVAL(&request->flags,0));
153 fprintf(fp," User = %s\n",(char *)GetString(request,user));
154 fprintf(fp," Domain = %s\n",(char *)GetString(request,domain));
157 void dumpSmbNtlmAuthChallenge(FILE *fp, tSmbNtlmAuthChallenge *challenge)
159 fprintf(fp,"NTLM Challenge:\n");
160 fprintf(fp," Ident = %s\n",challenge->ident);
161 fprintf(fp," mType = %ld\n",(long int)IVAL(&challenge->msgType,0));
162 fprintf(fp," Domain = %s\n",GetUnicodeString(challenge,uDomain));
163 fprintf(fp," Flags = %08x\n",IVAL(&challenge->flags,0));
164 fprintf(fp," Challenge = "); dumpRaw(fp, challenge->challengeData,8);
167 void dumpSmbNtlmAuthResponse(FILE *fp, tSmbNtlmAuthResponse *response)
169 fprintf(fp,"NTLM Response:\n");
170 fprintf(fp," Ident = %s\n",response->ident);
171 fprintf(fp," mType = %ld\n",(long int)IVAL(&response->msgType,0));
172 fprintf(fp," LmResp = "); DumpBuffer(fp,response,lmResponse);
173 fprintf(fp," NTResp = "); DumpBuffer(fp,response,ntResponse);
174 fprintf(fp," Domain = %s\n",GetUnicodeString(response,uDomain));
175 fprintf(fp," User = %s\n",GetUnicodeString(response,uUser));
176 fprintf(fp," Wks = %s\n",GetUnicodeString(response,uWks));
177 fprintf(fp," sKey = "); DumpBuffer(fp, response,sessionKey);
178 fprintf(fp," Flags = %08x\n",IVAL(&response->flags,0));
181 void buildSmbNtlmAuthRequest(tSmbNtlmAuthRequest *request, char *user, char *domain)
183 char *u = xstrdup(user);
184 char *p = strchr(u,'@');
193 request->bufIndex = 0;
194 memcpy(request->ident,"NTLMSSP\0\0\0",8);
195 SIVAL(&request->msgType,0,1);
196 SIVAL(&request->flags,0,0x0000b207); /* have to figure out what these mean */
197 AddString(request,user,u);
198 AddString(request,domain,domain);
202 void buildSmbNtlmAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, char *user, char *password)
204 uint8 lmRespData[24];
205 uint8 ntRespData[24];
206 char *d = xstrdup(GetUnicodeString(challenge,uDomain));
208 char *u = xstrdup(user);
209 char *p = strchr(u,'@');
217 SMBencrypt((uint8*)password, challenge->challengeData, lmRespData);
218 SMBNTencrypt((uint8*)password, challenge->challengeData, ntRespData);
220 response->bufIndex = 0;
221 memcpy(response->ident,"NTLMSSP\0\0\0",8);
222 SIVAL(&response->msgType,0,3);
224 AddBytes(response,lmResponse,lmRespData,24);
225 AddBytes(response,ntResponse,ntRespData,24);
226 AddUnicodeString(response,uDomain,domain);
227 AddUnicodeString(response,uUser,u);
228 AddUnicodeString(response,uWks,u);
229 AddString(response,sessionKey,NULL);
231 response->flags = challenge->flags;