Wenzhuo Zhang | 9 Mar 13:53 2008

too small font size in status window

Hi,

I have just tried OpenVPN 2.1_rc7 on Windows XP Home (Simplified Chinese
Edition) and Windows Vista Basic (Simplified Chinese Edition). I have
three minor issues with it:

1. The font size in the status window is too small for both XP and
Vista. See
http://web.zhmail.com/screenshot/20080309/OpenVPN_StatusWindow.PNG

2. Uninstaller does not delete start menu shortcuts on Vista.

3. If OpenVPN is already running as a service in Windows Vista, the
OpenVPN GUI can still connect and break routing unexpectedly. IMHO,
OpenVPN should allow only one instance for one particular connection.

Wenzhuo

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel
(Continue reading)

Wenzhuo Zhang | 10 Mar 02:49 2008

three minor issues with 2.1_rc7

Hi,

I have just tried OpenVPN 2.1_rc7 on Windows XP Home (Simplified Chinese
Edition) and Windows Vista Basic (Simplified Chinese Edition). I have
three minor issues with it:

1. The font size in the status window is too small for both XP and
Vista. See
http://web.zhmail.com/screenshot/20080309/OpenVPN_StatusWindow.PNG

2. Uninstaller does not delete start menu shortcuts on Vista.

3. If OpenVPN is already running as a service in Windows Vista, the
OpenVPN GUI can still connect and break routing unexpectedly. IMHO,
OpenVPN should allow only one instance for one particular connection.

Wenzhuo

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Openvpn-users mailing list
Openvpn-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-users
(Continue reading)

Wenzhuo Zhang | 11 Mar 01:02 2008

Re: too small font size in status window

Matt Wilks 写道:
>> 1. The font size in the status window is too small for both XP and
>> Vista. See
>> http://web.zhmail.com/screenshot/20080309/OpenVPN_StatusWindow.PNG
>>     
>
> I wonder if this has something to do with your Chinese fonts.  I haven't
> seen this on any installations I have made...
>   

All font sentings are factory default in both XP and Vista. This could
be an issue for all CJK editions of Windows.

>> 2. Uninstaller does not delete start menu shortcuts on Vista.
>>     
>
> OK, I'll take a look into this when I can.
>
>   
>> 3. If OpenVPN is already running as a service in Windows Vista, the
>> OpenVPN GUI can still connect and break routing unexpectedly. IMHO,
>> OpenVPN should allow only one instance for one particular connection.
>>     
>
> I'm not sure what you mean by "running as a service".  Does this mean
> that you started it up with the UTORvpn icon, connected, and started it
> up again with the UTORvpn icon?
>
>   

(Continue reading)

Wenzhuo Zhang | 11 Mar 01:33 2008

Re: [Openvpn-devel] too small font size in status window

Wenzhuo Zhang 写道:

>>> 3. If OpenVPN is already running as a service in Windows Vista, the
>>> OpenVPN GUI can still connect and break routing unexpectedly. IMHO,
>>> OpenVPN should allow only one instance for one particular connection.
>>>     
>> I'm not sure what you mean by "running as a service".  Does this mean
>> that you started it up with the UTORvpn icon, connected, and started it
>> up again with the UTORvpn icon?
>>
>>   
> 
> By running as a service, I mean starting the OpenVPN service through the
> Windows services.msc and setting it to Automatic there.

I am talking about client mode here. OpenVPN should allow only one
instance for one particular client-mode connection. If one instance is
running already, the second instance should abort.

Wenzhuo

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Openvpn-users mailing list
(Continue reading)

Friedrich Nietzsche | 11 Mar 12:24 2008
Picon

NSIS compile errors.

Hi I get compile errors with the current RC, is this intended? why cant I compile it?

Den perfekta mixen av nöjesnyheter & livekonserter! MSN Video
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel
Mirek Zajic | 12 Mar 13:25 2008
Picon

Re: NTLMv2 patch corrected

Hello,
I have finally made some changes to the NTLMv2 patch according to Alon's 
comments. Now it should also be architecture independent.

Miroslav Zajic
NextSoft s.r.o.

diff -Naur openvpn-2.1/ntlm.c openvpn-NTLMv2-predelane-2.1/ntlm.c
--- openvpn-2.1/ntlm.c    2008-01-13 21:25:52.915264000 +0100
+++ openvpn-NTLMv2-predelane-2.1/ntlm.c    2008-03-12 11:36:40.687500000 
+0100
 <at>  <at>  -3,6 +3,8  <at>  <at> 
  *
  *  Copyright (C) 2004 William Preston
  *
+ *  *NTLMv2 support and domain name parsing by Miroslav Zajic, Nextsoft 
s.r.o.*
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
 <at>  <at>  -70,6 +72,61  <at>  <at> 
   memcpy (result, md, 16);
 }

