summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-01-31 22:42:45 +0000
committerDamien Miller <djm@mindrot.org>2020-02-01 10:20:24 +1100
commitc2bd7f74b0e0f3a3ee9d19ac549e6ba89013abaf (patch)
treef90d36f2501a863ff0c3d1041d93a2ef827c54d1 /sshd.c
parentba261a1dd33266168ead4f8f40446dcece4d1600 (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.c65
1 files changed, 49 insertions, 16 deletions
diff --git a/sshd.c b/sshd.c
index 46fdf7ee3..57fab0425 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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 */
252struct sshbuf *cfg; 252struct sshbuf *cfg;
253 253
254/* Included files from the configuration file */
255struct include_list includes = TAILQ_HEAD_INITIALIZER(includes);
256
254/* message to be displayed after login */ 257/* message to be displayed after login */
255struct sshbuf *loginmsg; 258struct sshbuf *loginmsg;
256 259
@@ -870,30 +873,45 @@ usage(void)
870static void 873static void
871send_rexec_state(int fd, struct sshbuf *conf) 874send_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)
901static void 919static void
902recv_rexec_state(int fd, struct sshbuf *conf) 920recv_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