diff options
-rw-r--r-- | readconf.c | 19 | ||||
-rw-r--r-- | readconf.h | 7 | ||||
-rw-r--r-- | ssh_config.5 | 18 | ||||
-rw-r--r-- | sshconnect.c | 30 |
4 files changed, 52 insertions, 22 deletions
diff --git a/readconf.c b/readconf.c index b11c628f9..4f38b27cf 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.c,v 1.277 2017/05/30 18:58:37 bluhm Exp $ */ | 1 | /* $OpenBSD: readconf.c,v 1.278 2017/09/03 23:33:13 djm 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 |
@@ -751,6 +751,16 @@ static const struct multistate multistate_yesnoask[] = { | |||
751 | { "ask", 2 }, | 751 | { "ask", 2 }, |
752 | { NULL, -1 } | 752 | { NULL, -1 } |
753 | }; | 753 | }; |
754 | static const struct multistate multistate_strict_hostkey[] = { | ||
755 | { "true", SSH_STRICT_HOSTKEY_YES }, | ||
756 | { "false", SSH_STRICT_HOSTKEY_OFF }, | ||
757 | { "yes", SSH_STRICT_HOSTKEY_YES }, | ||
758 | { "no", SSH_STRICT_HOSTKEY_OFF }, | ||
759 | { "ask", SSH_STRICT_HOSTKEY_ASK }, | ||
760 | { "off", SSH_STRICT_HOSTKEY_OFF }, | ||
761 | { "accept-new", SSH_STRICT_HOSTKEY_NEW }, | ||
762 | { NULL, -1 } | ||
763 | }; | ||
754 | static const struct multistate multistate_yesnoaskconfirm[] = { | 764 | static const struct multistate multistate_yesnoaskconfirm[] = { |
755 | { "true", 1 }, | 765 | { "true", 1 }, |
756 | { "false", 0 }, | 766 | { "false", 0 }, |
@@ -984,7 +994,7 @@ parse_time: | |||
984 | 994 | ||
985 | case oStrictHostKeyChecking: | 995 | case oStrictHostKeyChecking: |
986 | intptr = &options->strict_host_key_checking; | 996 | intptr = &options->strict_host_key_checking; |
987 | multistate_ptr = multistate_yesnoask; | 997 | multistate_ptr = multistate_strict_hostkey; |
988 | goto parse_multistate; | 998 | goto parse_multistate; |
989 | 999 | ||
990 | case oCompression: | 1000 | case oCompression: |
@@ -1927,7 +1937,7 @@ fill_default_options(Options * options) | |||
1927 | if (options->check_host_ip == -1) | 1937 | if (options->check_host_ip == -1) |
1928 | options->check_host_ip = 1; | 1938 | options->check_host_ip = 1; |
1929 | if (options->strict_host_key_checking == -1) | 1939 | if (options->strict_host_key_checking == -1) |
1930 | options->strict_host_key_checking = 2; /* 2 is default */ | 1940 | options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK; |
1931 | if (options->compression == -1) | 1941 | if (options->compression == -1) |
1932 | options->compression = 0; | 1942 | options->compression = 0; |
1933 | if (options->tcp_keep_alive == -1) | 1943 | if (options->tcp_keep_alive == -1) |
@@ -2329,9 +2339,10 @@ fmt_intarg(OpCodes code, int val) | |||
2329 | case oAddressFamily: | 2339 | case oAddressFamily: |
2330 | return fmt_multistate_int(val, multistate_addressfamily); | 2340 | return fmt_multistate_int(val, multistate_addressfamily); |
2331 | case oVerifyHostKeyDNS: | 2341 | case oVerifyHostKeyDNS: |
2332 | case oStrictHostKeyChecking: | ||
2333 | case oUpdateHostkeys: | 2342 | case oUpdateHostkeys: |
2334 | return fmt_multistate_int(val, multistate_yesnoask); | 2343 | return fmt_multistate_int(val, multistate_yesnoask); |
2344 | case oStrictHostKeyChecking: | ||
2345 | return fmt_multistate_int(val, multistate_strict_hostkey); | ||
2335 | case oControlMaster: | 2346 | case oControlMaster: |
2336 | return fmt_multistate_int(val, multistate_controlmaster); | 2347 | return fmt_multistate_int(val, multistate_controlmaster); |
2337 | case oTunnel: | 2348 | case oTunnel: |
diff --git a/readconf.h b/readconf.h index 94dd427f5..22fe5c187 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: readconf.h,v 1.122 2017/05/30 18:58:37 bluhm Exp $ */ | 1 | /* $OpenBSD: readconf.h,v 1.123 2017/09/03 23:33:13 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -190,6 +190,11 @@ typedef struct { | |||
190 | #define SSH_UPDATE_HOSTKEYS_YES 1 | 190 | #define SSH_UPDATE_HOSTKEYS_YES 1 |
191 | #define SSH_UPDATE_HOSTKEYS_ASK 2 | 191 | #define SSH_UPDATE_HOSTKEYS_ASK 2 |
192 | 192 | ||
193 | #define SSH_STRICT_HOSTKEY_OFF 0 | ||
194 | #define SSH_STRICT_HOSTKEY_NEW 1 | ||
195 | #define SSH_STRICT_HOSTKEY_YES 2 | ||
196 | #define SSH_STRICT_HOSTKEY_ASK 3 | ||
197 | |||
193 | void initialize_options(Options *); | 198 | void initialize_options(Options *); |
194 | void fill_default_options(Options *); | 199 | void fill_default_options(Options *); |
195 | void fill_default_options_for_canonicalization(Options *); | 200 | void fill_default_options_for_canonicalization(Options *); |
diff --git a/ssh_config.5 b/ssh_config.5 index 15ca0b4f9..3823da6f3 100644 --- a/ssh_config.5 +++ b/ssh_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: ssh_config.5,v 1.253 2017/07/23 23:37:02 djm Exp $ | 36 | .\" $OpenBSD: ssh_config.5,v 1.254 2017/09/03 23:33:13 djm Exp $ |
37 | .Dd $Mdocdate: July 23 2017 $ | 37 | .Dd $Mdocdate: September 3 2017 $ |
38 | .Dt SSH_CONFIG 5 | 38 | .Dt SSH_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -1459,9 +1459,17 @@ frequently made. | |||
1459 | This option forces the user to manually | 1459 | This option forces the user to manually |
1460 | add all new hosts. | 1460 | add all new hosts. |
1461 | If this flag is set to | 1461 | If this flag is set to |
1462 | .Cm no , | 1462 | .Dq accept-new |
1463 | ssh will automatically add new host keys to the | 1463 | then ssh will automatically add new new host keys to the user |
1464 | user known hosts files. | 1464 | known hosts files, but will not permit connections to hosts with |
1465 | changed host keys. | ||
1466 | If this flag is set to | ||
1467 | .Dq no | ||
1468 | or | ||
1469 | .Dq off , | ||
1470 | ssh will automatically add new host keys to the user known hosts files, | ||
1471 | and allow connections to hosts with changed hostkeys to proceed subject | ||
1472 | to some restrictions. | ||
1465 | If this flag is set to | 1473 | If this flag is set to |
1466 | .Cm ask | 1474 | .Cm ask |
1467 | (the default), | 1475 | (the default), |
diff --git a/sshconnect.c b/sshconnect.c index 4013ec7db..2842d9e59 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.284 2017/09/01 05:53:56 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.285 2017/09/03 23:33:13 djm 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 |
@@ -891,7 +891,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
891 | if (readonly || want_cert) | 891 | if (readonly || want_cert) |
892 | goto fail; | 892 | goto fail; |
893 | /* The host is new. */ | 893 | /* The host is new. */ |
894 | if (options.strict_host_key_checking == 1) { | 894 | if (options.strict_host_key_checking == |
895 | SSH_STRICT_HOSTKEY_YES) { | ||
895 | /* | 896 | /* |
896 | * User has requested strict host key checking. We | 897 | * User has requested strict host key checking. We |
897 | * will not add the host key automatically. The only | 898 | * will not add the host key automatically. The only |
@@ -900,7 +901,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
900 | error("No %s host key is known for %.200s and you " | 901 | error("No %s host key is known for %.200s and you " |
901 | "have requested strict checking.", type, host); | 902 | "have requested strict checking.", type, host); |
902 | goto fail; | 903 | goto fail; |
903 | } else if (options.strict_host_key_checking == 2) { | 904 | } else if (options.strict_host_key_checking == |
905 | SSH_STRICT_HOSTKEY_ASK) { | ||
904 | char msg1[1024], msg2[1024]; | 906 | char msg1[1024], msg2[1024]; |
905 | 907 | ||
906 | if (show_other_keys(host_hostkeys, host_key)) | 908 | if (show_other_keys(host_hostkeys, host_key)) |
@@ -944,8 +946,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
944 | hostkey_trusted = 1; /* user explicitly confirmed */ | 946 | hostkey_trusted = 1; /* user explicitly confirmed */ |
945 | } | 947 | } |
946 | /* | 948 | /* |
947 | * If not in strict mode, add the key automatically to the | 949 | * If in "new" or "off" strict mode, add the key automatically |
948 | * local known_hosts file. | 950 | * to the local known_hosts file. |
949 | */ | 951 | */ |
950 | if (options.check_host_ip && ip_status == HOST_NEW) { | 952 | if (options.check_host_ip && ip_status == HOST_NEW) { |
951 | snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); | 953 | snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); |
@@ -987,7 +989,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
987 | * If strict host key checking is in use, the user will have | 989 | * If strict host key checking is in use, the user will have |
988 | * to edit the key manually and we can only abort. | 990 | * to edit the key manually and we can only abort. |
989 | */ | 991 | */ |
990 | if (options.strict_host_key_checking) { | 992 | if (options.strict_host_key_checking != |
993 | SSH_STRICT_HOSTKEY_OFF) { | ||
991 | error("%s host key for %.200s was revoked and you have " | 994 | error("%s host key for %.200s was revoked and you have " |
992 | "requested strict checking.", type, host); | 995 | "requested strict checking.", type, host); |
993 | goto fail; | 996 | goto fail; |
@@ -1040,7 +1043,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
1040 | * If strict host key checking is in use, the user will have | 1043 | * If strict host key checking is in use, the user will have |
1041 | * to edit the key manually and we can only abort. | 1044 | * to edit the key manually and we can only abort. |
1042 | */ | 1045 | */ |
1043 | if (options.strict_host_key_checking) { | 1046 | if (options.strict_host_key_checking != |
1047 | SSH_STRICT_HOSTKEY_OFF) { | ||
1044 | error("%s host key for %.200s has changed and you have " | 1048 | error("%s host key for %.200s has changed and you have " |
1045 | "requested strict checking.", type, host); | 1049 | "requested strict checking.", type, host); |
1046 | goto fail; | 1050 | goto fail; |
@@ -1127,15 +1131,17 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | |||
1127 | "\nMatching host key in %s:%lu", | 1131 | "\nMatching host key in %s:%lu", |
1128 | host_found->file, host_found->line); | 1132 | host_found->file, host_found->line); |
1129 | } | 1133 | } |
1130 | if (options.strict_host_key_checking == 1) { | 1134 | if (options.strict_host_key_checking == |
1131 | logit("%s", msg); | 1135 | SSH_STRICT_HOSTKEY_ASK) { |
1132 | error("Exiting, you have requested strict checking."); | ||
1133 | goto fail; | ||
1134 | } else if (options.strict_host_key_checking == 2) { | ||
1135 | strlcat(msg, "\nAre you sure you want " | 1136 | strlcat(msg, "\nAre you sure you want " |
1136 | "to continue connecting (yes/no)? ", sizeof(msg)); | 1137 | "to continue connecting (yes/no)? ", sizeof(msg)); |
1137 | if (!confirm(msg)) | 1138 | if (!confirm(msg)) |
1138 | goto fail; | 1139 | goto fail; |
1140 | } else if (options.strict_host_key_checking != | ||
1141 | SSH_STRICT_HOSTKEY_OFF) { | ||
1142 | logit("%s", msg); | ||
1143 | error("Exiting, you have requested strict checking."); | ||
1144 | goto fail; | ||
1139 | } else { | 1145 | } else { |
1140 | logit("%s", msg); | 1146 | logit("%s", msg); |
1141 | } | 1147 | } |