+static void
+gen_hmac_md5 (const char* data, int data_len, const char* key, int 
key_len,char *result)
+{
+    unsigned int len;
+
+    HMAC_CTX c;
+    HMAC_Init (&c, key, key_len, EVP_md5());
+    HMAC_Update (&c, data, data_len);
+    HMAC_Final (&c, result, &len);
+    HMAC_CTX_cleanup(&c);
+}
+
+static void
+gen_timestamp (unsigned char *timestamp)
+{
+    /* Copies 8 bytes long timestamp into "timestamp" buffer.
+     * Timestamp is Little-endian, 64-bit signed value representing the 
number of tenths of a microsecond since January 1, 1601.
+     */
+
+    UINTEGER64 timestamp_ull;
+
+    timestamp_ull = openvpn_time(NULL);
+    timestamp_ull = (timestamp_ull + UINT64(11644473600)) * 
UINT64(10000000);
+
+    /* store little endian value */
+    timestamp[0]=  timestamp_ull & UINT64(0xFF);
+    timestamp[1]= (timestamp_ull & UINT64(0xFF00)) >> 8;
+    timestamp[2]= (timestamp_ull & UINT64(0xFF0000)) >> 16;
+    timestamp[3]= (timestamp_ull & UINT64(0xFF000000)) >> 24;
+    timestamp[4]= (timestamp_ull & UINT64(0xFF00000000)) >> 32;
+    timestamp[5]= (timestamp_ull & UINT64(0xFF0000000000)) >> 40;
+    timestamp[6]= (timestamp_ull & UINT64(0xFF000000000000)) >> 48;
+    timestamp[7]= (timestamp_ull & UINT64(0xFF00000000000000)) >> 52;
+}
+
+static void
+gen_nonce (unsigned char *nonce)
+{
+    /* Generates 8 random bytes to be used as client nonce */
+    int i;
+
+    for(i=0;i<8;i++){
+        nonce[i] = (unsigned char)get_random();
+    }
+}
+
+unsigned char *my_strupr(unsigned char *str)
+{
+    /* converts string to uppercase in place */
+    unsigned char *tmp = str;;
+
+    do *str = toupper(*str); while (*(++str));
+    return tmp;
+}
+
 static int
 unicodize (char *dst, const char *src)
 {
 <at>  <at>  -85,6 +142,18  <at>  <at> 
   return i;
 }

+static void
+add_security_buffer(int sb_offset, void *data, int length, unsigned 
char *msg_buf, int *msg_bufpos)
+{
+    /* Adds security buffer data to a message and sets security 
buffer's offset and length */
+    msg_buf[sb_offset] = (unsigned char)length;
+    msg_buf[sb_offset + 2] = msg_buf[sb_offset];
+    msg_buf[sb_offset + 4] = (unsigned char)(*msg_bufpos & 0xff);
+    msg_buf[sb_offset + 5] = (unsigned char)((*msg_bufpos & 0xff00) >> 8);
+    memcpy(&msg_buf[*msg_bufpos], data, msg_buf[sb_offset]);
+    *msg_bufpos += length;
+}
+
 const char *
 ntlm_phase_1 (const struct http_proxy_info *p, struct gc_arena *gc)
 {
 <at>  <at>  -105,23 +174,56  <at>  <at> 
 const char *
 ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, 
struct gc_arena *gc)
 {
+    /* NTLM handshake
+     *
+     * http://davenport.sourceforge.net/ntlm.html
+     *
+     */
+   
   char pwbuf[sizeof (p->up.password) * 2]; /* for unicode password */
   char buf2[128]; /* decoded reply from proxy */
-  char phase3[146];
+  unsigned char phase3[464];

   char md4_hash[21];
-  char challenge[8], response[24];
-  int i, ret_val, buflen;
+  char challenge[8], ntlm_response[24];
+  int i, ret_val;
   des_cblock key1, key2, key3;
   des_key_schedule sched1, sched2, sched3;

-  /* try a minimal NTLM handshake
-   *
-   * http://davenport.sourceforge.net/ntlm.html
-   *
-   */
+    char ntlmv2_response[144];
+    char userdomain_u[256]; /* for uppercase unicode username and domain */
+    char userdomain[128];   /* the same as previous but ascii */
+    char ntlmv2_hash[16];
+    char ntlmv2_hmacmd5[16];
+    char *ntlmv2_blob = ntlmv2_response + 16; /* inside 
ntlmv2_response, length: 128 */
+    int ntlmv2_blob_size=0;
+    int phase3_bufpos = 0x40; /* offset to next security buffer data to 
be added */
+    int len;
+
+    char domain[128];
+    char username[128];
+    char *separator;
+
+    bool ntlmv2_enabled = (p->auth_method == HTTP_AUTH_NTLM2);
+
   ASSERT (strlen (p->up.username) > 0);
   ASSERT (strlen (p->up.password) > 0);
+   
+    /* username parsing */
+    separator = strchr(p->up.username, '\\');
+    if (separator == NULL) {
+        strncpy(username, p->up.username, sizeof(username)-1);
+        username[sizeof(username)-1]=0;
+        domain[0]=0;
+    } else {
+        strncpy(username, separator+1, sizeof(username)-1);
+        username[sizeof(username)-1]=0;
+        len = separator - p->up.username;
+        if (len > sizeof(domain) - 1) len = sizeof(domain) - 1;
+        strncpy(domain, p->up.username,  len);
+        domain[len]=0;
+    }
+

   /* fill 1st 16 bytes with md4 hash, disregard terminating null */
   gen_md4_hash (pwbuf, unicodize (pwbuf, p->up.password) - 2, md4_hash);
 <at>  <at>  -139,48 +241,95  <at>  <at> 
     challenge[i] = buf2[i+24];
   }

