version 1.127, 2001/06/26 20:14:11 |
version 1.128, 2001/07/09 05:58:47 |
|
|
int |
int |
main(int ac, char **av) |
main(int ac, char **av) |
{ |
{ |
int i, opt, optind, exit_status, ok; |
int i, opt, exit_status, ok; |
u_short fwd_port, fwd_host_port; |
u_short fwd_port, fwd_host_port; |
char *optarg, *p, *cp, buf[256]; |
char *p, *cp, buf[256]; |
struct stat st; |
struct stat st; |
struct passwd *pw; |
struct passwd *pw; |
int dummy; |
int dummy; |
|
|
/* Parse command-line arguments. */ |
/* Parse command-line arguments. */ |
host = NULL; |
host = NULL; |
|
|
for (optind = 1; optind < ac; optind++) { |
again: |
if (av[optind][0] != '-') { |
while ((opt = getopt(ac, av, |
if (host) |
"1246nfxXgpaAki:I:tvVqe:c:m:p:l:R:L:D:CNTo:sb:")) != -1) { |
break; |
|
if (strchr(av[optind], '@')) { |
|
p = xstrdup(av[optind]); |
|
cp = strchr(p, '@'); |
|
if(cp == NULL || cp == p) |
|
usage(); |
|
options.user = p; |
|
*cp = '\0'; |
|
host = ++cp; |
|
} else |
|
host = av[optind]; |
|
continue; |
|
} |
|
opt = av[optind][1]; |
|
if (!opt) |
|
usage(); |
|
if (strchr("eilcmpbILRDo", opt)) { /* options with arguments */ |
|
optarg = av[optind] + 2; |
|
if (strcmp(optarg, "") == 0) { |
|
if (optind >= ac - 1) |
|
usage(); |
|
optarg = av[++optind]; |
|
} |
|
} else { |
|
if (av[optind][2]) |
|
usage(); |
|
optarg = NULL; |
|
} |
|
switch (opt) { |
switch (opt) { |
case '1': |
case '1': |
options.protocol = SSH_PROTO_1; |
options.protocol = SSH_PROTO_1; |
|
|
#endif |
#endif |
case 'i': |
case 'i': |
if (stat(optarg, &st) < 0) { |
if (stat(optarg, &st) < 0) { |
fprintf(stderr, "Warning: Identity file %s does not exist.\n", |
fprintf(stderr, "Warning: Identity file %s " |
optarg); |
"does not exist.\n", optarg); |
break; |
break; |
} |
} |
if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) |
if (options.num_identity_files >= |
fatal("Too many identity files specified (max %d)", |
SSH_MAX_IDENTITY_FILES) |
SSH_MAX_IDENTITY_FILES); |
fatal("Too many identity files specified " |
options.identity_files[options.num_identity_files++] = xstrdup(optarg); |
"(max %d)", SSH_MAX_IDENTITY_FILES); |
|
options.identity_files[options.num_identity_files++] = |
|
xstrdup(optarg); |
break; |
break; |
case 'I': |
case 'I': |
#ifdef SMARTCARD |
#ifdef SMARTCARD |
|
|
} else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { |
} else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { |
options.log_level++; |
options.log_level++; |
break; |
break; |
} else { |
} else |
fatal("Too high debugging level."); |
fatal("Too high debugging level."); |
} |
|
/* fallthrough */ |
/* fallthrough */ |
case 'V': |
case 'V': |
fprintf(stderr, |
fprintf(stderr, |
|
|
break; |
break; |
case 'e': |
case 'e': |
if (optarg[0] == '^' && optarg[2] == 0 && |
if (optarg[0] == '^' && optarg[2] == 0 && |
(u_char) optarg[1] >= 64 && (u_char) optarg[1] < 128) |
(u_char) optarg[1] >= 64 && |
|
(u_char) optarg[1] < 128) |
options.escape_char = (u_char) optarg[1] & 31; |
options.escape_char = (u_char) optarg[1] & 31; |
else if (strlen(optarg) == 1) |
else if (strlen(optarg) == 1) |
options.escape_char = (u_char) optarg[0]; |
options.escape_char = (u_char) optarg[0]; |
else if (strcmp(optarg, "none") == 0) |
else if (strcmp(optarg, "none") == 0) |
options.escape_char = SSH_ESCAPECHAR_NONE; |
options.escape_char = SSH_ESCAPECHAR_NONE; |
else { |
else { |
fprintf(stderr, "Bad escape character '%s'.\n", optarg); |
fprintf(stderr, "Bad escape character '%s'.\n", |
|
optarg); |
exit(1); |
exit(1); |
} |
} |
break; |
break; |
|
|
/* SSH1 only */ |
/* SSH1 only */ |
options.cipher = cipher_number(optarg); |
options.cipher = cipher_number(optarg); |
if (options.cipher == -1) { |
if (options.cipher == -1) { |
fprintf(stderr, "Unknown cipher type '%s'\n", optarg); |
fprintf(stderr, |
|
"Unknown cipher type '%s'\n", |
|
optarg); |
exit(1); |
exit(1); |
} |
} |
if (options.cipher == SSH_CIPHER_3DES) { |
if (options.cipher == SSH_CIPHER_3DES) |
options.ciphers = "3des-cbc"; |
options.ciphers = "3des-cbc"; |
} else if (options.cipher == SSH_CIPHER_BLOWFISH) { |
else if (options.cipher == SSH_CIPHER_BLOWFISH) |
options.ciphers = "blowfish-cbc"; |
options.ciphers = "blowfish-cbc"; |
} else { |
else |
options.ciphers = (char *)-1; |
options.ciphers = (char *)-1; |
} |
|
} |
} |
break; |
break; |
case 'm': |
case 'm': |
if (mac_valid(optarg)) |
if (mac_valid(optarg)) |
options.macs = xstrdup(optarg); |
options.macs = xstrdup(optarg); |
else { |
else { |
fprintf(stderr, "Unknown mac type '%s'\n", optarg); |
fprintf(stderr, "Unknown mac type '%s'\n", |
|
optarg); |
exit(1); |
exit(1); |
} |
} |
break; |
break; |
|
|
&fwd_host_port) != 3 && |
&fwd_host_port) != 3 && |
sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, |
sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, |
&fwd_host_port) != 3) { |
&fwd_host_port) != 3) { |
fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); |
fprintf(stderr, |
|
"Bad forwarding specification '%s'.\n", |
|
optarg); |
usage(); |
usage(); |
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
add_remote_forward(&options, fwd_port, buf, fwd_host_port); |
add_remote_forward(&options, fwd_port, buf, |
|
fwd_host_port); |
break; |
break; |
case 'L': |
case 'L': |
if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, |
if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, |
&fwd_host_port) != 3 && |
&fwd_host_port) != 3 && |
sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, |
sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, |
&fwd_host_port) != 3) { |
&fwd_host_port) != 3) { |
fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); |
fprintf(stderr, |
|
"Bad forwarding specification '%s'.\n", |
|
optarg); |
usage(); |
usage(); |
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
add_local_forward(&options, fwd_port, buf, fwd_host_port); |
add_local_forward(&options, fwd_port, buf, |
|
fwd_host_port); |
break; |
break; |
|
|
case 'D': |
case 'D': |
fwd_port = a2port(optarg); |
fwd_port = a2port(optarg); |
if (fwd_port == 0) { |
if (fwd_port == 0) { |
fprintf(stderr, "Bad dynamic port '%s'\n", optarg); |
fprintf(stderr, "Bad dynamic port '%s'\n", |
|
optarg); |
exit(1); |
exit(1); |
} |
} |
add_local_forward(&options, fwd_port, "socks4", 0); |
add_local_forward(&options, fwd_port, "socks4", 0); |
|
|
break; |
break; |
case 'o': |
case 'o': |
dummy = 1; |
dummy = 1; |
if (process_config_line(&options, host ? host : "", optarg, |
if (process_config_line(&options, host ? host : "", |
"command-line", 0, &dummy) != 0) |
optarg, "command-line", 0, &dummy) != 0) |
exit(1); |
exit(1); |
break; |
break; |
case 's': |
case 's': |
|
|
} |
} |
} |
} |
|
|
|
ac -= optind; |
|
av += optind; |
|
|
|
if (ac > 0 && !host && **av != '-') { |
|
if (strchr(*av, '@')) { |
|
p = xstrdup(*av); |
|
cp = strchr(p, '@'); |
|
if (cp == NULL || cp == p) |
|
usage(); |
|
options.user = p; |
|
*cp = '\0'; |
|
host = ++cp; |
|
} else |
|
host = *av; |
|
ac--, av++; |
|
if (ac > 0) { |
|
optind = 0; |
|
optreset = 1; |
|
goto again; |
|
} |
|
} |
|
|
/* Check that we got a host name. */ |
/* Check that we got a host name. */ |
if (!host) |
if (!host) |
usage(); |
usage(); |
|
|
* is no limit on the length of the command, except by the maximum |
* is no limit on the length of the command, except by the maximum |
* packet size. Also sets the tty flag if there is no command. |
* packet size. Also sets the tty flag if there is no command. |
*/ |
*/ |
if (optind == ac) { |
if (!ac) { |
/* No command specified - execute shell on a tty. */ |
/* No command specified - execute shell on a tty. */ |
tty_flag = 1; |
tty_flag = 1; |
if (subsystem_flag) { |
if (subsystem_flag) { |
fprintf(stderr, "You must specify a subsystem to invoke.\n"); |
fprintf(stderr, |
|
"You must specify a subsystem to invoke.\n"); |
usage(); |
usage(); |
} |
} |
} else { |
} else { |
/* A command has been specified. Store it into the |
/* A command has been specified. Store it into the buffer. */ |
buffer. */ |
for (i = 0; i < ac; i++) { |
for (i = optind; i < ac; i++) { |
if (i) |
if (i > optind) |
|
buffer_append(&command, " ", 1); |
buffer_append(&command, " ", 1); |
buffer_append(&command, av[i], strlen(av[i])); |
buffer_append(&command, av[i], strlen(av[i])); |
} |
} |