|
Lines 219-224
channel_lookup(int id)
Link Here
|
| 219 |
case SSH_CHANNEL_LARVAL: |
219 |
case SSH_CHANNEL_LARVAL: |
| 220 |
case SSH_CHANNEL_CONNECTING: |
220 |
case SSH_CHANNEL_CONNECTING: |
| 221 |
case SSH_CHANNEL_DYNAMIC: |
221 |
case SSH_CHANNEL_DYNAMIC: |
|
|
222 |
case SSH_CHANNEL_RDYNAMIC: |
| 222 |
case SSH_CHANNEL_OPENING: |
223 |
case SSH_CHANNEL_OPENING: |
| 223 |
case SSH_CHANNEL_OPEN: |
224 |
case SSH_CHANNEL_OPEN: |
| 224 |
case SSH_CHANNEL_INPUT_DRAINING: |
225 |
case SSH_CHANNEL_INPUT_DRAINING: |
|
Lines 556-561
channel_still_open(void)
Link Here
|
| 556 |
continue; |
557 |
continue; |
| 557 |
case SSH_CHANNEL_OPENING: |
558 |
case SSH_CHANNEL_OPENING: |
| 558 |
case SSH_CHANNEL_OPEN: |
559 |
case SSH_CHANNEL_OPEN: |
|
|
560 |
case SSH_CHANNEL_RDYNAMIC: |
| 559 |
case SSH_CHANNEL_X11_OPEN: |
561 |
case SSH_CHANNEL_X11_OPEN: |
| 560 |
case SSH_CHANNEL_MUX_CLIENT: |
562 |
case SSH_CHANNEL_MUX_CLIENT: |
| 561 |
return 1; |
563 |
return 1; |
|
Lines 601-606
channel_find_open(void)
Link Here
|
| 601 |
case SSH_CHANNEL_LARVAL: |
603 |
case SSH_CHANNEL_LARVAL: |
| 602 |
case SSH_CHANNEL_AUTH_SOCKET: |
604 |
case SSH_CHANNEL_AUTH_SOCKET: |
| 603 |
case SSH_CHANNEL_OPEN: |
605 |
case SSH_CHANNEL_OPEN: |
|
|
606 |
case SSH_CHANNEL_RDYNAMIC: |
| 604 |
case SSH_CHANNEL_X11_OPEN: |
607 |
case SSH_CHANNEL_X11_OPEN: |
| 605 |
return i; |
608 |
return i; |
| 606 |
case SSH_CHANNEL_INPUT_DRAINING: |
609 |
case SSH_CHANNEL_INPUT_DRAINING: |
|
Lines 654-659
channel_open_message(void)
Link Here
|
| 654 |
case SSH_CHANNEL_OPENING: |
657 |
case SSH_CHANNEL_OPENING: |
| 655 |
case SSH_CHANNEL_CONNECTING: |
658 |
case SSH_CHANNEL_CONNECTING: |
| 656 |
case SSH_CHANNEL_DYNAMIC: |
659 |
case SSH_CHANNEL_DYNAMIC: |
|
|
660 |
case SSH_CHANNEL_RDYNAMIC: |
| 657 |
case SSH_CHANNEL_OPEN: |
661 |
case SSH_CHANNEL_OPEN: |
| 658 |
case SSH_CHANNEL_X11_OPEN: |
662 |
case SSH_CHANNEL_X11_OPEN: |
| 659 |
case SSH_CHANNEL_INPUT_DRAINING: |
663 |
case SSH_CHANNEL_INPUT_DRAINING: |
|
Lines 1041-1047
channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1041 |
/* try to decode a socks4 header */ |
1045 |
/* try to decode a socks4 header */ |
| 1042 |
/* ARGSUSED */ |
1046 |
/* ARGSUSED */ |
| 1043 |
static int |
1047 |
static int |
| 1044 |
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) |
1048 |
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset, |
|
|
1049 |
Buffer * input, Buffer * output) |
| 1045 |
{ |
1050 |
{ |
| 1046 |
char *p, *host; |
1051 |
char *p, *host; |
| 1047 |
u_int len, have, i, found, need; |
1052 |
u_int len, have, i, found, need; |
|
Lines 1055-1065
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1055 |
|
1060 |
|
| 1056 |
debug2("channel %d: decode socks4", c->self); |
1061 |
debug2("channel %d: decode socks4", c->self); |
| 1057 |
|
1062 |
|
| 1058 |
have = buffer_len(&c->input); |
1063 |
have = buffer_len(input); |
| 1059 |
len = sizeof(s4_req); |
1064 |
len = sizeof(s4_req); |
| 1060 |
if (have < len) |
1065 |
if (have < len) |
| 1061 |
return 0; |
1066 |
return 0; |
| 1062 |
p = (char *)buffer_ptr(&c->input); |
1067 |
p = (char *)buffer_ptr(input); |
| 1063 |
|
1068 |
|
| 1064 |
need = 1; |
1069 |
need = 1; |
| 1065 |
/* SOCKS4A uses an invalid IP address 0.0.0.x */ |
1070 |
/* SOCKS4A uses an invalid IP address 0.0.0.x */ |
|
Lines 1084-1106
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1084 |
} |
1089 |
} |
| 1085 |
if (found < need) |
1090 |
if (found < need) |
| 1086 |
return 0; |
1091 |
return 0; |
| 1087 |
buffer_get(&c->input, (char *)&s4_req.version, 1); |
1092 |
buffer_get(input, (char *)&s4_req.version, 1); |
| 1088 |
buffer_get(&c->input, (char *)&s4_req.command, 1); |
1093 |
buffer_get(input, (char *)&s4_req.command, 1); |
| 1089 |
buffer_get(&c->input, (char *)&s4_req.dest_port, 2); |
1094 |
buffer_get(input, (char *)&s4_req.dest_port, 2); |
| 1090 |
buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); |
1095 |
buffer_get(input, (char *)&s4_req.dest_addr, 4); |
| 1091 |
have = buffer_len(&c->input); |
1096 |
have = buffer_len(input); |
| 1092 |
p = (char *)buffer_ptr(&c->input); |
1097 |
p = (char *)buffer_ptr(input); |
| 1093 |
if (memchr(p, '\0', have) == NULL) |
1098 |
if (memchr(p, '\0', have) == NULL) { |
| 1094 |
fatal("channel %d: decode socks4: user not nul terminated", |
1099 |
error("channel %d: decode socks4: user not nul terminated", |
| 1095 |
c->self); |
1100 |
c->self); |
|
|
1101 |
return -1; |
| 1102 |
} |
| 1096 |
len = strlen(p); |
1103 |
len = strlen(p); |
| 1097 |
debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); |
1104 |
debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); |
| 1098 |
len++; /* trailing '\0' */ |
1105 |
len++; /* trailing '\0' */ |
| 1099 |
if (len > have) |
1106 |
if (len > have) { |
| 1100 |
fatal("channel %d: decode socks4: len %d > have %d", |
1107 |
error("channel %d: decode socks4: len %d > have %d", |
| 1101 |
c->self, len, have); |
1108 |
c->self, len, have); |
|
|
1109 |
return -1; |
| 1110 |
} |
| 1102 |
strlcpy(username, p, sizeof(username)); |
1111 |
strlcpy(username, p, sizeof(username)); |
| 1103 |
buffer_consume(&c->input, len); |
1112 |
buffer_consume(input, len); |
| 1104 |
|
1113 |
|
| 1105 |
free(c->path); |
1114 |
free(c->path); |
| 1106 |
c->path = NULL; |
1115 |
c->path = NULL; |
|
Lines 1108-1129
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1108 |
host = inet_ntoa(s4_req.dest_addr); |
1117 |
host = inet_ntoa(s4_req.dest_addr); |
| 1109 |
c->path = xstrdup(host); |
1118 |
c->path = xstrdup(host); |
| 1110 |
} else { /* SOCKS4A: two strings */ |
1119 |
} else { /* SOCKS4A: two strings */ |
| 1111 |
have = buffer_len(&c->input); |
1120 |
have = buffer_len(input); |
| 1112 |
p = (char *)buffer_ptr(&c->input); |
1121 |
p = (char *)buffer_ptr(input); |
| 1113 |
len = strlen(p); |
1122 |
len = strlen(p); |
| 1114 |
debug2("channel %d: decode socks4a: host %s/%d", |
1123 |
debug2("channel %d: decode socks4a: host %s/%d", |
| 1115 |
c->self, p, len); |
1124 |
c->self, p, len); |
| 1116 |
len++; /* trailing '\0' */ |
1125 |
len++; /* trailing '\0' */ |
| 1117 |
if (len > have) |
1126 |
if (len > have) { |
| 1118 |
fatal("channel %d: decode socks4a: len %d > have %d", |
1127 |
error("channel %d: decode socks4a: len %d > have %d", |
| 1119 |
c->self, len, have); |
1128 |
c->self, len, have); |
|
|
1129 |
return -1; |
| 1130 |
} |
| 1120 |
if (len > NI_MAXHOST) { |
1131 |
if (len > NI_MAXHOST) { |
| 1121 |
error("channel %d: hostname \"%.100s\" too long", |
1132 |
error("channel %d: hostname \"%.100s\" too long", |
| 1122 |
c->self, p); |
1133 |
c->self, p); |
| 1123 |
return -1; |
1134 |
return -1; |
| 1124 |
} |
1135 |
} |
| 1125 |
c->path = xstrdup(p); |
1136 |
c->path = xstrdup(p); |
| 1126 |
buffer_consume(&c->input, len); |
1137 |
buffer_consume(input, len); |
| 1127 |
} |
1138 |
} |
| 1128 |
c->host_port = ntohs(s4_req.dest_port); |
1139 |
c->host_port = ntohs(s4_req.dest_port); |
| 1129 |
|
1140 |
|
|
Lines 1139-1145
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1139 |
s4_rsp.command = 90; /* cd: req granted */ |
1150 |
s4_rsp.command = 90; /* cd: req granted */ |
| 1140 |
s4_rsp.dest_port = 0; /* ignored */ |
1151 |
s4_rsp.dest_port = 0; /* ignored */ |
| 1141 |
s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */ |
1152 |
s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */ |
| 1142 |
buffer_append(&c->output, &s4_rsp, sizeof(s4_rsp)); |
1153 |
buffer_append(output, &s4_rsp, sizeof(s4_rsp)); |
| 1143 |
return 1; |
1154 |
return 1; |
| 1144 |
} |
1155 |
} |
| 1145 |
|
1156 |
|
|
Lines 1154-1160
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1154 |
|
1165 |
|
| 1155 |
/* ARGSUSED */ |
1166 |
/* ARGSUSED */ |
| 1156 |
static int |
1167 |
static int |
| 1157 |
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) |
1168 |
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset, |
|
|
1169 |
Buffer * input, Buffer * output) |
| 1158 |
{ |
1170 |
{ |
| 1159 |
struct { |
1171 |
struct { |
| 1160 |
u_int8_t version; |
1172 |
u_int8_t version; |
|
Lines 1168-1177
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1168 |
u_int have, need, i, found, nmethods, addrlen, af; |
1180 |
u_int have, need, i, found, nmethods, addrlen, af; |
| 1169 |
|
1181 |
|
| 1170 |
debug2("channel %d: decode socks5", c->self); |
1182 |
debug2("channel %d: decode socks5", c->self); |
| 1171 |
p = buffer_ptr(&c->input); |
1183 |
p = buffer_ptr(input); |
| 1172 |
if (p[0] != 0x05) |
1184 |
if (p[0] != 0x05) |
| 1173 |
return -1; |
1185 |
return -1; |
| 1174 |
have = buffer_len(&c->input); |
1186 |
have = buffer_len(input); |
| 1175 |
if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { |
1187 |
if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { |
| 1176 |
/* format: ver | nmethods | methods */ |
1188 |
/* format: ver | nmethods | methods */ |
| 1177 |
if (have < 2) |
1189 |
if (have < 2) |
|
Lines 1191-1200
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1191 |
c->self); |
1203 |
c->self); |
| 1192 |
return -1; |
1204 |
return -1; |
| 1193 |
} |
1205 |
} |
| 1194 |
buffer_consume(&c->input, nmethods + 2); |
1206 |
buffer_consume(input, nmethods + 2); |
| 1195 |
buffer_put_char(&c->output, 0x05); /* version */ |
1207 |
buffer_put_char(output, 0x05); /* version */ |
| 1196 |
buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */ |
1208 |
buffer_put_char(output, SSH_SOCKS5_NOAUTH); /* method */ |
| 1197 |
FD_SET(c->sock, writeset); |
1209 |
|
|
|
1210 |
if (c->type == SSH_CHANNEL_DYNAMIC) |
| 1211 |
FD_SET(c->sock, writeset); |
| 1212 |
|
| 1198 |
c->flags |= SSH_SOCKS5_AUTHDONE; |
1213 |
c->flags |= SSH_SOCKS5_AUTHDONE; |
| 1199 |
debug2("channel %d: socks5 auth done", c->self); |
1214 |
debug2("channel %d: socks5 auth done", c->self); |
| 1200 |
return 0; /* need more */ |
1215 |
return 0; /* need more */ |
|
Lines 1231-1241
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1231 |
need++; |
1246 |
need++; |
| 1232 |
if (have < need) |
1247 |
if (have < need) |
| 1233 |
return 0; |
1248 |
return 0; |
| 1234 |
buffer_consume(&c->input, sizeof(s5_req)); |
1249 |
buffer_consume(input, sizeof(s5_req)); |
| 1235 |
if (s5_req.atyp == SSH_SOCKS5_DOMAIN) |
1250 |
if (s5_req.atyp == SSH_SOCKS5_DOMAIN) |
| 1236 |
buffer_consume(&c->input, 1); /* host string length */ |
1251 |
buffer_consume(input, 1); /* host string length */ |
| 1237 |
buffer_get(&c->input, &dest_addr, addrlen); |
1252 |
buffer_get(input, &dest_addr, addrlen); |
| 1238 |
buffer_get(&c->input, (char *)&dest_port, 2); |
1253 |
buffer_get(input, (char *)&dest_port, 2); |
| 1239 |
dest_addr[addrlen] = '\0'; |
1254 |
dest_addr[addrlen] = '\0'; |
| 1240 |
free(c->path); |
1255 |
free(c->path); |
| 1241 |
c->path = NULL; |
1256 |
c->path = NULL; |
|
Lines 1262-1270
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1262 |
s5_rsp.atyp = SSH_SOCKS5_IPV4; |
1277 |
s5_rsp.atyp = SSH_SOCKS5_IPV4; |
| 1263 |
dest_port = 0; /* ignored */ |
1278 |
dest_port = 0; /* ignored */ |
| 1264 |
|
1279 |
|
| 1265 |
buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp)); |
1280 |
buffer_append(output, &s5_rsp, sizeof(s5_rsp)); |
| 1266 |
buffer_put_int(&c->output, ntohl(INADDR_ANY)); /* bind address */ |
1281 |
buffer_put_int(output, ntohl(INADDR_ANY)); /* bind address */ |
| 1267 |
buffer_append(&c->output, &dest_port, sizeof(dest_port)); |
1282 |
buffer_append(output, &dest_port, sizeof(dest_port)); |
| 1268 |
return 1; |
1283 |
return 1; |
| 1269 |
} |
1284 |
} |
| 1270 |
|
1285 |
|
|
Lines 1298-1337
channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1298 |
{ |
1313 |
{ |
| 1299 |
u_char *p; |
1314 |
u_char *p; |
| 1300 |
u_int have; |
1315 |
u_int have; |
| 1301 |
int ret; |
1316 |
int ret, gaierr, sock = -1; |
|
|
1317 |
char strport[NI_MAXSERV]; |
| 1318 |
Buffer * inbuf, * outbuf; |
| 1319 |
struct addrinfo hints; |
| 1320 |
struct channel_connect cctx; |
| 1321 |
|
| 1322 |
if (c->type == SSH_CHANNEL_DYNAMIC) { |
| 1323 |
inbuf = &c->input; |
| 1324 |
outbuf = &c->output; |
| 1325 |
} else if (c->type == SSH_CHANNEL_RDYNAMIC) { |
| 1326 |
inbuf = &c->output; |
| 1327 |
outbuf = &c->input; |
| 1328 |
} else { |
| 1329 |
fatal("cannot happen"); |
| 1330 |
} |
| 1302 |
|
1331 |
|
| 1303 |
have = buffer_len(&c->input); |
1332 |
have = buffer_len(inbuf); |
| 1304 |
debug2("channel %d: pre_dynamic: have %d", c->self, have); |
1333 |
debug2("channel %d: pre_dynamic: have %d", c->self, have); |
| 1305 |
/* buffer_dump(&c->input); */ |
1334 |
/* buffer_dump(&c->input); */ |
| 1306 |
/* check if the fixed size part of the packet is in buffer. */ |
1335 |
/* check if the fixed size part of the packet is in buffer. */ |
| 1307 |
if (have < 3) { |
1336 |
if (have < 3) { |
| 1308 |
/* need more */ |
1337 |
/* need more */ |
| 1309 |
FD_SET(c->sock, readset); |
1338 |
if (c->type == SSH_CHANNEL_DYNAMIC) |
|
|
1339 |
FD_SET(c->sock, readset); |
| 1340 |
|
| 1310 |
return; |
1341 |
return; |
| 1311 |
} |
1342 |
} |
| 1312 |
/* try to guess the protocol */ |
1343 |
/* try to guess the protocol */ |
| 1313 |
p = buffer_ptr(&c->input); |
1344 |
p = buffer_ptr(inbuf); |
| 1314 |
switch (p[0]) { |
1345 |
switch (p[0]) { |
| 1315 |
case 0x04: |
1346 |
case 0x04: |
| 1316 |
ret = channel_decode_socks4(c, readset, writeset); |
1347 |
ret = channel_decode_socks4(c, readset, writeset, inbuf, outbuf); |
| 1317 |
break; |
1348 |
break; |
| 1318 |
case 0x05: |
1349 |
case 0x05: |
| 1319 |
ret = channel_decode_socks5(c, readset, writeset); |
1350 |
ret = channel_decode_socks5(c, readset, writeset, inbuf, outbuf); |
| 1320 |
break; |
1351 |
break; |
| 1321 |
default: |
1352 |
default: |
| 1322 |
ret = -1; |
1353 |
ret = -1; |
| 1323 |
break; |
1354 |
break; |
| 1324 |
} |
1355 |
} |
| 1325 |
if (ret < 0) { |
1356 |
if (ret < 0) { |
| 1326 |
chan_mark_dead(c); |
1357 |
if (c->type == SSH_CHANNEL_DYNAMIC) |
|
|
1358 |
chan_mark_dead(c); |
| 1359 |
else { |
| 1360 |
close(c->sock); |
| 1361 |
c->sock = c->rfd = c->wfd = c->efd = -1; |
| 1362 |
buffer_clear(&c->input); |
| 1363 |
buffer_clear(&c->output); |
| 1364 |
if (compat20) |
| 1365 |
packet_start(SSH2_MSG_CHANNEL_CLOSE); |
| 1366 |
else |
| 1367 |
packet_start(SSH_MSG_CHANNEL_CLOSE); |
| 1368 |
packet_put_int(c->remote_id); |
| 1369 |
packet_send(); |
| 1370 |
c->flags |= CHAN_CLOSE_SENT; |
| 1371 |
c->type = SSH_CHANNEL_ABANDONED; |
| 1372 |
} |
| 1327 |
} else if (ret == 0) { |
1373 |
} else if (ret == 0) { |
| 1328 |
debug2("channel %d: pre_dynamic: need more", c->self); |
1374 |
debug2("channel %d: pre_dynamic: need more", c->self); |
| 1329 |
/* need more */ |
1375 |
/* need more */ |
| 1330 |
FD_SET(c->sock, readset); |
1376 |
if (c->type == SSH_CHANNEL_DYNAMIC) |
|
|
1377 |
FD_SET(c->sock, readset); |
| 1331 |
} else { |
1378 |
} else { |
| 1332 |
/* switch to the next state */ |
1379 |
if (c->type == SSH_CHANNEL_DYNAMIC) { |
| 1333 |
c->type = SSH_CHANNEL_OPENING; |
1380 |
/* switch to the next state */ |
| 1334 |
port_open_helper(c, "direct-tcpip"); |
1381 |
c->type = SSH_CHANNEL_OPENING; |
|
|
1382 |
port_open_helper(c, "direct-tcpip"); |
| 1383 |
} else { |
| 1384 |
close(c->sock); |
| 1385 |
c->sock = c->rfd = c->wfd = c->efd = -1; |
| 1386 |
memset(&hints, 0, sizeof(hints)); |
| 1387 |
hints.ai_family = IPv4or6; |
| 1388 |
hints.ai_socktype = SOCK_STREAM; |
| 1389 |
snprintf(strport, sizeof strport, "%d", c->host_port); |
| 1390 |
if ((gaierr = getaddrinfo(c->path, strport, &hints, &cctx.aitop)) != 0) { |
| 1391 |
error("channel_pre_dynamic %.100s: unknown host (%s)", c->path, |
| 1392 |
ssh_gai_strerror(gaierr)); |
| 1393 |
buffer_clear(&c->input); |
| 1394 |
buffer_clear(&c->output); |
| 1395 |
if (compat20) |
| 1396 |
packet_start(SSH2_MSG_CHANNEL_CLOSE); |
| 1397 |
else |
| 1398 |
packet_start(SSH_MSG_CHANNEL_CLOSE); |
| 1399 |
packet_put_int(c->remote_id); |
| 1400 |
packet_send(); |
| 1401 |
c->flags |= CHAN_CLOSE_SENT; |
| 1402 |
c->type = SSH_CHANNEL_ABANDONED; |
| 1403 |
return; |
| 1404 |
} |
| 1405 |
|
| 1406 |
cctx.host = xstrdup(c->path); |
| 1407 |
cctx.port = c->host_port; |
| 1408 |
cctx.ai = cctx.aitop; |
| 1409 |
|
| 1410 |
if ((sock = connect_next(&cctx)) == -1) { |
| 1411 |
error("connect to %.100s port %d failed: %s", |
| 1412 |
c->path, c->host_port, strerror(errno)); |
| 1413 |
channel_connect_ctx_free(&cctx); |
| 1414 |
buffer_clear(&c->input); |
| 1415 |
buffer_clear(&c->output); |
| 1416 |
if (compat20) |
| 1417 |
packet_start(SSH2_MSG_CHANNEL_CLOSE); |
| 1418 |
else |
| 1419 |
packet_start(SSH_MSG_CHANNEL_CLOSE); |
| 1420 |
packet_put_int(c->remote_id); |
| 1421 |
packet_send(); |
| 1422 |
c->flags |= CHAN_CLOSE_SENT; |
| 1423 |
c->type = SSH_CHANNEL_ABANDONED; |
| 1424 |
return; |
| 1425 |
} |
| 1426 |
|
| 1427 |
c->type = SSH_CHANNEL_CONNECTING; |
| 1428 |
c->connect_ctx = cctx; |
| 1429 |
c->rfd = sock; |
| 1430 |
c->wfd = sock; |
| 1431 |
c->flags |= CHAN_RD_ACKD; |
| 1432 |
channel_register_fds(c, c->rfd, c->wfd, c->efd, 0, 1, 0); |
| 1433 |
FD_SET(c->sock, writeset); |
| 1434 |
} |
| 1335 |
} |
1435 |
} |
| 1336 |
} |
1436 |
} |
| 1337 |
|
1437 |
|
|
Lines 1587-1593
channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1587 |
static void |
1687 |
static void |
| 1588 |
channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) |
1688 |
channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) |
| 1589 |
{ |
1689 |
{ |
| 1590 |
int err = 0, sock; |
1690 |
int err = 0, sock, ackd = 0; |
| 1591 |
socklen_t sz = sizeof(err); |
1691 |
socklen_t sz = sizeof(err); |
| 1592 |
|
1692 |
|
| 1593 |
if (FD_ISSET(c->sock, writeset)) { |
1693 |
if (FD_ISSET(c->sock, writeset)) { |
|
Lines 1600-1615
channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1600 |
c->self, c->connect_ctx.host, c->connect_ctx.port); |
1700 |
c->self, c->connect_ctx.host, c->connect_ctx.port); |
| 1601 |
channel_connect_ctx_free(&c->connect_ctx); |
1701 |
channel_connect_ctx_free(&c->connect_ctx); |
| 1602 |
c->type = SSH_CHANNEL_OPEN; |
1702 |
c->type = SSH_CHANNEL_OPEN; |
| 1603 |
if (compat20) { |
1703 |
if (c->flags & CHAN_RD_ACKD) { |
| 1604 |
packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); |
1704 |
ackd = 1; |
| 1605 |
packet_put_int(c->remote_id); |
1705 |
c->flags &= ~CHAN_RD_ACKD; |
| 1606 |
packet_put_int(c->self); |
|
|
| 1607 |
packet_put_int(c->local_window); |
| 1608 |
packet_put_int(c->local_maxpacket); |
| 1609 |
} else { |
1706 |
} else { |
| 1610 |
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); |
1707 |
if (compat20) { |
| 1611 |
packet_put_int(c->remote_id); |
1708 |
packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); |
| 1612 |
packet_put_int(c->self); |
1709 |
packet_put_int(c->remote_id); |
|
|
1710 |
packet_put_int(c->self); |
| 1711 |
packet_put_int(c->local_window); |
| 1712 |
packet_put_int(c->local_maxpacket); |
| 1713 |
} else { |
| 1714 |
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); |
| 1715 |
packet_put_int(c->remote_id); |
| 1716 |
packet_put_int(c->self); |
| 1717 |
} |
| 1613 |
} |
1718 |
} |
| 1614 |
} else { |
1719 |
} else { |
| 1615 |
debug("channel %d: connection failed: %s", |
1720 |
debug("channel %d: connection failed: %s", |
|
Lines 1625-1645
channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
Link Here
|
| 1625 |
error("connect_to %.100s port %d: failed.", |
1730 |
error("connect_to %.100s port %d: failed.", |
| 1626 |
c->connect_ctx.host, c->connect_ctx.port); |
1731 |
c->connect_ctx.host, c->connect_ctx.port); |
| 1627 |
channel_connect_ctx_free(&c->connect_ctx); |
1732 |
channel_connect_ctx_free(&c->connect_ctx); |
| 1628 |
if (compat20) { |
1733 |
if (c->flags & CHAN_RD_ACKD) { |
| 1629 |
packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); |
1734 |
ackd = 1; |
|
|
1735 |
c->flags &= ~CHAN_RD_ACKD; |
| 1736 |
close(c->sock); |
| 1737 |
c->sock = c->rfd = c->wfd = c->efd = -1; |
| 1738 |
buffer_clear(&c->input); |
| 1739 |
buffer_clear(&c->output); |
| 1740 |
if (compat20) |
| 1741 |
packet_start(SSH2_MSG_CHANNEL_CLOSE); |
| 1742 |
else |
| 1743 |
packet_start(SSH_MSG_CHANNEL_CLOSE); |
| 1630 |
packet_put_int(c->remote_id); |
1744 |
packet_put_int(c->remote_id); |
| 1631 |
packet_put_int(SSH2_OPEN_CONNECT_FAILED); |
1745 |
packet_send(); |
| 1632 |
if (!(datafellows & SSH_BUG_OPENFAILURE)) { |
1746 |
c->flags |= CHAN_CLOSE_SENT; |
| 1633 |
packet_put_cstring(strerror(err)); |
1747 |
c->type = SSH_CHANNEL_ABANDONED; |
| 1634 |
packet_put_cstring(""); |
|
|
| 1635 |
} |
| 1636 |
} else { |
1748 |
} else { |
| 1637 |
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
1749 |
if (compat20) { |
| 1638 |
packet_put_int(c->remote_id); |
1750 |
packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); |
|
|
1751 |
packet_put_int(c->remote_id); |
| 1752 |
packet_put_int(SSH2_OPEN_CONNECT_FAILED); |
| 1753 |
if (!(datafellows & SSH_BUG_OPENFAILURE)) { |
| 1754 |
packet_put_cstring(strerror(err)); |
| 1755 |
packet_put_cstring(""); |
| 1756 |
} |
| 1757 |
} else { |
| 1758 |
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); |
| 1759 |
packet_put_int(c->remote_id); |
| 1760 |
} |
| 1639 |
} |
1761 |
} |
| 1640 |
chan_mark_dead(c); |
1762 |
if (!ackd) |
|
|
1763 |
chan_mark_dead(c); |
| 1641 |
} |
1764 |
} |
| 1642 |
packet_send(); |
1765 |
|
|
|
1766 |
if (!ackd) |
| 1767 |
packet_send(); |
| 1768 |
} |
| 1769 |
} |
| 1770 |
|
| 1771 |
static void |
| 1772 |
channel_post_rdynamic(Channel *c, fd_set *readset, fd_set *writeset) |
| 1773 |
{ |
| 1774 |
if (c->sock != -1) { |
| 1775 |
FD_SET(c->sock, readset); |
| 1776 |
FD_SET(c->sock, writeset); |
| 1643 |
} |
1777 |
} |
| 1644 |
} |
1778 |
} |
| 1645 |
|
1779 |
|
|
Lines 2024-2029
channel_handler_init_20(void)
Link Here
|
| 2024 |
channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; |
2158 |
channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; |
| 2025 |
channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; |
2159 |
channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; |
| 2026 |
channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; |
2160 |
channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; |
|
|
2161 |
channel_pre[SSH_CHANNEL_RDYNAMIC] = &channel_pre_dynamic; |
| 2027 |
channel_pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener; |
2162 |
channel_pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener; |
| 2028 |
channel_pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client; |
2163 |
channel_pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client; |
| 2029 |
|
2164 |
|
|
Lines 2036-2041
channel_handler_init_20(void)
Link Here
|
| 2036 |
channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; |
2171 |
channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener; |
| 2037 |
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; |
2172 |
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; |
| 2038 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
2173 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
|
|
2174 |
channel_post[SSH_CHANNEL_RDYNAMIC] = &channel_post_rdynamic; |
| 2039 |
channel_post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener; |
2175 |
channel_post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener; |
| 2040 |
channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client; |
2176 |
channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client; |
| 2041 |
} |
2177 |
} |
|
Lines 2052-2057
channel_handler_init_13(void)
Link Here
|
| 2052 |
channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; |
2188 |
channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining; |
| 2053 |
channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; |
2189 |
channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; |
| 2054 |
channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; |
2190 |
channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; |
|
|
2191 |
channel_pre[SSH_CHANNEL_RDYNAMIC] = &channel_pre_dynamic; |
| 2055 |
|
2192 |
|
| 2056 |
channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; |
2193 |
channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; |
| 2057 |
channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
2194 |
channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
|
Lines 2060-2065
channel_handler_init_13(void)
Link Here
|
| 2060 |
channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; |
2197 |
channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13; |
| 2061 |
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; |
2198 |
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; |
| 2062 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
2199 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
|
|
2200 |
channel_post[SSH_CHANNEL_RDYNAMIC] = &channel_post_rdynamic; |
| 2063 |
} |
2201 |
} |
| 2064 |
|
2202 |
|
| 2065 |
static void |
2203 |
static void |
|
Lines 2072-2077
channel_handler_init_15(void)
Link Here
|
| 2072 |
channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; |
2210 |
channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; |
| 2073 |
channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; |
2211 |
channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; |
| 2074 |
channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; |
2212 |
channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; |
|
|
2213 |
channel_pre[SSH_CHANNEL_RDYNAMIC] = &channel_pre_dynamic; |
| 2075 |
|
2214 |
|
| 2076 |
channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
2215 |
channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; |
| 2077 |
channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
2216 |
channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; |
|
Lines 2079-2084
channel_handler_init_15(void)
Link Here
|
| 2079 |
channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; |
2218 |
channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; |
| 2080 |
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; |
2219 |
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting; |
| 2081 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
2220 |
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open; |
|
|
2221 |
channel_post[SSH_CHANNEL_RDYNAMIC] = &channel_post_rdynamic; |
| 2082 |
} |
2222 |
} |
| 2083 |
|
2223 |
|
| 2084 |
static void |
2224 |
static void |
|
Lines 2234-2243
channel_output_poll(void)
Link Here
|
| 2234 |
*/ |
2374 |
*/ |
| 2235 |
if (compat13) { |
2375 |
if (compat13) { |
| 2236 |
if (c->type != SSH_CHANNEL_OPEN && |
2376 |
if (c->type != SSH_CHANNEL_OPEN && |
| 2237 |
c->type != SSH_CHANNEL_INPUT_DRAINING) |
2377 |
c->type != SSH_CHANNEL_INPUT_DRAINING && |
|
|
2378 |
c->type != SSH_CHANNEL_RDYNAMIC) |
| 2238 |
continue; |
2379 |
continue; |
| 2239 |
} else { |
2380 |
} else { |
| 2240 |
if (c->type != SSH_CHANNEL_OPEN) |
2381 |
if (c->type != SSH_CHANNEL_OPEN && |
|
|
2382 |
c->type != SSH_CHANNEL_RDYNAMIC) |
| 2241 |
continue; |
2383 |
continue; |
| 2242 |
} |
2384 |
} |
| 2243 |
if (compat20 && |
2385 |
if (compat20 && |
|
Lines 2362-2368
channel_input_data(int type, u_int32_t seq, void *ctxt)
Link Here
|
| 2362 |
|
2504 |
|
| 2363 |
/* Ignore any data for non-open channels (might happen on close) */ |
2505 |
/* Ignore any data for non-open channels (might happen on close) */ |
| 2364 |
if (c->type != SSH_CHANNEL_OPEN && |
2506 |
if (c->type != SSH_CHANNEL_OPEN && |
| 2365 |
c->type != SSH_CHANNEL_X11_OPEN) |
2507 |
c->type != SSH_CHANNEL_X11_OPEN && |
|
|
2508 |
c->type != SSH_CHANNEL_RDYNAMIC) |
| 2366 |
return 0; |
2509 |
return 0; |
| 2367 |
|
2510 |
|
| 2368 |
/* Get the data. */ |
2511 |
/* Get the data. */ |
|
Lines 3296-3301
open_listen_match_tcpip(ForwardPermission *allowed_open,
Link Here
|
| 3296 |
return 0; |
3439 |
return 0; |
| 3297 |
if (allowed_open->listen_port != requestedport) |
3440 |
if (allowed_open->listen_port != requestedport) |
| 3298 |
return 0; |
3441 |
return 0; |
|
|
3442 |
if (allowed_open->port_to_connect == 0 && |
| 3443 |
strcmp("socks", allowed_open->host_to_connect)==0 && |
| 3444 |
allowed_open->listen_port == requestedport) |
| 3445 |
return 1; |
| 3299 |
if (!translate && allowed_open->listen_host == NULL && |
3446 |
if (!translate && allowed_open->listen_host == NULL && |
| 3300 |
requestedhost == NULL) |
3447 |
requestedhost == NULL) |
| 3301 |
return 1; |
3448 |
return 1; |
|
Lines 3684-3690
connect_to(const char *name, int port, char *ctype, char *rname)
Link Here
|
| 3684 |
|
3831 |
|
| 3685 |
memset(&cctx, 0, sizeof(cctx)); |
3832 |
memset(&cctx, 0, sizeof(cctx)); |
| 3686 |
|
3833 |
|
| 3687 |
if (port == PORT_STREAMLOCAL) { |
3834 |
if (port == 0) { |
|
|
3835 |
sock = socket(AF_INET, SOCK_STREAM, 0); |
| 3836 |
c = channel_new(ctype, SSH_CHANNEL_RDYNAMIC, sock, sock, -1, |
| 3837 |
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1); |
| 3838 |
return c; |
| 3839 |
} else if (port == PORT_STREAMLOCAL) { |
| 3688 |
struct sockaddr_un *sunaddr; |
3840 |
struct sockaddr_un *sunaddr; |
| 3689 |
struct addrinfo *ai; |
3841 |
struct addrinfo *ai; |
| 3690 |
|
3842 |
|