1 /*
2  * camel-network-settings.c
3  *
4  * This library is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this library. If not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17 
18 #include "camel-network-settings.h"
19 
20 #include <camel/camel-enumtypes.h>
21 #include <camel/camel-settings.h>
22 #include <camel/camel-net-utils.h>
23 
24 #define AUTH_MECHANISM_KEY  "CamelNetworkSettings:auth-mechanism"
25 #define HOST_KEY            "CamelNetworkSettings:host"
26 #define PORT_KEY            "CamelNetworkSettings:port"
27 #define SECURITY_METHOD_KEY "CamelNetworkSettings:security-method"
28 #define USER_KEY            "CamelNetworkSettings:user"
29 
30 /* XXX Because interfaces have no initialization method, we can't
31  *     allocate a per-instance mutex in a thread-safe manner.  So
32  *     we have to use a single static mutex for all instances. */
33 G_LOCK_DEFINE_STATIC (property_lock);
34 
G_DEFINE_INTERFACE(CamelNetworkSettings,camel_network_settings,CAMEL_TYPE_SETTINGS)35 G_DEFINE_INTERFACE (
36 	CamelNetworkSettings,
37 	camel_network_settings,
38 	CAMEL_TYPE_SETTINGS)
39 
40 static void
41 camel_network_settings_default_init (CamelNetworkSettingsInterface *iface)
42 {
43 	g_object_interface_install_property (
44 		iface,
45 		g_param_spec_string (
46 			"auth-mechanism",
47 			"Auth Mechanism",
48 			"Authentication mechanism name",
49 			NULL,
50 			G_PARAM_READWRITE |
51 			G_PARAM_CONSTRUCT |
52 			G_PARAM_STATIC_STRINGS));
53 
54 	g_object_interface_install_property (
55 		iface,
56 		g_param_spec_string (
57 			"host",
58 			"Host",
59 			"Host name for the network service",
60 			"",
61 			G_PARAM_READWRITE |
62 			G_PARAM_CONSTRUCT |
63 			G_PARAM_STATIC_STRINGS));
64 
65 	g_object_interface_install_property (
66 		iface,
67 		g_param_spec_uint (
68 			"port",
69 			"Port",
70 			"Port number for the network service",
71 			0, G_MAXUINT16, 0,
72 			G_PARAM_READWRITE |
73 			G_PARAM_CONSTRUCT |
74 			G_PARAM_STATIC_STRINGS));
75 
76 	g_object_interface_install_property (
77 		iface,
78 		g_param_spec_enum (
79 			"security-method",
80 			"Security Method",
81 			"Method used to establish a network connection",
82 			CAMEL_TYPE_NETWORK_SECURITY_METHOD,
83 			CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT,
84 			G_PARAM_READWRITE |
85 			G_PARAM_CONSTRUCT |
86 			G_PARAM_STATIC_STRINGS));
87 
88 	g_object_interface_install_property (
89 		iface,
90 		g_param_spec_string (
91 			"user",
92 			"User",
93 			"User name for the network account",
94 			NULL,
95 			G_PARAM_READWRITE |
96 			G_PARAM_CONSTRUCT |
97 			G_PARAM_STATIC_STRINGS));
98 }
99 
100 /**
101  * camel_network_settings_get_auth_mechanism:
102  * @settings: a #CamelNetworkSettings
103  *
104  * Returns the mechanism name used to authenticate to a network service.
105  * Often this refers to a SASL mechanism such as "LOGIN" or "GSSAPI".
106  *
107  * Returns: the authentication mechanism name
108  *
109  * Since: 3.4
110  **/
111 const gchar *
camel_network_settings_get_auth_mechanism(CamelNetworkSettings * settings)112 camel_network_settings_get_auth_mechanism (CamelNetworkSettings *settings)
113 {
114 	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
115 
116 	return g_object_get_data (G_OBJECT (settings), AUTH_MECHANISM_KEY);
117 }
118 
119 /**
120  * camel_network_settings_dup_auth_mechanism:
121  * @settings: a #CamelNetworkSettings
122  *
123  * Thread-safe variation of camel_network_settings_get_auth_mechanism().
124  * Use this function when accessing @settings from multiple threads.
125  *
126  * The returned string should be freed with g_free() when no longer needed.
127  *
128  * Returns: a newly-allocated copy of #CamelNetworkSettings:auth-mechanism
129  *
130  * Since: 3.4
131  **/
132 gchar *
camel_network_settings_dup_auth_mechanism(CamelNetworkSettings * settings)133 camel_network_settings_dup_auth_mechanism (CamelNetworkSettings *settings)
134 {
135 	const gchar *protected;
136 	gchar *duplicate;
137 
138 	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
139 
140 	G_LOCK (property_lock);
141 
142 	protected = camel_network_settings_get_auth_mechanism (settings);
143 	duplicate = g_strdup (protected);
144 
145 	G_UNLOCK (property_lock);
146 
147 	return duplicate;
148 }
149 
150 /**
151  * camel_network_settings_set_auth_mechanism:
152  * @settings: a #CamelNetworkSettings
153  * @auth_mechanism: an authentication mechanism name, or %NULL
154  *
155  * Sets the mechanism name used to authenticate to a network service.
156  * Often this refers to a SASL mechanism such as "LOGIN" or "GSSAPI".
157  * The #CamelNetworkSettings:auth-mechanism property is automatically
158  * stripped of leading and trailing whitespace.
159  *
160  * Since: 3.4
161  **/
162 void
camel_network_settings_set_auth_mechanism(CamelNetworkSettings * settings,const gchar * auth_mechanism)163 camel_network_settings_set_auth_mechanism (CamelNetworkSettings *settings,
164                                            const gchar *auth_mechanism)
165 {
166 	gchar *stripped_auth_mechanism = NULL;
167 
168 	g_return_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings));
169 
170 	/* Strip leading and trailing whitespace. */
171 	if (auth_mechanism != NULL)
172 		stripped_auth_mechanism =
173 			g_strstrip (g_strdup (auth_mechanism));
174 
175 	G_LOCK (property_lock);
176 
177 	g_object_set_data_full (
178 		G_OBJECT (settings),
179 		AUTH_MECHANISM_KEY,
180 		stripped_auth_mechanism,
181 		(GDestroyNotify) g_free);
182 
183 	G_UNLOCK (property_lock);
184 
185 	g_object_notify (G_OBJECT (settings), "auth-mechanism");
186 }
187 
188 /**
189  * camel_network_settings_get_host:
190  * @settings: a #CamelNetworkSettings
191  *
192  * Returns the host name used to authenticate to a network service.
193  *
194  * Returns: the host name of a network service
195  *
196  * Since: 3.4
197  **/
198 const gchar *
camel_network_settings_get_host(CamelNetworkSettings * settings)199 camel_network_settings_get_host (CamelNetworkSettings *settings)
200 {
201 	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
202 
203 	return g_object_get_data (G_OBJECT (settings), HOST_KEY);
204 }
205 
206 /**
207  * camel_network_settings_dup_host:
208  * @settings: a #CamelNetworkSettings
209  *
210  * Thread-safe variation of camel_network_settings_get_host().
211  * Use this function when accessing @settings from multiple threads.
212  *
213  * The returned string should be freed with g_free() when no longer needed.
214  *
215  * Returns: a newly-allocated copy of #CamelNetworkSettings:host
216  *
217  * Since: 3.4
218  **/
219 gchar *
camel_network_settings_dup_host(CamelNetworkSettings * settings)220 camel_network_settings_dup_host (CamelNetworkSettings *settings)
221 {
222 	const gchar *protected;
223 	gchar *duplicate;
224 
225 	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
226 
227 	G_LOCK (property_lock);
228 
229 	protected = camel_network_settings_get_host (settings);
230 	duplicate = g_strdup (protected);
231 
232 	G_UNLOCK (property_lock);
233 
234 	return duplicate;
235 }
236 
237 /**
238  * camel_network_settings_dup_host_ensure_ascii:
239  * @settings: a #CamelNetworkSettings
240  *
241  * Just like camel_network_settings_dup_host(), only makes sure that
242  * the returned host name will be converted into its ASCII form in case
243  * of IDNA value.
244  *
245  * Returns: a newly-allocated copy of #CamelNetworkSettings:host with
246  *    only ASCII letters.
247  *
248  * Since: 3.16
249  **/
250 gchar *
camel_network_settings_dup_host_ensure_ascii(CamelNetworkSettings * settings)251 camel_network_settings_dup_host_ensure_ascii (CamelNetworkSettings *settings)
252 {
253 	const gchar *protected;
254 	gchar *duplicate;
255 
256 	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
257 
258 	G_LOCK (property_lock);
259 
260 	protected = camel_network_settings_get_host (settings);
261 	if (protected && *protected)
262 		duplicate = camel_host_idna_to_ascii (protected);
263 	else
264 		duplicate = g_strdup (protected);
265 
266 	G_UNLOCK (property_lock);
267 
268 	return duplicate;
269 }
270 
271 /**
272  * camel_network_settings_set_host:
273  * @settings: a #CamelNetworkSettings
274  * @host: a host name, or %NULL
275  *
276  * Sets the host name used to authenticate to a network service.  The
277  * #CamelNetworkSettings:host property is automatically stripped of
278  * leading and trailing whitespace.
279  *
280  * Since: 3.4
281  **/
282 void
camel_network_settings_set_host(CamelNetworkSettings * settings,const gchar * host)283 camel_network_settings_set_host (CamelNetworkSettings *settings,
284                                  const gchar *host)
285 {
286 	gchar *stripped_host = NULL;
287 
288 	g_return_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings));
289 
290 	/* Make sure this property is never NULL. */
291 	if (host == NULL)
292 		host = "";
293 
294 	/* Strip leading and trailing whitespace. */
295 	stripped_host = g_strstrip (g_strdup (host));
296 
297 	G_LOCK (property_lock);
298 
299 	g_object_set_data_full (
300 		G_OBJECT (settings),
301 		HOST_KEY, stripped_host,
302 		(GDestroyNotify) g_free);
303 
304 	G_UNLOCK (property_lock);
305 
306 	g_object_notify (G_OBJECT (settings), "host");
307 }
308 
309 /**
310  * camel_network_settings_get_port:
311  * @settings: a #CamelNetworkSettings
312  *
313  * Returns the port number used to authenticate to a network service.
314  *
315  * Returns: the port number of a network service
316  *
317  * Since: 3.4
318  **/
319 guint16
camel_network_settings_get_port(CamelNetworkSettings * settings)320 camel_network_settings_get_port (CamelNetworkSettings *settings)
321 {
322 	gpointer data;
323 
324 	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), 0);
325 
326 	data = g_object_get_data (G_OBJECT (settings), PORT_KEY);
327 
328 	return (guint16) GPOINTER_TO_UINT (data);
329 }
330 
331 /**
332  * camel_network_settings_set_port:
333  * @settings: a #CamelNetworkSettings
334  * @port: a port number
335  *
336  * Sets the port number used to authenticate to a network service.
337  *
338  * Since: 3.4
339  **/
340 void
camel_network_settings_set_port(CamelNetworkSettings * settings,guint16 port)341 camel_network_settings_set_port (CamelNetworkSettings *settings,
342                                  guint16 port)
343 {
344 	g_return_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings));
345 
346 	g_object_set_data (
347 		G_OBJECT (settings), PORT_KEY,
348 		GUINT_TO_POINTER ((guint) port));
349 
350 	g_object_notify (G_OBJECT (settings), "port");
351 }
352 
353 /**
354  * camel_network_settings_get_security_method:
355  * @settings: a #CamelNetworkSettings
356  *
357  * Returns the method used to establish a secure (or unsecure) network
358  * connection.
359  *
360  * Returns: the security method
361  *
362  * Since: 3.2
363  **/
364 CamelNetworkSecurityMethod
camel_network_settings_get_security_method(CamelNetworkSettings * settings)365 camel_network_settings_get_security_method (CamelNetworkSettings *settings)
366 {
367 	gpointer data;
368 
369 	g_return_val_if_fail (
370 		CAMEL_IS_NETWORK_SETTINGS (settings),
371 		CAMEL_NETWORK_SECURITY_METHOD_NONE);
372 
373 	data = g_object_get_data (G_OBJECT (settings), SECURITY_METHOD_KEY);
374 
375 	return (CamelNetworkSecurityMethod) GPOINTER_TO_INT (data);
376 }
377 
378 /**
379  * camel_network_settings_set_security_method:
380  * @settings: a #CamelNetworkSettings
381  * @method: the security method
382  *
383  * Sets the method used to establish a secure (or unsecure) network
384  * connection.  Note that changing this setting has no effect on an
385  * already-established network connection.
386  *
387  * Since: 3.2
388  **/
389 void
camel_network_settings_set_security_method(CamelNetworkSettings * settings,CamelNetworkSecurityMethod method)390 camel_network_settings_set_security_method (CamelNetworkSettings *settings,
391                                             CamelNetworkSecurityMethod method)
392 {
393 	g_return_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings));
394 
395 	g_object_set_data (
396 		G_OBJECT (settings),
397 		SECURITY_METHOD_KEY,
398 		GINT_TO_POINTER (method));
399 
400 	g_object_notify (G_OBJECT (settings), "security-method");
401 }
402 
403 /**
404  * camel_network_settings_get_user:
405  * @settings: a #CamelNetworkSettings
406  *
407  * Returns the user name used to authenticate to a network service.
408  *
409  * Returns: the user name of a network service
410  *
411  * Since: 3.4
412  **/
413 const gchar *
camel_network_settings_get_user(CamelNetworkSettings * settings)414 camel_network_settings_get_user (CamelNetworkSettings *settings)
415 {
416 	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
417 
418 	return g_object_get_data (G_OBJECT (settings), USER_KEY);
419 }
420 
421 /**
422  * camel_network_settings_dup_user:
423  * @settings: a #CamelNetworkSettings
424  *
425  * Thread-safe variation of camel_network_settings_get_user().
426  * Use this function when accessing @settings from multiple threads.
427  *
428  * The returned string should be freed with g_free() when no longer needed.
429  *
430  * Returns: a newly-allocated copy of #CamelNetworkSettings:user
431  *
432  * Since: 3.4
433  **/
434 gchar *
camel_network_settings_dup_user(CamelNetworkSettings * settings)435 camel_network_settings_dup_user (CamelNetworkSettings *settings)
436 {
437 	const gchar *protected;
438 	gchar *duplicate;
439 
440 	g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
441 
442 	G_LOCK (property_lock);
443 
444 	protected = camel_network_settings_get_user (settings);
445 	duplicate = g_strdup (protected);
446 
447 	G_UNLOCK (property_lock);
448 
449 	return duplicate;
450 }
451 
452 /**
453  * camel_network_settings_set_user:
454  * @settings: a #CamelNetworkSettings
455  * @user: a user name, or %NULL
456  *
457  * Sets the user name used to authenticate to a network service.  The
458  * #CamelNetworkSettings:user property is automatically stripped of
459  * leading and trailing whitespace.
460  *
461  * Since: 3.4
462  **/
463 void
camel_network_settings_set_user(CamelNetworkSettings * settings,const gchar * user)464 camel_network_settings_set_user (CamelNetworkSettings *settings,
465                                  const gchar *user)
466 {
467 	gchar *stripped_user = NULL;
468 
469 	g_return_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings));
470 
471 	/* Make sure this property is never NULL. */
472 	if (user == NULL)
473 		user = "";
474 
475 	/* Strip leading and trailing whitespace. */
476 	stripped_user = g_strstrip (g_strdup (user));
477 
478 	G_LOCK (property_lock);
479 
480 	g_object_set_data_full (
481 		G_OBJECT (settings),
482 		USER_KEY, stripped_user,
483 		(GDestroyNotify) g_free);
484 
485 	G_UNLOCK (property_lock);
486 
487 	g_object_notify (G_OBJECT (settings), "user");
488 }
489 
490