diff options
author | Darren Tucker <dtucker@zip.com.au> | 2012-05-19 19:37:01 +1000 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2012-05-19 19:37:01 +1000 |
commit | fbcf827559b38f7992e1bd0bcdc4b4ccdf63bc74 (patch) | |
tree | f13d5eac3813d70d50c50196716981b79c606063 | |
parent | 593538911a4d27f11f8d56e32abe141223c25916 (diff) |
- (dtucker) OpenBSD CVS Sync
- dtucker@cvs.openbsd.org 2012/05/13 01:42:32
[servconf.h servconf.c sshd.8 sshd.c auth.c sshd_config.5]
Add "Match LocalAddress" and "Match LocalPort" to sshd and adjust tests
to match. Feedback and ok djm@ markus@.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | auth.c | 7 | ||||
-rw-r--r-- | servconf.c | 163 | ||||
-rw-r--r-- | servconf.h | 22 | ||||
-rw-r--r-- | sshd.8 | 6 | ||||
-rw-r--r-- | sshd.c | 39 | ||||
-rw-r--r-- | sshd_config.5 | 6 |
7 files changed, 181 insertions, 67 deletions
@@ -4,6 +4,11 @@ | |||
4 | - (dtucker) [configure.ac contrib/Makefile] bz#1996: use AC_PATH_TOOL to find | 4 | - (dtucker) [configure.ac contrib/Makefile] bz#1996: use AC_PATH_TOOL to find |
5 | pkg-config so it does the right thing when cross-compiling. Patch from | 5 | pkg-config so it does the right thing when cross-compiling. Patch from |
6 | cjwatson at debian org. | 6 | cjwatson at debian org. |
7 | - (dtucker) OpenBSD CVS Sync | ||
8 | - dtucker@cvs.openbsd.org 2012/05/13 01:42:32 | ||
9 | [servconf.h servconf.c sshd.8 sshd.c auth.c sshd_config.5] | ||
10 | Add "Match LocalAddress" and "Match LocalPort" to sshd and adjust tests | ||
11 | to match. Feedback and ok djm@ markus@. | ||
7 | 12 | ||
8 | 20120504 | 13 | 20120504 |
9 | - (dtucker) [configure.ac] Include <sys/param.h> rather than <sys/types.h> | 14 | - (dtucker) [configure.ac] Include <sys/param.h> rather than <sys/types.h> |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.c,v 1.95 2012/04/11 13:17:54 djm Exp $ */ | 1 | /* $OpenBSD: auth.c,v 1.96 2012/05/13 01:42:32 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -545,9 +545,10 @@ getpwnamallow(const char *user) | |||
545 | #endif | 545 | #endif |
546 | #endif | 546 | #endif |
547 | struct passwd *pw; | 547 | struct passwd *pw; |
548 | struct connection_info *ci = get_connection_info(1, options.use_dns); | ||
548 | 549 | ||
549 | parse_server_match_config(&options, user, | 550 | ci->user = user; |
550 | get_canonical_hostname(options.use_dns), get_remote_ipaddr()); | 551 | parse_server_match_config(&options, ci); |
551 | 552 | ||
552 | #if defined(_AIX) && defined(HAVE_SETAUTHDB) | 553 | #if defined(_AIX) && defined(HAVE_SETAUTHDB) |
553 | aix_setauthdb(user); | 554 | aix_setauthdb(user); |
diff --git a/servconf.c b/servconf.c index a8a40f97e..12f43c91e 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,4 +1,5 @@ | |||
1 | /* $OpenBSD: servconf.c,v 1.225 2012/04/12 02:42:32 djm Exp $ */ | 1 | |
2 | /* $OpenBSD: servconf.c,v 1.226 2012/05/13 01:42:32 dtucker Exp $ */ | ||
2 | /* | 3 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 5 | * All rights reserved |
@@ -45,6 +46,8 @@ | |||
45 | #include "match.h" | 46 | #include "match.h" |
46 | #include "channels.h" | 47 | #include "channels.h" |
47 | #include "groupaccess.h" | 48 | #include "groupaccess.h" |
49 | #include "canohost.h" | ||
50 | #include "packet.h" | ||
48 | 51 | ||
49 | static void add_listen_addr(ServerOptions *, char *, int); | 52 | static void add_listen_addr(ServerOptions *, char *, int); |
50 | static void add_one_listen_addr(ServerOptions *, char *, int); | 53 | static void add_one_listen_addr(ServerOptions *, char *, int); |
@@ -539,6 +542,20 @@ add_one_listen_addr(ServerOptions *options, char *addr, int port) | |||
539 | options->listen_addrs = aitop; | 542 | options->listen_addrs = aitop; |
540 | } | 543 | } |
541 | 544 | ||
545 | struct connection_info * | ||
546 | get_connection_info(int populate, int use_dns) | ||
547 | { | ||
548 | static struct connection_info ci; | ||
549 | |||
550 | if (!populate) | ||
551 | return &ci; | ||
552 | ci.host = get_canonical_hostname(use_dns); | ||
553 | ci.address = get_remote_ipaddr(); | ||
554 | ci.laddress = get_local_ipaddr(packet_get_connection_in()); | ||
555 | ci.lport = get_local_port(); | ||
556 | return &ci; | ||
557 | } | ||
558 | |||
542 | /* | 559 | /* |
543 | * The strategy for the Match blocks is that the config file is parsed twice. | 560 | * The strategy for the Match blocks is that the config file is parsed twice. |
544 | * | 561 | * |
@@ -600,20 +617,25 @@ out: | |||
600 | return result; | 617 | return result; |
601 | } | 618 | } |
602 | 619 | ||
620 | /* | ||
621 | * All of the attributes on a single Match line are ANDed together, so we need to check every | ||
622 | * attribute and set the result to zero if any attribute does not match. | ||
623 | */ | ||
603 | static int | 624 | static int |
604 | match_cfg_line(char **condition, int line, const char *user, const char *host, | 625 | match_cfg_line(char **condition, int line, struct connection_info *ci) |
605 | const char *address) | ||
606 | { | 626 | { |
607 | int result = 1; | 627 | int result = 1, port; |
608 | char *arg, *attrib, *cp = *condition; | 628 | char *arg, *attrib, *cp = *condition; |
609 | size_t len; | 629 | size_t len; |
610 | 630 | ||
611 | if (user == NULL) | 631 | if (ci == NULL) |
612 | debug3("checking syntax for 'Match %s'", cp); | 632 | debug3("checking syntax for 'Match %s'", cp); |
613 | else | 633 | else |
614 | debug3("checking match for '%s' user %s host %s addr %s", cp, | 634 | debug3("checking match for '%s' user %s host %s addr %s " |
615 | user ? user : "(null)", host ? host : "(null)", | 635 | "laddr %s lport %d", cp, ci->user ? ci->user : "(null)", |
616 | address ? address : "(null)"); | 636 | ci->host ? ci->host : "(null)", |
637 | ci->address ? ci->address : "(null)", | ||
638 | ci->laddress ? ci->laddress : "(null)", ci->lport); | ||
617 | 639 | ||
618 | while ((attrib = strdelim(&cp)) && *attrib != '\0') { | 640 | while ((attrib = strdelim(&cp)) && *attrib != '\0') { |
619 | if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { | 641 | if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { |
@@ -622,37 +644,45 @@ match_cfg_line(char **condition, int line, const char *user, const char *host, | |||
622 | } | 644 | } |
623 | len = strlen(arg); | 645 | len = strlen(arg); |
624 | if (strcasecmp(attrib, "user") == 0) { | 646 | if (strcasecmp(attrib, "user") == 0) { |
625 | if (!user) { | 647 | if (ci == NULL || ci->user == NULL) { |
626 | result = 0; | 648 | result = 0; |
627 | continue; | 649 | continue; |
628 | } | 650 | } |
629 | if (match_pattern_list(user, arg, len, 0) != 1) | 651 | if (match_pattern_list(ci->user, arg, len, 0) != 1) |
630 | result = 0; | 652 | result = 0; |
631 | else | 653 | else |
632 | debug("user %.100s matched 'User %.100s' at " | 654 | debug("user %.100s matched 'User %.100s' at " |
633 | "line %d", user, arg, line); | 655 | "line %d", ci->user, arg, line); |
634 | } else if (strcasecmp(attrib, "group") == 0) { | 656 | } else if (strcasecmp(attrib, "group") == 0) { |
635 | switch (match_cfg_line_group(arg, line, user)) { | 657 | if (ci == NULL || ci->user == NULL) { |
658 | result = 0; | ||
659 | continue; | ||
660 | } | ||
661 | switch (match_cfg_line_group(arg, line, ci->user)) { | ||
636 | case -1: | 662 | case -1: |
637 | return -1; | 663 | return -1; |
638 | case 0: | 664 | case 0: |
639 | result = 0; | 665 | result = 0; |
640 | } | 666 | } |
641 | } else if (strcasecmp(attrib, "host") == 0) { | 667 | } else if (strcasecmp(attrib, "host") == 0) { |
642 | if (!host) { | 668 | if (ci == NULL || ci->host == NULL) { |
643 | result = 0; | 669 | result = 0; |
644 | continue; | 670 | continue; |
645 | } | 671 | } |
646 | if (match_hostname(host, arg, len) != 1) | 672 | if (match_hostname(ci->host, arg, len) != 1) |
647 | result = 0; | 673 | result = 0; |
648 | else | 674 | else |
649 | debug("connection from %.100s matched 'Host " | 675 | debug("connection from %.100s matched 'Host " |
650 | "%.100s' at line %d", host, arg, line); | 676 | "%.100s' at line %d", ci->host, arg, line); |
651 | } else if (strcasecmp(attrib, "address") == 0) { | 677 | } else if (strcasecmp(attrib, "address") == 0) { |
652 | switch (addr_match_list(address, arg)) { | 678 | if (ci == NULL || ci->address == NULL) { |
679 | result = 0; | ||
680 | continue; | ||
681 | } | ||
682 | switch (addr_match_list(ci->address, arg)) { | ||
653 | case 1: | 683 | case 1: |
654 | debug("connection from %.100s matched 'Address " | 684 | debug("connection from %.100s matched 'Address " |
655 | "%.100s' at line %d", address, arg, line); | 685 | "%.100s' at line %d", ci->address, arg, line); |
656 | break; | 686 | break; |
657 | case 0: | 687 | case 0: |
658 | case -1: | 688 | case -1: |
@@ -661,12 +691,47 @@ match_cfg_line(char **condition, int line, const char *user, const char *host, | |||
661 | case -2: | 691 | case -2: |
662 | return -1; | 692 | return -1; |
663 | } | 693 | } |
694 | } else if (strcasecmp(attrib, "localaddress") == 0){ | ||
695 | if (ci == NULL || ci->laddress == NULL) { | ||
696 | result = 0; | ||
697 | continue; | ||
698 | } | ||
699 | switch (addr_match_list(ci->laddress, arg)) { | ||
700 | case 1: | ||
701 | debug("connection from %.100s matched " | ||
702 | "'LocalAddress %.100s' at line %d", | ||
703 | ci->laddress, arg, line); | ||
704 | break; | ||
705 | case 0: | ||
706 | case -1: | ||
707 | result = 0; | ||
708 | break; | ||
709 | case -2: | ||
710 | return -1; | ||
711 | } | ||
712 | } else if (strcasecmp(attrib, "localport") == 0) { | ||
713 | if ((port = a2port(arg)) == -1) { | ||
714 | error("Invalid LocalPort '%s' on Match line", | ||
715 | arg); | ||
716 | return -1; | ||
717 | } | ||
718 | if (ci == NULL || ci->lport == 0) { | ||
719 | result = 0; | ||
720 | continue; | ||
721 | } | ||
722 | /* TODO support port lists */ | ||
723 | if (port == ci->lport) | ||
724 | debug("connection from %.100s matched " | ||
725 | "'LocalPort %d' at line %d", | ||
726 | ci->laddress, port, line); | ||
727 | else | ||
728 | result = 0; | ||
664 | } else { | 729 | } else { |
665 | error("Unsupported Match attribute %s", attrib); | 730 | error("Unsupported Match attribute %s", attrib); |
666 | return -1; | 731 | return -1; |
667 | } | 732 | } |
668 | } | 733 | } |
669 | if (user != NULL) | 734 | if (ci != NULL) |
670 | debug3("match %sfound", result ? "" : "not "); | 735 | debug3("match %sfound", result ? "" : "not "); |
671 | *condition = cp; | 736 | *condition = cp; |
672 | return result; | 737 | return result; |
@@ -713,8 +778,8 @@ static const struct multistate multistate_privsep[] = { | |||
713 | 778 | ||
714 | int | 779 | int |
715 | process_server_config_line(ServerOptions *options, char *line, | 780 | process_server_config_line(ServerOptions *options, char *line, |
716 | const char *filename, int linenum, int *activep, const char *user, | 781 | const char *filename, int linenum, int *activep, |
717 | const char *host, const char *address) | 782 | struct connection_info *connectinfo) |
718 | { | 783 | { |
719 | char *cp, **charptr, *arg, *p; | 784 | char *cp, **charptr, *arg, *p; |
720 | int cmdline = 0, *intptr, value, value2, n; | 785 | int cmdline = 0, *intptr, value, value2, n; |
@@ -745,7 +810,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
745 | if (*activep && opcode != sMatch) | 810 | if (*activep && opcode != sMatch) |
746 | debug3("%s:%d setting %s %s", filename, linenum, arg, cp); | 811 | debug3("%s:%d setting %s %s", filename, linenum, arg, cp); |
747 | if (*activep == 0 && !(flags & SSHCFG_MATCH)) { | 812 | if (*activep == 0 && !(flags & SSHCFG_MATCH)) { |
748 | if (user == NULL) { | 813 | if (connectinfo == NULL) { |
749 | fatal("%s line %d: Directive '%s' is not allowed " | 814 | fatal("%s line %d: Directive '%s' is not allowed " |
750 | "within a Match block", filename, linenum, arg); | 815 | "within a Match block", filename, linenum, arg); |
751 | } else { /* this is a directive we have already processed */ | 816 | } else { /* this is a directive we have already processed */ |
@@ -1316,7 +1381,7 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1316 | if (cmdline) | 1381 | if (cmdline) |
1317 | fatal("Match directive not supported as a command-line " | 1382 | fatal("Match directive not supported as a command-line " |
1318 | "option"); | 1383 | "option"); |
1319 | value = match_cfg_line(&cp, linenum, user, host, address); | 1384 | value = match_cfg_line(&cp, linenum, connectinfo); |
1320 | if (value < 0) | 1385 | if (value < 0) |
1321 | fatal("%s line %d: Bad Match condition", filename, | 1386 | fatal("%s line %d: Bad Match condition", filename, |
1322 | linenum); | 1387 | linenum); |
@@ -1478,16 +1543,58 @@ load_server_config(const char *filename, Buffer *conf) | |||
1478 | } | 1543 | } |
1479 | 1544 | ||
1480 | void | 1545 | void |
1481 | parse_server_match_config(ServerOptions *options, const char *user, | 1546 | parse_server_match_config(ServerOptions *options, |
1482 | const char *host, const char *address) | 1547 | struct connection_info *connectinfo) |
1483 | { | 1548 | { |
1484 | ServerOptions mo; | 1549 | ServerOptions mo; |
1485 | 1550 | ||
1486 | initialize_server_options(&mo); | 1551 | initialize_server_options(&mo); |
1487 | parse_server_config(&mo, "reprocess config", &cfg, user, host, address); | 1552 | parse_server_config(&mo, "reprocess config", &cfg, connectinfo); |
1488 | copy_set_server_options(options, &mo, 0); | 1553 | copy_set_server_options(options, &mo, 0); |
1489 | } | 1554 | } |
1490 | 1555 | ||
1556 | int parse_server_match_testspec(struct connection_info *ci, char *spec) | ||
1557 | { | ||
1558 | char *p; | ||
1559 | |||
1560 | while ((p = strsep(&spec, ",")) && *p != '\0') { | ||
1561 | if (strncmp(p, "addr=", 5) == 0) { | ||
1562 | ci->address = xstrdup(p + 5); | ||
1563 | } else if (strncmp(p, "host=", 5) == 0) { | ||
1564 | ci->host = xstrdup(p + 5); | ||
1565 | } else if (strncmp(p, "user=", 5) == 0) { | ||
1566 | ci->user = xstrdup(p + 5); | ||
1567 | } else if (strncmp(p, "laddr=", 6) == 0) { | ||
1568 | ci->laddress = xstrdup(p + 6); | ||
1569 | } else if (strncmp(p, "lport=", 6) == 0) { | ||
1570 | ci->lport = a2port(p + 6); | ||
1571 | if (ci->lport == -1) { | ||
1572 | fprintf(stderr, "Invalid port '%s' in test mode" | ||
1573 | " specification %s\n", p+6, p); | ||
1574 | return -1; | ||
1575 | } | ||
1576 | } else { | ||
1577 | fprintf(stderr, "Invalid test mode specification %s\n", | ||
1578 | p); | ||
1579 | return -1; | ||
1580 | } | ||
1581 | } | ||
1582 | return 0; | ||
1583 | } | ||
1584 | |||
1585 | /* | ||
1586 | * returns 1 for a complete spec, 0 for partial spec and -1 for an | ||
1587 | * empty spec. | ||
1588 | */ | ||
1589 | int server_match_spec_complete(struct connection_info *ci) | ||
1590 | { | ||
1591 | if (ci->user && ci->host && ci->address) | ||
1592 | return 1; /* complete */ | ||
1593 | if (!ci->user && !ci->host && !ci->address) | ||
1594 | return -1; /* empty */ | ||
1595 | return 0; /* partial */ | ||
1596 | } | ||
1597 | |||
1491 | /* Helper macros */ | 1598 | /* Helper macros */ |
1492 | #define M_CP_INTOPT(n) do {\ | 1599 | #define M_CP_INTOPT(n) do {\ |
1493 | if (src->n != -1) \ | 1600 | if (src->n != -1) \ |
@@ -1561,7 +1668,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
1561 | 1668 | ||
1562 | void | 1669 | void |
1563 | parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, | 1670 | parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, |
1564 | const char *user, const char *host, const char *address) | 1671 | struct connection_info *connectinfo) |
1565 | { | 1672 | { |
1566 | int active, linenum, bad_options = 0; | 1673 | int active, linenum, bad_options = 0; |
1567 | char *cp, *obuf, *cbuf; | 1674 | char *cp, *obuf, *cbuf; |
@@ -1569,11 +1676,11 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, | |||
1569 | debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); | 1676 | debug2("%s: config %s len %d", __func__, filename, buffer_len(conf)); |
1570 | 1677 | ||
1571 | obuf = cbuf = xstrdup(buffer_ptr(conf)); | 1678 | obuf = cbuf = xstrdup(buffer_ptr(conf)); |
1572 | active = user ? 0 : 1; | 1679 | active = connectinfo ? 0 : 1; |
1573 | linenum = 1; | 1680 | linenum = 1; |
1574 | while ((cp = strsep(&cbuf, "\n")) != NULL) { | 1681 | while ((cp = strsep(&cbuf, "\n")) != NULL) { |
1575 | if (process_server_config_line(options, cp, filename, | 1682 | if (process_server_config_line(options, cp, filename, |
1576 | linenum++, &active, user, host, address) != 0) | 1683 | linenum++, &active, connectinfo) != 0) |
1577 | bad_options++; | 1684 | bad_options++; |
1578 | } | 1685 | } |
1579 | xfree(obuf); | 1686 | xfree(obuf); |
diff --git a/servconf.h b/servconf.h index 66ba387dd..2ffaecdcd 100644 --- a/servconf.h +++ b/servconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: servconf.h,v 1.100 2012/04/12 02:42:32 djm Exp $ */ | 1 | /* $OpenBSD: servconf.h,v 1.101 2012/05/13 01:42:32 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -170,6 +170,16 @@ typedef struct { | |||
170 | char *version_addendum; /* Appended to SSH banner */ | 170 | char *version_addendum; /* Appended to SSH banner */ |
171 | } ServerOptions; | 171 | } ServerOptions; |
172 | 172 | ||
173 | /* Information about the incoming connection as used by Match */ | ||
174 | struct connection_info { | ||
175 | const char *user; | ||
176 | const char *host; /* possibly resolved hostname */ | ||
177 | const char *address; /* remote address */ | ||
178 | const char *laddress; /* local address */ | ||
179 | int lport; /* local port */ | ||
180 | }; | ||
181 | |||
182 | |||
173 | /* | 183 | /* |
174 | * These are string config options that must be copied between the | 184 | * These are string config options that must be copied between the |
175 | * Match sub-config and the main config, and must be sent from the | 185 | * Match sub-config and the main config, and must be sent from the |
@@ -184,15 +194,17 @@ typedef struct { | |||
184 | M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ | 194 | M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ |
185 | } while (0) | 195 | } while (0) |
186 | 196 | ||
197 | struct connection_info *get_connection_info(int, int); | ||
187 | void initialize_server_options(ServerOptions *); | 198 | void initialize_server_options(ServerOptions *); |
188 | void fill_default_server_options(ServerOptions *); | 199 | void fill_default_server_options(ServerOptions *); |
189 | int process_server_config_line(ServerOptions *, char *, const char *, int, | 200 | int process_server_config_line(ServerOptions *, char *, const char *, int, |
190 | int *, const char *, const char *, const char *); | 201 | int *, struct connection_info *); |
191 | void load_server_config(const char *, Buffer *); | 202 | void load_server_config(const char *, Buffer *); |
192 | void parse_server_config(ServerOptions *, const char *, Buffer *, | 203 | void parse_server_config(ServerOptions *, const char *, Buffer *, |
193 | const char *, const char *, const char *); | 204 | struct connection_info *); |
194 | void parse_server_match_config(ServerOptions *, const char *, const char *, | 205 | void parse_server_match_config(ServerOptions *, struct connection_info *); |
195 | const char *); | 206 | int parse_server_match_testspec(struct connection_info *, char *); |
207 | int server_match_spec_complete(struct connection_info *); | ||
196 | void copy_set_server_options(ServerOptions *, ServerOptions *, int); | 208 | void copy_set_server_options(ServerOptions *, ServerOptions *, int); |
197 | void dump_config(ServerOptions *); | 209 | void dump_config(ServerOptions *); |
198 | char *derelativise_path(const char *); | 210 | char *derelativise_path(const char *); |
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: sshd.8,v 1.264 2011/09/23 00:22:04 dtucker Exp $ | 36 | .\" $OpenBSD: sshd.8,v 1.265 2012/05/13 01:42:32 dtucker Exp $ |
37 | .Dd $Mdocdate: September 23 2011 $ | 37 | .Dd $Mdocdate: May 13 2012 $ |
38 | .Dt SSHD 8 | 38 | .Dt SSHD 8 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -114,6 +114,8 @@ The connection parameters are supplied as keyword=value pairs. | |||
114 | The keywords are | 114 | The keywords are |
115 | .Dq user , | 115 | .Dq user , |
116 | .Dq host , | 116 | .Dq host , |
117 | .Dq laddr , | ||
118 | .Dq lport , | ||
117 | and | 119 | and |
118 | .Dq addr . | 120 | .Dq addr . |
119 | All are required and may be supplied in any order, either with multiple | 121 | All are required and may be supplied in any order, either with multiple |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.390 2012/04/12 02:42:32 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.391 2012/05/13 01:42:32 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1325,14 +1325,14 @@ main(int ac, char **av) | |||
1325 | int opt, i, j, on = 1; | 1325 | int opt, i, j, on = 1; |
1326 | int sock_in = -1, sock_out = -1, newsock = -1; | 1326 | int sock_in = -1, sock_out = -1, newsock = -1; |
1327 | const char *remote_ip; | 1327 | const char *remote_ip; |
1328 | char *test_user = NULL, *test_host = NULL, *test_addr = NULL; | ||
1329 | int remote_port; | 1328 | int remote_port; |
1330 | char *line, *p, *cp; | 1329 | char *line; |
1331 | int config_s[2] = { -1 , -1 }; | 1330 | int config_s[2] = { -1 , -1 }; |
1332 | u_int64_t ibytes, obytes; | 1331 | u_int64_t ibytes, obytes; |
1333 | mode_t new_umask; | 1332 | mode_t new_umask; |
1334 | Key *key; | 1333 | Key *key; |
1335 | Authctxt *authctxt; | 1334 | Authctxt *authctxt; |
1335 | struct connection_info *connection_info = get_connection_info(0, 0); | ||
1336 | 1336 | ||
1337 | #ifdef HAVE_SECUREWARE | 1337 | #ifdef HAVE_SECUREWARE |
1338 | (void)set_auth_parameters(ac, av); | 1338 | (void)set_auth_parameters(ac, av); |
@@ -1454,20 +1454,9 @@ main(int ac, char **av) | |||
1454 | test_flag = 2; | 1454 | test_flag = 2; |
1455 | break; | 1455 | break; |
1456 | case 'C': | 1456 | case 'C': |
1457 | cp = optarg; | 1457 | if (parse_server_match_testspec(connection_info, |
1458 | while ((p = strsep(&cp, ",")) && *p != '\0') { | 1458 | optarg) == -1) |
1459 | if (strncmp(p, "addr=", 5) == 0) | 1459 | exit(1); |
1460 | test_addr = xstrdup(p + 5); | ||
1461 | else if (strncmp(p, "host=", 5) == 0) | ||
1462 | test_host = xstrdup(p + 5); | ||
1463 | else if (strncmp(p, "user=", 5) == 0) | ||
1464 | test_user = xstrdup(p + 5); | ||
1465 | else { | ||
1466 | fprintf(stderr, "Invalid test " | ||
1467 | "mode specification %s\n", p); | ||
1468 | exit(1); | ||
1469 | } | ||
1470 | } | ||
1471 | break; | 1460 | break; |
1472 | case 'u': | 1461 | case 'u': |
1473 | utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL); | 1462 | utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL); |
@@ -1479,7 +1468,7 @@ main(int ac, char **av) | |||
1479 | case 'o': | 1468 | case 'o': |
1480 | line = xstrdup(optarg); | 1469 | line = xstrdup(optarg); |
1481 | if (process_server_config_line(&options, line, | 1470 | if (process_server_config_line(&options, line, |
1482 | "command-line", 0, NULL, NULL, NULL, NULL) != 0) | 1471 | "command-line", 0, NULL, NULL) != 0) |
1483 | exit(1); | 1472 | exit(1); |
1484 | xfree(line); | 1473 | xfree(line); |
1485 | break; | 1474 | break; |
@@ -1535,13 +1524,10 @@ main(int ac, char **av) | |||
1535 | * the parameters we need. If we're not doing an extended test, | 1524 | * the parameters we need. If we're not doing an extended test, |
1536 | * do not silently ignore connection test params. | 1525 | * do not silently ignore connection test params. |
1537 | */ | 1526 | */ |
1538 | if (test_flag >= 2 && | 1527 | if (test_flag >= 2 && server_match_spec_complete(connection_info) == 0) |
1539 | (test_user != NULL || test_host != NULL || test_addr != NULL) | ||
1540 | && (test_user == NULL || test_host == NULL || test_addr == NULL)) | ||
1541 | fatal("user, host and addr are all required when testing " | 1528 | fatal("user, host and addr are all required when testing " |
1542 | "Match configs"); | 1529 | "Match configs"); |
1543 | if (test_flag < 2 && (test_user != NULL || test_host != NULL || | 1530 | if (test_flag < 2 && server_match_spec_complete(connection_info) >= 0) |
1544 | test_addr != NULL)) | ||
1545 | fatal("Config test connection parameter (-C) provided without " | 1531 | fatal("Config test connection parameter (-C) provided without " |
1546 | "test mode (-T)"); | 1532 | "test mode (-T)"); |
1547 | 1533 | ||
@@ -1553,7 +1539,7 @@ main(int ac, char **av) | |||
1553 | load_server_config(config_file_name, &cfg); | 1539 | load_server_config(config_file_name, &cfg); |
1554 | 1540 | ||
1555 | parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, | 1541 | parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, |
1556 | &cfg, NULL, NULL, NULL); | 1542 | &cfg, NULL); |
1557 | 1543 | ||
1558 | seed_rng(); | 1544 | seed_rng(); |
1559 | 1545 | ||
@@ -1715,9 +1701,8 @@ main(int ac, char **av) | |||
1715 | } | 1701 | } |
1716 | 1702 | ||
1717 | if (test_flag > 1) { | 1703 | if (test_flag > 1) { |
1718 | if (test_user != NULL && test_addr != NULL && test_host != NULL) | 1704 | if (server_match_spec_complete(connection_info) == 1) |
1719 | parse_server_match_config(&options, test_user, | 1705 | parse_server_match_config(&options, connection_info); |
1720 | test_host, test_addr); | ||
1721 | dump_config(&options); | 1706 | dump_config(&options); |
1722 | } | 1707 | } |
1723 | 1708 | ||
diff --git a/sshd_config.5 b/sshd_config.5 index 27ee19146..17df9e6cd 100644 --- a/sshd_config.5 +++ b/sshd_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: sshd_config.5,v 1.138 2012/04/12 02:43:55 djm Exp $ | 36 | .\" $OpenBSD: sshd_config.5,v 1.139 2012/05/13 01:42:32 dtucker Exp $ |
37 | .Dd $Mdocdate: April 12 2012 $ | 37 | .Dd $Mdocdate: May 13 2012 $ |
38 | .Dt SSHD_CONFIG 5 | 38 | .Dt SSHD_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -677,6 +677,8 @@ The available criteria are | |||
677 | .Cm User , | 677 | .Cm User , |
678 | .Cm Group , | 678 | .Cm Group , |
679 | .Cm Host , | 679 | .Cm Host , |
680 | .Cm LocalAddress , | ||
681 | .Cm LocalPort , | ||
680 | and | 682 | and |
681 | .Cm Address . | 683 | .Cm Address . |
682 | The match patterns may consist of single entries or comma-separated | 684 | The match patterns may consist of single entries or comma-separated |