|
Lines 197-217
Link Here
|
| 197 |
*/ |
197 |
*/ |
| 198 |
|
198 |
|
| 199 |
void |
199 |
void |
| 200 |
add_local_forward(Options *options, u_short port, const char *host, |
200 |
add_local_forward(Options *options, const char *listen_host, |
| 201 |
u_short host_port) |
201 |
u_short listen_port, const char *connect_host, |
|
|
202 |
u_short connect_port) |
| 202 |
{ |
203 |
{ |
| 203 |
Forward *fwd; |
204 |
Forward *fwd; |
| 204 |
#ifndef NO_IPPORT_RESERVED_CONCEPT |
205 |
#ifndef NO_IPPORT_RESERVED_CONCEPT |
| 205 |
extern uid_t original_real_uid; |
206 |
extern uid_t original_real_uid; |
| 206 |
if (port < IPPORT_RESERVED && original_real_uid != 0) |
207 |
if (listen_port < IPPORT_RESERVED && original_real_uid != 0) |
| 207 |
fatal("Privileged ports can only be forwarded by root."); |
208 |
fatal("Privileged ports can only be forwarded by root."); |
| 208 |
#endif |
209 |
#endif |
| 209 |
if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) |
210 |
if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) |
| 210 |
fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); |
211 |
fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); |
| 211 |
fwd = &options->local_forwards[options->num_local_forwards++]; |
212 |
fwd = &options->local_forwards[options->num_local_forwards++]; |
| 212 |
fwd->port = port; |
213 |
fwd->listen_host = xstrdup(listen_host); |
| 213 |
fwd->host = xstrdup(host); |
214 |
fwd->listen_port = listen_port; |
| 214 |
fwd->host_port = host_port; |
215 |
fwd->connect_host = xstrdup(connect_host); |
|
|
216 |
fwd->connect_port = connect_port; |
| 215 |
} |
217 |
} |
| 216 |
|
218 |
|
| 217 |
/* |
219 |
/* |
|
Lines 220-236
Link Here
|
| 220 |
*/ |
222 |
*/ |
| 221 |
|
223 |
|
| 222 |
void |
224 |
void |
| 223 |
add_remote_forward(Options *options, u_short port, const char *host, |
225 |
add_remote_forward(Options *options, const char *listen_host, |
| 224 |
u_short host_port) |
226 |
u_short listen_port, const char *connect_host, |
|
|
227 |
u_short connect_port) |
| 225 |
{ |
228 |
{ |
| 226 |
Forward *fwd; |
229 |
Forward *fwd; |
| 227 |
if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) |
230 |
if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) |
| 228 |
fatal("Too many remote forwards (max %d).", |
231 |
fatal("Too many remote forwards (max %d).", |
| 229 |
SSH_MAX_FORWARDS_PER_DIRECTION); |
232 |
SSH_MAX_FORWARDS_PER_DIRECTION); |
| 230 |
fwd = &options->remote_forwards[options->num_remote_forwards++]; |
233 |
fwd = &options->remote_forwards[options->num_remote_forwards++]; |
| 231 |
fwd->port = port; |
234 |
fwd->listen_host = xstrdup(listen_host); |
| 232 |
fwd->host = xstrdup(host); |
235 |
fwd->listen_port = listen_port; |
| 233 |
fwd->host_port = host_port; |
236 |
fwd->connect_host = xstrdup(connect_host); |
|
|
237 |
fwd->connect_port = connect_port; |
| 234 |
} |
238 |
} |
| 235 |
|
239 |
|
| 236 |
static void |
240 |
static void |
|
Lines 238-248
Link Here
|
| 238 |
{ |
242 |
{ |
| 239 |
int i; |
243 |
int i; |
| 240 |
|
244 |
|
| 241 |
for (i = 0; i < options->num_local_forwards; i++) |
245 |
for (i = 0; i < options->num_local_forwards; i++) { |
| 242 |
xfree(options->local_forwards[i].host); |
246 |
xfree(options->local_forwards[i].listen_host); |
|
|
247 |
xfree(options->local_forwards[i].connect_host); |
| 248 |
} |
| 243 |
options->num_local_forwards = 0; |
249 |
options->num_local_forwards = 0; |
| 244 |
for (i = 0; i < options->num_remote_forwards; i++) |
250 |
for (i = 0; i < options->num_remote_forwards; i++) { |
| 245 |
xfree(options->remote_forwards[i].host); |
251 |
xfree(options->remote_forwards[i].listen_host); |
|
|
252 |
xfree(options->remote_forwards[i].connect_host); |
| 253 |
} |
| 246 |
options->num_remote_forwards = 0; |
254 |
options->num_remote_forwards = 0; |
| 247 |
} |
255 |
} |
| 248 |
|
256 |
|
|
Lines 274-283
Link Here
|
| 274 |
char *line, const char *filename, int linenum, |
282 |
char *line, const char *filename, int linenum, |
| 275 |
int *activep) |
283 |
int *activep) |
| 276 |
{ |
284 |
{ |
| 277 |
char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg; |
285 |
char *s, *string, **charptr, *endofnumber, *keyword, *arg, *arg2; |
| 278 |
int opcode, *intptr, value; |
286 |
int opcode, *intptr, value, i; |
| 279 |
u_short fwd_port, fwd_host_port; |
287 |
u_short fwd_lport, fwd_cport; |
| 280 |
char sfwd_host_port[6]; |
288 |
char *fwd_lhost, *fwd_chost, *fwdarg[4]; |
| 281 |
|
289 |
|
| 282 |
s = line; |
290 |
s = line; |
| 283 |
/* Get the keyword. (Each line is supposed to begin with a keyword). */ |
291 |
/* Get the keyword. (Each line is supposed to begin with a keyword). */ |
|
Lines 597-623
Link Here
|
| 597 |
if (!arg || *arg == '\0') |
605 |
if (!arg || *arg == '\0') |
| 598 |
fatal("%.200s line %d: Missing port argument.", |
606 |
fatal("%.200s line %d: Missing port argument.", |
| 599 |
filename, linenum); |
607 |
filename, linenum); |
| 600 |
if ((fwd_port = a2port(arg)) == 0) |
608 |
arg2 = strdelim(&s); /* optional second arg */ |
| 601 |
fatal("%.200s line %d: Bad listen port.", |
609 |
|
| 602 |
filename, linenum); |
610 |
for (i = 0; i < 4; ++i) { |
| 603 |
arg = strdelim(&s); |
611 |
fwdarg[i] = hpdelim(&arg); |
| 604 |
if (!arg || *arg == '\0') |
612 |
if (!fwdarg[i]) |
| 605 |
fatal("%.200s line %d: Missing second argument.", |
613 |
break; |
| 606 |
filename, linenum); |
614 |
if (i<2 && !arg && arg2) { |
| 607 |
if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && |
615 |
arg = arg2; |
| 608 |
sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2) |
616 |
arg2 = NULL; |
|
|
617 |
} |
| 618 |
} |
| 619 |
switch(i) { |
| 620 |
case 3: |
| 621 |
fwd_lhost = ""; |
| 622 |
fwd_lport = a2port(fwdarg[0]); |
| 623 |
fwd_chost = cleanhostname(fwdarg[1]); |
| 624 |
fwd_cport = a2port(fwdarg[2]); |
| 625 |
break; |
| 626 |
case 4: |
| 627 |
fwd_lhost = cleanhostname(fwdarg[0]); |
| 628 |
fwd_lport = a2port(fwdarg[1]); |
| 629 |
fwd_chost = cleanhostname(fwdarg[2]); |
| 630 |
fwd_cport = a2port(fwdarg[3]); |
| 631 |
|
| 632 |
break; |
| 633 |
default: |
| 609 |
fatal("%.200s line %d: Bad forwarding specification.", |
634 |
fatal("%.200s line %d: Bad forwarding specification.", |
| 610 |
filename, linenum); |
635 |
filename, linenum); |
| 611 |
if ((fwd_host_port = a2port(sfwd_host_port)) == 0) |
636 |
/* NOTREACHED */ |
|
|
637 |
} |
| 638 |
|
| 639 |
if (fwd_lport == 0) |
| 640 |
fatal("%.200s line %d: Bad listen port.", |
| 641 |
filename, linenum); |
| 642 |
if (fwd_cport == 0) |
| 612 |
fatal("%.200s line %d: Bad forwarding port.", |
643 |
fatal("%.200s line %d: Bad forwarding port.", |
| 613 |
filename, linenum); |
644 |
filename, linenum); |
|
|
645 |
|
| 614 |
if (*activep) { |
646 |
if (*activep) { |
| 615 |
if (opcode == oLocalForward) |
647 |
if (opcode == oLocalForward) |
| 616 |
add_local_forward(options, fwd_port, buf, |
648 |
add_local_forward(options, |
| 617 |
fwd_host_port); |
649 |
fwd_lhost, fwd_lport, |
|
|
650 |
fwd_chost, fwd_cport); |
| 618 |
else if (opcode == oRemoteForward) |
651 |
else if (opcode == oRemoteForward) |
| 619 |
add_remote_forward(options, fwd_port, buf, |
652 |
add_remote_forward(options, |
| 620 |
fwd_host_port); |
653 |
fwd_lhost, fwd_lport, |
|
|
654 |
fwd_chost, fwd_cport); |
| 621 |
} |
655 |
} |
| 622 |
break; |
656 |
break; |
| 623 |
|
657 |
|
|
Lines 626-637
Link Here
|
| 626 |
if (!arg || *arg == '\0') |
660 |
if (!arg || *arg == '\0') |
| 627 |
fatal("%.200s line %d: Missing port argument.", |
661 |
fatal("%.200s line %d: Missing port argument.", |
| 628 |
filename, linenum); |
662 |
filename, linenum); |
| 629 |
fwd_port = a2port(arg); |
663 |
fwd_lport = 0; |
| 630 |
if (fwd_port == 0) |
664 |
fwd_lhost = hpdelim(&arg); |
|
|
665 |
if (!fwd_lhost) |
| 666 |
fatal("%.200s line %d: Bad forwarding specification.", |
| 667 |
filename, linenum); |
| 668 |
if (arg) { |
| 669 |
fwd_lport = a2port(arg); |
| 670 |
fwd_lhost = cleanhostname(fwd_lhost); |
| 671 |
} else { |
| 672 |
fwd_lport = a2port(fwd_lhost); |
| 673 |
fwd_lhost = ""; |
| 674 |
} |
| 675 |
if (fwd_lport == 0) |
| 631 |
fatal("%.200s line %d: Badly formatted port number.", |
676 |
fatal("%.200s line %d: Badly formatted port number.", |
| 632 |
filename, linenum); |
677 |
filename, linenum); |
| 633 |
if (*activep) |
678 |
if (*activep) |
| 634 |
add_local_forward(options, fwd_port, "socks4", 0); |
679 |
add_local_forward(options, fwd_lhost, fwd_lport, |
|
|
680 |
"socks4", 0); |
| 635 |
break; |
681 |
break; |
| 636 |
|
682 |
|
| 637 |
case oClearAllForwardings: |
683 |
case oClearAllForwardings: |
|
Lines 921-924
Link Here
|
| 921 |
/* options->hostname will be set in the main program if appropriate */ |
967 |
/* options->hostname will be set in the main program if appropriate */ |
| 922 |
/* options->host_key_alias should not be set by default */ |
968 |
/* options->host_key_alias should not be set by default */ |
| 923 |
/* options->preferred_authentications will be set in ssh */ |
969 |
/* options->preferred_authentications will be set in ssh */ |
|
|
970 |
} |
| 971 |
|
| 972 |
/* |
| 973 |
* parse_forward |
| 974 |
* parses a string containing a port forwarding specification of the form: |
| 975 |
* [listenhost:]listenport:connecthost:connectport |
| 976 |
* returns number of arguments parsed or zero on error |
| 977 |
*/ |
| 978 |
int |
| 979 |
parse_forward(Forward *fwd, const char *fwdspec) |
| 980 |
{ |
| 981 |
int i; |
| 982 |
char *p, *cp, *fwdarg[4]; |
| 983 |
|
| 984 |
cp = p = xstrdup(fwdspec); |
| 985 |
|
| 986 |
/* skip leading spaces */ |
| 987 |
while (*cp && isspace(*cp)) |
| 988 |
cp++; |
| 989 |
|
| 990 |
for (i = 0; i < 4; ++i) |
| 991 |
if ( !(fwdarg[i] = hpdelim(&cp)) ) |
| 992 |
break; |
| 993 |
switch(i) { |
| 994 |
case 3: |
| 995 |
fwd->listen_host = xstrdup(""); |
| 996 |
fwd->listen_port = a2port(fwdarg[0]); |
| 997 |
fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); |
| 998 |
fwd->connect_port = a2port(fwdarg[2]); |
| 999 |
break; |
| 1000 |
|
| 1001 |
case 4: |
| 1002 |
fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); |
| 1003 |
fwd->listen_port = a2port(fwdarg[1]); |
| 1004 |
fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); |
| 1005 |
fwd->connect_port = a2port(fwdarg[3]); |
| 1006 |
break; |
| 1007 |
default: |
| 1008 |
i = 0; /* failure */ |
| 1009 |
} |
| 1010 |
|
| 1011 |
xfree(p); |
| 1012 |
|
| 1013 |
if (fwd->listen_port == 0 && fwd->connect_port == 0) |
| 1014 |
i = 0; /* failure */ |
| 1015 |
|
| 1016 |
return(i); |
| 924 |
} |
1017 |
} |