-  create_des_keys ((unsigned char *)md4_hash, key1);
-  des_set_key_unchecked ((des_cblock *)key1, sched1);
-  des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)response, 
sched1, DES_ENCRYPT);
-
-  create_des_keys ((unsigned char *)&(md4_hash[7]), key2);
-  des_set_key_unchecked ((des_cblock *)key2, sched2);
-  des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)&(response[8]), sched2, DES_ENCRYPT);
-
-  create_des_keys ((unsigned char *)&(md4_hash[14]), key3);
-  des_set_key_unchecked ((des_cblock *)key3, sched3);
-  des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)&(response[16]), sched3, DES_ENCRYPT);
-
-  /* clear reply */
-  memset (phase3, 0, sizeof (phase3));
-
-  strcpy (phase3, "NTLMSSP\0");
-  phase3[8] = 3; /* type 3 */
-
-  buflen = 0x58 + strlen (p->up.username);
-  if (buflen > (int) sizeof (phase3))
-    buflen = sizeof (phase3);
-
-  phase3[0x10] = buflen; /* lm not used */
-  phase3[0x20] = buflen; /* default domain (i.e. proxy's domain) */
-  phase3[0x30] = buflen; /* no workstation name supplied */
-  phase3[0x38] = buflen; /* no session key */
-
-  phase3[0x14] = 24; /* ntlm response is 24 bytes long */
-  phase3[0x16] = phase3[0x14];
-  phase3[0x18] = 0x40; /* ntlm offset */
-  memcpy (&(phase3[0x40]), response, 24);
-
-
-  phase3[0x24] = strlen (p->up.username); /* username in ascii */
-  phase3[0x26] = phase3[0x24];
-  phase3[0x28] = 0x58;
-  strncpy (&(phase3[0x58]), p->up.username, sizeof (phase3) - 0x58);
-
+    if (ntlmv2_enabled){ /* Generate NTLMv2 response */
+       
+        /* NTLMv2 hash */
+        my_strupr(strcpy(userdomain, username));
+        if (strlen(username) + strlen(domain) < sizeof(userdomain))
+            strcat(userdomain, domain);
+        else
+            msg (M_INFO, "Warning: Username or domain too long");
+        unicodize (userdomain_u, userdomain);
+        gen_hmac_md5(userdomain_u, 2 * strlen(userdomain), md4_hash, 
16, ntlmv2_hash);
+
+        /* NTLMv2 Blob */
+        memset(ntlmv2_blob, 0, 128);                /* Clear blob 
buffer */
+        ntlmv2_blob[0x00]=1;                        /* Signature */
+        ntlmv2_blob[0x01]=1;                        /* Signature */
+        ntlmv2_blob[0x04]=0;                        /* Reserved */
+        gen_timestamp(&ntlmv2_blob[0x08]);          /* 64-bit Timestamp */
+        gen_nonce(&ntlmv2_blob[0x10]);              /* 64-bit Client 
Nonce */
+        ntlmv2_blob[0x18]=0;                        /* Unknown, zero 
should work */
+
+        /* Add target information block to the blob */
+        int tib_len;
+        if (( *((long *)&buf2[0x14]) & 0x00800000) == 0x00800000){ /* 
Check for Target Information block */
+            tib_len = buf2[0x28];/* Get Target Information block size */
+            if (tib_len > 96) tib_len = 96;
+            char *tib_ptr = buf2 + buf2[0x2c]; /* Get Target 
Information block pointer */
+            memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); /* Copy 
Target Information block into the blob */
+        } else {
+            tib_len = 0;
+        }
+
+        ntlmv2_blob[0x1c + tib_len] = 0;            /* Unknown, zero 
works */
+
+        /* Get blob length */
+        ntlmv2_blob_size = 0x20 + tib_len;
+
+        /* Add challenge from message 2 */
+        memcpy(&ntlmv2_response[8], challenge, 8);
+
+        /* hmac-md5 */
+        gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, 
ntlmv2_hash, 16, ntlmv2_hmacmd5);
+       
+        /* Add hmac-md5 result to the blob */
+        memcpy(ntlmv2_response, ntlmv2_hmacmd5, 16); /* Note: This 
overwrites challenge previously written at ntlmv2_response[8..15] */
+   
+    } else { /* Generate NTLM response */
+
+        create_des_keys ((unsigned char *)md4_hash, key1);
+        des_set_key_unchecked ((des_cblock *)key1, sched1);
+        des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)ntlm_response, sched1, DES_ENCRYPT);
+
+        create_des_keys ((unsigned char *)&(md4_hash[7]), key2);
+        des_set_key_unchecked ((des_cblock *)key2, sched2);
+        des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)&(ntlm_response[8]), sched2, DES_ENCRYPT);
+
+        create_des_keys ((unsigned char *)&(md4_hash[14]), key3);
+        des_set_key_unchecked ((des_cblock *)key3, sched3);
+        des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)&(ntlm_response[16]), sched3, DES_ENCRYPT);
+    }
+   
+   
+    memset (phase3, 0, sizeof (phase3)); /* clear reply */
+
+    strcpy (phase3, "NTLMSSP\0"); /* signature */
+    phase3[8] = 3; /* type 3 */
+
+    if (ntlmv2_enabled){ /* NTLMv2 response */
+        add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 
16, phase3, &phase3_bufpos);
+    }else{ /* NTLM response */
+        add_security_buffer(0x14, ntlm_response, 24, phase3, 
&phase3_bufpos);
+    }
+   
+    /* username in ascii */
+    add_security_buffer(0x24, username, strlen (username), phase3, 
&phase3_bufpos);
+
+    /* Set domain. If <domain> is empty, default domain will be used 
(i.e. proxy's domain) */
+    add_security_buffer(0x1c, domain, strlen (domain), phase3, 
&phase3_bufpos);
+   
+
+    /* other security buffers will be empty */
+    phase3[0x10] = phase3_bufpos; /* lm not used */
+    phase3[0x30] = phase3_bufpos; /* no workstation name supplied */
+    phase3[0x38] = phase3_bufpos; /* no session key */
+   
+    /* flags */
   phase3[0x3c] = 0x02; /* negotiate oem */
   phase3[0x3d] = 0x02; /* negotiate ntlm */

-  return ((const char *)make_base64_string2 ((unsigned char *)phase3, 
buflen, gc));
+  return ((const char *)make_base64_string2 ((unsigned char *)phase3, 
phase3_bufpos, gc));
 }

 #else
