~ubuntu-branches/ubuntu/oneiric/openvpn/oneiric

« back to all changes in this revision

Viewing changes to .pc/jjo-ipv6-support.patch/socks.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-06-16 18:33:37 UTC
  • mfrom: (1.1.17 upstream) (10.2.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110616183337-fv50u3kmiabewjq0
Tags: 2.2.0-2ubuntu1
* Merge from debian unstable.  Remaining changes:
 + debian/openvpn.init.d:
    - Do not use start-stop-daemon and </dev/null to avoid blocking boot.
    - Show per-VPN result messages.
    - Add "--script-security 2" by default for backwards compatabliity.
  + debian/control: Add lsb-base >= 3.2-14 to allow status_of_proc()
  + debian/update-resolv-conf: Support multiple domains.
  + fix bug where '--script-security 2' would be passed for all
    daemons after the first. (LP: #794916

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
39
#include "win32.h"
39
40
#include "socket.h"
40
41
#include "fdmisc.h"
 
42
#include "misc.h"
41
43
#include "proxy.h"
42
44
 
43
45
#include "memdbg.h"
44
46
 
 
47
#define UP_TYPE_SOCKS           "SOCKS Proxy"
45
48
 
46
49
void
47
50
socks_adjust_frame_parameters (struct frame *frame, int proto)
53
56
struct socks_proxy_info *
54
57
socks_proxy_new (const char *server,
55
58
                 int port,
 
59
                 const char *authfile,
56
60
                 bool retry,
57
61
                 struct auto_proxy_info *auto_proxy_info)
58
62
{
77
81
 
78
82
  strncpynt (p->server, server, sizeof (p->server));
79
83
  p->port = port;
 
84
 
 
85
  if (authfile)
 
86
    strncpynt (p->authfile, authfile, sizeof (p->authfile));
 
87
  else
 
88
    p->authfile[0] = 0;
 
89
 
80
90
  p->retry = retry;
81
91
  p->defined = true;
82
92
 
90
100
}
91
101
 
92
102
static bool
93
 
socks_handshake (socket_descriptor_t sd, volatile int *signal_received)
94
 
{
95
 
  char buf[2];
96
 
  int len = 0;
97
 
  const int timeout_sec = 5;
98
 
 
99
 
  /* VER = 5, NMETHODS = 1, METHODS = [0] */
100
 
  const ssize_t size = send (sd, "\x05\x01\x00", 3, MSG_NOSIGNAL);
101
 
  if (size != 3)
 
103
socks_username_password_auth (struct socks_proxy_info *p,
 
104
                              socket_descriptor_t sd,
 
105
                              volatile int *signal_received)
 
106
{
 
107
  char to_send[516];
 
108
  char buf[2];
 
109
  int len = 0;
 
110
  const int timeout_sec = 5;
 
111
  struct user_pass creds;
 
112
  ssize_t size;
 
113
 
 
114
  creds.defined = 0;
 
115
  get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT);
 
116
 
 
117
  if( !creds.username || (strlen(creds.username) > 255)
 
118
      || !creds.password || (strlen(creds.password) > 255) ) {
 
119
          msg (M_NONFATAL,
 
120
               "SOCKS username and/or password exceeds 255 characters.  "
 
121
               "Authentication not possible.");
 
122
          return false;
 
123
  }
 
124
  openvpn_snprintf (to_send, sizeof (to_send), "\x01%c%s%c%s", (int) strlen(creds.username),
 
125
            creds.username, (int) strlen(creds.password), creds.password);
 
126
  size = send (sd, to_send, strlen(to_send), MSG_NOSIGNAL);
 
127
 
 
128
  if (size != strlen (to_send))
 
129
    {
 
130
      msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port write failed on send()");
 
131
      return false;
 
132
    }
 
133
 
 
134
  while (len < 2)
 
135
    {
 
136
      int status;
 
137
      ssize_t size;
 
138
      fd_set reads;
 
139
      struct timeval tv;
 
140
      char c;
 
141
 
 
142
      FD_ZERO (&reads);
 
143
      FD_SET (sd, &reads);
 
144
      tv.tv_sec = timeout_sec;
 
145
      tv.tv_usec = 0;
 
146
 
 
147
      status = select (sd + 1, &reads, NULL, NULL, &tv);
 
148
 
 
149
      get_signal (signal_received);
 
150
      if (*signal_received)
 
151
        return false;
 
152
 
 
153
      /* timeout? */
 
154
      if (status == 0)
 
155
        {
 
156
          msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read timeout expired");
 
157
          return false;
 
158
        }
 
159
 
 
160
      /* error */
 
161
      if (status < 0)
 
162
        {
 
163
          msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on select()");
 
164
          return false;
 
165
        }
 
166
 
 
167
      /* read single char */
 
168
      size = recv(sd, &c, 1, MSG_NOSIGNAL);
 
169
 
 
170
      /* error? */
 
171
      if (size != 1)
 
172
        {
 
173
          msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on recv()");
 
174
          return false;
 
175
        }
 
176
 
 
177
      /* store char in buffer */
 
178
      buf[len++] = c;
 
179
    }
 
180
 
 
181
  /* VER = 5, SUCCESS = 0 --> auth success */
 
182
  if (buf[0] != 5 && buf[1] != 0)
 
183
  {
 
184
    msg (D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication");
 
185
    return false;
 
186
  }
 
187
 
 
188
  return true;
 
189
}
 
190
 
 
191
static bool
 
192
socks_handshake (struct socks_proxy_info *p,
 
193
                 socket_descriptor_t sd,
 
194
                 volatile int *signal_received)
 
195
{
 
196
  char buf[2];
 
197
  int len = 0;
 
198
  const int timeout_sec = 5;
 
199
 
 
200
  /* VER = 5, NMETHODS = 2, METHODS = [0 (no auth), 2 (plain login)] */
 
201
  const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL);
 
202
  if (size != 4)
102
203
    {
103
204
      msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port write failed on send()");
104
205
      return false;
151
252
      buf[len++] = c;
152
253
    }
153
254
 
154
 
  /* VER == 5 && METHOD == 0 */
155
 
  if (buf[0] != '\x05' || buf[1] != '\x00')
 
255
  /* VER == 5 */
 
256
  if (buf[0] != '\x05')
156
257
    {
157
258
      msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status");
158
259
      return false;
159
260
    }
160
261
 
 
262
  /* select the appropriate authentication method */
 
263
  switch (buf[1])
 
264
    {
 
265
    case 0: /* no authentication */
 
266
      break;
 
267
 
 
268
    case 2: /* login/password */
 
269
      if (!p->authfile[0])
 
270
      {
 
271
        msg(D_LINK_ERRORS, "socks_handshake: server asked for username/login auth but we were "
 
272
                           "not provided any credentials");
 
273
        return false;
 
274
      }
 
275
 
 
276
      if (!socks_username_password_auth(p, sd, signal_received))
 
277
        return false;
 
278
 
 
279
      break;
 
280
 
 
281
    default: /* unknown auth method */
 
282
      msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method");
 
283
      return false;
 
284
    }
 
285
 
161
286
  return true;
162
287
}
163
288
 
281
406
  char buf[128];
282
407
  size_t len;
283
408
 
284
 
  if (!socks_handshake (sd, signal_received))
 
409
  if (!socks_handshake (p, sd, signal_received))
285
410
    goto error;
286
411
 
287
412
  /* format Socks CONNECT message */
328
453
                                struct openvpn_sockaddr *relay_addr,
329
454
                                volatile int *signal_received)
330
455
{
331
 
  if (!socks_handshake (ctrl_sd, signal_received))
 
456
  if (!socks_handshake (p, ctrl_sd, signal_received))
332
457
    goto error;
333
458
 
334
459
  {