1 /*
2
3 Copyright (c) 2018 Joseph deBlaquiere
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"),
7 to deal in the Software without restriction, including without limitation
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 and/or sell copies of the Software, and to permit persons to whom
10 the Software is furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included
13 in all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 IN THE SOFTWARE.
22
23 */
24
25 #include "assert.h"
26 #include "../libdill.h"
27 #include <stdio.h>
28 #include <string.h>
29
30 static char *auth_user = NULL;
31 static char *auth_pass = NULL;
32
auth_fn(const char * user,const char * pass)33 int auth_fn(const char *user, const char* pass) {
34 if(auth_user) {
35 if(!user) return 0;
36 if(strcmp(user, auth_user) != 0) return 0;
37 }
38 if(auth_pass) {
39 if(!pass) return 0;
40 if(strcmp(pass, auth_pass) != 0) return 0;
41 }
42 return 1;
43 }
44
45 // forwards input to output. signal and return on error (connection closed)
forward(int in_s,int out_s,int ch)46 coroutine void forward(int in_s, int out_s, int ch) {
47 while (1) {
48 uint8_t d[1];
49 if(brecv(in_s, d, 1, -1)) break;
50 if(bsend(out_s, d, 1, -1)) break;
51 }
52 chdone(ch);
53 return;
54 }
55
do_proxy(int s)56 coroutine void do_proxy(int s) {
57 if((!auth_user) || (!auth_pass)){
58 if(socks5_proxy_auth(s, NULL, -1)) goto in_close;
59 } else {
60 if(socks5_proxy_auth(s, auth_fn, -1)) goto in_close;
61 }
62
63 struct ipaddr addr;
64 int cmd = socks5_proxy_recvcommand(s, &addr, -1);
65 if(cmd != SOCKS5_CONNECT) {
66 socks5_proxy_sendreply(s, SOCKS5_COMMAND_NOT_SUPPORTED, &addr, -1);
67 goto in_close;
68 }
69
70 int s_rem = tcp_connect(&addr, -1);
71 if(s_rem < 0) goto in_close;
72
73 if(ipaddr_remote(&addr, "0.0.0.0", 0, IPADDR_IPV4, -1)) goto both_close;
74
75 if(socks5_proxy_sendreply(s, SOCKS5_SUCCESS, &addr, -1)) goto both_close;
76
77 // channels for outboud, inbound to signal done (to close connection)
78 int och[2], ich[2];
79 if(chmake(och)) goto both_close;
80 if(chmake(ich)) goto both_close;
81
82 // start coroutines to handle inbound and outbound forwarding
83 int ob = go(forward(s, s_rem, och[1]));
84 if(ob < 0) goto both_close;
85 int ib = go(forward(s_rem, s, ich[1]));
86 if(ib < 0) goto both_close;
87
88 // wait for message in channel - one side closed, tcp_done the other
89 struct chclause cc[] = {{CHRECV, och[0], &cmd, 1},
90 {CHRECV, ich[0], &cmd, 1}};
91 switch(choose(cc, 2, -1)) {
92 case 0:
93 if(bundle_wait(ob, -1)) break;
94 tcp_done(s_rem, -1);
95 bundle_wait(ib, -1);
96 break;
97 case 1:
98 if(bundle_wait(ib, -1)) break;
99 tcp_done(s, -1);
100 bundle_wait(ob, -1);
101 break;
102 case -1:
103 break;
104 default:
105 // unexpected answer
106 assert(0);
107 }
108 both_close:
109 tcp_close(s_rem, -1);
110 in_close:
111 tcp_close(s, -1);
112 return;
113 }
114
main(int argc,char ** argv)115 int main(int argc, char** argv) {
116 if (argc >=3) {
117 // set up auth
118 auth_user = argv[1];
119 auth_pass = argv[2];
120 }
121 int workers = bundle();
122 struct ipaddr addr;
123 int rc = ipaddr_local(&addr, NULL, 1080, 0);
124 assert(rc == 0);
125 int ls = tcp_listen(&addr, 10);
126 assert(ls >= 0);
127 printf("SOCKS5 proxy listening on :1080\n");
128 while(1) {
129 struct ipaddr caddr;
130 int s = tcp_accept(ls, &caddr, -1);
131 assert(s >= 0);
132 rc = bundle_go(workers, do_proxy(s));
133 assert(rc == 0);
134 }
135 }
136