diff -Naur openvpn-2.1/ntlm.h openvpn-NTLMv2-predelane-2.1/ntlm.h
--- openvpn-2.1/ntlm.h    2008-01-13 21:25:52.935292800 +0100
+++ openvpn-NTLMv2-predelane-2.1/ntlm.h    2008-03-12 11:35:36.296875000 
+0100
 <at>  <at>  -3,6 +3,18  <at>  <at> 

 #if NTLM

+/* 64bit datatype macros */
+#ifdef _MSC_VER
+    /* MS compilers */
+#define UINTEGER64 __int64
+#define UINT64(c) c ## Ui64
+#else
+    /* Non MS compilers */
+#define UINTEGER64 unsigned long long
+#define UINT64(c) c ## LL
+#endif
+
+
 const char *ntlm_phase_1 (const struct http_proxy_info *p, struct 
gc_arena *gc);
 const char *ntlm_phase_3 (const struct http_proxy_info *p, const char 
*phase_2, struct gc_arena *gc);

diff -Naur openvpn-2.1/proxy.c openvpn-NTLMv2-predelane-2.1/proxy.c
--- openvpn-2.1/proxy.c    2008-01-13 21:25:52.945307200 +0100
+++ openvpn-NTLMv2-predelane-2.1/proxy.c    2008-01-15 
11:46:12.737156800 +0100
 <at>  <at>  -294,19 +294,21  <at>  <at> 
     p->auth_method = HTTP_AUTH_BASIC;
       else if (!strcmp (o->auth_method_string, "ntlm"))
     p->auth_method = HTTP_AUTH_NTLM;
+      else if (!strcmp (o->auth_method_string, "ntlm2"))
+    p->auth_method = HTTP_AUTH_NTLM2;
       else
-    msg (M_FATAL, "ERROR: unknown HTTP authentication method: '%s' -- 
only the 'none', 'basic', or 'ntlm' methods are currently supported",
+    msg (M_FATAL, "ERROR: unknown HTTP authentication method: '%s' -- 
only the 'none', 'basic', 'ntlm', or 'ntlm2' methods are currently 
supported",
          o->auth_method_string);
     }

-  /* only basic and NTLM authentication supported so far */
-  if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == 
HTTP_AUTH_NTLM)
+  /* only basic and NTLM/NTLMv2 authentication supported so far */
+  if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == 
HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2)
     {
       get_user_pass_http (p, true);
     }

 #if !NTLM
-  if (p->auth_method == HTTP_AUTH_NTLM)
+  if (p->auth_method == HTTP_AUTH_NTLM || p->auth_method == 
HTTP_AUTH_NTLM2)
     msg (M_FATAL, "Sorry, this version of " PACKAGE_NAME " was built 
without NTLM Proxy support.");
 #endif

 <at>  <at>  -374,6 +376,12  <at>  <at> 

 #if NTLM
     case HTTP_AUTH_NTLM:
+    case HTTP_AUTH_NTLM2:
+      /* keep-alive connection */
+      openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: Keep-Alive");
+      if (!send_line_crlf (sd, buf))
+    goto error;
+
       openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s",
             ntlm_phase_1 (p, &gc));
       msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 1");
 <at>  <at>  -411,7 +419,7  <at>  <at> 
       msg (D_PROXY, "Proxy requires authentication");

       /* check for NTLM */
