]> Pileus Git - ~andy/fetchmail/blob - libntlm-0.21/smbutil.c
Add files from ESR's dev directory that weren't under version control
[~andy/fetchmail] / libntlm-0.21 / smbutil.c
1 #include <unistd.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <ctype.h>
5 #include <assert.h>
6 #include <string.h>
7 #include "ntlm.h"
8 #include "smbencrypt.h"
9 #include "smbbyteorder.h"
10
11 char versionString[] ="libntlm version 0.21";
12
13 /* Utility routines that handle NTLM auth structures. */
14
15 /* The [IS]VAL macros are to take care of byte order for non-Intel
16  * Machines -- I think this file is OK, but it hasn't been tested.
17  * The other files (the ones stolen from Samba) should be OK.
18  */
19
20
21 /* I am not crazy about these macros -- they seem to have gotten
22  * a bit complex.  A new scheme for handling string/buffer fields
23  * in the structures probably needs to be designed
24  */
25
26 #define AddBytes(ptr, header, buf, count) \
27 { \
28 if (buf && count) \
29   { \
30   SSVAL(&ptr->header.len,0,count); \
31   SSVAL(&ptr->header.maxlen,0,count); \
32   SIVAL(&ptr->header.offset,0,((ptr->buffer - ((uint8*)ptr)) + ptr->bufIndex)); \
33   memcpy(ptr->buffer+ptr->bufIndex, buf, count); \
34   ptr->bufIndex += count; \
35   } \
36 else \
37   { \
38   ptr->header.len = \
39   ptr->header.maxlen = 0; \
40   SIVAL(&ptr->header.offset,0,ptr->bufIndex); \
41   } \
42 }
43
44 #define AddString(ptr, header, string) \
45 { \
46 char *p = string; \
47 int len = 0; \
48 if (p) len = strlen(p); \
49 AddBytes(ptr, header, ((unsigned char*)p), len); \
50 }
51
52 #define AddUnicodeString(ptr, header, string) \
53 { \
54 char *p = string; \
55 unsigned char *b = NULL; \
56 int len = 0; \
57 if (p) \
58   { \
59   len = strlen(p); \
60   b = strToUnicode(p); \
61   } \
62 AddBytes(ptr, header, b, len*2); \
63 }
64
65
66 #define GetUnicodeString(structPtr, header) \
67 unicodeToString(((char*)structPtr) + IVAL(&structPtr->header.offset,0) , SVAL(&structPtr->header.len,0)/2)
68 #define GetString(structPtr, header) \
69 toString((((char *)structPtr) + IVAL(&structPtr->header.offset,0)), SVAL(&structPtr->header.len,0))
70 #define DumpBuffer(fp, structPtr, header) \
71 dumpRaw(fp,((unsigned char*)structPtr)+IVAL(&structPtr->header.offset,0),SVAL(&structPtr->header.len,0))
72
73
74 static void dumpRaw(FILE *fp, unsigned char *buf, size_t len)
75   {
76   int i;
77   
78   for (i=0; i<len; ++i)
79     fprintf(fp,"%02x ",buf[i]);
80     
81     fprintf(fp,"\n");
82   }
83
84 static char *unicodeToString(char *p, size_t len)
85   {
86   int i;
87   static char buf[1024];
88
89   assert(len+1 < sizeof buf);
90   
91   for (i=0; i<len; ++i)
92     {  
93     buf[i] = *p & 0x7f;
94     p += 2;
95     }
96
97   buf[i] = '\0';
98   return buf;
99   }
100
101 static unsigned char *strToUnicode(char *p)
102   {
103   static unsigned char buf[1024];
104   size_t l = strlen(p);
105   int i = 0;
106   
107   assert(l*2 < sizeof buf);
108   
109   while (l--)
110     {
111     buf[i++] = *p++;
112     buf[i++] = 0;
113     }
114   
115   return buf;
116   }
117
118 static unsigned char *toString(char *p, size_t len)
119   {
120   static unsigned char buf[1024];
121   
122   assert(len+1 < sizeof buf);
123   
124   memcpy(buf,p,len);
125   buf[len] = 0;
126   return buf;
127   }
128
129 void dumpSmbNtlmAuthRequest(FILE *fp, tSmbNtlmAuthRequest *request)
130   {
131   fprintf(fp,"NTLM Request:\n");
132   fprintf(fp,"      Ident = %s\n",request->ident);
133   fprintf(fp,"      mType = %d\n",IVAL(&request->msgType,0));
134   fprintf(fp,"      Flags = %08x\n",IVAL(&request->flags,0));
135   fprintf(fp,"       User = %s\n",GetString(request,user));
136   fprintf(fp,"     Domain = %s\n",GetString(request,domain));
137   }
138
139 void dumpSmbNtlmAuthChallenge(FILE *fp, tSmbNtlmAuthChallenge *challenge)
140   {
141   fprintf(fp,"NTLM Challenge:\n");
142   fprintf(fp,"      Ident = %s\n",challenge->ident);
143   fprintf(fp,"      mType = %d\n",IVAL(&challenge->msgType,0));
144   fprintf(fp,"     Domain = %s\n",GetUnicodeString(challenge,uDomain));
145   fprintf(fp,"      Flags = %08x\n",IVAL(&challenge->flags,0));
146   fprintf(fp,"  Challenge = "); dumpRaw(fp, challenge->challengeData,8);
147   }
148
149 void dumpSmbNtlmAuthResponse(FILE *fp, tSmbNtlmAuthResponse *response)
150   {
151   fprintf(fp,"NTLM Response:\n");
152   fprintf(fp,"      Ident = %s\n",response->ident);
153   fprintf(fp,"      mType = %d\n",IVAL(&response->msgType,0));
154   fprintf(fp,"     LmResp = "); DumpBuffer(fp,response,lmResponse);
155   fprintf(fp,"     NTResp = "); DumpBuffer(fp,response,ntResponse);
156   fprintf(fp,"     Domain = %s\n",GetUnicodeString(response,uDomain));
157   fprintf(fp,"       User = %s\n",GetUnicodeString(response,uUser));
158   fprintf(fp,"        Wks = %s\n",GetUnicodeString(response,uWks));
159   fprintf(fp,"       sKey = "); DumpBuffer(fp, response,sessionKey);
160   fprintf(fp,"      Flags = %08x\n",IVAL(&response->flags,0));
161   }
162
163 void buildSmbNtlmAuthRequest(tSmbNtlmAuthRequest *request, char *user, char *domain)
164   {
165     char *u = strdup(user);
166     char *p = strchr(u,'@');
167     
168     if (p)
169       {
170         if (!domain) 
171           domain = p+1;
172         *p = '\0';
173       }
174     
175     request->bufIndex = 0;
176     memcpy(request->ident,"NTLMSSP\0\0\0",8);
177     SIVAL(&request->msgType,0,1);
178     SIVAL(&request->flags,0,0x0000b207);  /* have to figure out what these mean */
179     AddString(request,user,u);
180     AddString(request,domain,domain);
181     free(u);
182   }
183
184 void buildSmbNtlmAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, char *user, char *password)
185   {
186     uint8 lmRespData[24];
187     uint8 ntRespData[24];
188     char *d = strdup(GetUnicodeString(challenge,uDomain));
189     char *domain = d;
190     char *u = strdup(user);
191     char *p = strchr(u,'@');
192     
193     if (p)
194       {
195         domain = p+1;
196         *p = '\0';
197       }
198     
199     SMBencrypt(password,   challenge->challengeData, lmRespData);
200     SMBNTencrypt(password, challenge->challengeData, ntRespData);
201     
202     response->bufIndex = 0;
203     memcpy(response->ident,"NTLMSSP\0\0\0",8);
204     SIVAL(&response->msgType,0,3);
205     
206     AddBytes(response,lmResponse,lmRespData,24);
207     AddBytes(response,ntResponse,ntRespData,24);
208     AddUnicodeString(response,uDomain,domain);
209     AddUnicodeString(response,uUser,u);
210     AddUnicodeString(response,uWks,u);
211     AddString(response,sessionKey,NULL);
212   
213     response->flags = challenge->flags;
214     
215     free(d);
216     free(u);
217   }
218