Browse code

Merge branch 'feat_misc' into beta2.2

Conflicts:
Makefile.am
openvpn.8
options.c
socket.c
ssl.c
- feat_misc is missing a lot of bugfix2.1 changes

Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>

David Sommerseth authored on 2010/11/13 08:55:02
Showing 7 changed files
... ...
@@ -417,6 +417,7 @@ init_proxy_dowork (struct context *c)
417 417
     {
418 418
       c->c1.socks_proxy = socks_proxy_new (c->options.ce.socks_proxy_server,
419 419
 					   c->options.ce.socks_proxy_port,
420
+					   c->options.ce.socks_proxy_authfile,
420 421
 					   c->options.ce.socks_proxy_retry,
421 422
 					   c->options.auto_proxy_info);
422 423
       if (c->c1.socks_proxy)
... ...
@@ -128,8 +128,11 @@ static const char usage_message[] =
128 128
   "                  AGENT user-agent\n"
129 129
 #endif
130 130
 #ifdef ENABLE_SOCKS
131
-  "--socks-proxy s [p]: Connect to remote host through a Socks5 proxy at address\n"
132
-  "                  s and port p (default port = 1080).\n"
131
+  "--socks-proxy s [p] [up] : Connect to remote host through a Socks5 proxy at\n"
132
+  "                  address s and port p (default port = 1080).\n"
133
+  "                  If proxy authentication is required,\n"
134
+  "                  up is a file containing username/password on 2 lines, or\n"
135
+  "                  'stdin' to prompt for console.\n"
133 136
   "--socks-proxy-retry : Retry indefinitely on Socks proxy errors.\n"
134 137
 #endif
135 138
   "--resolv-retry n: If hostname resolve fails for --remote, retry\n"
... ...
@@ -4505,6 +4508,7 @@ add_option (struct options *options,
4505 4505
 	  options->ce.socks_proxy_port = 1080;
4506 4506
 	}
4507 4507
       options->ce.socks_proxy_server = p[1];
4508
+      options->ce.socks_proxy_authfile = p[3]; /* might be NULL */
4508 4509
     }
4509 4510
   else if (streq (p[0], "socks-proxy-retry"))
