~ubuntu-branches/ubuntu/karmic/openvpn/karmic

« back to all changes in this revision

Viewing changes to ntlm.c

  • Committer: Bazaar Package Importer
  • Author(s): Alberto Gonzalez Iniesta
  • Date: 2008-07-23 10:38:13 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20080723103813-axq5wohvwjr4jo0s
Tags: 2.1~rc8-1
* New upstream version
* Added Build-dep on libpkcs11-helper1 to re-enable PKCS#11
  support. Sorry for the delay Florian :) (Closes: #475353)

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 *  Copyright (C) 2004 William Preston
5
5
 *
 
6
 *  *NTLMv2 support and domain name parsing by Miroslav Zajic, Nextsoft s.r.o.*
 
7
 *
6
8
 *  This program is free software; you can redistribute it and/or modify
7
9
 *  it under the terms of the GNU General Public License as published by
8
10
 *  the Free Software Foundation; either version 2 of the License, or
19
21
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
22
 */
21
23
 
22
 
#ifdef WIN32
23
 
#include "config-win32.h"
24
 
#else
25
 
#include "config.h"
26
 
#endif
27
 
 
28
24
#include "syshead.h"
29
25
 
30
26
#if NTLM
41
37
 
42
38
#include "memdbg.h"
43
39
 
 
40
 
 
41
/* 64bit datatype macros */
 
42
#ifdef _MSC_VER 
 
43
        /* MS compilers */
 
44
#       define UINTEGER64 __int64
 
45
#       define UINT64(c) c ## Ui64
 
46
#else 
 
47
        /* Non MS compilers */
 
48
#       define UINTEGER64 unsigned long long
 
49
#       define UINT64(c) c ## LL
 
50
#endif
 
51
 
 
52
 
 
53
 
 
54
 
44
55
static void
45
56
create_des_keys(const unsigned char *hash, unsigned char *key)
46
57
{
70
81
  memcpy (result, md, 16);
71
82
}
72
83
 
 
84
static void
 
85
gen_hmac_md5 (const char* data, int data_len, const char* key, int key_len,char *result)
 
86
{
 
87
        unsigned int len;
 
88
 
 
89
        HMAC_CTX c;
 
90
        HMAC_Init (&c, key, key_len, EVP_md5());
 
91
        HMAC_Update (&c, data, data_len);
 
92
        HMAC_Final (&c, result, &len);
 
93
        HMAC_CTX_cleanup(&c);
 
94
}
 
95
 
 
96
static void
 
97
gen_timestamp (unsigned char *timestamp)
 
98
 
99
        /* Copies 8 bytes long timestamp into "timestamp" buffer. 
 
100
         * Timestamp is Little-endian, 64-bit signed value representing the number of tenths of a microsecond since January 1, 1601.
 
101
         */
 
102
 
 
103
        UINTEGER64 timestamp_ull;
 
104
 
 
105
        timestamp_ull = openvpn_time(NULL);
 
106
        timestamp_ull = (timestamp_ull + UINT64(11644473600)) * UINT64(10000000);
 
107
 
 
108
        /* store little endian value */
 
109
        timestamp[0]= timestamp_ull & UINT64(0xFF);
 
110
        timestamp[1]= (timestamp_ull  >> 8)  & UINT64(0xFF);
 
111
        timestamp[2]= (timestamp_ull  >> 16) & UINT64(0xFF);
 
112
        timestamp[3]= (timestamp_ull  >> 24) & UINT64(0xFF);
 
113
        timestamp[4]= (timestamp_ull  >> 32) & UINT64(0xFF);
 
114
        timestamp[5]= (timestamp_ull  >> 40) & UINT64(0xFF);
 
115
        timestamp[6]= (timestamp_ull  >> 48) & UINT64(0xFF);
 
116
        timestamp[7]= (timestamp_ull  >> 56) & UINT64(0xFF);
 
117
}
 
118
 
 
119
static void
 
120
gen_nonce (unsigned char *nonce)
 
121
 
