diff options
author | djm@openbsd.org <djm@openbsd.org> | 2020-01-31 22:42:45 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2020-02-01 10:20:24 +1100 |
commit | c2bd7f74b0e0f3a3ee9d19ac549e6ba89013abaf (patch) | |
tree | f90d36f2501a863ff0c3d1041d93a2ef827c54d1 /sshd.c | |
parent | ba261a1dd33266168ead4f8f40446dcece4d1600 (diff) |
upstream: Add a sshd_config "Include" directive to allow inclusion
of files. This has sensible semantics wrt Match blocks and accepts glob(3)
patterns to specify the included files. Based on patch by Jakub Jelen in
bz2468; feedback and ok markus@
OpenBSD-Commit-ID: 36ed0e845b872e33f03355b936a4fff02d5794ff
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 65 |
1 files changed, 49 insertions, 16 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.545 2020/01/24 23:56:01 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.546 2020/01/31 22:42:45 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 |
@@ -251,6 +251,9 @@ struct sshauthopt *auth_opts = NULL; | |||
251 | /* sshd_config buffer */ | 251 | /* sshd_config buffer */ |
252 | struct sshbuf *cfg; | 252 | struct sshbuf *cfg; |
253 | 253 | ||
254 | /* Included files from the configuration file */ | ||
255 | struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); | ||
256 | |||
254 | /* message to be displayed after login */ | 257 | /* message to be displayed after login */ |
255 | struct sshbuf *loginmsg; | 258 | struct sshbuf *loginmsg; |
256 | 259 | ||
@@ -870,30 +873,45 @@ usage(void) | |||
870 | static void | 873 | static void |
871 | send_rexec_state(int fd, struct sshbuf *conf) | 874 | send_rexec_state(int fd, struct sshbuf *conf) |
872 | { | 875 | { |
873 | struct sshbuf *m; | 876 | struct sshbuf *m = NULL, *inc = NULL; |
877 | struct include_item *item = NULL; | ||
874 | int r; | 878 | int r; |
875 | 879 | ||
876 | debug3("%s: entering fd = %d config len %zu", __func__, fd, | 880 | debug3("%s: entering fd = %d config len %zu", __func__, fd, |
877 | sshbuf_len(conf)); | 881 | sshbuf_len(conf)); |
878 | 882 | ||
883 | if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) | ||
884 | fatal("%s: sshbuf_new failed", __func__); | ||
885 | |||
886 | /* pack includes into a string */ | ||
887 | TAILQ_FOREACH(item, &includes, entry) { | ||
888 | if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 || | ||
889 | (r = sshbuf_put_cstring(inc, item->filename)) != 0 || | ||
890 | (r = sshbuf_put_stringb(inc, item->contents)) != 0) | ||
891 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
892 | } | ||
893 | |||
879 | /* | 894 | /* |
880 | * Protocol from reexec master to child: | 895 | * Protocol from reexec master to child: |
881 | * string configuration | 896 | * string configuration |
882 | * string rngseed (only if OpenSSL is not self-seeded) | 897 | * string included_files[] { |
898 | * string selector | ||
899 | * string filename | ||
900 | * string contents | ||
901 | * } | ||
902 | * string rng_seed (if required) | ||
883 | */ | 903 | */ |
884 | if ((m = sshbuf_new()) == NULL) | 904 | if ((r = sshbuf_put_stringb(m, conf)) != 0 || |
885 | fatal("%s: sshbuf_new failed", __func__); | 905 | (r = sshbuf_put_stringb(m, inc)) != 0) |
886 | if ((r = sshbuf_put_stringb(m, conf)) != 0) | ||
887 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 906 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
888 | |||
889 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) | 907 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) |
890 | rexec_send_rng_seed(m); | 908 | rexec_send_rng_seed(m); |
891 | #endif | 909 | #endif |
892 | |||
893 | if (ssh_msg_send(fd, 0, m) == -1) | 910 | if (ssh_msg_send(fd, 0, m) == -1) |
894 | fatal("%s: ssh_msg_send failed", __func__); | 911 | fatal("%s: ssh_msg_send failed", __func__); |
895 | 912 | ||
896 | sshbuf_free(m); | 913 | sshbuf_free(m); |
914 | sshbuf_free(inc); | ||
897 | 915 | ||
898 | debug3("%s: done", __func__); | 916 | debug3("%s: done", __func__); |
899 | } | 917 | } |
@@ -901,14 +919,15 @@ send_rexec_state(int fd, struct sshbuf *conf) | |||
901 | static void | 919 | static void |
902 | recv_rexec_state(int fd, struct sshbuf *conf) | 920 | recv_rexec_state(int fd, struct sshbuf *conf) |
903 | { | 921 | { |
904 | struct sshbuf *m; | 922 | struct sshbuf *m, *inc; |
905 | u_char *cp, ver; | 923 | u_char *cp, ver; |
906 | size_t len; | 924 | size_t len; |
907 | int r; | 925 | int r; |
926 | struct include_item *item; | ||
908 | 927 | ||
909 | debug3("%s: entering fd = %d", __func__, fd); | 928 | debug3("%s: entering fd = %d", __func__, fd); |
910 | 929 | ||
911 | if ((m = sshbuf_new()) == NULL) | 930 | if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) |
912 | fatal("%s: sshbuf_new failed", __func__); | 931 | fatal("%s: sshbuf_new failed", __func__); |
913 | if (ssh_msg_recv(fd, m) == -1) | 932 | if (ssh_msg_recv(fd, m) == -1) |
914 | fatal("%s: ssh_msg_recv failed", __func__); | 933 | fatal("%s: ssh_msg_recv failed", __func__); |
@@ -916,14 +935,28 @@ recv_rexec_state(int fd, struct sshbuf *conf) | |||
916 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 935 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
917 | if (ver != 0) | 936 | if (ver != 0) |
918 | fatal("%s: rexec version mismatch", __func__); | 937 | fatal("%s: rexec version mismatch", __func__); |
919 | if ((r = sshbuf_get_string(m, &cp, &len)) != 0) | 938 | if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || |
920 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 939 | (r = sshbuf_get_stringb(m, inc)) != 0) |
921 | if (conf != NULL && (r = sshbuf_put(conf, cp, len))) | ||
922 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 940 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
941 | |||
923 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) | 942 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) |
924 | rexec_recv_rng_seed(m); | 943 | rexec_recv_rng_seed(m); |
925 | #endif | 944 | #endif |
926 | 945 | ||
946 | if (conf != NULL && (r = sshbuf_put(conf, cp, len))) | ||
947 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
948 | |||
949 | while (sshbuf_len(inc) != 0) { | ||
950 | item = xcalloc(1, sizeof(*item)); | ||
951 | if ((item->contents = sshbuf_new()) == NULL) | ||
952 | fatal("%s: sshbuf_new failed", __func__); | ||
953 | if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 || | ||
954 | (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 || | ||
955 | (r = sshbuf_get_stringb(inc, item->contents)) != 0) | ||
956 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
957 | TAILQ_INSERT_TAIL(&includes, item, entry); | ||
958 | } | ||
959 | |||
927 | free(cp); | 960 | free(cp); |
928 | sshbuf_free(m); | 961 | sshbuf_free(m); |
929 | 962 | ||
@@ -1600,7 +1633,7 @@ main(int ac, char **av) | |||
1600 | case 'o': | 1633 | case 'o': |
1601 | line = xstrdup(optarg); | 1634 | line = xstrdup(optarg); |
1602 | if (process_server_config_line(&options, line, | 1635 | if (process_server_config_line(&options, line, |
1603 | "command-line", 0, NULL, NULL) != 0) | 1636 | "command-line", 0, NULL, NULL, &includes) != 0) |
1604 | exit(1); | 1637 | exit(1); |
1605 | free(line); | 1638 | free(line); |
1606 | break; | 1639 | break; |
@@ -1669,7 +1702,7 @@ main(int ac, char **av) | |||
1669 | load_server_config(config_file_name, cfg); | 1702 | load_server_config(config_file_name, cfg); |
1670 | 1703 | ||
1671 | parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, | 1704 | parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, |
1672 | cfg, NULL); | 1705 | cfg, &includes, NULL); |
1673 | 1706 | ||
1674 | /* Fill in default values for those options not explicitly set. */ | 1707 | /* Fill in default values for those options not explicitly set. */ |
1675 | fill_default_server_options(&options); | 1708 | fill_default_server_options(&options); |
@@ -1895,7 +1928,7 @@ main(int ac, char **av) | |||
1895 | if (connection_info == NULL) | 1928 | if (connection_info == NULL) |
1896 | connection_info = get_connection_info(ssh, 0, 0); | 1929 | connection_info = get_connection_info(ssh, 0, 0); |
1897 | connection_info->test = 1; | 1930 | connection_info->test = 1; |
1898 | parse_server_match_config(&options, connection_info); | 1931 | parse_server_match_config(&options, &includes, connection_info); |
1899 | dump_config(&options); | 1932 | dump_config(&options); |
1900 | } | 1933 | } |
1901 | 1934 | ||