4510 4511
     {
... ...
@@ -95,6 +95,7 @@ struct connection_entry
95 95
 #ifdef ENABLE_SOCKS
96 96
   const char *socks_proxy_server;
97 97
   int socks_proxy_port;
98
+  const char *socks_proxy_authfile;
98 99
   bool socks_proxy_retry;
99 100
 #endif
100 101
 
... ...
@@ -952,16 +952,14 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s
952 952
   argv_printf (&argv, "%s add",
953 953
 		ROUTE_PATH);
954 954
 
955
-#if 0
956
-  if (r->metric_defined)
957
-    argv_printf_cat (&argv, "-rtt %d", r->metric);
958
-#endif
959
-
960 955
   argv_printf_cat (&argv, "%s -netmask %s %s",
961 956
 	      network,
962 957
 	      netmask,
963 958
 	      gateway);
964 959
 
960
+  if (r->metric_defined)
961
+    argv_printf_cat (&argv, "%d", r->metric);
962
+
965 963
   argv_msg (D_ROUTE, &argv);
966 964
   status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add command failed");
967 965
 
... ...
@@ -23,10 +23,11 @@
23 23
  */
24 24
 
25 25
 /*
26
- * 2004-01-30: Added Socks5 proxy support
26
+ * 2004-01-30: Added Socks5 proxy support, see RFC 1928
27 27
  *   (Christof Meerwald, http://cmeerw.org)
28 28
  *
29
- * see RFC 1928, only supports "no authentication"
29
+ * 2010-10-10: Added Socks5 plain text authentication support (RFC 1929)
30
+ *   (Pierre Bourdon <delroth@gmail.com>)
30 31
  */
31 32
 
32 33
 #include "syshead.h"
... ...
@@ -38,10 +39,12 @@
38 38
 #include "win32.h"
39 39
 #include "socket.h"
40 40
 #include "fdmisc.h"
41
+#include "misc.h"
41 42
 #include "proxy.h"
42 43
 
43 44
 #include "memdbg.h"
44 45
 
46
+#define UP_TYPE_SOCKS		"SOCKS Proxy"
45 47
 
46 48
 void
47 49
 socks_adjust_frame_parameters (struct frame *frame, int proto)
... ...
@@ -53,6 +56,7 @@ socks_adjust_frame_parameters (struct frame *frame, int proto)
53 53
 struct socks_proxy_info *
54 54
 socks_proxy_new (const char *server,
55 55
 		 int port,
56
+		 const char *authfile,
56 57
 		 bool retry,
57 58
 		 struct auto_proxy_info *auto_proxy_info)
58 59
 {
... ...
@@ -77,6 +81,12 @@ socks_proxy_new (const char *server,
77 77
 
78 78
   strncpynt (p->server, server, sizeof (p->server));
79 79
   p->port = port;
80
+
81
+  if (authfile)
82
+    strncpynt (p->authfile, authfile, sizeof (p->authfile));
83
+  else
84
+    p->authfile[0] = 0;
85
+
80 86
   p->retry = retry;
81 87
   p->defined = true;
82 88
 
... ...
@@ -90,15 +100,99 @@ socks_proxy_close (struct socks_proxy_info *sp)
90 90
 }
91 91
 
92 92
 static bool
93
-socks_handshake (socket_descriptor_t sd, volatile int *signal_received)
93
+socks_username_password_auth (struct socks_proxy_info *p,
94
+                              socket_descriptor_t sd,
95
+                              volatile int *signal_received)
96
+{
97
+  char to_send[516];
98
+  char buf[2];
99
+  int len = 0;
100
+  const int timeout_sec = 5;
101
+  struct user_pass creds;
102
+  ssize_t size;
103
+
104
+  creds.defined = 0;
105
+
106
+  get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT);
107
+  snprintf (to_send, sizeof (to_send), "\x01%c%s%c%s", strlen(creds.username),
108
+            creds.username, strlen(creds.password), creds.password);
109
+  size = send (sd, to_send, strlen(to_send), MSG_NOSIGNAL);
110
+
111
+  if (size != strlen (to_send))
112
+    {
113
+      msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port write failed on send()");
114
+      return false;
115
+    }
116
+
117
+  while (len < 2)
118
+    {
119
+      int status;
120
+      ssize_t size;
121
+      fd_set reads;
122
+      struct timeval tv;
123
+      char c;
124
+
125
+      FD_ZERO (&reads);
126
+      FD_SET (sd, &reads);
127
+      tv.tv_sec = timeout_sec;
128
+      tv.tv_usec = 0;
129
+
130
+      status = select (sd + 1, &reads, NULL, NULL, &tv);
131
+
132
+      get_signal (signal_received);
133
+      if (*signal_received)
134
+	return false;
135
+
136
+      /* timeout? */
137
+      if (status == 0)
138
+	{
139
+	  msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read timeout expired");
140
+	  return false;
141
+	}
142
+
143
+      /* error */
144
+      if (status < 0)
145
+	{
146
+	  msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on select()");
147
+	  return false;
148
+	}
149
+
150
+      /* read single char */
151
+      size = recv(sd, &c, 1, MSG_NOSIGNAL);
152
+
153
+      /* error? */
154
+      if (size != 1)
155
+	{
156
+	  msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on recv()");
157
+	  return false;
158
+	}
159
+
160
+      /* store char in buffer */
161
+      buf[len++] = c;
162
+    }
163
+
164
+  /* VER = 5, SUCCESS = 0 --> auth success */
165
+  if (buf[0] != 5 && buf[1] != 0)
166
+  {
167
+    msg (D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication");
168
+    return false;
169
+  }
170
+
171
+  return true;
172
+}
173
+
174
+static bool
175
+socks_handshake (struct socks_proxy_info *p,
176
+                 socket_descriptor_t sd,
177
+                 volatile int *signal_received)
94 178
 {
95 179
   char buf[2];
96 180
   int len = 0;
97 181
   const int timeout_sec = 5;
98 182
 
99
-  /* VER = 5, NMETHODS = 1, METHODS = [0] */
100
-  const ssize_t size = send (sd, "\x05\x01\x00", 3, MSG_NOSIGNAL);
101
-  if (size != 3)
183
+  /* VER = 5, NMETHODS = 2, METHODS = [0 (no auth), 2 (plain login)] */
184
+  const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL);
185
+  if (size != 4)
102 186
     {
103 187
       msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port write failed on send()");
104 188
       return false;
... ...
@@ -151,13 +245,37 @@ socks_handshake (socket_descriptor_t sd, volatile int *signal_received)
151 151
       buf[len++] = c;
152 152
     }
153 153
 
154
-  /* VER == 5 && METHOD == 0 */
155
-  if (buf[0] != '\x05' || buf[1] != '\x00')
154
+  /* VER == 5 */
155
+  if (buf[0] != '\x05')
156 156
     {
157 157
       msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status");
158 158
       return false;
159 159
     }
160 160
 
161
+  /* select the appropriate authentication method */
162
+  switch (buf[1])
163
+    {
164
+    case 0: /* no authentication */
165
+      break;
166
+
167
+    case 2: /* login/password */
168
+      if (!p->authfile[0])
169
+      {
170
+	msg(D_LINK_ERRORS, "socks_handshake: server asked for username/login auth but we were "
171
+	                   "not provided any credentials");
172
+	return false;
173
+      }
174
+
175
+      if (!socks_username_password_auth(p, sd, signal_received))
176
+	return false;
177
+
178
+      break;
179
+
180
+    default: /* unknown auth method */
181
+      msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method");
182
+      return false;
183
+    }
184
+
161 185
   return true;
162 186
 }
163 187
 
... ...
@@ -281,7 +399,7 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p,
281 281
   char buf[128];
282 282
   size_t len;
283 283
 
284
-  if (!socks_handshake (sd, signal_received))
284
+  if (!socks_handshake (p, sd, signal_received))
285 285
     goto error;
286 286
 
287 287
   /* format Socks CONNECT message */
... ...
@@ -328,7 +446,7 @@ establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
328 328
 				struct openvpn_sockaddr *relay_addr,
329 329
 			        volatile int *signal_received)
