|
Lines 82-87
Link Here
|
| 82 |
#include "key.h" |
82 |
#include "key.h" |
| 83 |
#include "authfd.h" |
83 |
#include "authfd.h" |
| 84 |
#include "pathnames.h" |
84 |
#include "pathnames.h" |
|
|
85 |
#include "ssherr.h" |
| 85 |
|
86 |
|
| 86 |
/* -- channel core */ |
87 |
/* -- channel core */ |
| 87 |
|
88 |
|
|
Lines 1161-1177
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1161 |
#define SSH_SOCKS5_IPV6 0x04 |
1162 |
#define SSH_SOCKS5_IPV6 0x04 |
| 1162 |
#define SSH_SOCKS5_CONNECT 0x01 |
1163 |
#define SSH_SOCKS5_CONNECT 0x01 |
| 1163 |
#define SSH_SOCKS5_SUCCESS 0x00 |
1164 |
#define SSH_SOCKS5_SUCCESS 0x00 |
|
|
1165 |
#define SSH_SOCKS5_GENERICERROR 0x01 |
| 1166 |
#define SSH_SOCKS5_RULESETBLOCK 0x02 |
| 1167 |
#define SSH_SOCKS5_CONNREFUSED 0x05 |
| 1168 |
#define SSH_SOCKS5_BADATYP 0x08 |
| 1169 |
|
| 1170 |
struct socks5_msg { |
| 1171 |
u_int8_t version; |
| 1172 |
u_int8_t command; |
| 1173 |
u_int8_t reserved; |
| 1174 |
u_int8_t atyp; |
| 1175 |
}; |
| 1176 |
|
| 1177 |
static void |
| 1178 |
socks5_error(Channel *c, u_int8_t code) |
| 1179 |
{ |
| 1180 |
struct socks5_msg e; |
| 1181 |
int r; |
| 1182 |
|
| 1183 |
memset(&e, 0, sizeof(e)); |
| 1184 |
if ((r = sshbuf_put_u8(&c->output, 5)) != 0 || /* version */ |
| 1185 |
(r = sshbuf_put_u8(&c->output, code)) != 0 || |
| 1186 |
(r = sshbuf_put_u8(&c->output, 0)) != 0 || /* reserved */ |
| 1187 |
(r = sshbuf_put_u8(&c->output, SSH_SOCKS5_DOMAIN)) != 0 || |
| 1188 |
(r = sshbuf_put_u8(&c->output, 0)) != 0 || /* fake addr len = 0 */ |
| 1189 |
(r = sshbuf_put_u16(&c->output, 0)) != 0) /* fake port number */ |
| 1190 |
fatal("%s: construct SOCKS5 reply: %s", __func__, ssh_err(r)); |
| 1191 |
/* Don't try to do anything further with this request */ |
| 1192 |
sshbuf_reset(&c->input); |
| 1193 |
} |
| 1164 |
|
1194 |
|
| 1165 |
/* ARGSUSED */ |
1195 |
/* ARGSUSED */ |
| 1166 |
static int |
1196 |
static int |
| 1167 |
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) |
1197 |
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) |
| 1168 |
{ |
1198 |
{ |
| 1169 |
struct { |
1199 |
struct socks5_msg s5_req, s5_rsp; |
| 1170 |
u_int8_t version; |
|
|
| 1171 |
u_int8_t command; |
| 1172 |
u_int8_t reserved; |
| 1173 |
u_int8_t atyp; |
| 1174 |
} s5_req, s5_rsp; |
| 1175 |
u_int16_t dest_port; |
1200 |
u_int16_t dest_port; |
| 1176 |
char dest_addr[255+1], ntop[INET6_ADDRSTRLEN]; |
1201 |
char dest_addr[255+1], ntop[INET6_ADDRSTRLEN]; |
| 1177 |
u_char *p; |
1202 |
u_char *p; |
|
Lines 1199-1204
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1199 |
if (!found) { |
1224 |
if (!found) { |
| 1200 |
debug("channel %d: method SSH_SOCKS5_NOAUTH not found", |
1225 |
debug("channel %d: method SSH_SOCKS5_NOAUTH not found", |
| 1201 |
c->self); |
1226 |
c->self); |
|
|
1227 |
socks5_error(c, SSH_SOCKS5_GENERICERROR); |
| 1228 |
FD_SET(c->sock, writeset); |
| 1202 |
return -1; |
1229 |
return -1; |
| 1203 |
} |
1230 |
} |
| 1204 |
buffer_consume(&c->input, nmethods + 2); |
1231 |
buffer_consume(&c->input, nmethods + 2); |
|
Lines 1217-1222
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1217 |
s5_req.command != SSH_SOCKS5_CONNECT || |
1244 |
s5_req.command != SSH_SOCKS5_CONNECT || |
| 1218 |
s5_req.reserved != 0x00) { |
1245 |
s5_req.reserved != 0x00) { |
| 1219 |
debug2("channel %d: only socks5 connect supported", c->self); |
1246 |
debug2("channel %d: only socks5 connect supported", c->self); |
|
|
1247 |
socks5_error(c, SSH_SOCKS5_GENERICERROR); |
| 1248 |
FD_SET(c->sock, writeset); |
| 1220 |
return -1; |
1249 |
return -1; |
| 1221 |
} |
1250 |
} |
| 1222 |
switch (s5_req.atyp){ |
1251 |
switch (s5_req.atyp){ |
|
Lines 1234-1239
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1234 |
break; |
1263 |
break; |
| 1235 |
default: |
1264 |
default: |
| 1236 |
debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); |
1265 |
debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); |
|
|
1266 |
socks5_error(c, SSH_SOCKS5_BADATYP); |
| 1267 |
FD_SET(c->sock, writeset); |
| 1237 |
return -1; |
1268 |
return -1; |
| 1238 |
} |
1269 |
} |
| 1239 |
need = sizeof(s5_req) + addrlen + 2; |
1270 |
need = sizeof(s5_req) + addrlen + 2; |
|
Lines 1253-1264
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1253 |
if (addrlen >= NI_MAXHOST) { |
1284 |
if (addrlen >= NI_MAXHOST) { |
| 1254 |
error("channel %d: dynamic request: socks5 hostname " |
1285 |
error("channel %d: dynamic request: socks5 hostname " |
| 1255 |
"\"%.100s\" too long", c->self, dest_addr); |
1286 |
"\"%.100s\" too long", c->self, dest_addr); |
|
|
1287 |
socks5_error(c, SSH_SOCKS5_RULESETBLOCK); |
| 1288 |
FD_SET(c->sock, writeset); |
| 1256 |
return -1; |
1289 |
return -1; |
| 1257 |
} |
1290 |
} |
| 1258 |
c->path = xstrdup(dest_addr); |
1291 |
c->path = xstrdup(dest_addr); |
| 1259 |
} else { |
1292 |
} else { |
| 1260 |
if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL) |
1293 |
if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL) { |
|
|
1294 |
error("channel %d: dynamic request: socks5 address " |
| 1295 |
"invalid", c->self); |
| 1296 |
socks5_error(c, SSH_SOCKS5_RULESETBLOCK); |
| 1297 |
FD_SET(c->sock, writeset); |
| 1261 |
return -1; |
1298 |
return -1; |
|
|
1299 |
} |
| 1262 |
c->path = xstrdup(ntop); |
1300 |
c->path = xstrdup(ntop); |
| 1263 |
} |
1301 |
} |
| 1264 |
c->host_port = ntohs(dest_port); |
1302 |
c->host_port = ntohs(dest_port); |
|
Lines 1333-1339
channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1333 |
break; |
1371 |
break; |
| 1334 |
} |
1372 |
} |
| 1335 |
if (ret < 0) { |
1373 |
if (ret < 0) { |
| 1336 |
chan_mark_dead(c); |
1374 |
chan_read_failed(c); |
|
|
1375 |
c->type = SSH_CHANNEL_OUTPUT_DRAINING; |
| 1337 |
} else if (ret == 0) { |
1376 |
} else if (ret == 0) { |
| 1338 |
debug2("channel %d: pre_dynamic: need more", c->self); |
1377 |
debug2("channel %d: pre_dynamic: need more", c->self); |
| 1339 |
/* need more */ |
1378 |
/* need more */ |
|
Lines 2012-2018
channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 2012 |
|
2051 |
|
| 2013 |
/* ARGSUSED */ |
2052 |
/* ARGSUSED */ |
| 2014 |
static void |
2053 |
static void |
| 2015 |
channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset) |
2054 |
channel_post_output_drain(Channel *c, fd_set *readset, fd_set *writeset) |
| 2016 |
{ |
2055 |
{ |
| 2017 |
int len; |
2056 |
int len; |
| 2018 |
|
2057 |
|
|
Lines 2043-2048
channel_handler_init_20(void)
Link Here
|
| 2043 |
channel_pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener; |
2082 |
channel_pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener; |
| 2044 |
channel_pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client; |
2083 |
channel_pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client; |
| 2045 |
|
2084 |
|
|
|
2085 |
channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; |
| 2046 |
channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; |
2086 |
channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; |
| 2047 |
channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
2087 |
channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
| 2048 |
channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; |
2088 |
channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; |
|
Lines 2054-2059
channel_handler_init_20(void)
Link Here
|
| 2054 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
2094 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
| 2055 |
channel_post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener; |
2095 |
channel_post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener; |
| 2056 |
channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client; |
2096 |
channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client; |
|
|
2097 |
channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain; |
| 2057 |
} |
2098 |
} |
| 2058 |
|
2099 |
|
| 2059 |
static void |
2100 |
static void |
|
Lines 2073-2079
channel_handler_init_13(void)
Link Here
|
| 2073 |
channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
2114 |
channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
| 2074 |
channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
2115 |
channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
| 2075 |
channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; |
2116 |
channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; |
| 2076 |
channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; |
2117 |
channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain; |
| 2077 |
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; |
2118 |
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; |
| 2078 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
2119 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
| 2079 |
} |
2120 |
} |
|
Lines 2199-2205
channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
Link Here
|
| 2199 |
u_int n, sz, nfdset; |
2240 |
u_int n, sz, nfdset; |
| 2200 |
|
2241 |
|
| 2201 |
n = MAX(*maxfdp, channel_max_fd); |
2242 |
n = MAX(*maxfdp, channel_max_fd); |
| 2202 |
|
|
|
| 2203 |
nfdset = howmany(n+1, NFDBITS); |
2243 |
nfdset = howmany(n+1, NFDBITS); |
| 2204 |
/* Explicitly test here, because xrealloc isn't always called */ |
2244 |
/* Explicitly test here, because xrealloc isn't always called */ |
| 2205 |
if (nfdset && SIZE_MAX / nfdset < sizeof(fd_mask)) |
2245 |
if (nfdset && SIZE_MAX / nfdset < sizeof(fd_mask)) |
|
Lines 2615-2620
reason2txt(int reason)
Link Here
|
| 2615 |
return "unknown reason"; |
2655 |
return "unknown reason"; |
| 2616 |
} |
2656 |
} |
| 2617 |
|
2657 |
|
|
|
2658 |
static int |
| 2659 |
reason_to_socks5(int reason) |
| 2660 |
{ |
| 2661 |
switch (reason) { |
| 2662 |
case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED: |
| 2663 |
return SSH_SOCKS5_RULESETBLOCK; |
| 2664 |
case SSH2_OPEN_CONNECT_FAILED: |
| 2665 |
return SSH_SOCKS5_CONNREFUSED; |
| 2666 |
} |
| 2667 |
return SSH_SOCKS5_GENERICERROR; |
| 2668 |
} |
| 2669 |
|
| 2618 |
/* ARGSUSED */ |
2670 |
/* ARGSUSED */ |
| 2619 |
int |
2671 |
int |
| 2620 |
channel_input_open_failure(int type, u_int32_t seq, void *ctxt) |
2672 |
channel_input_open_failure(int type, u_int32_t seq, void *ctxt) |
|
Lines 2626-2632
channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
Link Here
|
| 2626 |
id = packet_get_int(); |
2678 |
id = packet_get_int(); |
| 2627 |
c = channel_lookup(id); |
2679 |
c = channel_lookup(id); |
| 2628 |
|
2680 |
|
| 2629 |
if (c==NULL || c->type != SSH_CHANNEL_OPENING) |
2681 |
if (c == NULL || c->type != SSH_CHANNEL_OPENING) |
| 2630 |
packet_disconnect("Received open failure for " |
2682 |
packet_disconnect("Received open failure for " |
| 2631 |
"non-opening channel %d.", id); |
2683 |
"non-opening channel %d.", id); |
| 2632 |
if (compat20) { |
2684 |
if (compat20) { |
|
Lines 2639-2644
channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
Link Here
|
| 2639 |
reason2txt(reason), msg ? ": ": "", msg ? msg : ""); |
2691 |
reason2txt(reason), msg ? ": ": "", msg ? msg : ""); |
| 2640 |
free(msg); |
2692 |
free(msg); |
| 2641 |
free(lang); |
2693 |
free(lang); |
|
|
2694 |
|
| 2695 |
/* Translate failures to SOCKS codes */ |
| 2696 |
if (c->remote_name != NULL && |
| 2697 |
strcmp(c->remote_name, "dynamic-tcpip") == 0 && |
| 2698 |
(c->flags & SSH_SOCKS5_AUTHDONE)) { |
| 2699 |
socks5_error(c, reason_to_socks5(reason)); |
| 2700 |
/* XXX wakeup c->sock for reply */ |
| 2701 |
} |
| 2702 |
|
| 2642 |
if (c->open_confirm) { |
2703 |
if (c->open_confirm) { |
| 2643 |
debug2("callback start"); |
2704 |
debug2("callback start"); |
| 2644 |
c->open_confirm(c->self, 0, c->open_confirm_ctx); |
2705 |
c->open_confirm(c->self, 0, c->open_confirm_ctx); |
|
Lines 2647-2653
channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
Link Here
|
| 2647 |
} |
2708 |
} |
| 2648 |
packet_check_eom(); |
2709 |
packet_check_eom(); |
| 2649 |
/* Schedule the channel for cleanup/deletion. */ |
2710 |
/* Schedule the channel for cleanup/deletion. */ |
| 2650 |
chan_mark_dead(c); |
2711 |
chan_read_failed(c); |
|
|
2712 |
c->type = SSH_CHANNEL_OUTPUT_DRAINING; |
| 2651 |
return 0; |
2713 |
return 0; |
| 2652 |
} |
2714 |
} |
| 2653 |
|
2715 |
|