|
Lines 1136-1146
Link Here
|
| 1136 |
/* try to decode a socks5 header */ |
1136 |
/* try to decode a socks5 header */ |
| 1137 |
#define SSH_SOCKS5_AUTHDONE 0x1000 |
1137 |
#define SSH_SOCKS5_AUTHDONE 0x1000 |
| 1138 |
#define SSH_SOCKS5_NOAUTH 0x00 |
1138 |
#define SSH_SOCKS5_NOAUTH 0x00 |
|
|
1139 |
#define SSH_SOCKS5_NOAUTHMETHOD 0xFF |
| 1139 |
#define SSH_SOCKS5_IPV4 0x01 |
1140 |
#define SSH_SOCKS5_IPV4 0x01 |
| 1140 |
#define SSH_SOCKS5_DOMAIN 0x03 |
1141 |
#define SSH_SOCKS5_DOMAIN 0x03 |
| 1141 |
#define SSH_SOCKS5_IPV6 0x04 |
1142 |
#define SSH_SOCKS5_IPV6 0x04 |
| 1142 |
#define SSH_SOCKS5_CONNECT 0x01 |
1143 |
#define SSH_SOCKS5_CONNECT 0x01 |
| 1143 |
#define SSH_SOCKS5_SUCCESS 0x00 |
1144 |
#define SSH_SOCKS5_SUCCESS 0x00 |
|
|
1145 |
#define SSH_SOCKS5_GENERICERROR 0x01 |
| 1146 |
#define SSH_SOCKS5_RULESETBLOCK 0x02 |
| 1147 |
#define SSH_SOCKS5_CONNREFUSED 0x05 |
| 1148 |
#define SSH_SOCKS5_BADATYP 0x08 |
| 1144 |
|
1149 |
|
| 1145 |
/* ARGSUSED */ |
1150 |
/* ARGSUSED */ |
| 1146 |
static int |
1151 |
static int |
|
Lines 1214-1219
Link Here
|
| 1214 |
break; |
1219 |
break; |
| 1215 |
default: |
1220 |
default: |
| 1216 |
debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); |
1221 |
debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); |
|
|
1222 |
s5_rsp.version = 0x05; |
| 1223 |
s5_rsp.command = SSH_SOCKS5_BADATYP; |
| 1224 |
s5_rsp.reserved = 0; /* ignored */ |
| 1225 |
s5_rsp.atyp = SSH_SOCKS5_DOMAIN; |
| 1226 |
dest_port = 0; /* ignored */ |
| 1227 |
|
| 1228 |
buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp)); |
| 1229 |
buffer_put_char(&c->output, 0x00); /* fake fqdn length = 0 */ |
| 1230 |
buffer_append(&c->output, &dest_port, sizeof(dest_port)); |
| 1231 |
FD_SET(c->sock, writeset); |
| 1232 |
/* TODO ensure the bytes buffered by above function are sent, which might require changing the return value below */ |
| 1217 |
return -1; |
1233 |
return -1; |
| 1218 |
} |
1234 |
} |
| 1219 |
need = sizeof(s5_req) + addrlen + 2; |
1235 |
need = sizeof(s5_req) + addrlen + 2; |
|
Lines 1233-1238
Link Here
|
| 1233 |
if (addrlen >= NI_MAXHOST) { |
1249 |
if (addrlen >= NI_MAXHOST) { |
| 1234 |
error("channel %d: dynamic request: socks5 hostname " |
1250 |
error("channel %d: dynamic request: socks5 hostname " |
| 1235 |
"\"%.100s\" too long", c->self, dest_addr); |
1251 |
"\"%.100s\" too long", c->self, dest_addr); |
|
|
1252 |
|
| 1253 |
s5_rsp.version = 0x05; |
| 1254 |
s5_rsp.command = SSH_SOCKS5_RULESETBLOCK; |
| 1255 |
s5_rsp.reserved = 0; /* ignored */ |
| 1256 |
s5_rsp.atyp = SSH_SOCKS5_DOMAIN; |
| 1257 |
dest_port = 0; /* ignored */ |
| 1258 |
|
| 1259 |
buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp)); |
| 1260 |
buffer_put_char(&c->output, 0x00); /* fake fqdn length = 0 */ |
| 1261 |
buffer_append(&c->output, &dest_port, sizeof(dest_port)); |
| 1262 |
FD_SET(c->sock, writeset); |
| 1263 |
/* TODO ensure the bytes buffered by above function are sent, which might require changing the return value below */ |
| 1236 |
return -1; |
1264 |
return -1; |
| 1237 |
} |
1265 |
} |
| 1238 |
c->path = xstrdup(dest_addr); |
1266 |
c->path = xstrdup(dest_addr); |
|
Lines 2572-2577
Link Here
|
| 2572 |
return "unknown reason"; |
2600 |
return "unknown reason"; |
| 2573 |
} |
2601 |
} |
| 2574 |
|
2602 |
|
|
|
2603 |
static int |
| 2604 |
reason2socks5(int reason) |
| 2605 |
{ |
| 2606 |
switch (reason) { |
| 2607 |
case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED: |
| 2608 |
return SSH_SOCKS5_RULESETBLOCK; |
| 2609 |
case SSH2_OPEN_CONNECT_FAILED: |
| 2610 |
return SSH_SOCKS5_CONNREFUSED; |
| 2611 |
} |
| 2612 |
return SSH_SOCKS5_GENERICERROR; |
| 2613 |
} |
| 2614 |
|
| 2575 |
/* ARGSUSED */ |
2615 |
/* ARGSUSED */ |
| 2576 |
int |
2616 |
int |
| 2577 |
channel_input_open_failure(int type, u_int32_t seq, void *ctxt) |
2617 |
channel_input_open_failure(int type, u_int32_t seq, void *ctxt) |
|
Lines 2596-2601
Link Here
|
| 2596 |
reason2txt(reason), msg ? ": ": "", msg ? msg : ""); |
2636 |
reason2txt(reason), msg ? ": ": "", msg ? msg : ""); |
| 2597 |
free(msg); |
2637 |
free(msg); |
| 2598 |
free(lang); |
2638 |
free(lang); |
|
|
2639 |
/* TODO should this perhaps occur after open_confirm? */ |
| 2640 |
if (c->remote_name && strcmp(c->remote_name, "dynamic-tcpip") == 0 && (c->flags & SSH_SOCKS5_AUTHDONE)) { |
| 2641 |
/* struct copied from channel_decode_socks5() */ |
| 2642 |
struct { |
| 2643 |
u_int8_t version; |
| 2644 |
u_int8_t command; |
| 2645 |
u_int8_t reserved; |
| 2646 |
u_int8_t atyp; |
| 2647 |
} s5_rsp; |
| 2648 |
u_int16_t dest_port; |
| 2649 |
|
| 2650 |
s5_rsp.version = 0x05; |
| 2651 |
s5_rsp.command = reason2socks5(reason); |
| 2652 |
s5_rsp.reserved = 0; /* ignored */ |
| 2653 |
s5_rsp.atyp = SSH_SOCKS5_DOMAIN; |
| 2654 |
dest_port = 0; /* ignored */ |
| 2655 |
|
| 2656 |
buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp)); |
| 2657 |
buffer_put_char(&c->output, 0x00); /* fake fqdn length = 0 */ |
| 2658 |
buffer_append(&c->output, &dest_port, sizeof(dest_port)); |
| 2659 |
FD_SET(c->sock, writeset); |
| 2660 |
|
| 2661 |
/* TODO will the data above get sent despite the chan_mark_dead() below? */ |
| 2662 |
} |
| 2599 |
if (c->open_confirm) { |
2663 |
if (c->open_confirm) { |
| 2600 |
debug2("callback start"); |
2664 |
debug2("callback start"); |
| 2601 |
c->open_confirm(c->self, 0, c->open_confirm_ctx); |
2665 |
c->open_confirm(c->self, 0, c->open_confirm_ctx); |