Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
libnice
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
libnice
Commits
7c043a27
Commit
7c043a27
authored
Dec 10, 2008
by
Youness Alaoui
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for SOCKS5 proxy servers
parent
09d4596b
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
509 additions
and
2 deletions
+509
-2
agent/agent.c
agent/agent.c
+23
-1
socket/Makefile.am
socket/Makefile.am
+3
-1
socket/socket.h
socket/socket.h
+1
-0
socket/socks5.c
socket/socks5.c
+427
-0
socket/socks5.h
socket/socks5.h
+55
-0
No files found.
agent/agent.c
View file @
7c043a27
...
@@ -909,7 +909,29 @@ priv_add_new_candidate_discovery_turn (NiceAgent *agent,
...
@@ -909,7 +909,29 @@ priv_add_new_candidate_discovery_turn (NiceAgent *agent,
}
}
cdisco
->
nicesock
=
socket
;
cdisco
->
nicesock
=
socket
;
}
else
{
}
else
{
NiceAddress
proxy_server
;
socket
=
NULL
;
if
(
agent
->
proxy_type
!=
NICE_PROXY_TYPE_NONE
&&
agent
->
proxy_ip
!=
NULL
&&
nice_address_set_from_string
(
&
proxy_server
,
agent
->
proxy_ip
))
{
nice_address_set_port
(
&
proxy_server
,
agent
->
proxy_port
);
socket
=
nice_tcp_bsd_socket_new
(
agent
,
component
->
ctx
,
&
proxy_server
);
if
(
socket
&&
agent
->
proxy_type
==
NICE_PROXY_TYPE_SOCKS5
)
{
socket
=
nice_socks5_socket_new
(
agent
,
socket
,
&
turn
->
server
,
agent
->
proxy_username
,
agent
->
proxy_password
);
}
else
{
/* TODO add HTTP support */
nice_socket_free
(
socket
);
socket
=
NULL
;
}
}
if
(
socket
==
NULL
)
{
socket
=
nice_tcp_bsd_socket_new
(
agent
,
component
->
ctx
,
&
turn
->
server
);
socket
=
nice_tcp_bsd_socket_new
(
agent
,
component
->
ctx
,
&
turn
->
server
);
}
if
(
turn
->
type
==
NICE_RELAY_TYPE_TURN_TLS
&&
if
(
turn
->
type
==
NICE_RELAY_TYPE_TURN_TLS
&&
agent
->
compatibility
==
NICE_COMPATIBILITY_GOOGLE
)
{
agent
->
compatibility
==
NICE_COMPATIBILITY_GOOGLE
)
{
socket
=
nice_pseudossl_socket_new
(
agent
,
socket
);
socket
=
nice_pseudossl_socket_new
(
agent
,
socket
);
...
...
socket/Makefile.am
View file @
7c043a27
...
@@ -28,6 +28,8 @@ libsocket_la_SOURCES = \
...
@@ -28,6 +28,8 @@ libsocket_la_SOURCES = \
tcp-bsd.c
\
tcp-bsd.c
\
pseudossl.h
\
pseudossl.h
\
pseudossl.c
\
pseudossl.c
\
socks5.h
\
socks5.c
\
turn.h
\
turn.h
\
turn.c
\
turn.c
\
tcp-turn.h
\
tcp-turn.h
\
...
@@ -40,5 +42,5 @@ test_bsd_LDADD = $(COMMON_LDADD)
...
@@ -40,5 +42,5 @@ test_bsd_LDADD = $(COMMON_LDADD)
TESTS
=
$(check_PROGRAMS)
TESTS
=
$(check_PROGRAMS)
pkginclude_HEADERS
=
socket.h udp-bsd.h tcp-bsd.h pseudossl.h turn.h tcp-turn.h
pkginclude_HEADERS
=
socket.h udp-bsd.h tcp-bsd.h pseudossl.h turn.h tcp-turn.h
socks5.h
socket/socket.h
View file @
7c043a27
...
@@ -85,6 +85,7 @@ nice_socket_free (NiceSocket *sock);
...
@@ -85,6 +85,7 @@ nice_socket_free (NiceSocket *sock);
#include "udp-bsd.h"
#include "udp-bsd.h"
#include "tcp-bsd.h"
#include "tcp-bsd.h"
#include "pseudossl.h"
#include "pseudossl.h"
#include "socks5.h"
#include "turn.h"
#include "turn.h"
#include "tcp-turn.h"
#include "tcp-turn.h"
...
...
socket/socks5.c
0 → 100644
View file @
7c043a27
/*
* This file is part of the Nice GLib ICE library.
*
* (C) 2006-2008 Collabora Ltd.
* Contact: Dafydd Harries
* Contact: Olivier Crete
* (C) 2006, 2007 Nokia Corporation. All rights reserved.
* Contact: Kai Vehmanen
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Nice GLib ICE library.
*
* The Initial Developers of the Original Code are Collabora Ltd and Nokia
* Corporation. All Rights Reserved.
*
* Contributors:
* Dafydd Harries, Collabora Ltd.
* Olivier Crete, Collabora Ltd.
* Rémi Denis-Courmont, Nokia
* Kai Vehmanen
*
* Alternatively, the contents of this file may be used under the terms of the
* the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
* case the provisions of LGPL are applicable instead of those above. If you
* wish to allow use of your version of this file only under the terms of the
* LGPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replace
* them with the notice and other provisions required by the LGPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the LGPL.
*/
/*
* Implementation of TCP relay socket interface using TCP Berkeley sockets. (See
* http://en.wikipedia.org/wiki/Berkeley_sockets.)
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "socks5.h"
#include <string.h>
#ifndef G_OS_WIN32
#include <unistd.h>
#endif
typedef
enum
{
SOCKS_STATE_INIT
,
SOCKS_STATE_AUTH
,
SOCKS_STATE_CONNECT
,
SOCKS_STATE_CONNECTED
,
SOCKS_STATE_ERROR
}
SocksState
;
typedef
struct
{
SocksState
state
;
NiceSocket
*
base_socket
;
NiceAddress
addr
;
gchar
*
username
;
gchar
*
password
;
GQueue
send_queue
;
}
Socks5Priv
;
struct
to_be_sent
{
guint
length
;
gchar
*
buf
;
NiceAddress
to
;
};
static
void
socket_close
(
NiceSocket
*
sock
);
static
gint
socket_recv
(
NiceSocket
*
sock
,
NiceAddress
*
from
,
guint
len
,
gchar
*
buf
);
static
gboolean
socket_send
(
NiceSocket
*
sock
,
const
NiceAddress
*
to
,
guint
len
,
const
gchar
*
buf
);
static
gboolean
socket_is_reliable
(
NiceSocket
*
sock
);
static
void
add_to_be_sent
(
NiceSocket
*
sock
,
const
NiceAddress
*
to
,
const
gchar
*
buf
,
guint
len
);
static
void
free_to_be_sent
(
struct
to_be_sent
*
tbs
);
NiceSocket
*
nice_socks5_socket_new
(
NiceAgent
*
agent
,
NiceSocket
*
base_socket
,
NiceAddress
*
addr
,
gchar
*
username
,
gchar
*
password
)
{
Socks5Priv
*
priv
;
NiceSocket
*
sock
=
NULL
;
if
(
addr
)
{
sock
=
g_slice_new0
(
NiceSocket
);
sock
->
priv
=
priv
=
g_slice_new0
(
Socks5Priv
);
priv
->
base_socket
=
base_socket
;
priv
->
addr
=
*
addr
;
priv
->
username
=
g_strdup
(
username
);
priv
->
password
=
g_strdup
(
password
);
sock
->
fileno
=
priv
->
base_socket
->
fileno
;
sock
->
addr
=
priv
->
base_socket
->
addr
;
sock
->
send
=
socket_send
;
sock
->
recv
=
socket_recv
;
sock
->
is_reliable
=
socket_is_reliable
;
sock
->
close
=
socket_close
;
/* Send SOCKS5 handshake */
{
gchar
msg
[
4
];
gint
len
=
3
;
msg
[
0
]
=
0x05
;
/* SOCKS version */
msg
[
1
]
=
0x01
;
/* number of methods supported */
msg
[
2
]
=
0x00
;
/* no authentication method*/
g_debug
(
"user/pass : %s - %s"
,
username
,
password
);
/* add support for authentication method */
if
(
username
||
password
)
{
msg
[
1
]
=
0x02
;
/* number of methods supported */
msg
[
3
]
=
0x02
;
/* authentication method */
len
++
;
}
/* We send 'to' NULL because it will always be to an already connected
* TCP base socket, which ignores the destination */
nice_socket_send
(
priv
->
base_socket
,
NULL
,
len
,
msg
);
priv
->
state
=
SOCKS_STATE_INIT
;
}
}
return
sock
;
}
static
void
socket_close
(
NiceSocket
*
sock
)
{
Socks5Priv
*
priv
=
sock
->
priv
;
if
(
priv
->
base_socket
)
nice_socket_free
(
priv
->
base_socket
);
if
(
priv
->
username
)
g_free
(
priv
->
username
);
if
(
priv
->
password
)
g_free
(
priv
->
password
);
g_queue_foreach
(
&
priv
->
send_queue
,
(
GFunc
)
free_to_be_sent
,
NULL
);
g_queue_clear
(
&
priv
->
send_queue
);
g_slice_free
(
Socks5Priv
,
sock
->
priv
);
}
static
gint
socket_recv
(
NiceSocket
*
sock
,
NiceAddress
*
from
,
guint
len
,
gchar
*
buf
)
{
Socks5Priv
*
priv
=
sock
->
priv
;
switch
(
priv
->
state
)
{
case
SOCKS_STATE_CONNECTED
:
if
(
priv
->
base_socket
)
return
nice_socket_recv
(
priv
->
base_socket
,
from
,
len
,
buf
);
break
;
case
SOCKS_STATE_INIT
:
{
gchar
data
[
2
];
gint
ret
=
-
1
;
nice_debug
(
"Socks5 state Init"
);
if
(
priv
->
base_socket
)
ret
=
nice_socket_recv
(
priv
->
base_socket
,
from
,
sizeof
(
data
),
data
);
if
(
ret
<=
0
)
{
return
ret
;
}
else
if
(
ret
==
sizeof
(
data
))
{
if
(
data
[
0
]
==
0x05
)
{
if
(
data
[
1
]
==
0x02
)
{
gchar
msg
[
515
];
gint
len
=
0
;
if
(
priv
->
username
||
priv
->
password
)
{
gint
ulen
=
0
;
gint
plen
=
0
;
if
(
priv
->
username
)
ulen
=
strlen
(
priv
->
username
);
if
(
priv
->
password
)
plen
=
strlen
(
priv
->
password
);
msg
[
len
++
]
=
0x01
;
/* auth version */
msg
[
len
++
]
=
ulen
;
/* username length */
memcpy
(
msg
+
len
,
priv
->
username
,
ulen
);
/* Username */
len
+=
ulen
;
msg
[
len
++
]
=
plen
;
/* Password length */
memcpy
(
msg
+
len
,
priv
->
password
,
plen
);
/* Password */
len
+=
plen
;
nice_socket_send
(
priv
->
base_socket
,
NULL
,
len
,
msg
);
priv
->
state
=
SOCKS_STATE_AUTH
;
}
else
{
/* Authentication required but no auth info available */
goto
error
;
}
}
else
if
(
data
[
1
]
==
0x00
)
{
goto
send_connect
;
}
else
{
/* method not supported by socks server */
goto
error
;
}
}
else
{
/* invalid SOCKS server version */
goto
error
;
}
}
else
{
/* read error */
goto
error
;
}
}
break
;
case
SOCKS_STATE_AUTH
:
{
gchar
data
[
2
];
gint
ret
=
-
1
;
nice_debug
(
"Socks5 state auth"
);
if
(
priv
->
base_socket
)
ret
=
nice_socket_recv
(
priv
->
base_socket
,
from
,
sizeof
(
data
),
data
);
if
(
ret
<=
0
)
{
return
ret
;
}
else
if
(
ret
==
sizeof
(
data
))
{
if
(
data
[
0
]
==
0x01
&&
data
[
1
]
==
0x00
)
{
/* Authenticated */
goto
send_connect
;
}
else
{
/* Authentication failed */
goto
error
;
}
}
}
break
;
case
SOCKS_STATE_CONNECT
:
{
gchar
data
[
22
];
gint
ret
=
-
1
;
nice_debug
(
"Socks5 state connect"
);
if
(
priv
->
base_socket
)
ret
=
nice_socket_recv
(
priv
->
base_socket
,
from
,
4
,
data
);
if
(
ret
<=
0
)
{
return
ret
;
}
else
if
(
ret
==
4
)
{
if
(
data
[
0
]
==
0x05
)
{
switch
(
data
[
1
])
{
case
0x00
:
if
(
data
[
2
]
==
0x00
)
{
struct
to_be_sent
*
tbs
=
NULL
;
switch
(
data
[
3
])
{
case
0x01
:
/* IPV4 bound address */
ret
=
nice_socket_recv
(
priv
->
base_socket
,
from
,
6
,
data
);
if
(
ret
!=
6
)
{
/* Could not read server bound address */
goto
error
;
}
break
;
case
0x04
:
/* IPV6 bound address */
ret
=
nice_socket_recv
(
priv
->
base_socket
,
from
,
18
,
data
);
if
(
ret
!=
18
)
{
/* Could not read server bound address */
goto
error
;
}
break
;
default:
/* Unsupported address type */
goto
error
;
}
while
((
tbs
=
g_queue_pop_head
(
&
priv
->
send_queue
)))
{
nice_socket_send
(
priv
->
base_socket
,
&
tbs
->
to
,
tbs
->
length
,
tbs
->
buf
);
g_free
(
tbs
->
buf
);
g_slice_free
(
struct
to_be_sent
,
tbs
);
}
priv
->
state
=
SOCKS_STATE_CONNECTED
;
}
else
{
/* Wrong reserved value */
goto
error
;
}
break
;
case
0x01
:
/* general SOCKS server failure */
case
0x02
:
/* connection not allowed by ruleset */
case
0x03
:
/* Network unreachable */
case
0x04
:
/* Host unreachable */
case
0x05
:
/* Connection refused */
case
0x06
:
/* TTL expired */
case
0x07
:
/* Command not supported */
case
0x08
:
/* Address type not supported */
default:
/* Unknown error */
goto
error
;
break
;
}
}
else
{
/* Wrong server version */
goto
error
;
}
}
else
{
/* Invalid data received */
goto
error
;
}
}
break
;
default:
/* Unknown status */
goto
error
;
}
return
0
;
send_connect:
{
gchar
msg
[
22
];
gint
len
=
0
;
struct
sockaddr_storage
name
;
nice_address_copy_to_sockaddr
(
&
priv
->
addr
,
(
struct
sockaddr
*
)
&
name
);
msg
[
len
++
]
=
0x05
;
/* SOCKS version */
msg
[
len
++
]
=
0x01
;
/* connect command */
msg
[
len
++
]
=
0x00
;
/* reserved */
if
(
name
.
ss_family
==
AF_INET
)
{
msg
[
len
++
]
=
0x01
;
/* IPV4 address type */
/* Address */
memcpy
(
msg
+
len
,
&
((
struct
sockaddr_in
*
)
&
name
)
->
sin_addr
,
4
);
len
+=
4
;
/* Port */
memcpy
(
msg
+
len
,
&
((
struct
sockaddr_in
*
)
&
name
)
->
sin_port
,
2
);
len
+=
2
;
}
else
if
(
name
.
ss_family
==
AF_INET6
)
{
msg
[
len
++
]
=
0x04
;
/* IPV6 address type */
/* Address */
memcpy
(
msg
+
len
,
&
((
struct
sockaddr_in6
*
)
&
name
)
->
sin6_addr
,
16
);
len
+=
16
;
/* Port */
memcpy
(
msg
+
len
,
&
((
struct
sockaddr_in6
*
)
&
name
)
->
sin6_port
,
2
);
len
+=
2
;
}
nice_socket_send
(
priv
->
base_socket
,
NULL
,
len
,
msg
);
priv
->
state
=
SOCKS_STATE_CONNECT
;
return
0
;
}
error:
nice_debug
(
"Socks5 error"
);
if
(
priv
->
base_socket
)
nice_socket_free
(
priv
->
base_socket
);
priv
->
base_socket
=
NULL
;
priv
->
state
=
SOCKS_STATE_ERROR
;
return
-
1
;
}
static
gboolean
socket_send
(
NiceSocket
*
sock
,
const
NiceAddress
*
to
,
guint
len
,
const
gchar
*
buf
)
{
Socks5Priv
*
priv
=
sock
->
priv
;
if
(
priv
->
state
==
SOCKS_STATE_CONNECTED
)
{
if
(
priv
->
base_socket
)
return
nice_socket_send
(
priv
->
base_socket
,
to
,
len
,
buf
);
else
return
FALSE
;
}
else
{
add_to_be_sent
(
sock
,
to
,
buf
,
len
);
}
return
TRUE
;
}
static
gboolean
socket_is_reliable
(
NiceSocket
*
sock
)
{
return
TRUE
;
}
static
void
add_to_be_sent
(
NiceSocket
*
sock
,
const
NiceAddress
*
to
,
const
gchar
*
buf
,
guint
len
)
{
Socks5Priv
*
priv
=
sock
->
priv
;
struct
to_be_sent
*
tbs
=
NULL
;
if
(
len
<=
0
)
return
;
tbs
=
g_slice_new0
(
struct
to_be_sent
);
tbs
->
buf
=
g_memdup
(
buf
,
len
);
tbs
->
length
=
len
;
if
(
to
)
tbs
->
to
=
*
to
;
g_queue_push_tail
(
&
priv
->
send_queue
,
tbs
);
}
static
void
free_to_be_sent
(
struct
to_be_sent
*
tbs
)
{
g_free
(
tbs
->
buf
);
g_slice_free
(
struct
to_be_sent
,
tbs
);
}
socket/socks5.h
0 → 100644
View file @
7c043a27
/*
* This file is part of the Nice GLib ICE library.
*
* (C) 2006, 2007 Collabora Ltd.
* Contact: Dafydd Harries
* (C) 2006, 2007 Nokia Corporation. All rights reserved.
* Contact: Kai Vehmanen
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Nice GLib ICE library.
*
* The Initial Developers of the Original Code are Collabora Ltd and Nokia
* Corporation. All Rights Reserved.
*
* Contributors:
* Dafydd Harries, Collabora Ltd.
*
* Alternatively, the contents of this file may be used under the terms of the
* the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
* case the provisions of LGPL are applicable instead of those above. If you
* wish to allow use of your version of this file only under the terms of the
* LGPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replace
* them with the notice and other provisions required by the LGPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the LGPL.
*/
#ifndef _SOCKS5_H
#define _SOCKS5_H
#include "socket.h"
#include "agent.h"
G_BEGIN_DECLS
NiceSocket
*
nice_socks5_socket_new
(
NiceAgent
*
agent
,
NiceSocket
*
base_socket
,
NiceAddress
*
addr
,
gchar
*
username
,
gchar
*
password
);
G_END_DECLS
#endif
/* _SOCKS5_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment