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