-
Notifications
You must be signed in to change notification settings - Fork 8
/
socks.h
286 lines (261 loc) · 17.9 KB
/
socks.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/* ------------------------------------------------------------------------------------------------------------------ */
/* TS-Warp - Transparent proxy server and traffic wrapper */
/* ------------------------------------------------------------------------------------------------------------------ */
/*
* Copyright (c) 2021-2024, Mikhail Zakharov <[email protected]>
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* -- Socks protocol definitions ------------------------------------------------------------------------------------ */
#define PROXY_PROTO_SOCKS_V4 '4'
#define PROXY_PROTO_SOCKS_V5 '5'
/* -- Socks4 -------------------------------------------------------------------------------------------------------- */
#define SOCKS4_CMD_TCPCONNECT 0x01
#define SOCKS4_CMD_TCPBIND 0x02
typedef struct {
uint8_t ver; /* Socks version */
uint8_t cmd; /* Command
0x01: TCP Connect;
0x02: TCP port Binding */
uint16_t dstport; /* Dest port number in a network byte order */
uint32_t dstaddr; /* IPv4 Address 4 bytes in network byte order */
unsigned char id[256]; /* Null-terminated user ID string */
} s4_request;
typedef struct {
uint8_t nul; /* NUL-byte */
uint8_t status; /* Returned status
0x5A: Request granted
0x5B: Request rejected or failed
0x5C: Request failed: client is not running identd (or not reachable from server)
0x5D: Request failed because client's identd could not confirm the user ID */
uint16_t dstport; /* Dest port number in a network byte order */
uint32_t dstaddr; /* IPv4 Address 4 bytes in network byte order */
} s4_reply;
/* Socks4 server replies. Only 0x5a and 0x5b are interesting */
#define SOCKS4_REPLY_OK 0x5a /* Request granted */
#define SOCKS4_REPLY_KO 0x5b /* Request rejected or failed */
#define SOCKS4_REPLY_KO_IDENT1 0x5c /* Request failed because client is not running identd */
#define SOCKS4_REPLY_KO_IDENT2 0x5d /* Request failed because client's identd couldn't confirm user */
/* -- Socks5 -------------------------------------------------------------------------------------------------------- */
#define AUTH_MAX_METHODS 255
#define AUTH_METHOD_NOAUTH 0x00
#define AUTH_METHOD_GSSAPI 0x01
#define AUTH_METHOD_UNAME 0x02
/* 0x03–0x7F: methods assigned by IANA */
#define AUTH_METHOD_CHAP 0x03 /* Challenge-Handshake Auth Proto */
/* 0x04 Unassigned */
#define AUTH_METHOD_CRAM 0x05 /* Challenge-Response Auth Method */
#define AUTH_METHOD_SSL 0x06 /* Secure Sockets Layer */
#define AUTH_METHOD_NDS 0x07 /* NDS Authentication (Novell?) */
#define AUTH_METHOD_MAF 0x08 /* Multi-Authentication Framework */
#define AUTH_METHOD_JPB 0x09 /* JSON Parameter Block */
/* 0x0A–0x7F Unassigned */
/* 0x80–0xFE Reserved for private use */
#define AUTH_METHOD_NOACCEPT 0xFF /* No methods accepted by server */
typedef struct {
uint8_t ver; /* Socks version */
uint8_t nauth; /* Number of auth methods */
uint8_t auth[AUTH_MAX_METHODS]; /* Authentication methods */
} s5_request_hello;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t cauth; /* Chosen auth method */
} s5_reply_hello;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t idlen; /* Username length */
uint8_t *id; /* ID 1-255 chars */
uint8_t pwlen; /* Password length */
uint8_t *pw; /* Password 1-255 */
} s5_request_auth;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t status; /* 0x00: OK, else KO */
} s5_reply_auth;
/* Useful Socks5 request field definitions of s5_request* structures */
/* Command: cmd */
#define SOCKS5_CMD_TCPCONNECT 0x01
#define SOCKS5_CMD_TCPBIND 0x02
#define SOCKS5_CMD_UDPASSOCIATE 0x03
/* Address type: atype */
#define SOCKS5_ATYPE_NONE 0x00 /* NB! Non standard, for ts-warp only */
#define SOCKS5_ATYPE_IPV4 0x01
#define SOCKS5_ATYPE_NAME 0x03
#define SOCKS5_ATYPE_IPV6 0x04
/* Address type: atype max length */
#define SOCKS5_ATYPE_IPV4_LEN 4
#define SOCKS5_ATYPE_NAME_LEN 256 /* 1 + HOST_NAME_MAX */
#define SOCKS5_ATYPE_IPV6_LEN 16
typedef struct {
uint8_t ver; /* Socks version */
uint8_t cmd; /* Command
0x01: TCP Connect;
0x02: TCP port Binding, e.g. FTP;
0x03: associate a UDP port */
uint8_t rsv; /* 0x00: Reserved */
uint8_t atype; /* Destination address type
0x01: IPv4 address
0x03: Domain name
0x04: IPv6 address */
uint8_t dsthost[1 + HOST_NAME_MAX + 2]; /* Destination address + port in a net byte order:
IPv4 address: 4 bytes
Domain name: 1 byte Length + 1-255 bytes Name
IPv6 address: 16 bytes
Dest port: 2 bytes */
} s5_request;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t cmd; /* Command
0x01: TCP Connect;
0x02: TCP port Binding, e.g. FTP;
0x03: associate a UDP port */
uint8_t rsv; /* 0x00: Reserved */
uint8_t atype; /* Destination address type
0x01: IPv4 address
0x03: Domain name
0x04: IPv6 address */
uint8_t dstaddr[4]; /* Destination address
IPv4 address: 4 bytes
Domain name: 1 byte Length + 1-255 bytes Name
IPv6 address: 16 bytes */
uint16_t dstport; /* Dest port number in a network byte order */
} s5_request_ipv4;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t cmd; /* Command
0x01: TCP Connect;
0x02: TCP port Binding, e.g. FTP;
0x03: associate a UDP port */
uint8_t rsv; /* 0x00: Reserved */
uint8_t atype; /* Destination address type
0x01: IPv4 address
0x03: Domain name
0x04: IPv6 address */
uint8_t dstaddr[16]; /* Destination address
IPv4 address: 4 bytes
Domain name: 1 byte Length + 1-255 bytes Name
IPv6 address: 16 bytes */
uint16_t dstport; /* Dest port number in a network byte order */
} s5_request_ipv6;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t cmd; /* Command
0x01: TCP Connect;
0x02: TCP port Binding, e.g. FTP;
0x03: associate a UDP port */
uint8_t rsv; /* 0x00: Reserved */
uint8_t atype; /* Destination address type */
} s5_request_short;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t status; /* Returned status
0x00: Request granted
0x01: General failure
0x02: Connection not allowed by ruleset
0x03: Network unreachable
0x04: Host unreachable
0x05: Connection refused by destination host
0x06: TTL expired
0x07: Command not supported / protocol error
0x08: Address type not supported */
uint8_t rsv; /* 0x00: Reserved */
uint8_t atype; /* Server bound address type
0x01: IPv4 address
0x03: Domain name
0x04: IPv6 address */
uint8_t bndaddrport[1 + HOST_NAME_MAX + 2]; /* A buffer to accomodate all types of addresses and a port */
} s5_reply;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t status; /* Returned status
0x00: Request granted
0x01: General failure
0x02: Connection not allowed by ruleset
0x03: Network unreachable
0x04: Host unreachable
0x05: Connection refused by destination host
0x06: TTL expired
0x07: Command not supported / protocol error
0x08: Address type not supported */
uint8_t rsv; /* 0x00: Reserved */
uint8_t atype; /* Server bound address type
0x01: IPv4 address
0x03: Domain name
0x04: IPv6 address */
uint8_t dstaddr[4]; /* Destination address
IPv4 address: 4 bytes
Domain name: 1 byte Length + 1-255 bytes Name
IPv6 address: 16 bytes */
uint16_t dstport; /* Dest port number in a network byte order */
} s5_reply_ipv4;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t status; /* Returned status
0x00: Request granted
0x01: General failure
0x02: Connection not allowed by ruleset
0x03: Network unreachable
0x04: Host unreachable
0x05: Connection refused by destination host
0x06: TTL expired
0x07: Command not supported / protocol error
0x08: Address type not supported */
uint8_t rsv; /* 0x00: Reserved */
uint8_t atype; /* Server bound address type
0x01: IPv4 address
0x03: Domain name
0x04: IPv6 address */
uint8_t dstaddr[16]; /* Destination address
IPv4 address: 4 bytes
Domain name: 1 byte Length + 1-255 bytes Name
IPv6 address: 16 bytes */
uint16_t dstport; /* Dest port number in a network byte order */
} s5_reply_ipv6;
typedef struct {
uint8_t ver; /* Socks version */
uint8_t status; /* Returned status
0x00: Request granted
0x01: General failure
0x02: Connection not allowed by ruleset
0x03: Network unreachable
0x04: Host unreachable
0x05: Connection refused by destination host
0x06: TTL expired
0x07: Command not supported / protocol error
0x08: Address type not supported */
uint8_t rsv; /* 0x00: Reserved */
uint8_t atype; /* Server bound address type 0x01: IPv4 address */
} s5_reply_short;
/* Socks5 reply statuses */
#define SOCKS5_REPLY_OK 0x00 /* Request granted */
#define SOCKS5_REPLY_KO 0x01 /* General failure */
#define SOCKS5_REPLY_DENIED 0x02 /* Connection not allowed by ruleset */
#define SOCKS5_REPLY_NET_UNREACH 0x03 /* Network unreacheable */
#define SOCKS5_REPLY_HOST_UNREACH 0x04 /* Host unreacheable */
#define SOCKS5_REPLY_CONN_REFUSED 0x05 /* Connection refused by target host */
#define SOCKS5_REPLY_TTL_EXPIRED 0x06 /* TTL expired */
#define SOCKS5_REPLY_UNSUPPORTED 0x07 /* Command unsupported / protocol error */
#define SOCKS5_REPLY_ATYPE_ERROR 0x08 /* Address type is not supported */
/* -- Function prototypes ------------------------------------------------------------------------------------------- */
int socks4_client_request(chs cs, uint8_t cmd, struct sockaddr_in *daddr, char *user);
int socks5_client_hello(chs cs, unsigned int auth_method, ...);
int socks5_client_auth(chs cs, char *user, char *password);
int socks5_client_request(chs cs, uint8_t cmd, struct sockaddr_storage *daddr, char *dname);
int socks5_server_hello(int socket);
uint8_t socks5_server_request(int socket, struct uvaddr *daddr);
uint8_t socks5_server_reply(int socket, struct sockaddr_storage *iaddr, uint8_t atype);