330 330
 {
331
-  if (!socks_handshake (ctrl_sd, signal_received))
331
+  if (!socks_handshake (p, ctrl_sd, signal_received))
332 332
     goto error;
333 333
 
334 334
   {
... ...
@@ -43,12 +43,14 @@ struct socks_proxy_info {
43 43
 
44 44
   char server[128];
45 45
   int port;
46
+  char authfile[256];
46 47
 };
47 48
 
48 49
 void socks_adjust_frame_parameters (struct frame *frame, int proto);
49 50
 
50 51
 struct socks_proxy_info *socks_proxy_new (const char *server,
51 52
 					  int port,
53
+					  const char *authfile,
52 54
 					  bool retry,
53 55
 					  struct auto_proxy_info *auto_proxy_info);
54 56
 
... ...
@@ -63,6 +63,7 @@ static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc);
63 63
 
64 64
 #ifdef TARGET_SOLARIS
65 65
 static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual);
66
+#include <stropts.h>
66 67
 #endif
67 68
 
68 69
 bool
... ...
@@ -701,12 +702,45 @@ do_ifconfig (struct tuntap *tt,
701 701
 			    );
702 702
 	}
703 703
       else
704
-	no_tap_ifconfig ();
704
+        if (tt->topology == TOP_SUBNET)
705
+	{
706
+          argv_printf (&argv,
707
+                              "%s %s %s %s netmask %s mtu %d up",
708
+                              IFCONFIG_PATH,
709
+                              actual,
710
+                              ifconfig_local,
711
+                              ifconfig_local,
712
+                              ifconfig_remote_netmask,
713
+                              tun_mtu
714
+                              );
715
+	}
716
+        else
717
+          argv_printf (&argv,
718
+                            " %s %s %s netmask %s broadcast + up",
719
+                            IFCONFIG_PATH,
720
+                            actual,
721
+                            ifconfig_local,
722
+                            ifconfig_remote_netmask
723
+                            );
705 724
 
706 725
       argv_msg (M_INFO, &argv);
707 726
       if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed"))
708 727
 	solaris_error_close (tt, es, actual);
709 728
 
729
+      if (!tun && tt->topology == TOP_SUBNET)
730
+	{
731
+	  /* Add a network route for the local tun interface */
732
+	  struct route r;
733
+	  CLEAR (r);      
734
+	  r.defined = true;       
735
+	  r.network = tt->local & tt->remote_netmask;
736
+	  r.netmask = tt->remote_netmask;
737
+	  r.gateway = tt->local;  
738
+	  r.metric_defined = true;
739
+	  r.metric = 0;
740
+	  add_route (&r, tt, 0, es);
741
+	}
742
+
710 743
       tt->did_ifconfig = true;
711 744
 
712 745
 #elif defined(TARGET_OPENBSD)
... ...
@@ -1372,15 +1406,17 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len)
1372 1372
 void
1373 1373
 open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1374 1374
 {
1375
-  int if_fd, muxid, ppa = -1;
1376
-  struct ifreq ifr;
1375
+  int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1;
1376
+  struct lifreq ifr;
1377 1377
   const char *ptr;
1378
-  const char *ip_node;
1378
+  const char *ip_node, *arp_node;
1379 1379
   const char *dev_tuntap_type;
1380 1380
   int link_type;
1381 1381
   bool is_tun;
1382
+  struct strioctl  strioc_if, strioc_ppa;
1382 1383
 
1383
-  ipv6_support (ipv6, false, tt);
1384
+  ipv6_support (ipv6, true, tt);
1385
+  memset(&ifr, 0x0, sizeof(ifr));
1384 1386
 
1385 1387
   if (tt->type == DEV_TYPE_NULL)
1386 1388
     {
... ...
@@ -1399,9 +1435,10 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
1399 1399
     }
1400 1400
   else if (tt->type == DEV_TYPE_TAP)
1401 1401
     {
1402
-      ip_node = "/dev/ip";
1402
+      ip_node = "/dev/udp";
1403 1403
       if (!dev_node)
1404 1404
 	dev_node = "/dev/tap";
1405
+      arp_node = dev_node;
1405 1406
       dev_tuntap_type = "tap";
1406 1407
       link_type = I_PLINK; /* was: I_LINK */
1407 1408
       is_tun = false;
... ...
@@ -1428,7 +1465,11 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
1428 1428
     msg (M_ERR, "Can't open %s", dev_node);
1429 1429
 
1430 1430
   /* Assign a new PPA and get its unit number. */
1431
-  if ((ppa = ioctl (tt->fd, TUNNEWPPA, ppa)) < 0)
1431
+  strioc_ppa.ic_cmd = TUNNEWPPA;
1432
+  strioc_ppa.ic_timout = 0;
1433
+  strioc_ppa.ic_len = sizeof(ppa);
1434
+  strioc_ppa.ic_dp = (char *)&ppa;
1435
+  if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0)
1432 1436
     msg (M_ERR, "Can't assign new interface");
1433 1437
 
1434 1438
   if ((if_fd = open (dev_node, O_RDWR, 0)) < 0)
... ...
@@ -1437,27 +1478,83 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6
1437 1437
   if (ioctl (if_fd, I_PUSH, "ip") < 0)
1438 1438
     msg (M_ERR, "Can't push IP module");
1439 1439
 
1440
+  if (tt->type == DEV_TYPE_TUN)
1441
+    {
1440 1442
   /* Assign ppa according to the unit number returned by tun device */
1441 1443
   if (ioctl (if_fd, IF_UNITSEL, (char *) &ppa) < 0)
1442 1444
     msg (M_ERR, "Can't set PPA %d", ppa);
1443
-
1444
-  if ((muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0)
1445
-    msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type);
1446
-
1447
-  close (if_fd);
1445
+    }
1448 1446
 
1449 1447
   tt->actual_name = (char *) malloc (32);
1450 1448
   check_malloc_return (tt->actual_name);
1451 1449
 
1452 1450
   openvpn_snprintf (tt->actual_name, 32, "%s%d", dev_tuntap_type, ppa);
1453 1451
 
1452
+  if (tt->type == DEV_TYPE_TAP)
1453
+    {
1454
+          if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
1455
+            msg (M_ERR, "Can't get flags\n");
1456
+          strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
1457
+          ifr.lifr_ppa = ppa;
1458
+          /* Assign ppa according to the unit number returned by tun device */
1459
+          if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
1460
+            msg (M_ERR, "Can't set PPA %d", ppa);
1461
+          if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
1462
+            msg (M_ERR, "Can't get flags\n");
1463
+          /* Push arp module to if_fd */
1464
+          if (ioctl (if_fd, I_PUSH, "arp") < 0)
1465
+            msg (M_ERR, "Can't push ARP module");
1466
+
1467
+          /* Pop any modules on the stream */
1468
+          while (true)
1469
+            {
1470
+                 if (ioctl (tt->ip_fd, I_POP, NULL) < 0)
1471
+                     break;
1472
+            }
1473
+          /* Push arp module to ip_fd */
1474
+          if (ioctl (tt->ip_fd, I_PUSH, "arp") < 0)
1475
+            msg (M_ERR, "Can't push ARP module\n");
1476
+
1477
+          /* Open arp_fd */
1478
+          if ((arp_fd = open (arp_node, O_RDWR, 0)) < 0)
1479
+            msg (M_ERR, "Can't open %s\n", arp_node);
1480
+          /* Push arp module to arp_fd */
1481
+          if (ioctl (arp_fd, I_PUSH, "arp") < 0)
1482
+            msg (M_ERR, "Can't push ARP module\n");
1483
+
1484
+          /* Set ifname to arp */
1485
+          strioc_if.ic_cmd = SIOCSLIFNAME;
1486
+          strioc_if.ic_timout = 0;
1487
+          strioc_if.ic_len = sizeof(ifr);
1488
+          strioc_if.ic_dp = (char *)&ifr;
1489
+          if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
1490
+              msg (M_ERR, "Can't set ifname to arp\n");
1491
+          }
1492
+   }
1493
+
1494
+  if ((ip_muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0)
1495
+    msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type);
1496
+
1497
+  if (tt->type == DEV_TYPE_TAP) {
1498
+          if ((arp_muxid = ioctl (tt->ip_fd, link_type, arp_fd)) < 0)
1499
+            msg (M_ERR, "Can't link %s device to ARP", dev_tuntap_type);
1500
+          close (arp_fd);
1501
+  }
1502
+
1454 1503
   CLEAR (ifr);