122
        /* Generates 8 random bytes to be used as client nonce */
 
123
        int i;
 
124
 
 
125
        for(i=0;i<8;i++){
 
126
                nonce[i] = (unsigned char)get_random();
 
127
        }
 
128
}
 
129
 
 
130
unsigned char *my_strupr(unsigned char *str)
 
131
 
132
        /* converts string to uppercase in place */
 
133
        unsigned char *tmp = str;;
 
134
 
 
135
        do *str = toupper(*str); while (*(++str));
 
136
        return tmp;
 
137
}
 
138
 
73
139
static int
74
140
unicodize (char *dst, const char *src)
75
141
{
85
151
  return i;
86
152
}
87
153
 
 
154
static void
 
155
add_security_buffer(int sb_offset, void *data, int length, unsigned char *msg_buf, int *msg_bufpos)
 
156
{
 
157
        /* Adds security buffer data to a message and sets security buffer's offset and length */
 
158
        msg_buf[sb_offset] = (unsigned char)length;
 
159
        msg_buf[sb_offset + 2] = msg_buf[sb_offset];
 
160
        msg_buf[sb_offset + 4] = (unsigned char)(*msg_bufpos & 0xff);
 
161
        msg_buf[sb_offset + 5] = (unsigned char)((*msg_bufpos >> 8) & 0xff);
 
162
        memcpy(&msg_buf[*msg_bufpos], data, msg_buf[sb_offset]);
 
163
        *msg_bufpos += length;
 
164
}
 
165
 
88
166
const char *
89
167
ntlm_phase_1 (const struct http_proxy_info *p, struct gc_arena *gc)
90
168
{
105
183
const char *
106
184
ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_arena *gc)
107
185
{
 
186
        /* NTLM handshake
 
187
         *
 
188
         * http://davenport.sourceforge.net/ntlm.html
 
189
         *
 
190
         */
 
191
        
108
192
  char pwbuf[sizeof (p->up.password) * 2]; /* for unicode password */
109
193
  char buf2[128]; /* decoded reply from proxy */
110
 
  char phase3[146];
 
194
  unsigned char phase3[464];
111
195
 
112
196
  char md4_hash[21];
113
 
  char challenge[8], response[24];
114
 
  int i, ret_val, buflen;
 
197
  char challenge[8], ntlm_response[24];
 
198
  int i, ret_val;
115
199
  des_cblock key1, key2, key3;
116
200
  des_key_schedule sched1, sched2, sched3;
117
201
 
118
 
  /* try a minimal NTLM handshake
119
 
   *
120
 
   * http://davenport.sourceforge.net/ntlm.html
121
 
   *
122
 
   */
 
202
        char ntlmv2_response[144];
 
203
        char userdomain_u[256]; /* for uppercase unicode username and domain */
 
204
        char userdomain[128];   /* the same as previous but ascii */
 
205
        char ntlmv2_hash[16];
 
206
        char ntlmv2_hmacmd5[16];
 
207
        char *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */
 
208
        int ntlmv2_blob_size=0;
 
209
        int phase3_bufpos = 0x40; /* offset to next security buffer data to be added */
 
210
        int len;
 
211
 
 
212
        char domain[128];
 
213
        char username[128];
 
214
        char *separator;
 
215
 
 
216
        bool ntlmv2_enabled = (p->auth_method == HTTP_AUTH_NTLM2);
 
217
 
123
218
  ASSERT (strlen (p->up.username) > 0);
124
219
  ASSERT (strlen (p->up.password) > 0);
 
220
        
 
221
        /* username parsing */
 
222
        separator = strchr(p->up.username, '\\');
 
223
        if (separator == NULL) {
 
224
                strncpy(username, p->up.username, sizeof(username)-1);
 
225
                username[sizeof(username)-1]=0;
 
226
                domain[0]=0;
 
227
        } else {
 
228
                strncpy(username, separator+1, sizeof(username)-1);
 
229
                username[sizeof(username)-1]=0;
 
230
                len = separator - p->up.username;
 
231
                if (len > sizeof(domain) - 1) len = sizeof(domain) - 1;
 
232
                strncpy(domain, p->up.username,  len);
 
233
                domain[len]=0;
 
234
        }
 
235
 
125
236
 
126
237
  /* fill 1st 16 bytes with md4 hash, disregard terminating null */
127
238
  gen_md4_hash (pwbuf, unicodize (pwbuf, p->up.password) - 2, md4_hash);
139
250
    challenge[i] = buf2[i+24];
140
251
  }