-      if (p->auth_method == HTTP_AUTH_NTLM)
+      if (p->auth_method == HTTP_AUTH_NTLM || p->auth_method == 
HTTP_AUTH_NTLM2)
         {
 #if NTLM
           /* look for the phase 2 response */
 <at>  <at>  -456,6 +464,12  <at>  <at> 
           if (!send_line_crlf (sd, buf))
             goto error;

+          /* keep-alive connection */
+          openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: 
Keep-Alive");
+          if (!send_line_crlf (sd, buf))
+            goto error;
+
+         
           /* send HOST etc, */
           openvpn_sleep (1);
           openvpn_snprintf (buf, sizeof(buf), "Host: %s", host);
diff -Naur openvpn-2.1/proxy.h openvpn-NTLMv2-predelane-2.1/proxy.h
--- openvpn-2.1/proxy.h    2008-01-13 21:25:52.975350400 +0100
+++ openvpn-NTLMv2-predelane-2.1/proxy.h    2008-01-15 
11:25:00.097190400 +0100
 <at>  <at>  -59,6 +59,7  <at>  <at> 
 #define HTTP_AUTH_BASIC 1
 #define HTTP_AUTH_NTLM  2
 #define HTTP_AUTH_N     3
+#define HTTP_AUTH_NTLM2 4

 struct http_proxy_options {
   const char *server;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Alon Bar-Lev | 12 Mar 16:02 2008
Picon

Re: NTLMv2 patch corrected

On 3/12/08, Mirek Zajic <zajic <at> nextsoft.cz> wrote:
> Hello,
>  I have finally made some changes to the NTLMv2 patch according to Alon's
>  comments. Now it should also be architecture independent.
>
>  Miroslav Zajic
>  NextSoft s.r.o.

Hi!
Great!
Some more comments... :)

>  +    timestamp_ull = openvpn_time(NULL);
>  +    timestamp_ull = (timestamp_ull + UINT64(11644473600)) *
>  UINT64(10000000);

Just noticed that openvpn has: openvpn_gettimeofday() which works also
for WIN32... Maybe use this one?

>  +    msg_buf[sb_offset + 5] = (unsigned char)((*msg_bufpos & 0xff00) >> 8);

always & such with 0xff.

> diff -Naur openvpn-2.1/ntlm.h openvpn-NTLMv2-predelane-2.1/ntlm.h
>  --- openvpn-2.1/ntlm.h    2008-01-13 21:25:52.935292800 +0100
>  +++ openvpn-NTLMv2-predelane-2.1/ntlm.h    2008-03-12 11:35:36.296875000
>  +0100
>   <at>  <at>  -3,6 +3,18  <at>  <at> 
>
>   #if NTLM
>
>  +/* 64bit datatype macros */
>  +#ifdef _MSC_VER
>  +    /* MS compilers */
>  +#define UINTEGER64 __int64
>  +#define UINT64(c) c ## Ui64
>  +#else
>  +    /* Non MS compilers */
>  +#define UINTEGER64 unsigned long long
>  +#define UINT64(c) c ## LL
>  +#endif
>  +
>

Why not use long long for both platforms, it is already used in common.h...
Also you can use ull suffix for both platforms.

Anyway... this belongs to the .c file, it is not used by any other files.
But I don't think it is required at all.

Alon.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Mirek Zajic | 12 Mar 16:38 2008
Picon

Re: NTLMv2 patch corrected

Thans for your comments. There are some things that have to be explained 
before I'll make the changes, please read bellow.

Alon Bar-Lev napsal(a):
> On 3/12/08, Mirek Zajic <zajic <at> nextsoft.cz> wrote:
>   
>> Hello,
>>  I have finally made some changes to the NTLMv2 patch according to Alon's
>>  comments. Now it should also be architecture independent.
>>
>>  Miroslav Zajic
>>  NextSoft s.r.o.
>>     
>
> Hi!
> Great!
> Some more comments... :)
>
>   
>>  +    timestamp_ull = openvpn_time(NULL);
>>  +    timestamp_ull = (timestamp_ull + UINT64(11644473600)) *
>>  UINT64(10000000);
>>     
>
> Just noticed that openvpn has: openvpn_gettimeofday() which works also
> for WIN32... Maybe use this one?
>
>   
openvpn_time works fine, why to change?
>>  +    msg_buf[sb_offset + 5] = (unsigned char)((*msg_bufpos & 0xff00) >> 8);
>>     
>
> always & such with 0xff.
>   
Please explain, I don't understand
>   
>> diff -Naur openvpn-2.1/ntlm.h openvpn-NTLMv2-predelane-2.1/ntlm.h
>>  --- openvpn-2.1/ntlm.h    2008-01-13 21:25:52.935292800 +0100
>>  +++ openvpn-NTLMv2-predelane-2.1/ntlm.h    2008-03-12 11:35:36.296875000
>>  +0100
>>   <at>  <at>  -3,6 +3,18  <at>  <at> 
>>
>>   #if NTLM
>>
>>  +/* 64bit datatype macros */
>>  +#ifdef _MSC_VER
>>  +    /* MS compilers */
>>  +#define UINTEGER64 __int64
>>  +#define UINT64(c) c ## Ui64
>>  +#else
>>  +    /* Non MS compilers */
>>  +#define UINTEGER64 unsigned long long
>>  +#define UINT64(c) c ## LL
>>  +#endif
>>  +
>>
>>     
>
> Why not use long long for both platforms, it is already used in common.h...
> Also you can use ull suffix for both platforms.
>
> Anyway... this belongs to the .c file, it is not used by any other files.
> But I don't think it is required at all.
>
> Alon.
>   
Some Microsoft compilers doesn't support long long, but they support 
__int64. The same is with LL/Ui64 postfix. I think that this is correct. 
But I'm not sure about  the location. Maybe that it should be placed in 
some common header (common.h?) for further usage by other modules.

Thanks
Miroslav Zajic
NextSoft s.r.o.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Alon Bar-Lev | 13 Mar 14:45 2008
Picon

Re: NTLMv2 patch corrected

On 3/12/08, Mirek Zajic <zajic <at> nextsoft.cz> wrote:
>  > Just noticed that openvpn has: openvpn_gettimeofday() which works also
>  > for WIN32... Maybe use this one?
>  >
>  >
>
> openvpn_time works fine, why to change?

I remember you used gettimeofday in previous versions... I missed the
openvpn_gettimeofday() availability... Maybe the protocol do require
more precise timing... I truly don't know.

>
> >>  +    msg_buf[sb_offset + 5] = (unsigned char)((*msg_bufpos & 0xff00) >> 8);
>  >>
>  >
>  > always & such with 0xff.
>  >
>
> Please explain, I don't understand

msg_buf[sb_offset + 5] = (unsigned char)((*msg_bufpos >> 8) & 0xff);

> Some Microsoft compilers doesn't support long long, but they support
>  __int64. The same is with LL/Ui64 postfix. I think that this is correct.
>  But I'm not sure about  the location. Maybe that it should be placed in
>  some common header (common.h?) for further usage by other modules.

This is James call... But currently OpenVPN cannot be compiled on
these compilers anyway... So adding these macros is not required.

Anyway... This is about as far as I can help.

Alon.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Mirek Zajic | 13 Mar 15:53 2008
Picon

Re: NTLMv2 patch corrected

I'm sending NTLMv2 patch again. I hope that everything is correct now 
:-) Again thanks to Alon for his feedback.

Miroslav Zajic
NextSoft s.r.o.

P.S. I moved int64 macros to ntlm.c. I left them unchanged, becouse they 
could be useful in future.

diff -Naur openvpn-2.1/ntlm.c openvpn-NTLMv2-predelane-2.1/ntlm.c
--- openvpn-2.1/ntlm.c    2008-01-13 21:25:52.915264000 +0100
+++ openvpn-NTLMv2-predelane-2.1/ntlm.c    2008-03-13 15:29:31.109375000 
+0100
 <at>  <at>  -3,6 +3,8  <at>  <at> 
  *
  *  Copyright (C) 2004 William Preston
  *
