1 /*
2 * e-source-proxy.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 /**
19 * SECTION: e-source-proxy
20 * @include: libedataserver/libedataserver.h
21 * @short_description: #ESource extension for network proxy settings
22 *
23 * The #ESourceProxy extension defines a network proxy profile.
24 *
25 * An #ESource instance with this extension can serve as a #GProxyResolver.
26 *
27 * Access the extension as follows:
28 *
29 * |[
30 * #include <libedataserver/libedataserver.h>
31 *
32 * ESourceProxy *extension;
33 *
34 * extension = e_source_get_extension (source, E_SOURCE_EXTENSION_PROXY);
35 * ]|
36 **/
37
38 #include "evolution-data-server-config.h"
39
40 #include <glib/gi18n-lib.h>
41
42 #include <libedataserver/e-source-enumtypes.h>
43 #include <libedataserver/e-data-server-util.h>
44
45 #include "e-source-proxy.h"
46
47 typedef struct _AsyncContext AsyncContext;
48
49 struct _ESourceProxyPrivate {
50 EProxyMethod method;
51 gchar *autoconfig_url;
52 gchar **ignore_hosts;
53
54 gchar *ftp_host;
55 guint16 ftp_port;
56
57 gchar *http_host;
58 guint16 http_port;
59 gboolean http_use_auth;
60 gchar *http_auth_user;
61 gchar *http_auth_password;
62
63 gchar *https_host;
64 guint16 https_port;
65
66 gchar *socks_host;
67 guint16 socks_port;
68 };
69
70 struct _AsyncContext {
71 gchar *uri;
72 gchar **proxies;
73 };
74
75 enum {
76 PROP_0,
77 PROP_AUTOCONFIG_URL,
78 PROP_FTP_HOST,
79 PROP_FTP_PORT,
80 PROP_HTTP_AUTH_PASSWORD,
81 PROP_HTTP_AUTH_USER,
82 PROP_HTTP_HOST,
83 PROP_HTTP_PORT,
84 PROP_HTTP_USE_AUTH,
85 PROP_HTTPS_HOST,
86 PROP_HTTPS_PORT,
87 PROP_IGNORE_HOSTS,
88 PROP_METHOD,
89 PROP_SOCKS_HOST,
90 PROP_SOCKS_PORT
91 };
92
G_DEFINE_TYPE_WITH_PRIVATE(ESourceProxy,e_source_proxy,E_TYPE_SOURCE_EXTENSION)93 G_DEFINE_TYPE_WITH_PRIVATE (
94 ESourceProxy,
95 e_source_proxy,
96 E_TYPE_SOURCE_EXTENSION)
97
98 static void
99 async_context_free (AsyncContext *async_context)
100 {
101 g_free (async_context->uri);
102 g_strfreev (async_context->proxies);
103
104 g_slice_free (AsyncContext, async_context);
105 }
106
107 static gchar **
source_proxy_direct(void)108 source_proxy_direct (void)
109 {
110 gchar **proxies;
111
112 proxies = g_new (gchar *, 2);
113 proxies[0] = g_strdup ("direct://");
114 proxies[1] = NULL;
115
116 return proxies;
117 }
118
119 static gchar *
source_proxy_dup_http_proxy(ESourceProxy * extension,const gchar * http_host,guint16 http_port)120 source_proxy_dup_http_proxy (ESourceProxy *extension,
121 const gchar *http_host,
122 guint16 http_port)
123 {
124 GString *http_proxy = g_string_new ("http://");
125
126 if (e_source_proxy_get_http_use_auth (extension)) {
127 gchar *http_user;
128 gchar *http_pass;
129 gchar *enc_http_user;
130 gchar *enc_http_pass;
131
132 http_user = e_source_proxy_dup_http_auth_user (extension);
133 http_pass = e_source_proxy_dup_http_auth_password (extension);
134
135 enc_http_user = g_uri_escape_string (http_user, NULL, TRUE);
136 enc_http_pass = g_uri_escape_string (http_pass, NULL, TRUE);
137
138 g_string_append (http_proxy, enc_http_user);
139 g_string_append_c (http_proxy, ':');
140 g_string_append (http_proxy, enc_http_pass);
141 g_string_append_c (http_proxy, '@');
142
143 g_free (enc_http_user);
144 g_free (enc_http_pass);
145
146 g_free (http_user);
147 g_free (http_pass);
148 }
149
150 g_string_append_printf (http_proxy, "%s:%u", http_host, http_port);
151
152 return g_string_free (http_proxy, FALSE);
153 }
154
155 static gchar **
source_proxy_lookup_pacrunner(ESource * source,const gchar * uri,GCancellable * cancellable,GError ** error)156 source_proxy_lookup_pacrunner (ESource *source,
157 const gchar *uri,
158 GCancellable *cancellable,
159 GError **error)
160 {
161 GDBusProxy *pacrunner;
162 ESourceProxy *extension;
163 const gchar *extension_name;
164 gchar *autoconfig_url;
165 gchar **proxies = NULL;
166
167 extension_name = E_SOURCE_EXTENSION_PROXY;
168 extension = e_source_get_extension (source, extension_name);
169 autoconfig_url = e_source_proxy_dup_autoconfig_url (extension);
170
171 if (autoconfig_url == NULL) {
172 proxies = source_proxy_direct ();
173 goto exit;
174 }
175
176 pacrunner = g_dbus_proxy_new_for_bus_sync (
177 G_BUS_TYPE_SESSION,
178 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
179 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
180 NULL,
181 "org.gtk.GLib.PACRunner",
182 "/org/gtk/GLib/PACRunner",
183 "org.gtk.GLib.PACRunner",
184 cancellable, error);
185
186 if (pacrunner != NULL) {
187 GVariant *variant_proxies;
188
189 variant_proxies = g_dbus_proxy_call_sync (
190 pacrunner, "Lookup",
191 g_variant_new ("(ss)", autoconfig_url, uri),
192 G_DBUS_CALL_FLAGS_NONE, -1,
193 cancellable, error);
194
195 if (variant_proxies != NULL) {
196 g_variant_get (variant_proxies, "(^as)", &proxies);
197 g_variant_unref (variant_proxies);
198 }
199
200 g_object_unref (pacrunner);
201 }
202
203 exit:
204 g_free (autoconfig_url);
205
206 return proxies;
207 }
208
209 static void
source_proxy_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)210 source_proxy_set_property (GObject *object,
211 guint property_id,
212 const GValue *value,
213 GParamSpec *pspec)
214 {
215 switch (property_id) {
216 case PROP_AUTOCONFIG_URL:
217 e_source_proxy_set_autoconfig_url (
218 E_SOURCE_PROXY (object),
219 g_value_get_string (value));
220 return;
221
222 case PROP_FTP_HOST:
223 e_source_proxy_set_ftp_host (
224 E_SOURCE_PROXY (object),
225 g_value_get_string (value));
226 return;
227
228 case PROP_FTP_PORT:
229 e_source_proxy_set_ftp_port (
230 E_SOURCE_PROXY (object),
231 g_value_get_uint (value));
232 return;
233
234 case PROP_HTTP_AUTH_PASSWORD:
235 e_source_proxy_set_http_auth_password (
236 E_SOURCE_PROXY (object),
237 g_value_get_string (value));
238 return;
239
240 case PROP_HTTP_AUTH_USER:
241 e_source_proxy_set_http_auth_user (
242 E_SOURCE_PROXY (object),
243 g_value_get_string (value));
244 return;
245
246 case PROP_HTTP_HOST:
247 e_source_proxy_set_http_host (
248 E_SOURCE_PROXY (object),
249 g_value_get_string (value));
250 return;
251
252 case PROP_HTTP_PORT:
253 e_source_proxy_set_http_port (
254 E_SOURCE_PROXY (object),
255 g_value_get_uint (value));
256 return;
257
258 case PROP_HTTP_USE_AUTH:
259 e_source_proxy_set_http_use_auth (
260 E_SOURCE_PROXY (object),
261 g_value_get_boolean (value));
262 return;
263
264 case PROP_HTTPS_HOST:
265 e_source_proxy_set_https_host (
266 E_SOURCE_PROXY (object),
267 g_value_get_string (value));
268 return;
269
270 case PROP_HTTPS_PORT:
271 e_source_proxy_set_https_port (
272 E_SOURCE_PROXY (object),
273 g_value_get_uint (value));
274 return;
275
276 case PROP_IGNORE_HOSTS:
277 e_source_proxy_set_ignore_hosts (
278 E_SOURCE_PROXY (object),
279 g_value_get_boxed (value));
280 return;
281
282 case PROP_METHOD:
283 e_source_proxy_set_method (
284 E_SOURCE_PROXY (object),
285 g_value_get_enum (value));
286 return;
287
288 case PROP_SOCKS_HOST:
289 e_source_proxy_set_socks_host (
290 E_SOURCE_PROXY (object),
291 g_value_get_string (value));
292 return;
293
294 case PROP_SOCKS_PORT:
295 e_source_proxy_set_socks_port (
296 E_SOURCE_PROXY (object),
297 g_value_get_uint (value));
298 return;
299 }
300
301 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
302 }
303
304 static void
source_proxy_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)305 source_proxy_get_property (GObject *object,
306 guint property_id,
307 GValue *value,
308 GParamSpec *pspec)
309 {
310 switch (property_id) {
311 case PROP_AUTOCONFIG_URL:
312 g_value_take_string (
313 value,
314 e_source_proxy_dup_autoconfig_url (
315 E_SOURCE_PROXY (object)));
316 return;
317
318 case PROP_FTP_HOST:
319 g_value_take_string (
320 value,
321 e_source_proxy_dup_ftp_host (
322 E_SOURCE_PROXY (object)));
323 return;
324
325 case PROP_FTP_PORT:
326 g_value_set_uint (
327 value,
328 e_source_proxy_get_ftp_port (
329 E_SOURCE_PROXY (object)));
330 return;
331
332 case PROP_HTTP_AUTH_PASSWORD:
333 g_value_take_string (
334 value,
335 e_source_proxy_dup_http_auth_password (
336 E_SOURCE_PROXY (object)));
337 return;
338
339 case PROP_HTTP_AUTH_USER:
340 g_value_take_string (
341 value,
342 e_source_proxy_dup_http_auth_user (
343 E_SOURCE_PROXY (object)));
344 return;
345
346 case PROP_HTTP_HOST:
347 g_value_take_string (
348 value,
349 e_source_proxy_dup_http_host (
350 E_SOURCE_PROXY (object)));
351 return;
352
353 case PROP_HTTP_PORT:
354 g_value_set_uint (
355 value,
356 e_source_proxy_get_http_port (
357 E_SOURCE_PROXY (object)));
358 return;
359
360 case PROP_HTTP_USE_AUTH:
361 g_value_set_boolean (
362 value,
363 e_source_proxy_get_http_use_auth (
364 E_SOURCE_PROXY (object)));
365 return;
366
367 case PROP_HTTPS_HOST:
368 g_value_take_string (
369 value,
370 e_source_proxy_dup_https_host (
371 E_SOURCE_PROXY (object)));
372 return;
373
374 case PROP_HTTPS_PORT:
375 g_value_set_uint (
376 value,
377 e_source_proxy_get_https_port (
378 E_SOURCE_PROXY (object)));
379 return;
380
381 case PROP_IGNORE_HOSTS:
382 g_value_take_boxed (
383 value,
384 e_source_proxy_dup_ignore_hosts (
385 E_SOURCE_PROXY (object)));
386 return;
387
388 case PROP_METHOD:
389 g_value_set_enum (
390 value,
391 e_source_proxy_get_method (
392 E_SOURCE_PROXY (object)));
393 return;
394
395 case PROP_SOCKS_HOST:
396 g_value_take_string (
397 value,
398 e_source_proxy_dup_socks_host (
399 E_SOURCE_PROXY (object)));
400 return;
401
402 case PROP_SOCKS_PORT:
403 g_value_set_uint (
404 value,
405 e_source_proxy_get_socks_port (
406 E_SOURCE_PROXY (object)));
407 return;
408 }
409
410 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
411 }
412
413 static void
source_proxy_finalize(GObject * object)414 source_proxy_finalize (GObject *object)
415 {
416 ESourceProxyPrivate *priv;
417
418 priv = E_SOURCE_PROXY (object)->priv;
419
420 g_free (priv->autoconfig_url);
421 g_strfreev (priv->ignore_hosts);
422 g_free (priv->ftp_host);
423 g_free (priv->http_host);
424 g_free (priv->http_auth_user);
425 g_free (priv->http_auth_password);
426 g_free (priv->https_host);
427 g_free (priv->socks_host);
428
429 /* Chain up to parent's finalize() method. */
430 G_OBJECT_CLASS (e_source_proxy_parent_class)->finalize (object);
431 }
432
433 static void
e_source_proxy_class_init(ESourceProxyClass * class)434 e_source_proxy_class_init (ESourceProxyClass *class)
435 {
436 GObjectClass *object_class;
437 ESourceExtensionClass *extension_class;
438
439 object_class = G_OBJECT_CLASS (class);
440 object_class->set_property = source_proxy_set_property;
441 object_class->get_property = source_proxy_get_property;
442 object_class->finalize = source_proxy_finalize;
443
444 extension_class = E_SOURCE_EXTENSION_CLASS (class);
445 extension_class->name = E_SOURCE_EXTENSION_PROXY;
446
447 g_object_class_install_property (
448 object_class,
449 PROP_AUTOCONFIG_URL,
450 g_param_spec_string (
451 "autoconfig-url",
452 "Autoconfig URL",
453 "Proxy autoconfiguration URL",
454 NULL,
455 G_PARAM_READWRITE |
456 G_PARAM_CONSTRUCT |
457 G_PARAM_EXPLICIT_NOTIFY |
458 G_PARAM_STATIC_STRINGS |
459 E_SOURCE_PARAM_SETTING));
460
461 g_object_class_install_property (
462 object_class,
463 PROP_FTP_HOST,
464 g_param_spec_string (
465 "ftp-host",
466 "FTP Host",
467 "FTP proxy host name",
468 NULL,
469 G_PARAM_READWRITE |
470 G_PARAM_CONSTRUCT |
471 G_PARAM_EXPLICIT_NOTIFY |
472 G_PARAM_STATIC_STRINGS |
473 E_SOURCE_PARAM_SETTING));
474
475 g_object_class_install_property (
476 object_class,
477 PROP_FTP_PORT,
478 g_param_spec_uint (
479 "ftp-port",
480 "FTP Port",
481 "FTP proxy port",
482 0, G_MAXUINT16, 0,
483 G_PARAM_READWRITE |
484 G_PARAM_CONSTRUCT |
485 G_PARAM_EXPLICIT_NOTIFY |
486 G_PARAM_STATIC_STRINGS |
487 E_SOURCE_PARAM_SETTING));
488
489 g_object_class_install_property (
490 object_class,
491 PROP_HTTP_AUTH_PASSWORD,
492 g_param_spec_string (
493 "http-auth-password",
494 "HTTP Auth Password",
495 "HTTP proxy password",
496 NULL,
497 G_PARAM_READWRITE |
498 G_PARAM_CONSTRUCT |
499 G_PARAM_EXPLICIT_NOTIFY |
500 G_PARAM_STATIC_STRINGS |
501 E_SOURCE_PARAM_SETTING));
502
503 g_object_class_install_property (
504 object_class,
505 PROP_HTTP_AUTH_USER,
506 g_param_spec_string (
507 "http-auth-user",
508 "HTTP Auth User",
509 "HTTP proxy username",
510 NULL,
511 G_PARAM_READWRITE |
512 G_PARAM_CONSTRUCT |
513 G_PARAM_EXPLICIT_NOTIFY |
514 G_PARAM_STATIC_STRINGS |
515 E_SOURCE_PARAM_SETTING));
516
517 g_object_class_install_property (
518 object_class,
519 PROP_HTTP_HOST,
520 g_param_spec_string (
521 "http-host",
522 "HTTP Host",
523 "HTTP proxy host name",
524 NULL,
525 G_PARAM_READWRITE |
526 G_PARAM_CONSTRUCT |
527 G_PARAM_EXPLICIT_NOTIFY |
528 G_PARAM_STATIC_STRINGS |
529 E_SOURCE_PARAM_SETTING));
530
531 g_object_class_install_property (
532 object_class,
533 PROP_HTTP_PORT,
534 g_param_spec_uint (
535 "http-port",
536 "HTTP Port",
537 "HTTP proxy port",
538 0, G_MAXUINT16, 8080,
539 G_PARAM_READWRITE |
540 G_PARAM_CONSTRUCT |
541 G_PARAM_EXPLICIT_NOTIFY |
542 G_PARAM_STATIC_STRINGS |
543 E_SOURCE_PARAM_SETTING));
544
545 g_object_class_install_property (
546 object_class,
547 PROP_HTTP_USE_AUTH,
548 g_param_spec_boolean (
549 "http-use-auth",
550 "HTTP Use Auth",
551 "Whether HTTP proxy server "
552 "connections require authentication",
553 FALSE,
554 G_PARAM_READWRITE |
555 G_PARAM_CONSTRUCT |
556 G_PARAM_EXPLICIT_NOTIFY |
557 G_PARAM_STATIC_STRINGS |
558 E_SOURCE_PARAM_SETTING));
559
560 g_object_class_install_property (
561 object_class,
562 PROP_HTTPS_HOST,
563 g_param_spec_string (
564 "https-host",
565 "HTTPS Host",
566 "Secure HTTP proxy host name",
567 NULL,
568 G_PARAM_READWRITE |
569 G_PARAM_CONSTRUCT |
570 G_PARAM_EXPLICIT_NOTIFY |
571 G_PARAM_STATIC_STRINGS |
572 E_SOURCE_PARAM_SETTING));
573
574 g_object_class_install_property (
575 object_class,
576 PROP_HTTPS_PORT,
577 g_param_spec_uint (
578 "https-port",
579 "HTTPS Port",
580 "Secure HTTP proxy port",
581 0, G_MAXUINT16, 0,
582 G_PARAM_READWRITE |
583 G_PARAM_CONSTRUCT |
584 G_PARAM_EXPLICIT_NOTIFY |
585 G_PARAM_STATIC_STRINGS |
586 E_SOURCE_PARAM_SETTING));
587
588 g_object_class_install_property (
589 object_class,
590 PROP_IGNORE_HOSTS,
591 g_param_spec_boxed (
592 "ignore-hosts",
593 "Ignore Hosts",
594 "Hosts to connect directly",
595 G_TYPE_STRV,
596 G_PARAM_READWRITE |
597 G_PARAM_CONSTRUCT |
598 G_PARAM_EXPLICIT_NOTIFY |
599 G_PARAM_STATIC_STRINGS |
600 E_SOURCE_PARAM_SETTING));
601
602 g_object_class_install_property (
603 object_class,
604 PROP_METHOD,
605 g_param_spec_enum (
606 "method",
607 "Method",
608 "Proxy configuration method",
609 E_TYPE_PROXY_METHOD,
610 E_PROXY_METHOD_DEFAULT,
611 G_PARAM_READWRITE |
612 G_PARAM_CONSTRUCT |
613 G_PARAM_EXPLICIT_NOTIFY |
614 G_PARAM_STATIC_STRINGS |
615 E_SOURCE_PARAM_SETTING));
616
617 g_object_class_install_property (
618 object_class,
619 PROP_SOCKS_HOST,
620 g_param_spec_string (
621 "socks-host",
622 "SOCKS Host",
623 "SOCKS proxy host name",
624 NULL,
625 G_PARAM_READWRITE |
626 G_PARAM_CONSTRUCT |
627 G_PARAM_EXPLICIT_NOTIFY |
628 G_PARAM_STATIC_STRINGS |
629 E_SOURCE_PARAM_SETTING));
630
631 g_object_class_install_property (
632 object_class,
633 PROP_SOCKS_PORT,
634 g_param_spec_uint (
635 "socks-port",
636 "SOCKS Port",
637 "SOCKS proxy port",
638 0, G_MAXUINT16, 0,
639 G_PARAM_READWRITE |
640 G_PARAM_CONSTRUCT |
641 G_PARAM_EXPLICIT_NOTIFY |
642 G_PARAM_STATIC_STRINGS |
643 E_SOURCE_PARAM_SETTING));
644 }
645
646 static void
e_source_proxy_init(ESourceProxy * extension)647 e_source_proxy_init (ESourceProxy *extension)
648 {
649 extension->priv = e_source_proxy_get_instance_private (extension);
650 }
651
652 /**
653 * e_source_proxy_get_method:
654 * @extension: an #ESourceProxy
655 *
656 * Returns the proxy configuration method for @extension.
657 *
658 * The proxy configuration method determines the behavior of
659 * e_source_proxy_lookup().
660 *
661 * Returns: the proxy configuration method
662 *
663 * Since: 3.12
664 **/
665 EProxyMethod
e_source_proxy_get_method(ESourceProxy * extension)666 e_source_proxy_get_method (ESourceProxy *extension)
667 {
668 g_return_val_if_fail (
669 E_IS_SOURCE_PROXY (extension),
670 E_PROXY_METHOD_DEFAULT);
671
672 return extension->priv->method;
673 }
674
675 /**
676 * e_source_proxy_set_method:
677 * @extension: an #ESourceProxy
678 * @method: the proxy configuration method
679 *
680 * Sets the proxy configuration method for @extension.
681 *
682 * The proxy configuration method determines the behavior of
683 * e_source_proxy_lookup().
684 *
685 * Since: 3.12
686 **/
687 void
e_source_proxy_set_method(ESourceProxy * extension,EProxyMethod method)688 e_source_proxy_set_method (ESourceProxy *extension,
689 EProxyMethod method)
690 {
691 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
692
693 if (method == extension->priv->method)
694 return;
695
696 extension->priv->method = method;
697
698 g_object_notify (G_OBJECT (extension), "method");
699 }
700
701 /**
702 * e_source_proxy_get_autoconfig_url:
703 * @extension: an #ESourceProxy
704 *
705 * Returns the URL that provides proxy configuration values. When the
706 * @extension's #ESourceProxy:method is @E_PROXY_METHOD_AUTO, this URL
707 * is used to look up proxy information for all protocols.
708 *
709 * Returns: the autoconfiguration URL
710 *
711 * Since: 3.12
712 **/
713 const gchar *
e_source_proxy_get_autoconfig_url(ESourceProxy * extension)714 e_source_proxy_get_autoconfig_url (ESourceProxy *extension)
715 {
716 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
717
718 return extension->priv->autoconfig_url;
719 }
720
721 /**
722 * e_source_proxy_dup_autoconfig_url:
723 * @extension: an #ESourceProxy
724 *
725 * Thread-safe variation of e_source_proxy_get_autoconfig_url().
726 * Use this function when accessing @extension from multiple threads.
727 *
728 * The returned string should be freed with g_free() when no longer needed.
729 *
730 * Returns: a newly-allocated copy of #ESourceProxy:autoconfig-url
731 *
732 * Since: 3.12
733 **/
734 gchar *
e_source_proxy_dup_autoconfig_url(ESourceProxy * extension)735 e_source_proxy_dup_autoconfig_url (ESourceProxy *extension)
736 {
737 const gchar *protected;
738 gchar *duplicate;
739
740 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
741
742 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
743
744 protected = e_source_proxy_get_autoconfig_url (extension);
745 duplicate = g_strdup (protected);
746
747 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
748
749 return duplicate;
750 }
751
752 /**
753 * e_source_proxy_set_autoconfig_url:
754 * @extension: an #ESourceProxy
755 * @autoconfig_url: an autoconfiguration URL
756 *
757 * Sets the URL that provides proxy configuration values. When the
758 * @extension's #ESourceProxy:method is @E_PROXY_METHOD_AUTO, this URL
759 * is used to look up proxy information for all protocols.
760 *
761 * Since: 3.12
762 **/
763 void
e_source_proxy_set_autoconfig_url(ESourceProxy * extension,const gchar * autoconfig_url)764 e_source_proxy_set_autoconfig_url (ESourceProxy *extension,
765 const gchar *autoconfig_url)
766 {
767 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
768
769 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
770
771 if (e_util_strcmp0 (autoconfig_url, extension->priv->autoconfig_url) == 0) {
772 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
773 return;
774 }
775
776 g_free (extension->priv->autoconfig_url);
777 extension->priv->autoconfig_url = e_util_strdup_strip (autoconfig_url);
778
779 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
780
781 g_object_notify (G_OBJECT (extension), "autoconfig-url");
782 }
783
784 /**
785 * e_source_proxy_get_ignore_hosts:
786 * @extension: an #ESourceProxy
787 *
788 * Returns a %NULL-terminated string array of hosts which are connected to
789 * directly, rather than via the proxy (if it is active). The array elements
790 * can be hostnames, domains (using an initial wildcard like *.foo.com), IP
791 * host addresses (both IPv4 and IPv6) and network addresses with a netmask
792 * (something like 192.168.0.0/24).
793 *
794 * The returned array is owned by @extension and should not be modified or
795 * freed.
796 *
797 * Returns: (transfer none): a %NULL-terminated string array of hosts
798 *
799 * Since: 3.12
800 **/
801 const gchar * const *
e_source_proxy_get_ignore_hosts(ESourceProxy * extension)802 e_source_proxy_get_ignore_hosts (ESourceProxy *extension)
803 {
804 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
805
806 return (const gchar * const *) extension->priv->ignore_hosts;
807 }
808
809 /**
810 * e_source_proxy_dup_ignore_hosts:
811 * @extension: an #ESourceProxy
812 *
813 * Thread-safe variation of e_source_proxy_get_ignore_hosts().
814 * Use this function when accessing @extension from multiple threads.
815 *
816 * The returned string array should be freed with g_strfreev() when no
817 * longer needed.
818 *
819 * Returns: (transfer full): a newly-allocated copy of
820 * #ESourceProxy:ignore-hosts
821 *
822 * Since: 3.12
823 **/
824 gchar **
e_source_proxy_dup_ignore_hosts(ESourceProxy * extension)825 e_source_proxy_dup_ignore_hosts (ESourceProxy *extension)
826 {
827 const gchar * const *protected;
828 gchar **duplicate;
829
830 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
831
832 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
833
834 protected = e_source_proxy_get_ignore_hosts (extension);
835 duplicate = g_strdupv ((gchar **) protected);
836
837 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
838
839 return duplicate;
840 }
841
842 /**
843 * e_source_proxy_set_ignore_hosts:
844 * @extension: an #ESourceProxy
845 * @ignore_hosts: a %NULL-terminated string array of hosts
846 *
847 * Sets the hosts which are connected to directly, rather than via the proxy
848 * (if it is active). The array elements can be hostnames, domains (using an
849 * initial wildcard like *.foo.com), IP host addresses (both IPv4 and IPv6)
850 * and network addresses with a netmask (something like 192.168.0.0/24).
851 *
852 * Since: 3.12
853 **/
854 void
e_source_proxy_set_ignore_hosts(ESourceProxy * extension,const gchar * const * ignore_hosts)855 e_source_proxy_set_ignore_hosts (ESourceProxy *extension,
856 const gchar * const *ignore_hosts)
857 {
858 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
859
860 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
861
862 if (e_util_strv_equal (ignore_hosts, extension->priv->ignore_hosts)) {
863 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
864 return;
865 }
866
867 g_strfreev (extension->priv->ignore_hosts);
868 extension->priv->ignore_hosts = g_strdupv ((gchar **) ignore_hosts);
869
870 /* Strip leading and trailing whitespace from each element. */
871 if (extension->priv->ignore_hosts != NULL) {
872 guint length, ii;
873
874 length = g_strv_length (extension->priv->ignore_hosts);
875 for (ii = 0; ii < length; ii++)
876 g_strstrip (extension->priv->ignore_hosts[ii]);
877 }
878
879 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
880
881 g_object_notify (G_OBJECT (extension), "ignore-hosts");
882 }
883
884 /**
885 * e_source_proxy_get_ftp_host:
886 * @extension: an #ESourceProxy
887 *
888 * Returns the machine name to proxy FTP through when @extension's
889 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
890 *
891 * Returns: FTP proxy host name
892 *
893 * Since: 3.12
894 **/
895 const gchar *
e_source_proxy_get_ftp_host(ESourceProxy * extension)896 e_source_proxy_get_ftp_host (ESourceProxy *extension)
897 {
898 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
899
900 return extension->priv->ftp_host;
901 }
902
903 /**
904 * e_source_proxy_dup_ftp_host:
905 * @extension: an #ESourceProxy
906 *
907 * Thread-safe variation of e_source_proxy_get_ftp_host().
908 * Use this function when accessing @extension from multiple threads.
909 *
910 * The returned string should be freed with g_free() when no longer needed.
911 *
912 * Returns: a newly-allocated copy of #ESourceProxy:ftp-host
913 *
914 * Since: 3.12
915 **/
916 gchar *
e_source_proxy_dup_ftp_host(ESourceProxy * extension)917 e_source_proxy_dup_ftp_host (ESourceProxy *extension)
918 {
919 const gchar *protected;
920 gchar *duplicate;
921
922 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
923
924 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
925
926 protected = e_source_proxy_get_ftp_host (extension);
927 duplicate = g_strdup (protected);
928
929 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
930
931 return duplicate;
932 }
933
934 /**
935 * e_source_proxy_set_ftp_host:
936 * @extension: an #ESourceProxy
937 * @ftp_host: FTP proxy host name
938 *
939 * Sets the machine name to proxy FTP through when @extension's
940 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
941 *
942 * Since: 3.12
943 **/
944 void
e_source_proxy_set_ftp_host(ESourceProxy * extension,const gchar * ftp_host)945 e_source_proxy_set_ftp_host (ESourceProxy *extension,
946 const gchar *ftp_host)
947 {
948 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
949
950 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
951
952 if (e_util_strcmp0 (ftp_host, extension->priv->ftp_host) == 0) {
953 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
954 return;
955 }
956
957 g_free (extension->priv->ftp_host);
958 extension->priv->ftp_host = e_util_strdup_strip (ftp_host);
959
960 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
961
962 g_object_notify (G_OBJECT (extension), "ftp-host");
963 }
964
965 /**
966 * e_source_proxy_get_ftp_port:
967 * @extension: an #ESourceProxy
968 *
969 * Returns the port on the machine defined by #ESourceProxy:ftp-host to proxy
970 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
971 *
972 * Returns: FTP proxy port
973 *
974 * Since: 3.12
975 **/
976 guint16
e_source_proxy_get_ftp_port(ESourceProxy * extension)977 e_source_proxy_get_ftp_port (ESourceProxy *extension)
978 {
979 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), 0);
980
981 return extension->priv->ftp_port;
982 }
983
984 /**
985 * e_source_proxy_set_ftp_port:
986 * @extension: an #ESourceProxy
987 * @ftp_port: FTP proxy port
988 *
989 * Sets the port on the machine defined by #ESourceProxy:ftp-host to proxy
990 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
991 *
992 * Since: 3.12
993 **/
994 void
e_source_proxy_set_ftp_port(ESourceProxy * extension,guint16 ftp_port)995 e_source_proxy_set_ftp_port (ESourceProxy *extension,
996 guint16 ftp_port)
997 {
998 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
999
1000 if (ftp_port == extension->priv->ftp_port)
1001 return;
1002
1003 extension->priv->ftp_port = ftp_port;
1004
1005 g_object_notify (G_OBJECT (extension), "ftp-port");
1006 }
1007
1008 /**
1009 * e_source_proxy_get_http_host:
1010 * @extension: an #ESourceProxy
1011 *
1012 * Returns the machine name to proxy HTTP through when @extension's
1013 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1014 *
1015 * Returns: HTTP proxy host name
1016 *
1017 * Since: 3.12
1018 **/
1019 const gchar *
e_source_proxy_get_http_host(ESourceProxy * extension)1020 e_source_proxy_get_http_host (ESourceProxy *extension)
1021 {
1022 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1023
1024 return extension->priv->http_host;
1025 }
1026
1027 /**
1028 * e_source_proxy_dup_http_host:
1029 * @extension: an #ESourceProxy
1030 *
1031 * Thread-safe variation of e_source_proxy_get_http_host().
1032 * Use this function when accessing @extension from multiple threads.
1033 *
1034 * The returned string should be freed with g_free() when no longer needed.
1035 *
1036 * Returns: a newly-allocated copy of #ESourceProxy:http-host
1037 *
1038 * Since: 3.12
1039 **/
1040 gchar *
e_source_proxy_dup_http_host(ESourceProxy * extension)1041 e_source_proxy_dup_http_host (ESourceProxy *extension)
1042 {
1043 const gchar *protected;
1044 gchar *duplicate;
1045
1046 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1047
1048 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1049
1050 protected = e_source_proxy_get_http_host (extension);
1051 duplicate = g_strdup (protected);
1052
1053 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1054
1055 return duplicate;
1056 }
1057
1058 /**
1059 * e_source_proxy_set_http_host:
1060 * @extension: an #ESourceProxy
1061 * @http_host: HTTP proxy host name
1062 *
1063 * Sets the machine name to proxy HTTP through when @extension's
1064 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1065 *
1066 * Since: 3.12
1067 **/
1068 void
e_source_proxy_set_http_host(ESourceProxy * extension,const gchar * http_host)1069 e_source_proxy_set_http_host (ESourceProxy *extension,
1070 const gchar *http_host)
1071 {
1072 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1073
1074 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1075
1076 if (e_util_strcmp0 (http_host, extension->priv->http_host) == 0) {
1077 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1078 return;
1079 }
1080
1081 g_free (extension->priv->http_host);
1082 extension->priv->http_host = e_util_strdup_strip (http_host);
1083
1084 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1085
1086 g_object_notify (G_OBJECT (extension), "http-host");
1087 }
1088
1089 /**
1090 * e_source_proxy_get_http_port:
1091 * @extension: an #ESourceProxy
1092 *
1093 * Returns the port on the machine defined by #ESourceProxy:http-host to proxy
1094 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1095 *
1096 * Returns: HTTP proxy port
1097 *
1098 * Since: 3.12
1099 **/
1100 guint16
e_source_proxy_get_http_port(ESourceProxy * extension)1101 e_source_proxy_get_http_port (ESourceProxy *extension)
1102 {
1103 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), 0);
1104
1105 return extension->priv->http_port;
1106 }
1107
1108 /**
1109 * e_source_proxy_set_http_port:
1110 * @extension: an #ESourceProxy
1111 * @http_port: HTTP proxy port
1112 *
1113 * Sets the port on the machine defined by #ESourceProxy:http-host to proxy
1114 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1115 *
1116 * Since: 3.12
1117 **/
1118 void
e_source_proxy_set_http_port(ESourceProxy * extension,guint16 http_port)1119 e_source_proxy_set_http_port (ESourceProxy *extension,
1120 guint16 http_port)
1121 {
1122 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1123
1124 if (http_port == extension->priv->http_port)
1125 return;
1126
1127 extension->priv->http_port = http_port;
1128
1129 g_object_notify (G_OBJECT (extension), "http-port");
1130 }
1131
1132 /**
1133 * e_source_proxy_get_http_use_auth:
1134 * @extension: an #ESourceProxy
1135 *
1136 * Returns whether the HTTP proxy server at #ESourceProxy:http-host and
1137 * #ESourceProxy:http-port requires authentication.
1138 *
1139 * The username/password combo is defined by #ESourceProxy:http-auth-user
1140 * and #ESourceProxy:http-auth-password, but only applies when @extension's
1141 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1142 *
1143 * Returns: whether to authenticate HTTP proxy connections
1144 *
1145 * Since: 3.12
1146 **/
1147 gboolean
e_source_proxy_get_http_use_auth(ESourceProxy * extension)1148 e_source_proxy_get_http_use_auth (ESourceProxy *extension)
1149 {
1150 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), FALSE);
1151
1152 return extension->priv->http_use_auth;
1153 }
1154
1155 /**
1156 * e_source_proxy_set_http_use_auth:
1157 * @extension: an #ESourceProxy
1158 * @http_use_auth: whether to authenticate HTTP proxy connections
1159 *
1160 * Sets whether the HTTP proxy server at #ESourceProxy:http-host and
1161 * #ESourceProxy:http-port requires authentication.
1162 *
1163 * The username/password combo is defined by #ESourceProxy:http-auth-user
1164 * and #ESourceProxy:http-auth-password, but only applies when @extension's
1165 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1166 *
1167 * Since: 3.12
1168 **/
1169 void
e_source_proxy_set_http_use_auth(ESourceProxy * extension,gboolean http_use_auth)1170 e_source_proxy_set_http_use_auth (ESourceProxy *extension,
1171 gboolean http_use_auth)
1172 {
1173 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1174
1175 if (http_use_auth == extension->priv->http_use_auth)
1176 return;
1177
1178 extension->priv->http_use_auth = http_use_auth;
1179
1180 g_object_notify (G_OBJECT (extension), "http-use-auth");
1181 }
1182
1183 /**
1184 * e_source_proxy_get_http_auth_user:
1185 * @extension: an #ESourceProxy
1186 *
1187 * Returns the user name to pass as authentication when doing HTTP proxying
1188 * and #ESourceProxy:http-use-auth is %TRUE.
1189 *
1190 * Returns: HTTP proxy username
1191 *
1192 * Since: 3.12
1193 **/
1194 const gchar *
e_source_proxy_get_http_auth_user(ESourceProxy * extension)1195 e_source_proxy_get_http_auth_user (ESourceProxy *extension)
1196 {
1197 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1198
1199 return extension->priv->http_auth_user;
1200 }
1201
1202 /**
1203 * e_source_proxy_dup_http_auth_user:
1204 * @extension: an #ESourceProxy
1205 *
1206 * Thread-safe variation of e_source_proxy_get_http_auth_user().
1207 * Use this function when accessing @extension from multiple threads.
1208 *
1209 * The returned string should be freed with g_free() when no longer needed.
1210 *
1211 * Returns: a newly-allocated copy of #ESourceProxy:http-auth-user
1212 *
1213 * Since: 3.12
1214 **/
1215 gchar *
e_source_proxy_dup_http_auth_user(ESourceProxy * extension)1216 e_source_proxy_dup_http_auth_user (ESourceProxy *extension)
1217 {
1218 const gchar *protected;
1219 gchar *duplicate;
1220
1221 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1222
1223 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1224
1225 protected = e_source_proxy_get_http_auth_user (extension);
1226 duplicate = g_strdup (protected);
1227
1228 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1229
1230 return duplicate;
1231 }
1232
1233 /**
1234 * e_source_proxy_set_http_auth_user:
1235 * @extension: an #ESourceProxy
1236 * @http_auth_user: HTTP proxy username
1237 *
1238 * Sets the user name to pass as authentication when doing HTTP proxying
1239 * and #ESourceProxy:http-use-auth is %TRUE.
1240 *
1241 * Since: 3.12
1242 **/
1243 void
e_source_proxy_set_http_auth_user(ESourceProxy * extension,const gchar * http_auth_user)1244 e_source_proxy_set_http_auth_user (ESourceProxy *extension,
1245 const gchar *http_auth_user)
1246 {
1247 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1248
1249 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1250
1251 if (e_util_strcmp0 (http_auth_user, extension->priv->http_auth_user) == 0) {
1252 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1253 return;
1254 }
1255
1256 g_free (extension->priv->http_auth_user);
1257 extension->priv->http_auth_user = e_util_strdup_strip (http_auth_user);
1258
1259 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1260
1261 g_object_notify (G_OBJECT (extension), "http-auth-user");
1262 }
1263
1264 /**
1265 * e_source_proxy_get_http_auth_password:
1266 * @extension: an #ESourceProxy
1267 *
1268 * Returns the password to pass as authentication when doing HTTP proxying
1269 * and #ESourceProxy:http-use-auth is %TRUE.
1270 *
1271 * Returns: HTTP proxy password
1272 *
1273 * Since: 3.12
1274 **/
1275 const gchar *
e_source_proxy_get_http_auth_password(ESourceProxy * extension)1276 e_source_proxy_get_http_auth_password (ESourceProxy *extension)
1277 {
1278 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1279
1280 return extension->priv->http_auth_password;
1281 }
1282
1283 /**
1284 * e_source_proxy_dup_http_auth_password:
1285 * @extension: an #ESourceProxy
1286 *
1287 * Thread-safe variation of e_source_proxy_get_http_auth_password().
1288 * Use this function when accessing @extension from multiple threads.
1289 *
1290 * The returned string should be freed with g_free() when no longer needed.
1291 *
1292 * Returns: a newly-allocated copy of #ESourceProxy:http-auth-password
1293 *
1294 * Since: 3.12
1295 **/
1296 gchar *
e_source_proxy_dup_http_auth_password(ESourceProxy * extension)1297 e_source_proxy_dup_http_auth_password (ESourceProxy *extension)
1298 {
1299 const gchar *protected;
1300 gchar *duplicate;
1301
1302 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1303
1304 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1305
1306 protected = e_source_proxy_get_http_auth_password (extension);
1307 duplicate = g_strdup (protected);
1308
1309 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1310
1311 return duplicate;
1312 }
1313
1314 /**
1315 * e_source_proxy_set_http_auth_password:
1316 * @extension: an #ESourceProxy
1317 * @http_auth_password: HTTP proxy password
1318 *
1319 * Sets the password to pass as authentication when doing HTTP proxying
1320 * and #ESourceProxy:http-use-auth is %TRUE.
1321 *
1322 * Since: 3.12
1323 **/
1324 void
e_source_proxy_set_http_auth_password(ESourceProxy * extension,const gchar * http_auth_password)1325 e_source_proxy_set_http_auth_password (ESourceProxy *extension,
1326 const gchar *http_auth_password)
1327 {
1328 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1329
1330 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1331
1332 if (e_util_strcmp0 (http_auth_password, extension->priv->http_auth_password) == 0) {
1333 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1334 return;
1335 }
1336
1337 g_free (extension->priv->http_auth_password);
1338 extension->priv->http_auth_password = e_util_strdup_strip (http_auth_password);
1339
1340 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1341
1342 g_object_notify (G_OBJECT (extension), "http-auth-password");
1343 }
1344
1345 /**
1346 * e_source_proxy_get_https_host:
1347 * @extension: an #ESourceProxy
1348 *
1349 * Returns the machine name to proxy secure HTTP through when @extension's
1350 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1351 *
1352 * Returns: secure HTTP proxy host name
1353 *
1354 * Since: 3.12
1355 **/
1356 const gchar *
e_source_proxy_get_https_host(ESourceProxy * extension)1357 e_source_proxy_get_https_host (ESourceProxy *extension)
1358 {
1359 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1360
1361 return extension->priv->https_host;
1362 }
1363
1364 /**
1365 * e_source_proxy_dup_https_host:
1366 * @extension: an #ESourceProxy
1367 *
1368 * Threads-safe variation of e_source_proxy_get_https_host().
1369 * Use this function when accessing @extension from multiple threads.
1370 *
1371 * The returned string should be freed with g_free() when no longer needed.
1372 *
1373 * Returns: a newly-allocated copy of #ESourceProxy:https-host
1374 *
1375 * Since: 3.12
1376 **/
1377 gchar *
e_source_proxy_dup_https_host(ESourceProxy * extension)1378 e_source_proxy_dup_https_host (ESourceProxy *extension)
1379 {
1380 const gchar *protected;
1381 gchar *duplicate;
1382
1383 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1384
1385 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1386
1387 protected = e_source_proxy_get_https_host (extension);
1388 duplicate = g_strdup (protected);
1389
1390 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1391
1392 return duplicate;
1393 }
1394
1395 /**
1396 * e_source_proxy_set_https_host:
1397 * @extension: an #ESourceProxy
1398 * @https_host: secure HTTP proxy host name
1399 *
1400 * Sets the machine name to proxy secure HTTP through when @extension's
1401 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1402 *
1403 * Since: 3.12
1404 **/
1405 void
e_source_proxy_set_https_host(ESourceProxy * extension,const gchar * https_host)1406 e_source_proxy_set_https_host (ESourceProxy *extension,
1407 const gchar *https_host)
1408 {
1409 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1410
1411 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1412
1413 if (e_util_strcmp0 (https_host, extension->priv->https_host) == 0) {
1414 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1415 return;
1416 }
1417
1418 g_free (extension->priv->https_host);
1419 extension->priv->https_host = e_util_strdup_strip (https_host);
1420
1421 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1422
1423 g_object_notify (G_OBJECT (extension), "https-host");
1424 }
1425
1426 /**
1427 * e_source_proxy_get_https_port:
1428 * @extension: an #ESourceProxy
1429 *
1430 * Returns the port on the machine defined by #ESourceProxy:https-host to proxy
1431 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1432 *
1433 * Returns: secure HTTP proxy port
1434 *
1435 * Since: 3.12
1436 **/
1437 guint16
e_source_proxy_get_https_port(ESourceProxy * extension)1438 e_source_proxy_get_https_port (ESourceProxy *extension)
1439 {
1440 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), 0);
1441
1442 return extension->priv->https_port;
1443 }
1444
1445 /**
1446 * e_source_proxy_set_https_port:
1447 * @extension: an #ESourceProxy
1448 * @https_port: secure HTTP proxy port
1449 *
1450 * Sets the port on the machine defined by #ESourceProxy:https-host to proxy
1451 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1452 *
1453 * Since: 3.12
1454 **/
1455 void
e_source_proxy_set_https_port(ESourceProxy * extension,guint16 https_port)1456 e_source_proxy_set_https_port (ESourceProxy *extension,
1457 guint16 https_port)
1458 {
1459 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1460
1461 if (https_port == extension->priv->https_port)
1462 return;
1463
1464 extension->priv->https_port = https_port;
1465
1466 g_object_notify (G_OBJECT (extension), "https-port");
1467 }
1468
1469 /**
1470 * e_source_proxy_get_socks_host:
1471 * @extension: an #ESourceProxy
1472 *
1473 * Returns the machine name to use as a SOCKS proxy when @extension's
1474 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1475 *
1476 * Returns: SOCKS proxy host name
1477 *
1478 * Since: 3.12
1479 **/
1480 const gchar *
e_source_proxy_get_socks_host(ESourceProxy * extension)1481 e_source_proxy_get_socks_host (ESourceProxy *extension)
1482 {
1483 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1484
1485 return extension->priv->socks_host;
1486 }
1487
1488 /**
1489 * e_source_proxy_dup_socks_host:
1490 * @extension: an #ESourceProxy
1491 *
1492 * Thread-safe variation of e_source_proxy_get_socks_host().
1493 * Use this function when accessing @extension from multiple threads.
1494 *
1495 * The returned string should be freed with g_free() when no longer needed.
1496 *
1497 * Returns: a newly-allocated copy of #ESourceProxy:socks-host
1498 *
1499 * Since: 3.12
1500 **/
1501 gchar *
e_source_proxy_dup_socks_host(ESourceProxy * extension)1502 e_source_proxy_dup_socks_host (ESourceProxy *extension)
1503 {
1504 const gchar *protected;
1505 gchar *duplicate;
1506
1507 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), NULL);
1508
1509 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1510
1511 protected = e_source_proxy_get_socks_host (extension);
1512 duplicate = g_strdup (protected);
1513
1514 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1515
1516 return duplicate;
1517 }
1518
1519 /**
1520 * e_source_proxy_set_socks_host:
1521 * @extension: an #ESourceProxy
1522 * @socks_host: SOCKS proxy host name
1523 *
1524 * Sets the machine name to use as a SOCKS proxy when @extension's
1525 * #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1526 *
1527 * Since: 3.12
1528 **/
1529 void
e_source_proxy_set_socks_host(ESourceProxy * extension,const gchar * socks_host)1530 e_source_proxy_set_socks_host (ESourceProxy *extension,
1531 const gchar *socks_host)
1532 {
1533 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1534
1535 e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
1536
1537 if (e_util_strcmp0 (socks_host, extension->priv->socks_host) == 0) {
1538 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1539 return;
1540 }
1541
1542 g_free (extension->priv->socks_host);
1543 extension->priv->socks_host = e_util_strdup_strip (socks_host);
1544
1545 e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
1546
1547 g_object_notify (G_OBJECT (extension), "socks-host");
1548 }
1549
1550 /**
1551 * e_source_proxy_get_socks_port:
1552 * @extension: an #ESourceProxy
1553 *
1554 * Returns the port on the machine defined by #ESourceProxy:socks-host to proxy
1555 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1556 *
1557 * Returns: SOCKS proxy port
1558 *
1559 * Since: 3.12
1560 **/
1561 guint16
e_source_proxy_get_socks_port(ESourceProxy * extension)1562 e_source_proxy_get_socks_port (ESourceProxy *extension)
1563 {
1564 g_return_val_if_fail (E_IS_SOURCE_PROXY (extension), 0);
1565
1566 return extension->priv->socks_port;
1567 }
1568
1569 /**
1570 * e_source_proxy_set_socks_port:
1571 * @extension: an #ESourceProxy
1572 * @socks_port: SOCKS proxy port
1573 *
1574 * Sets the port on the machine defined by #ESourceProxy:socks-host to proxy
1575 * through when @extension's #ESourceProxy:method is @E_PROXY_METHOD_MANUAL.
1576 *
1577 * Since: 3.12
1578 **/
1579 void
e_source_proxy_set_socks_port(ESourceProxy * extension,guint16 socks_port)1580 e_source_proxy_set_socks_port (ESourceProxy *extension,
1581 guint16 socks_port)
1582 {
1583 g_return_if_fail (E_IS_SOURCE_PROXY (extension));
1584
1585 if (socks_port == extension->priv->socks_port)
1586 return;
1587
1588 extension->priv->socks_port = socks_port;
1589
1590 g_object_notify (G_OBJECT (extension), "socks-port");
1591 }
1592
1593 /**
1594 * e_source_proxy_lookup_sync:
1595 * @source: an #ESource
1596 * @uri: a URI representing the destination to connect to
1597 * @cancellable: optional #GCancellable object, or %NULL
1598 * @error: return location for a #GError, or %NULL
1599 *
1600 * Looks into @source's #ESourceProxy extension to determine what proxy,
1601 * if any, to use to connect to @uri. The returned proxy URIs are of the
1602 * same form described by g_proxy_resolver_lookup().
1603 *
1604 * The proxy extension's #ESourceProxy:method controls how proxy URIs are
1605 * determined:
1606 *
1607 * When using @E_PROXY_METHOD_DEFAULT, the function will defer to the
1608 * #GProxyResolver returned by g_proxy_resolver_get_default().
1609 *
1610 * When using @E_PROXY_METHOD_MANUAL, the function will configure a
1611 * #GSimpleProxyResolver from the HTTP, HTTPS, FTP and SOCKS properties,
1612 * as well as #ESourceProxy:ignore-hosts.
1613 *
1614 * When using @E_PROXY_METHOD_AUTO, the function will execute a proxy
1615 * auto-config (PAC) file at #ESourceProxy:autoconfig-url.
1616 *
1617 * When using @E_PROXY_METHOD_NONE, the function will only return
1618 * <literal>direct://</literal>.
1619 *
1620 * If @source does not have an #ESourceProxy extension, the function sets
1621 * @error to @G_IO_ERROR_NOT_SUPPORTED and returns %NULL.
1622 *
1623 * Free the returned proxy URIs with g_strfreev() when finished with them.
1624 *
1625 * Returns: (transfer full): a %NULL-terminated array of proxy URIs, or %NULL
1626 *
1627 * Since: 3.12
1628 **/
1629 gchar **
e_source_proxy_lookup_sync(ESource * source,const gchar * uri,GCancellable * cancellable,GError ** error)1630 e_source_proxy_lookup_sync (ESource *source,
1631 const gchar *uri,
1632 GCancellable *cancellable,
1633 GError **error)
1634 {
1635 GProxyResolver *resolver = NULL;
1636 ESourceProxy *extension;
1637 EProxyMethod method;
1638 const gchar *extension_name;
1639 gchar **proxies;
1640
1641 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
1642 g_return_val_if_fail (uri != NULL, NULL);
1643
1644 extension_name = E_SOURCE_EXTENSION_PROXY;
1645
1646 if (!e_source_has_extension (source, extension_name)) {
1647 g_set_error (
1648 error, G_IO_ERROR,
1649 G_IO_ERROR_NOT_SUPPORTED,
1650 _("Source “%s” does not support proxy lookups"),
1651 e_source_get_display_name (source));
1652 return NULL;
1653 }
1654
1655 extension = e_source_get_extension (source, extension_name);
1656 method = e_source_proxy_get_method (extension);
1657
1658 if (method == E_PROXY_METHOD_DEFAULT) {
1659 resolver = g_proxy_resolver_get_default ();
1660 if (resolver != NULL)
1661 g_object_ref (resolver);
1662 }
1663
1664 if (method == E_PROXY_METHOD_MANUAL) {
1665 gchar *ftp_proxy = NULL;
1666 gchar *http_proxy = NULL;
1667 gchar *https_proxy = NULL;
1668 gchar *socks_proxy = NULL;
1669 gchar **ignore_hosts;
1670 gchar *host;
1671 guint16 port;
1672
1673 host = e_source_proxy_dup_ftp_host (extension);
1674 port = e_source_proxy_get_ftp_port (extension);
1675 if (host != NULL && port > 0) {
1676 ftp_proxy = g_strdup_printf (
1677 "ftp://%s:%u", host, port);
1678 }
1679 g_free (host);
1680
1681 host = e_source_proxy_dup_http_host (extension);
1682 port = e_source_proxy_get_http_port (extension);
1683 if (host != NULL && port > 0) {
1684 /* This one is a little more complicated. */
1685 http_proxy = source_proxy_dup_http_proxy (
1686 extension, host, port);
1687 }
1688 g_free (host);
1689
1690 host = e_source_proxy_dup_https_host (extension);
1691 port = e_source_proxy_get_https_port (extension);
1692 if (host != NULL && port > 0) {
1693 https_proxy = g_strdup_printf (
1694 "http://%s:%u", host, port);
1695 }
1696 g_free (host);
1697
1698 host = e_source_proxy_dup_socks_host (extension);
1699 port = e_source_proxy_get_socks_port (extension);
1700 if (host != NULL && port > 0) {
1701 socks_proxy = g_strdup_printf (
1702 "socks://%s:%u", host, port);
1703 }
1704 g_free (host);
1705
1706 ignore_hosts = e_source_proxy_dup_ignore_hosts (extension);
1707 resolver = g_simple_proxy_resolver_new (NULL, ignore_hosts);
1708 g_strfreev (ignore_hosts);
1709
1710 if (ftp_proxy != NULL) {
1711 g_simple_proxy_resolver_set_uri_proxy (
1712 G_SIMPLE_PROXY_RESOLVER (resolver),
1713 "ftp", ftp_proxy);
1714 g_free (ftp_proxy);
1715 }
1716
1717 if (https_proxy != NULL) {
1718 g_simple_proxy_resolver_set_uri_proxy (
1719 G_SIMPLE_PROXY_RESOLVER (resolver),
1720 "https", https_proxy);
1721 g_free (https_proxy);
1722 } else if (http_proxy != NULL) {
1723 g_simple_proxy_resolver_set_uri_proxy (
1724 G_SIMPLE_PROXY_RESOLVER (resolver),
1725 "https", http_proxy);
1726 }
1727
1728 if (http_proxy != NULL) {
1729 g_simple_proxy_resolver_set_uri_proxy (
1730 G_SIMPLE_PROXY_RESOLVER (resolver),
1731 "http", http_proxy);
1732 g_free (http_proxy);
1733 }
1734
1735 if (socks_proxy != NULL) {
1736 g_simple_proxy_resolver_set_uri_proxy (
1737 G_SIMPLE_PROXY_RESOLVER (resolver),
1738 "socks", socks_proxy);
1739 g_simple_proxy_resolver_set_default_proxy (
1740 G_SIMPLE_PROXY_RESOLVER (resolver),
1741 socks_proxy);
1742 g_free (socks_proxy);
1743 }
1744 }
1745
1746 if (method == E_PROXY_METHOD_AUTO) {
1747 proxies = source_proxy_lookup_pacrunner (
1748 source, uri, cancellable, error);
1749
1750 } else if (resolver != NULL) {
1751 proxies = g_proxy_resolver_lookup (
1752 resolver, uri, cancellable, error);
1753
1754 } else {
1755 proxies = source_proxy_direct ();
1756 }
1757
1758 g_clear_object (&resolver);
1759
1760 return proxies;
1761 }
1762
1763 /* Helper for e_source_proxy_lookup() */
1764 static void
source_proxy_lookup_thread(GSimpleAsyncResult * simple,GObject * object,GCancellable * cancellable)1765 source_proxy_lookup_thread (GSimpleAsyncResult *simple,
1766 GObject *object,
1767 GCancellable *cancellable)
1768 {
1769 AsyncContext *async_context;
1770 GError *local_error = NULL;
1771
1772 async_context = g_simple_async_result_get_op_res_gpointer (simple);
1773
1774 async_context->proxies = e_source_proxy_lookup_sync (
1775 E_SOURCE (object),
1776 async_context->uri,
1777 cancellable, &local_error);
1778
1779 if (local_error != NULL)
1780 g_simple_async_result_take_error (simple, local_error);
1781 }
1782
1783 /**
1784 * e_source_proxy_lookup:
1785 * @source: an #ESource
1786 * @uri: a URI representing the destination to connect to
1787 * @cancellable: optional #GCancellable object, or %NULL
1788 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
1789 * @user_data: data to pass to the callback function
1790 *
1791 * Asynchronously determines what proxy, if any, to use to connect to @uri.
1792 * See e_source_proxy_lookup_sync() for more details.
1793 *
1794 * When the operation is finished, @callback will be called. You can then
1795 * call e_source_proxy_lookup_finish() to get the result of the operation.
1796 *
1797 * Since: 3.12
1798 **/
1799 void
e_source_proxy_lookup(ESource * source,const gchar * uri,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1800 e_source_proxy_lookup (ESource *source,
1801 const gchar *uri,
1802 GCancellable *cancellable,
1803 GAsyncReadyCallback callback,
1804 gpointer user_data)
1805 {
1806 GSimpleAsyncResult *simple;
1807 AsyncContext *async_context;
1808
1809 g_return_if_fail (E_IS_SOURCE (source));
1810 g_return_if_fail (uri != NULL);
1811
1812 async_context = g_slice_new0 (AsyncContext);
1813 async_context->uri = g_strdup (uri);
1814
1815 simple = g_simple_async_result_new (
1816 G_OBJECT (source), callback,
1817 user_data, e_source_proxy_lookup);
1818
1819 g_simple_async_result_set_check_cancellable (simple, cancellable);
1820
1821 g_simple_async_result_set_op_res_gpointer (
1822 simple, async_context, (GDestroyNotify) async_context_free);
1823
1824 g_simple_async_result_run_in_thread (
1825 simple, source_proxy_lookup_thread,
1826 G_PRIORITY_DEFAULT, cancellable);
1827
1828 g_object_unref (simple);
1829 }
1830
1831 /**
1832 * e_source_proxy_lookup_finish:
1833 * @source: an #ESource
1834 * @result: a #GAsyncResult
1835 * @error: return location for a #GError, or %NULL
1836 *
1837 * Finishes the operation started with e_source_proxy_lookup().
1838 *
1839 * Free the returned proxy URIs with g_strfreev() when finished with them.
1840 *
1841 * Returns: (transfer full): a %NULL-terminated array of proxy URIs, or %NULL
1842 *
1843 * Since: 3.12
1844 **/
1845 gchar **
e_source_proxy_lookup_finish(ESource * source,GAsyncResult * result,GError ** error)1846 e_source_proxy_lookup_finish (ESource *source,
1847 GAsyncResult *result,
1848 GError **error)
1849 {
1850 GSimpleAsyncResult *simple;
1851 AsyncContext *async_context;
1852 gchar **proxies;
1853
1854 g_return_val_if_fail (
1855 g_simple_async_result_is_valid (
1856 result, G_OBJECT (source), e_source_proxy_lookup), NULL);
1857
1858 simple = G_SIMPLE_ASYNC_RESULT (result);
1859 async_context = g_simple_async_result_get_op_res_gpointer (simple);
1860
1861 if (g_simple_async_result_propagate_error (simple, error))
1862 return NULL;
1863
1864 g_return_val_if_fail (async_context->proxies != NULL, NULL);
1865
1866 proxies = async_context->proxies;
1867 async_context->proxies = NULL;
1868
1869 return proxies;
1870 }
1871
1872