141
252
 
142
 
  create_des_keys ((unsigned char *)md4_hash, key1);
143
 
  des_set_key_unchecked ((des_cblock *)key1, sched1);
144
 
  des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)response, sched1, DES_ENCRYPT);
145
 
 
146
 
  create_des_keys ((unsigned char *)&(md4_hash[7]), key2);
147
 
  des_set_key_unchecked ((des_cblock *)key2, sched2);
148
 
  des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)&(response[8]), sched2, DES_ENCRYPT);
149
 
 
150
 
  create_des_keys ((unsigned char *)&(md4_hash[14]), key3);
151
 
  des_set_key_unchecked ((des_cblock *)key3, sched3);
152
 
  des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)&(response[16]), sched3, DES_ENCRYPT);
153
 
 
154
 
  /* clear reply */
155
 
  memset (phase3, 0, sizeof (phase3));
156
 
 
157
 
  strcpy (phase3, "NTLMSSP\0");
158
 
  phase3[8] = 3; /* type 3 */
159
 
 
160
 
  buflen = 0x58 + strlen (p->up.username);
161
 
  if (buflen > (int) sizeof (phase3))
162
 
    buflen = sizeof (phase3);
163
 
 
164
 
  phase3[0x10] = buflen; /* lm not used */
165
 
  phase3[0x20] = buflen; /* default domain (i.e. proxy's domain) */
166
 
  phase3[0x30] = buflen; /* no workstation name supplied */
167
 
  phase3[0x38] = buflen; /* no session key */
168
 
 
169
 
  phase3[0x14] = 24; /* ntlm response is 24 bytes long */
170
 
  phase3[0x16] = phase3[0x14];
171
 
  phase3[0x18] = 0x40; /* ntlm offset */
172
 
  memcpy (&(phase3[0x40]), response, 24);
173
 
 
174
 
 
175
 
  phase3[0x24] = strlen (p->up.username); /* username in ascii */
176
 
  phase3[0x26] = phase3[0x24];
177
 
  phase3[0x28] = 0x58;
178
 
  strncpy (&(phase3[0x58]), p->up.username, sizeof (phase3) - 0x58);
179
 
 
 
253
        if (ntlmv2_enabled){ /* Generate NTLMv2 response */
 
254
                
 
255
                /* NTLMv2 hash */
 
256
                my_strupr(strcpy(userdomain, username));
 
257
                if (strlen(username) + strlen(domain) < sizeof(userdomain))
 
258
                        strcat(userdomain, domain);
 
259
                else
 
260
                        msg (M_INFO, "Warning: Username or domain too long");
 
261
                unicodize (userdomain_u, userdomain);
 
262
                gen_hmac_md5(userdomain_u, 2 * strlen(userdomain), md4_hash, 16, ntlmv2_hash);
 
263
 
 
264
                /* NTLMv2 Blob */
 
265
                memset(ntlmv2_blob, 0, 128);                /* Clear blob buffer */ 
 
266
                ntlmv2_blob[0x00]=1;                        /* Signature */
 
267
                ntlmv2_blob[0x01]=1;                        /* Signature */
 
268
                ntlmv2_blob[0x04]=0;                        /* Reserved */
 
269
                gen_timestamp(&ntlmv2_blob[0x08]);          /* 64-bit Timestamp */
 
270
                gen_nonce(&ntlmv2_blob[0x10]);              /* 64-bit Client Nonce */
 
271
                ntlmv2_blob[0x18]=0;                        /* Unknown, zero should work */
 
272
 
 
273
                /* Add target information block to the blob */
 
274
                int tib_len;
 
275
                if (( *((long *)&buf2[0x14]) & 0x00800000) == 0x00800000){ /* Check for Target Information block */
 
276
                        tib_len = buf2[0x28];/* Get Target Information block size */
 
277
                        if (tib_len > 96) tib_len = 96;
 
278
                        char *tib_ptr = buf2 + buf2[0x2c]; /* Get Target Information block pointer */
 
279
                        memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); /* Copy Target Information block into the blob */
 
280
                } else {
 
281
                        tib_len = 0;
 
282
                }
 