+ *  *NTLMv2 support and domain name parsing by Miroslav Zajic, NextSoft 
s.r.o.*
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
 <at>  <at>  -41,6 +43,21  <at>  <at> 

 #include "memdbg.h"

+
+/* 64bit datatype macros */
+#ifdef _MSC_VER
+    /* MS compilers */
+#    define UINTEGER64 __int64
+#    define UINT64(c) c ## Ui64
+#else
+    /* Non MS compilers */
+#    define UINTEGER64 unsigned long long
+#    define UINT64(c) c ## LL
+#endif
+
+
+
+
 static void
 create_des_keys(const unsigned char *hash, unsigned char *key)
 {
 <at>  <at>  -70,6 +87,61  <at>  <at> 
   memcpy (result, md, 16);
 }

+static void
+gen_hmac_md5 (const char* data, int data_len, const char* key, int 
key_len,char *result)
+{
+    unsigned int len;
+
+    HMAC_CTX c;
+    HMAC_Init (&c, key, key_len, EVP_md5());
+    HMAC_Update (&c, data, data_len);
+    HMAC_Final (&c, result, &len);
+    HMAC_CTX_cleanup(&c);
+}
+
+static void
+gen_timestamp (unsigned char *timestamp)
+{
+    /* Copies 8 bytes long timestamp into "timestamp" buffer.
+     * Timestamp is Little-endian, 64-bit signed value representing the 
number of tenths of a microsecond since January 1, 1601.
+     */
+
+    UINTEGER64 timestamp_ull;
+
+    timestamp_ull = openvpn_time(NULL);
+    timestamp_ull = (timestamp_ull + UINT64(11644473600)) * 
UINT64(10000000);
+
+    /* store little endian value */
+    timestamp[0]= timestamp_ull & UINT64(0xFF);
+    timestamp[1]= (timestamp_ull  >> 8)  & UINT64(0xFF);
+    timestamp[2]= (timestamp_ull  >> 16) & UINT64(0xFF);
+    timestamp[3]= (timestamp_ull  >> 24) & UINT64(0xFF);
+    timestamp[4]= (timestamp_ull  >> 32) & UINT64(0xFF);
+    timestamp[5]= (timestamp_ull  >> 40) & UINT64(0xFF);
+    timestamp[6]= (timestamp_ull  >> 48) & UINT64(0xFF);
+    timestamp[7]= (timestamp_ull  >> 56) & UINT64(0xFF);
+}
+
+static void
+gen_nonce (unsigned char *nonce)
+{
+    /* Generates 8 random bytes to be used as client nonce */
+    int i;
+
+    for(i=0;i<8;i++){
+        nonce[i] = (unsigned char)get_random();
+    }
+}
+
+unsigned char *my_strupr(unsigned char *str)
+{
+    /* converts string to uppercase in place */
+    unsigned char *tmp = str;;
+
+    do *str = toupper(*str); while (*(++str));
+    return tmp;
+}
+
 static int
 unicodize (char *dst, const char *src)
 {
 <at>  <at>  -85,6 +157,18  <at>  <at> 
   return i;
 }

+static void
+add_security_buffer(int sb_offset, void *data, int length, unsigned 
char *msg_buf, int *msg_bufpos)
+{
+    /* Adds security buffer data to a message and sets security 
buffer's offset and length */
+    msg_buf[sb_offset] = (unsigned char)length;
+    msg_buf[sb_offset + 2] = msg_buf[sb_offset];
+    msg_buf[sb_offset + 4] = (unsigned char)(*msg_bufpos & 0xff);
+    msg_buf[sb_offset + 5] = (unsigned char)((*msg_bufpos >> 8) & 0xff);
+    memcpy(&msg_buf[*msg_bufpos], data, msg_buf[sb_offset]);
+    *msg_bufpos += length;
+}
+
 const char *
 ntlm_phase_1 (const struct http_proxy_info *p, struct gc_arena *gc)
 {
 <at>  <at>  -105,23 +189,56  <at>  <at> 
 const char *
 ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, 
struct gc_arena *gc)
 {
+    /* NTLM handshake
+     *
+     * http://davenport.sourceforge.net/ntlm.html
+     *
+     */
+   
   char pwbuf[sizeof (p->up.password) * 2]; /* for unicode password */
   char buf2[128]; /* decoded reply from proxy */
-  char phase3[146];
+  unsigned char phase3[464];

   char md4_hash[21];
-  char challenge[8], response[24];
-  int i, ret_val, buflen;
+  char challenge[8], ntlm_response[24];
+  int i, ret_val;
   des_cblock key1, key2, key3;
   des_key_schedule sched1, sched2, sched3;

-  /* try a minimal NTLM handshake
-   *
-   * http://davenport.sourceforge.net/ntlm.html
-   *
-   */
+    char ntlmv2_response[144];
+    char userdomain_u[256]; /* for uppercase unicode username and domain */
+    char userdomain[128];   /* the same as previous but ascii */
+    char ntlmv2_hash[16];
+    char ntlmv2_hmacmd5[16];
+    char *ntlmv2_blob = ntlmv2_response + 16; /* inside 
ntlmv2_response, length: 128 */
+    int ntlmv2_blob_size=0;
+    int phase3_bufpos = 0x40; /* offset to next security buffer data to 
be added */
+    int len;
+
+    char domain[128];
+    char username[128];
+    char *separator;
+
+    bool ntlmv2_enabled = (p->auth_method == HTTP_AUTH_NTLM2);
+
   ASSERT (strlen (p->up.username) > 0);
   ASSERT (strlen (p->up.password) > 0);
+   
+    /* username parsing */
+    separator = strchr(p->up.username, '\\');
+    if (separator == NULL) {
+        strncpy(username, p->up.username, sizeof(username)-1);
+        username[sizeof(username)-1]=0;
+        domain[0]=0;
+    } else {
+        strncpy(username, separator+1, sizeof(username)-1);
+        username[sizeof(username)-1]=0;
+        len = separator - p->up.username;
+        if (len > sizeof(domain) - 1) len = sizeof(domain) - 1;
+        strncpy(domain, p->up.username,  len);
+        domain[len]=0;
+    }
+

   /* fill 1st 16 bytes with md4 hash, disregard terminating null */
   gen_md4_hash (pwbuf, unicodize (pwbuf, p->up.password) - 2, md4_hash);
 <at>  <at>  -139,48 +256,95  <at>  <at> 
     challenge[i] = buf2[i+24];
   }

