|
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 |
if (listen_host == NULL) |
| 213 |
fwd->host = xstrdup(host); |
214 |
fwd->listen_host = NULL; |
| 214 |
fwd->host_port = host_port; |
215 |
else |
|
|
216 |
fwd->listen_host = xstrdup(listen_host); |
| 217 |
fwd->listen_port = listen_port; |
| 218 |
fwd->connect_host = xstrdup(connect_host); |
| 219 |
fwd->connect_port = connect_port; |
| 215 |
} |
220 |
} |
| 216 |
|
221 |
|
| 217 |
/* |
222 |
/* |
|
Lines 220-236
Link Here
|
| 220 |
*/ |
225 |
*/ |
| 221 |
|
226 |
|
| 222 |
void |
227 |
void |
| 223 |
add_remote_forward(Options *options, u_short port, const char *host, |
228 |
add_remote_forward(Options *options, const char *listen_host, |
| 224 |
u_short host_port) |
229 |
u_short listen_port, const char *connect_host, |
|
|
230 |
u_short connect_port) |
| 225 |
{ |
231 |
{ |
| 226 |
Forward *fwd; |
232 |
Forward *fwd; |
| 227 |
if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) |
233 |
if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) |
| 228 |
fatal("Too many remote forwards (max %d).", |
234 |
fatal("Too many remote forwards (max %d).", |
| 229 |
SSH_MAX_FORWARDS_PER_DIRECTION); |
235 |
SSH_MAX_FORWARDS_PER_DIRECTION); |
| 230 |
fwd = &options->remote_forwards[options->num_remote_forwards++]; |
236 |
fwd = &options->remote_forwards[options->num_remote_forwards++]; |
| 231 |
fwd->port = port; |
237 |
if (listen_host == NULL) |
| 232 |
fwd->host = xstrdup(host); |
238 |
fwd->listen_host = NULL; |
| 233 |
fwd->host_port = host_port; |
239 |
else |
|
|
240 |
fwd->listen_host = xstrdup(listen_host); |
| 241 |
fwd->listen_port = listen_port; |
| 242 |
fwd->connect_host = xstrdup(connect_host); |
| 243 |
fwd->connect_port = connect_port; |
| 234 |
} |
244 |
} |
| 235 |
|
245 |
|
| 236 |
static void |
246 |
static void |
|
Lines 238-248
Link Here
|
| 238 |
{ |
248 |
{ |
| 239 |
int i; |
249 |
int i; |
| 240 |
|
250 |
|
| 241 |
for (i = 0; i < options->num_local_forwards; i++) |
251 |
for (i = 0; i < options->num_local_forwards; i++) { |
| 242 |
xfree(options->local_forwards[i].host); |
252 |
xfree(options->local_forwards[i].listen_host); |
|
|
253 |
xfree(options->local_forwards[i].connect_host); |
| 254 |
} |
| 243 |
options->num_local_forwards = 0; |
255 |
options->num_local_forwards = 0; |
| 244 |
for (i = 0; i < options->num_remote_forwards; i++) |
256 |
for (i = 0; i < options->num_remote_forwards; i++) { |
| 245 |
xfree(options->remote_forwards[i].host); |
257 |
xfree(options->remote_forwards[i].listen_host); |
|
|
258 |
xfree(options->remote_forwards[i].connect_host); |
| 259 |
} |
| 246 |
options->num_remote_forwards = 0; |
260 |
options->num_remote_forwards = 0; |
| 247 |
} |
261 |
} |
| 248 |
|
262 |
|
|
Lines 274-283
Link Here
|
| 274 |
char *line, const char *filename, int linenum, |
288 |
char *line, const char *filename, int linenum, |
| 275 |
int *activep) |
289 |
int *activep) |
| 276 |
{ |
290 |
{ |
| 277 |
char buf[256], *s, *string, **charptr, *endofnumber, *keyword, *arg; |
291 |
char *s, *string, **charptr, *endofnumber, *keyword, *arg, *arg2, |
|
|
292 |
*fwdarg; |
| 278 |
int opcode, *intptr, value; |
293 |
int opcode, *intptr, value; |
| 279 |
u_short fwd_port, fwd_host_port; |
294 |
Forward fwd; |
| 280 |
char sfwd_host_port[6]; |
295 |
size_t size; |
| 281 |
|
296 |
|
| 282 |
s = line; |
297 |
s = line; |
| 283 |
/* Get the keyword. (Each line is supposed to begin with a keyword). */ |
298 |
/* Get the keyword. (Each line is supposed to begin with a keyword). */ |
|
Lines 597-623
Link Here
|
| 597 |
if (!arg || *arg == '\0') |
612 |
if (!arg || *arg == '\0') |
| 598 |
fatal("%.200s line %d: Missing port argument.", |
613 |
fatal("%.200s line %d: Missing port argument.", |
| 599 |
filename, linenum); |
614 |
filename, linenum); |
| 600 |
if ((fwd_port = a2port(arg)) == 0) |
615 |
arg2 = strdelim(&s); |
| 601 |
fatal("%.200s line %d: Bad listen port.", |
616 |
if (!arg2 || *arg2 == '\0') |
| 602 |
filename, linenum); |
|
|
| 603 |
arg = strdelim(&s); |
| 604 |
if (!arg || *arg == '\0') |
| 605 |
fatal("%.200s line %d: Missing second argument.", |
617 |
fatal("%.200s line %d: Missing second argument.", |
| 606 |
filename, linenum); |
618 |
filename, linenum); |
| 607 |
if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && |
619 |
|
| 608 |
sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2) |
620 |
/* construct a string for parse_forward */ |
|
|
621 |
size = strlen(arg) + strlen(arg2) + 2; |
| 622 |
fwdarg = (char *)xmalloc(size); |
| 623 |
strncat(fwdarg, arg, size); |
| 624 |
strncat(fwdarg, " ", size); |
| 625 |
strncat(fwdarg, arg2, size); |
| 626 |
|
| 627 |
if (parse_forward(&fwd, fwdarg) == 0) |
| 609 |
fatal("%.200s line %d: Bad forwarding specification.", |
628 |
fatal("%.200s line %d: Bad forwarding specification.", |
| 610 |
filename, linenum); |
629 |
filename, linenum); |
| 611 |
if ((fwd_host_port = a2port(sfwd_host_port)) == 0) |
630 |
if (fwd.listen_port == 0) |
|
|
631 |
fatal("%.200s line %d: Bad listen port.", |
| 632 |
filename, linenum); |
| 633 |
if (fwd.connect_port == 0) |
| 612 |
fatal("%.200s line %d: Bad forwarding port.", |
634 |
fatal("%.200s line %d: Bad forwarding port.", |
| 613 |
filename, linenum); |
635 |
filename, linenum); |
|
|
636 |
|
| 614 |
if (*activep) { |
637 |
if (*activep) { |
| 615 |
if (opcode == oLocalForward) |
638 |
if (opcode == oLocalForward) |
| 616 |
add_local_forward(options, fwd_port, buf, |
639 |
add_local_forward(options, |
| 617 |
fwd_host_port); |
640 |
fwd.listen_host, fwd.listen_port, |
|
|
641 |
fwd.connect_host, fwd.connect_port); |
| 618 |
else if (opcode == oRemoteForward) |
642 |
else if (opcode == oRemoteForward) |
| 619 |
add_remote_forward(options, fwd_port, buf, |
643 |
add_remote_forward(options, |
| 620 |
fwd_host_port); |
644 |
fwd.listen_host, fwd.listen_port, |
|
|
645 |
fwd.connect_host, fwd.connect_port); |
| 621 |
} |
646 |
} |
| 622 |
break; |
647 |
break; |
| 623 |
|
648 |
|
|
Lines 626-637
Link Here
|
| 626 |
if (!arg || *arg == '\0') |
651 |
if (!arg || *arg == '\0') |
| 627 |
fatal("%.200s line %d: Missing port argument.", |
652 |
fatal("%.200s line %d: Missing port argument.", |
| 628 |
filename, linenum); |
653 |
filename, linenum); |
| 629 |
fwd_port = a2port(arg); |
654 |
fwd.listen_port = 0; |
| 630 |
if (fwd_port == 0) |
655 |
fwd.listen_host = hpdelim(&arg); |
|
|
656 |
if (!fwd.listen_host) |
| 657 |
fatal("%.200s line %d: Bad forwarding specification.", |
| 658 |
filename, linenum); |
| 659 |
if (arg) { |
| 660 |
fwd.listen_port = a2port(arg); |
| 661 |
fwd.listen_host = cleanhostname(fwd.listen_host); |
| 662 |
} else { |
| 663 |
fwd.listen_port = a2port(fwd.listen_host); |
| 664 |
fwd.listen_host = ""; |
| 665 |
} |
| 666 |
if (fwd.listen_port == 0) |
| 631 |
fatal("%.200s line %d: Badly formatted port number.", |
667 |
fatal("%.200s line %d: Badly formatted port number.", |
| 632 |
filename, linenum); |
668 |
filename, linenum); |
| 633 |
if (*activep) |
669 |
if (*activep) |
| 634 |
add_local_forward(options, fwd_port, "socks4", 0); |
670 |
add_local_forward(options, fwd.listen_host, |
|
|
671 |
fwd.listen_port, "socks4", 0); |
| 635 |
break; |
672 |
break; |
| 636 |
|
673 |
|
| 637 |
case oClearAllForwardings: |
674 |
case oClearAllForwardings: |
|
Lines 921-924
Link Here
|
| 921 |
/* options->hostname will be set in the main program if appropriate */ |
958 |
/* options->hostname will be set in the main program if appropriate */ |
| 922 |
/* options->host_key_alias should not be set by default */ |
959 |
/* options->host_key_alias should not be set by default */ |
| 923 |
/* options->preferred_authentications will be set in ssh */ |
960 |
/* options->preferred_authentications will be set in ssh */ |
|
|
961 |
} |
| 962 |
|
| 963 |
/* |
| 964 |
* parse_forward |
| 965 |
* parses a string containing a port forwarding specification of the form: |
| 966 |
* [listenhost:]listenport:connecthost:connectport |
| 967 |
* returns number of arguments parsed or zero on error |
| 968 |
*/ |
| 969 |
int |
| 970 |
parse_forward(Forward *fwd, const char *fwdspec) |
| 971 |
{ |
| 972 |
int i; |
| 973 |
char *p, *cp, *fwdarg[4]; |
| 974 |
|
| 975 |
cp = p = xstrdup(fwdspec); |
| 976 |
|
| 977 |
/* skip leading spaces */ |
| 978 |
while (*cp && isspace(*cp)) |
| 979 |
cp++; |
| 980 |
|
| 981 |
for (i = 0; i < 4; ++i) |
| 982 |
if ( !(fwdarg[i] = hpdelim(&cp)) ) |
| 983 |
break; |
| 984 |
switch(i) { |
| 985 |
case 3: |
| 986 |
fwd->listen_host = NULL; |
| 987 |
fwd->listen_port = a2port(fwdarg[0]); |
| 988 |
fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); |
| 989 |
fwd->connect_port = a2port(fwdarg[2]); |
| 990 |
break; |
| 991 |
|
| 992 |
case 4: |
| 993 |
fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); |
| 994 |
fwd->listen_port = a2port(fwdarg[1]); |
| 995 |
fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); |
| 996 |
fwd->connect_port = a2port(fwdarg[3]); |
| 997 |
break; |
| 998 |
default: |
| 999 |
i = 0; /* failure */ |
| 1000 |
} |
| 1001 |
|
| 1002 |
xfree(p); |
| 1003 |
|
| 1004 |
if (fwd->listen_port == 0 && fwd->connect_port == 0) |
| 1005 |
i = 0; /* failure */ |
| 1006 |
|
| 1007 |
return(i); |
| 924 |
} |
1008 |
} |