283
 
 
284
                ntlmv2_blob[0x1c + tib_len] = 0;            /* Unknown, zero works */ 
 
285
 
 
286
                /* Get blob length */
 
287
                ntlmv2_blob_size = 0x20 + tib_len; 
 
288
 
 
289
                /* Add challenge from message 2 */
 
290
                memcpy(&ntlmv2_response[8], challenge, 8);
 
291
 
 
292
                /* hmac-md5 */
 
293
                gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, 16, ntlmv2_hmacmd5);
 
294
                
 
295
                /* Add hmac-md5 result to the blob */
 
296
                memcpy(ntlmv2_response, ntlmv2_hmacmd5, 16); /* Note: This overwrites challenge previously written at ntlmv2_response[8..15] */
 
297
        
 
298
        } else { /* Generate NTLM response */
 
299
 
 
300
                create_des_keys ((unsigned char *)md4_hash, key1);
 
301
                des_set_key_unchecked ((des_cblock *)key1, sched1);
 
302
                des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)ntlm_response, sched1, DES_ENCRYPT);
 
303
 
 
304
                create_des_keys ((unsigned char *)&(md4_hash[7]), key2);
 
305
                des_set_key_unchecked ((des_cblock *)key2, sched2);
 
306
                des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)&(ntlm_response[8]), sched2, DES_ENCRYPT);
 
307
 
 
308
                create_des_keys ((unsigned char *)&(md4_hash[14]), key3);
 
309
                des_set_key_unchecked ((des_cblock *)key3, sched3);
 
310
                des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)&(ntlm_response[16]), sched3, DES_ENCRYPT);
 
311
        }
 
312
        
 
313
        
 
314
        memset (phase3, 0, sizeof (phase3)); /* clear reply */
 
315
 
 
316
        strcpy (phase3, "NTLMSSP\0"); /* signature */
 
317
        phase3[8] = 3; /* type 3 */
 
318
 
 
319
        if (ntlmv2_enabled){ /* NTLMv2 response */
 
320
                add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 16, phase3, &phase3_bufpos);
 
321
        }else{ /* NTLM response */
 
322
                add_security_buffer(0x14, ntlm_response, 24, phase3, &phase3_bufpos);
 
323
        }
 
324
        
 
325
        /* username in ascii */
 
326
        add_security_buffer(0x24, username, strlen (username), phase3, &phase3_bufpos);
 
327
 
 
328
        /* Set domain. If <domain> is empty, default domain will be used (i.e. proxy's domain) */ 
 
329
        add_security_buffer(0x1c, domain, strlen (domain), phase3, &phase3_bufpos);
 
330
        
 
331
 
 
332
        /* other security buffers will be empty */
 
333
        phase3[0x10] = phase3_bufpos; /* lm not used */
 
334
        phase3[0x30] = phase3_bufpos; /* no workstation name supplied */
 
335
        phase3[0x38] = phase3_bufpos; /* no session key */
 
336
        
 
337
        /* flags */
180
338
  phase3[0x3c] = 0x02; /* negotiate oem */
181
339
  phase3[0x3d] = 0x02; /* negotiate ntlm */
182
340
 
183
 
  return ((const char *)make_base64_string2 ((unsigned char *)phase3, buflen, gc));
 
341
  return ((const char *)make_base64_string2 ((unsigned char *)phase3, phase3_bufpos, gc));
184
342
}
185
343
 
186
344
#else