-  create_des_keys ((unsigned char *)md4_hash, key1);
-  des_set_key_unchecked ((des_cblock *)key1, sched1);
-  des_ecb_encrypt ((des_cblock *)challenge, (des_cblock *)response, 
sched1, DES_ENCRYPT);
-
-  create_des_keys ((unsigned char *)&(md4_hash[7]), key2);
-  des_set_key_unchecked ((des_cblock *)key2, sched2);
-  des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)&(response[8]), sched2, DES_ENCRYPT);
-
-  create_des_keys ((unsigned char *)&(md4_hash[14]), key3);
-  des_set_key_unchecked ((des_cblock *)key3, sched3);
-  des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)&(response[16]), sched3, DES_ENCRYPT);
-
-  /* clear reply */
-  memset (phase3, 0, sizeof (phase3));
-
-  strcpy (phase3, "NTLMSSP\0");
-  phase3[8] = 3; /* type 3 */
-
-  buflen = 0x58 + strlen (p->up.username);
-  if (buflen > (int) sizeof (phase3))
-    buflen = sizeof (phase3);
-
-  phase3[0x10] = buflen; /* lm not used */
-  phase3[0x20] = buflen; /* default domain (i.e. proxy's domain) */
-  phase3[0x30] = buflen; /* no workstation name supplied */
-  phase3[0x38] = buflen; /* no session key */
-
-  phase3[0x14] = 24; /* ntlm response is 24 bytes long */
-  phase3[0x16] = phase3[0x14];
-  phase3[0x18] = 0x40; /* ntlm offset */
-  memcpy (&(phase3[0x40]), response, 24);
-
-
-  phase3[0x24] = strlen (p->up.username); /* username in ascii */
-  phase3[0x26] = phase3[0x24];
-  phase3[0x28] = 0x58;
-  strncpy (&(phase3[0x58]), p->up.username, sizeof (phase3) - 0x58);
-
+    if (ntlmv2_enabled){ /* Generate NTLMv2 response */
+       
+        /* NTLMv2 hash */
+        my_strupr(strcpy(userdomain, username));
+        if (strlen(username) + strlen(domain) < sizeof(userdomain))
+            strcat(userdomain, domain);
+        else
+            msg (M_INFO, "Warning: Username or domain too long");
+        unicodize (userdomain_u, userdomain);
+        gen_hmac_md5(userdomain_u, 2 * strlen(userdomain), md4_hash, 
16, ntlmv2_hash);
+
+        /* NTLMv2 Blob */
+        memset(ntlmv2_blob, 0, 128);                /* Clear blob 
buffer */
+        ntlmv2_blob[0x00]=1;                        /* Signature */
+        ntlmv2_blob[0x01]=1;                        /* Signature */
+        ntlmv2_blob[0x04]=0;                        /* Reserved */
+        gen_timestamp(&ntlmv2_blob[0x08]);          /* 64-bit Timestamp */
+        gen_nonce(&ntlmv2_blob[0x10]);              /* 64-bit Client 
Nonce */
+        ntlmv2_blob[0x18]=0;                        /* Unknown, zero 
should work */
+
+        /* Add target information block to the blob */
+        int tib_len;
+        if (( *((long *)&buf2[0x14]) & 0x00800000) == 0x00800000){ /* 
Check for Target Information block */
+            tib_len = buf2[0x28];/* Get Target Information block size */
+            if (tib_len > 96) tib_len = 96;
+            char *tib_ptr = buf2 + buf2[0x2c]; /* Get Target 
Information block pointer */
+            memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); /* Copy 
Target Information block into the blob */
+        } else {
+            tib_len = 0;
+        }
+
+        ntlmv2_blob[0x1c + tib_len] = 0;            /* Unknown, zero 
works */
+
+        /* Get blob length */
+        ntlmv2_blob_size = 0x20 + tib_len;
+
+        /* Add challenge from message 2 */
+        memcpy(&ntlmv2_response[8], challenge, 8);
+
+        /* hmac-md5 */
+        gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, 
ntlmv2_hash, 16, ntlmv2_hmacmd5);
+       
+        /* Add hmac-md5 result to the blob */
+        memcpy(ntlmv2_response, ntlmv2_hmacmd5, 16); /* Note: This 
overwrites challenge previously written at ntlmv2_response[8..15] */
+   
+    } else { /* Generate NTLM response */
+
+        create_des_keys ((unsigned char *)md4_hash, key1);
+        des_set_key_unchecked ((des_cblock *)key1, sched1);
+        des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)ntlm_response, sched1, DES_ENCRYPT);
+
+        create_des_keys ((unsigned char *)&(md4_hash[7]), key2);
+        des_set_key_unchecked ((des_cblock *)key2, sched2);
+        des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)&(ntlm_response[8]), sched2, DES_ENCRYPT);
+
+        create_des_keys ((unsigned char *)&(md4_hash[14]), key3);
+        des_set_key_unchecked ((des_cblock *)key3, sched3);
+        des_ecb_encrypt ((des_cblock *)challenge, (des_cblock 
*)&(ntlm_response[16]), sched3, DES_ENCRYPT);
+    }
+   
+   
+    memset (phase3, 0, sizeof (phase3)); /* clear reply */
+
+    strcpy (phase3, "NTLMSSP\0"); /* signature */
+    phase3[8] = 3; /* type 3 */
+
+    if (ntlmv2_enabled){ /* NTLMv2 response */
+        add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 
16, phase3, &phase3_bufpos);
+    }else{ /* NTLM response */
+        add_security_buffer(0x14, ntlm_response, 24, phase3, 
&phase3_bufpos);
+    }
+   
+    /* username in ascii */
+    add_security_buffer(0x24, username, strlen (username), phase3, 
&phase3_bufpos);
+
+    /* Set domain. If <domain> is empty, default domain will be used 
(i.e. proxy's domain) */
+    add_security_buffer(0x1c, domain, strlen (domain), phase3, 
&phase3_bufpos);
+   
+
+    /* other security buffers will be empty */
+    phase3[0x10] = phase3_bufpos; /* lm not used */
+    phase3[0x30] = phase3_bufpos; /* no workstation name supplied */
+    phase3[0x38] = phase3_bufpos; /* no session key */
+   
+    /* flags */
   phase3[0x3c] = 0x02; /* negotiate oem */
   phase3[0x3d] = 0x02; /* negotiate ntlm */