1455
-  strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name));
1456
-  ifr.ifr_ip_muxid = muxid;
1504
+  strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
1505
+  ifr.lifr_ip_muxid  = ip_muxid;
1506
+  if (tt->type == DEV_TYPE_TAP) {
1507
+          ifr.lifr_arp_muxid = arp_muxid;
1508
+  }
1457 1509
 
1458
-  if (ioctl (tt->ip_fd, SIOCSIFMUXID, &ifr) < 0)
1510
+  if (ioctl (tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
1459 1511
     {
1460
-      ioctl (tt->ip_fd, I_PUNLINK, muxid);
1512
+      if (tt->type == DEV_TYPE_TAP)
1513
+        {
1514
+              ioctl (tt->ip_fd, I_PUNLINK , arp_muxid);
1515
+        }
1516
+      ioctl (tt->ip_fd, I_PUNLINK, ip_muxid);
1461 1517
       msg (M_ERR, "Can't set multiplexor id");
1462 1518
     }
1463 1519
 
... ...
@@ -1475,18 +1572,24 @@ solaris_close_tun (struct tuntap *tt)
1475 1475
     {
1476 1476
       if (tt->ip_fd >= 0)
1477 1477
 	{
1478
-	  struct ifreq ifr;
1478
+          struct lifreq ifr;
1479 1479
 	  CLEAR (ifr);
1480
-	  strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name));
1480
+          strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
1481 1481
 
1482
-	  if (ioctl (tt->ip_fd, SIOCGIFFLAGS, &ifr) < 0)
1482
+          if (ioctl (tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
1483 1483
 	    msg (M_WARN | M_ERRNO, "Can't get iface flags");
1484 1484
 
1485
-	  if (ioctl (tt->ip_fd, SIOCGIFMUXID, &ifr) < 0)
1485
+          if (ioctl (tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
1486 1486
 	    msg (M_WARN | M_ERRNO, "Can't get multiplexor id");
1487 1487
 
1488
-	  if (ioctl (tt->ip_fd, I_PUNLINK, ifr.ifr_ip_muxid) < 0)
1489
-	    msg (M_WARN | M_ERRNO, "Can't unlink interface");
1488
+          if (tt->type == DEV_TYPE_TAP)
1489
+            {
1490
+                  if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
1491
+                    msg (M_WARN | M_ERRNO, "Can't unlink interface(arp)");
1492
+            }
1493
+
1494
+          if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
1495
+            msg (M_WARN | M_ERRNO, "Can't unlink interface(ip)");
1490 1496
 
1491 1497
 	  close (tt->ip_fd);
1492 1498
 	  tt->ip_fd = -1;