1 /* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "login-common.h"
4 #include "hostpid.h"
5 #include "var-expand.h"
6 #include "settings-parser.h"
7 #include "master-service.h"
8 #include "master-service-settings.h"
9 #include "master-service-ssl-settings.h"
10 #include "master-service-settings-cache.h"
11 #include "login-settings.h"
12 
13 #include <stddef.h>
14 #include <unistd.h>
15 
16 static bool login_settings_check(void *_set, pool_t pool, const char **error_r);
17 
18 #undef DEF
19 #define DEF(type, name) \
20 	SETTING_DEFINE_STRUCT_##type(#name, name, struct login_settings)
21 
22 static const struct setting_define login_setting_defines[] = {
23 	DEF(STR, login_trusted_networks),
24 	DEF(STR, login_source_ips),
25 	DEF(STR_VARS, login_greeting),
26 	DEF(STR, login_log_format_elements),
27 	DEF(STR, login_log_format),
28 	DEF(STR, login_access_sockets),
29 	DEF(STR_VARS, login_proxy_notify_path),
30 	DEF(STR, login_plugin_dir),
31 	DEF(STR, login_plugins),
32 	DEF(TIME_MSECS, login_proxy_timeout),
33 	DEF(UINT, login_proxy_max_reconnects),
34 	DEF(TIME, login_proxy_max_disconnect_delay),
35 	DEF(STR, login_proxy_rawlog_dir),
36 	DEF(STR, director_username_hash),
37 
38 	DEF(BOOL, auth_ssl_require_client_cert),
39 	DEF(BOOL, auth_ssl_username_from_cert),
40 
41 	DEF(BOOL, disable_plaintext_auth),
42 	DEF(BOOL, auth_verbose),
43 	DEF(BOOL, auth_debug),
44 	DEF(BOOL, verbose_proctitle),
45 
46 	DEF(UINT, mail_max_userip_connections),
47 
48 	SETTING_DEFINE_LIST_END
49 };
50 
51 static const struct login_settings login_default_settings = {
52 	.login_trusted_networks = "",
53 	.login_source_ips = "",
54 	.login_greeting = PACKAGE_NAME" ready.",
55 	.login_log_format_elements = "user=<%u> method=%m rip=%r lip=%l mpid=%e %c session=<%{session}>",
56 	.login_log_format = "%$: %s",
57 	.login_access_sockets = "",
58 	.login_proxy_notify_path = "proxy-notify",
59 	.login_plugin_dir = MODULEDIR"/login",
60 	.login_plugins = "",
61 	.login_proxy_timeout = 30*1000,
62 	.login_proxy_max_reconnects = 3,
63 	.login_proxy_max_disconnect_delay = 0,
64 	.login_proxy_rawlog_dir = "",
65 	.director_username_hash = "%u",
66 
67 	.auth_ssl_require_client_cert = FALSE,
68 	.auth_ssl_username_from_cert = FALSE,
69 
70 	.disable_plaintext_auth = TRUE,
71 	.auth_verbose = FALSE,
72 	.auth_debug = FALSE,
73 	.verbose_proctitle = FALSE,
74 
75 	.mail_max_userip_connections = 10
76 };
77 
78 const struct setting_parser_info login_setting_parser_info = {
79 	.module_name = "login",
80 	.defines = login_setting_defines,
81 	.defaults = &login_default_settings,
82 
83 	.type_offset = SIZE_MAX,
84 	.struct_size = sizeof(struct login_settings),
85 
86 	.parent_offset = SIZE_MAX,
87 
88 	.check_func = login_settings_check
89 };
90 
91 static const struct setting_parser_info *default_login_set_roots[] = {
92 	&login_setting_parser_info,
93 	NULL
94 };
95 
96 const struct setting_parser_info **login_set_roots = default_login_set_roots;
97 
98 static struct master_service_settings_cache *set_cache;
99 
100 /* <settings checks> */
login_settings_check(void * _set,pool_t pool,const char ** error_r ATTR_UNUSED)101 static bool login_settings_check(void *_set, pool_t pool,
102 				 const char **error_r ATTR_UNUSED)
103 {
104 	struct login_settings *set = _set;
105 
106 	set->log_format_elements_split =
107 		p_strsplit(pool, set->login_log_format_elements, " ");
108 
109 	if (set->auth_debug_passwords)
110 		set->auth_debug = TRUE;
111 	if (set->auth_debug)
112 		set->auth_verbose = TRUE;
113 	return TRUE;
114 }
115 /* </settings checks> */
116 
117 static const struct var_expand_table *
login_set_var_expand_table(const struct master_service_settings_input * input)118 login_set_var_expand_table(const struct master_service_settings_input *input)
119 {
120 	const struct var_expand_table stack_tab[] = {
121 		{ 'l', net_ip2addr(&input->local_ip), "lip" },
122 		{ 'r', net_ip2addr(&input->remote_ip), "rip" },
123 		{ 'p', my_pid, "pid" },
124 		{ 's', input->service, "service" },
125 		{ '\0', input->local_name, "local_name" },
126 		/* aliases */
127 		{ '\0', net_ip2addr(&input->local_ip), "local_ip" },
128 		{ '\0', net_ip2addr(&input->remote_ip), "remote_ip" },
129 		/* NOTE: Make sure login_log_format_elements_split has all these
130 		   variables (in client-common.c:get_var_expand_table()). */
131 		{ '\0', NULL, NULL }
132 	};
133 	struct var_expand_table *tab;
134 
135 	tab = t_malloc_no0(sizeof(stack_tab));
136 	memcpy(tab, stack_tab, sizeof(stack_tab));
137 	return tab;
138 }
139 
140 static void *
login_setting_dup(pool_t pool,const struct setting_parser_info * info,const void * src_set)141 login_setting_dup(pool_t pool, const struct setting_parser_info *info,
142 		  const void *src_set)
143 {
144 	const char *error;
145 	void *dest;
146 
147 	dest = settings_dup(info, src_set, pool);
148 	if (!settings_check(info, pool, dest, &error)) {
149 		const char *name = info->module_name;
150 
151 		i_fatal("settings_check(%s) failed: %s",
152 			name != NULL ? name : "unknown", error);
153 	}
154 	return dest;
155 }
156 
157 struct login_settings *
login_settings_read(pool_t pool,const struct ip_addr * local_ip,const struct ip_addr * remote_ip,const char * local_name,const struct master_service_ssl_settings ** ssl_set_r,const struct master_service_ssl_server_settings ** ssl_server_set_r,void *** other_settings_r)158 login_settings_read(pool_t pool,
159 		    const struct ip_addr *local_ip,
160 		    const struct ip_addr *remote_ip,
161 		    const char *local_name,
162 		    const struct master_service_ssl_settings **ssl_set_r,
163 		    const struct master_service_ssl_server_settings **ssl_server_set_r,
164 		    void ***other_settings_r)
165 {
166 	struct master_service_settings_input input;
167 	const char *error;
168 	const struct setting_parser_context *parser;
169 	void *const *cache_sets;
170 	void **sets;
171 	unsigned int i, count;
172 
173 	i_zero(&input);
174 	input.roots = login_set_roots;
175 	input.module = login_binary->process_name;
176 	input.service = login_binary->protocol;
177 	input.local_name = local_name;
178 
179 	if (local_ip != NULL)
180 		input.local_ip = *local_ip;
181 	if (remote_ip != NULL)
182 		input.remote_ip = *remote_ip;
183 
184 	if (set_cache == NULL) {
185 		set_cache = master_service_settings_cache_init(master_service,
186 							       input.module,
187 							       input.service);
188 		/* lookup filters
189 
190 		   this is only enabled if service_count > 1 because otherwise
191 		   login process will process only one request and this is only
192 		   useful when more than one request is processed.
193 		*/
194 		if (master_service_get_service_count(master_service) > 1)
195 			master_service_settings_cache_init_filter(set_cache);
196 	}
197 
198 	if (master_service_settings_cache_read(set_cache, &input, NULL,
199 					       &parser, &error) < 0)
200 		i_fatal("Error reading configuration: %s", error);
201 
202 	cache_sets = master_service_settings_parser_get_others(master_service, parser);
203 	for (count = 0; input.roots[count] != NULL; count++) ;
204 	i_assert(cache_sets[count] == NULL);
205 	sets = p_new(pool, void *, count + 1);
206 	for (i = 0; i < count; i++)
207 		sets[i] = login_setting_dup(pool, input.roots[i], cache_sets[i]);
208 
209 	if (settings_var_expand(&login_setting_parser_info, sets[0], pool,
210 				login_set_var_expand_table(&input), &error) <= 0)
211 		i_fatal("Failed to expand settings: %s", error);
212 
213 	*ssl_set_r =
214 		login_setting_dup(pool, &master_service_ssl_setting_parser_info,
215 				  settings_parser_get_list(parser)[1]);
216 	*ssl_server_set_r =
217 		login_setting_dup(pool, &master_service_ssl_server_setting_parser_info,
218 				  settings_parser_get_list(parser)[2]);
219 	*other_settings_r = sets + 1;
220 	return sets[0];
221 }
222 
login_settings_deinit(void)223 void login_settings_deinit(void)
224 {
225 	if (set_cache != NULL)
226 		master_service_settings_cache_deinit(&set_cache);
227 }
228