-  return ((const char *)make_base64_string2 ((unsigned char *)phase3, 
buflen, gc));
+  return ((const char *)make_base64_string2 ((unsigned char *)phase3, 
phase3_bufpos, gc));
 }

 #else
diff -Naur openvpn-2.1/proxy.c openvpn-NTLMv2-predelane-2.1/proxy.c
--- openvpn-2.1/proxy.c    2008-01-13 21:25:52.945307200 +0100
+++ openvpn-NTLMv2-predelane-2.1/proxy.c    2008-01-15 
11:46:12.737156800 +0100
 <at>  <at>  -294,19 +294,21  <at>  <at> 
     p->auth_method = HTTP_AUTH_BASIC;
       else if (!strcmp (o->auth_method_string, "ntlm"))
     p->auth_method = HTTP_AUTH_NTLM;
+      else if (!strcmp (o->auth_method_string, "ntlm2"))
+    p->auth_method = HTTP_AUTH_NTLM2;
       else
-    msg (M_FATAL, "ERROR: unknown HTTP authentication method: '%s' -- 
only the 'none', 'basic', or 'ntlm' methods are currently supported",
+    msg (M_FATAL, "ERROR: unknown HTTP authentication method: '%s' -- 
only the 'none', 'basic', 'ntlm', or 'ntlm2' methods are currently 
supported",
          o->auth_method_string);
     }

-  /* only basic and NTLM authentication supported so far */
-  if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == 
HTTP_AUTH_NTLM)
+  /* only basic and NTLM/NTLMv2 authentication supported so far */
+  if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == 
HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2)
     {
       get_user_pass_http (p, true);
     }

 #if !NTLM
-  if (p->auth_method == HTTP_AUTH_NTLM)
+  if (p->auth_method == HTTP_AUTH_NTLM || p->auth_method == 
HTTP_AUTH_NTLM2)
     msg (M_FATAL, "Sorry, this version of " PACKAGE_NAME " was built 
without NTLM Proxy support.");
 #endif

 <at>  <at>  -374,6 +376,12  <at>  <at> 

 #if NTLM
     case HTTP_AUTH_NTLM:
+    case HTTP_AUTH_NTLM2:
+      /* keep-alive connection */
+      openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: Keep-Alive");
+      if (!send_line_crlf (sd, buf))
+    goto error;
+
       openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s",
             ntlm_phase_1 (p, &gc));
       msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 1");
 <at>  <at>  -411,7 +419,7  <at>  <at> 
       msg (D_PROXY, "Proxy requires authentication");

       /* check for NTLM */
-      if (p->auth_method == HTTP_AUTH_NTLM)
+      if (p->auth_method == HTTP_AUTH_NTLM || p->auth_method == 
HTTP_AUTH_NTLM2)
         {
 #if NTLM
           /* look for the phase 2 response */
 <at>  <at>  -456,6 +464,12  <at>  <at> 
           if (!send_line_crlf (sd, buf))
             goto error;

+          /* keep-alive connection */
+          openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: 
Keep-Alive");
+          if (!send_line_crlf (sd, buf))
+            goto error;
+
+         
           /* send HOST etc, */
           openvpn_sleep (1);
           openvpn_snprintf (buf, sizeof(buf), "Host: %s", host);
diff -Naur openvpn-2.1/proxy.h openvpn-NTLMv2-predelane-2.1/proxy.h
--- openvpn-2.1/proxy.h    2008-01-13 21:25:52.975350400 +0100
+++ openvpn-NTLMv2-predelane-2.1/proxy.h    2008-01-15 
11:25:00.097190400 +0100
 <at>  <at>  -59,6 +59,7  <at>  <at> 
 #define HTTP_AUTH_BASIC 1
 #define HTTP_AUTH_NTLM  2
 #define HTTP_AUTH_N     3
+#define HTTP_AUTH_NTLM2 4

 struct http_proxy_options {
   const char *server;

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

Gmane