diff options
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 132 |
1 files changed, 69 insertions, 63 deletions
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: ssh.c,v 1.127 2001/06/26 20:14:11 markus Exp $"); | 42 | RCSID("$OpenBSD: ssh.c,v 1.128 2001/07/09 05:58:47 fgsch Exp $"); |
43 | 43 | ||
44 | #include <openssl/evp.h> | 44 | #include <openssl/evp.h> |
45 | #include <openssl/err.h> | 45 | #include <openssl/err.h> |
@@ -252,9 +252,9 @@ static void load_public_identity_files(void); | |||
252 | int | 252 | int |
253 | main(int ac, char **av) | 253 | main(int ac, char **av) |
254 | { | 254 | { |
255 | int i, opt, optind, exit_status, ok; | 255 | int i, opt, exit_status, ok; |
256 | u_short fwd_port, fwd_host_port; | 256 | u_short fwd_port, fwd_host_port; |
257 | char *optarg, *p, *cp, buf[256]; | 257 | char *p, *cp, buf[256]; |
258 | struct stat st; | 258 | struct stat st; |
259 | struct passwd *pw; | 259 | struct passwd *pw; |
260 | int dummy; | 260 | int dummy; |
@@ -311,37 +311,9 @@ main(int ac, char **av) | |||
311 | /* Parse command-line arguments. */ | 311 | /* Parse command-line arguments. */ |
312 | host = NULL; | 312 | host = NULL; |
313 | 313 | ||
314 | for (optind = 1; optind < ac; optind++) { | 314 | again: |
315 | if (av[optind][0] != '-') { | 315 | while ((opt = getopt(ac, av, |
316 | if (host) | 316 | "1246nfxXgpaAki:I:tvVqe:c:m:p:l:R:L:D:CNTo:sb:")) != -1) { |
317 | break; | ||
318 | if (strchr(av[optind], '@')) { | ||
319 | p = xstrdup(av[optind]); | ||
320 | cp = strchr(p, '@'); | ||
321 | if(cp == NULL || cp == p) | ||
322 | usage(); | ||
323 | options.user = p; | ||
324 | *cp = '\0'; | ||
325 | host = ++cp; | ||
326 | } else | ||
327 | host = av[optind]; | ||
328 | continue; | ||
329 | } | ||
330 | opt = av[optind][1]; | ||
331 | if (!opt) | ||
332 | usage(); | ||
333 | if (strchr("eilcmpbILRDo", opt)) { /* options with arguments */ | ||
334 | optarg = av[optind] + 2; | ||
335 | if (strcmp(optarg, "") == 0) { | ||
336 | if (optind >= ac - 1) | ||
337 | usage(); | ||
338 | optarg = av[++optind]; | ||
339 | } | ||
340 | } else { | ||
341 | if (av[optind][2]) | ||
342 | usage(); | ||
343 | optarg = NULL; | ||
344 | } | ||
345 | switch (opt) { | 317 | switch (opt) { |
346 | case '1': | 318 | case '1': |
347 | options.protocol = SSH_PROTO_1; | 319 | options.protocol = SSH_PROTO_1; |
@@ -388,14 +360,16 @@ main(int ac, char **av) | |||
388 | #endif | 360 | #endif |
389 | case 'i': | 361 | case 'i': |
390 | if (stat(optarg, &st) < 0) { | 362 | if (stat(optarg, &st) < 0) { |
391 | fprintf(stderr, "Warning: Identity file %s does not exist.\n", | 363 | fprintf(stderr, "Warning: Identity file %s " |
392 | optarg); | 364 | "does not exist.\n", optarg); |
393 | break; | 365 | break; |
394 | } | 366 | } |
395 | if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) | 367 | if (options.num_identity_files >= |
396 | fatal("Too many identity files specified (max %d)", | 368 | SSH_MAX_IDENTITY_FILES) |
397 | SSH_MAX_IDENTITY_FILES); | 369 | fatal("Too many identity files specified " |
398 | options.identity_files[options.num_identity_files++] = xstrdup(optarg); | 370 | "(max %d)", SSH_MAX_IDENTITY_FILES); |
371 | options.identity_files[options.num_identity_files++] = | ||
372 | xstrdup(optarg); | ||
399 | break; | 373 | break; |
400 | case 'I': | 374 | case 'I': |
401 | #ifdef SMARTCARD | 375 | #ifdef SMARTCARD |
@@ -416,9 +390,8 @@ main(int ac, char **av) | |||
416 | } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { | 390 | } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { |
417 | options.log_level++; | 391 | options.log_level++; |
418 | break; | 392 | break; |
419 | } else { | 393 | } else |
420 | fatal("Too high debugging level."); | 394 | fatal("Too high debugging level."); |
421 | } | ||
422 | /* fallthrough */ | 395 | /* fallthrough */ |
423 | case 'V': | 396 | case 'V': |
424 | fprintf(stderr, | 397 | fprintf(stderr, |
@@ -435,14 +408,16 @@ main(int ac, char **av) | |||
435 | break; | 408 | break; |
436 | case 'e': | 409 | case 'e': |
437 | if (optarg[0] == '^' && optarg[2] == 0 && | 410 | if (optarg[0] == '^' && optarg[2] == 0 && |
438 | (u_char) optarg[1] >= 64 && (u_char) optarg[1] < 128) | 411 | (u_char) optarg[1] >= 64 && |
412 | (u_char) optarg[1] < 128) | ||
439 | options.escape_char = (u_char) optarg[1] & 31; | 413 | options.escape_char = (u_char) optarg[1] & 31; |
440 | else if (strlen(optarg) == 1) | 414 | else if (strlen(optarg) == 1) |
441 | options.escape_char = (u_char) optarg[0]; | 415 | options.escape_char = (u_char) optarg[0]; |
442 | else if (strcmp(optarg, "none") == 0) | 416 | else if (strcmp(optarg, "none") == 0) |
443 | options.escape_char = SSH_ESCAPECHAR_NONE; | 417 | options.escape_char = SSH_ESCAPECHAR_NONE; |
444 | else { | 418 | else { |
445 | fprintf(stderr, "Bad escape character '%s'.\n", optarg); | 419 | fprintf(stderr, "Bad escape character '%s'.\n", |
420 | optarg); | ||
446 | exit(1); | 421 | exit(1); |
447 | } | 422 | } |
448 | break; | 423 | break; |
@@ -455,23 +430,25 @@ main(int ac, char **av) | |||
455 | /* SSH1 only */ | 430 | /* SSH1 only */ |
456 | options.cipher = cipher_number(optarg); | 431 | options.cipher = cipher_number(optarg); |
457 | if (options.cipher == -1) { | 432 | if (options.cipher == -1) { |
458 | fprintf(stderr, "Unknown cipher type '%s'\n", optarg); | 433 | fprintf(stderr, |
434 | "Unknown cipher type '%s'\n", | ||
435 | optarg); | ||
459 | exit(1); | 436 | exit(1); |
460 | } | 437 | } |
461 | if (options.cipher == SSH_CIPHER_3DES) { | 438 | if (options.cipher == SSH_CIPHER_3DES) |
462 | options.ciphers = "3des-cbc"; | 439 | options.ciphers = "3des-cbc"; |
463 | } else if (options.cipher == SSH_CIPHER_BLOWFISH) { | 440 | else if (options.cipher == SSH_CIPHER_BLOWFISH) |
464 | options.ciphers = "blowfish-cbc"; | 441 | options.ciphers = "blowfish-cbc"; |
465 | } else { | 442 | else |
466 | options.ciphers = (char *)-1; | 443 | options.ciphers = (char *)-1; |
467 | } | ||
468 | } | 444 | } |
469 | break; | 445 | break; |
470 | case 'm': | 446 | case 'm': |
471 | if (mac_valid(optarg)) | 447 | if (mac_valid(optarg)) |
472 | options.macs = xstrdup(optarg); | 448 | options.macs = xstrdup(optarg); |
473 | else { | 449 | else { |
474 | fprintf(stderr, "Unknown mac type '%s'\n", optarg); | 450 | fprintf(stderr, "Unknown mac type '%s'\n", |
451 | optarg); | ||
475 | exit(1); | 452 | exit(1); |
476 | } | 453 | } |
477 | break; | 454 | break; |
@@ -490,28 +467,35 @@ main(int ac, char **av) | |||
490 | &fwd_host_port) != 3 && | 467 | &fwd_host_port) != 3 && |
491 | sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, | 468 | sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, |
492 | &fwd_host_port) != 3) { | 469 | &fwd_host_port) != 3) { |
493 | fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); | 470 | fprintf(stderr, |
471 | "Bad forwarding specification '%s'.\n", | ||
472 | optarg); | ||
494 | usage(); | 473 | usage(); |
495 | /* NOTREACHED */ | 474 | /* NOTREACHED */ |
496 | } | 475 | } |
497 | add_remote_forward(&options, fwd_port, buf, fwd_host_port); | 476 | add_remote_forward(&options, fwd_port, buf, |
477 | fwd_host_port); | ||
498 | break; | 478 | break; |
499 | case 'L': | 479 | case 'L': |
500 | if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, | 480 | if (sscanf(optarg, "%hu/%255[^/]/%hu", &fwd_port, buf, |
501 | &fwd_host_port) != 3 && | 481 | &fwd_host_port) != 3 && |
502 | sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, | 482 | sscanf(optarg, "%hu:%255[^:]:%hu", &fwd_port, buf, |
503 | &fwd_host_port) != 3) { | 483 | &fwd_host_port) != 3) { |
504 | fprintf(stderr, "Bad forwarding specification '%s'.\n", optarg); | 484 | fprintf(stderr, |
485 | "Bad forwarding specification '%s'.\n", | ||
486 | optarg); | ||
505 | usage(); | 487 | usage(); |
506 | /* NOTREACHED */ | 488 | /* NOTREACHED */ |
507 | } | 489 | } |
508 | add_local_forward(&options, fwd_port, buf, fwd_host_port); | 490 | add_local_forward(&options, fwd_port, buf, |
491 | fwd_host_port); | ||
509 | break; | 492 | break; |
510 | 493 | ||
511 | case 'D': | 494 | case 'D': |
512 | fwd_port = a2port(optarg); | 495 | fwd_port = a2port(optarg); |
513 | if (fwd_port == 0) { | 496 | if (fwd_port == 0) { |
514 | fprintf(stderr, "Bad dynamic port '%s'\n", optarg); | 497 | fprintf(stderr, "Bad dynamic port '%s'\n", |
498 | optarg); | ||
515 | exit(1); | 499 | exit(1); |
516 | } | 500 | } |
517 | add_local_forward(&options, fwd_port, "socks4", 0); | 501 | add_local_forward(&options, fwd_port, "socks4", 0); |
@@ -529,8 +513,8 @@ main(int ac, char **av) | |||
529 | break; | 513 | break; |
530 | case 'o': | 514 | case 'o': |
531 | dummy = 1; | 515 | dummy = 1; |
532 | if (process_config_line(&options, host ? host : "", optarg, | 516 | if (process_config_line(&options, host ? host : "", |
533 | "command-line", 0, &dummy) != 0) | 517 | optarg, "command-line", 0, &dummy) != 0) |
534 | exit(1); | 518 | exit(1); |
535 | break; | 519 | break; |
536 | case 's': | 520 | case 's': |
@@ -544,6 +528,28 @@ main(int ac, char **av) | |||
544 | } | 528 | } |
545 | } | 529 | } |
546 | 530 | ||
531 | ac -= optind; | ||
532 | av += optind; | ||
533 | |||
534 | if (ac > 0 && !host && **av != '-') { | ||
535 | if (strchr(*av, '@')) { | ||
536 | p = xstrdup(*av); | ||
537 | cp = strchr(p, '@'); | ||
538 | if (cp == NULL || cp == p) | ||
539 | usage(); | ||
540 | options.user = p; | ||
541 | *cp = '\0'; | ||
542 | host = ++cp; | ||
543 | } else | ||
544 | host = *av; | ||
545 | ac--, av++; | ||
546 | if (ac > 0) { | ||
547 | optind = 0; | ||
548 | optreset = 1; | ||
549 | goto again; | ||
550 | } | ||
551 | } | ||
552 | |||
547 | /* Check that we got a host name. */ | 553 | /* Check that we got a host name. */ |
548 | if (!host) | 554 | if (!host) |
549 | usage(); | 555 | usage(); |
@@ -559,18 +565,18 @@ main(int ac, char **av) | |||
559 | * is no limit on the length of the command, except by the maximum | 565 | * is no limit on the length of the command, except by the maximum |
560 | * packet size. Also sets the tty flag if there is no command. | 566 | * packet size. Also sets the tty flag if there is no command. |
561 | */ | 567 | */ |
562 | if (optind == ac) { | 568 | if (!ac) { |
563 | /* No command specified - execute shell on a tty. */ | 569 | /* No command specified - execute shell on a tty. */ |
564 | tty_flag = 1; | 570 | tty_flag = 1; |
565 | if (subsystem_flag) { | 571 | if (subsystem_flag) { |
566 | fprintf(stderr, "You must specify a subsystem to invoke.\n"); | 572 | fprintf(stderr, |
573 | "You must specify a subsystem to invoke.\n"); | ||
567 | usage(); | 574 | usage(); |
568 | } | 575 | } |
569 | } else { | 576 | } else { |
570 | /* A command has been specified. Store it into the | 577 | /* A command has been specified. Store it into the buffer. */ |
571 | buffer. */ | 578 | for (i = 0; i < ac; i++) { |
572 | for (i = optind; i < ac; i++) { | 579 | if (i) |
573 | if (i > optind) | ||
574 | buffer_append(&command, " ", 1); | 580 | buffer_append(&command, " ", 1); |
575 | buffer_append(&command, av[i], strlen(av[i])); | 581 | buffer_append(&command, av[i], strlen(av[i])); |
576 | } | 582 | } |