2 * camel-network-service.c
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
19 #include "camel-network-service.h"
22 #include <glib/gi18n-lib.h>
24 #include <camel/camel-enumtypes.h>
25 #include <camel/camel-network-settings.h>
26 #include <camel/camel-service.h>
27 #include <camel/camel-session.h>
28 #include <camel/camel-tcp-stream-raw.h>
30 #include <camel/camel-tcp-stream-ssl.h>
32 #define PRIVATE_KEY "CamelNetworkService:private"
34 #define CAMEL_NETWORK_SERVICE_GET_PRIVATE(obj) \
35 (g_object_get_data (G_OBJECT (obj), PRIVATE_KEY))
37 typedef struct _CamelNetworkServicePrivate CamelNetworkServicePrivate;
39 struct _CamelNetworkServicePrivate {
43 /* Forward Declarations */
44 void camel_network_service_init (CamelNetworkService *service);
48 camel_network_service,
51 static CamelNetworkServicePrivate *
52 network_service_private_new (CamelNetworkService *service)
54 return g_slice_new0 (CamelNetworkServicePrivate);
58 network_service_private_free (CamelNetworkServicePrivate *priv)
60 g_slice_free (CamelNetworkServicePrivate, priv);
64 network_service_connect_sync (CamelNetworkService *service,
65 GCancellable *cancellable,
68 CamelNetworkSecurityMethod method;
69 CamelNetworkSettings *network_settings;
70 CamelSettings *settings;
71 CamelSession *session;
73 const gchar *service_name;
81 session = camel_service_ref_session (CAMEL_SERVICE (service));
82 settings = camel_service_ref_settings (CAMEL_SERVICE (service));
83 g_return_val_if_fail (CAMEL_IS_NETWORK_SETTINGS (settings), NULL);
85 network_settings = CAMEL_NETWORK_SETTINGS (settings);
86 method = camel_network_settings_get_security_method (network_settings);
87 host = camel_network_settings_dup_host (network_settings);
88 port = camel_network_settings_get_port (network_settings);
90 g_object_unref (settings);
92 service_name = camel_network_service_get_service_name (service, method);
93 default_port = camel_network_service_get_default_port (service, method);
95 /* If the URL explicitly gives a port number, make
96 * it override the service name and default port. */
98 service_name = g_alloca (16);
99 sprintf ((gchar *) service_name, "%u", port);
104 case CAMEL_NETWORK_SECURITY_METHOD_NONE:
105 stream = camel_tcp_stream_raw_new ();
108 case CAMEL_NETWORK_SECURITY_METHOD_STARTTLS_ON_STANDARD_PORT:
109 stream = camel_tcp_stream_ssl_new_raw (
111 CAMEL_TCP_STREAM_SSL_ENABLE_TLS);
114 case CAMEL_NETWORK_SECURITY_METHOD_SSL_ON_ALTERNATE_PORT:
115 stream = camel_tcp_stream_ssl_new (
117 CAMEL_TCP_STREAM_SSL_ENABLE_SSL2 |
118 CAMEL_TCP_STREAM_SSL_ENABLE_SSL3);
122 g_return_val_if_reached (NULL);
125 camel_session_get_socks_proxy (session, host, &socks_host, &socks_port);
127 if (socks_host != NULL) {
128 camel_tcp_stream_set_socks_proxy (
129 CAMEL_TCP_STREAM (stream),
130 socks_host, socks_port);
134 status = camel_tcp_stream_connect (
135 CAMEL_TCP_STREAM (stream), host,
136 service_name, default_port, cancellable, error);
139 /* Translators: The first '%s' is replaced with a host name, the second '%s' with service name or port number */
141 error, _("Could not connect to '%s:%s': "), host, service_name ? service_name : "???");
142 g_object_unref (stream);
148 g_object_unref (session);
154 camel_network_service_default_init (CamelNetworkServiceInterface *interface)
156 interface->connect_sync = network_service_connect_sync;
160 camel_network_service_init (CamelNetworkService *service)
162 /* This is called from CamelService during instance
163 * construction. It is not part of the public API. */
165 g_return_if_fail (CAMEL_IS_NETWORK_SERVICE (service));
167 g_object_set_data_full (
168 G_OBJECT (service), PRIVATE_KEY,
169 network_service_private_new (service),
170 (GDestroyNotify) network_service_private_free);
174 * camel_network_service_get_service_name:
175 * @service: a #CamelNetworkService
176 * @method: a #CamelNetworkSecurityMethod
178 * Returns the standard network service name for @service and the security
179 * method @method, as defined in /etc/services. For example, the service
180 * name for unencrypted IMAP or encrypted IMAP using STARTTLS is "imap",
181 * but the service name for IMAP over SSL is "imaps".
183 * Returns: the network service name for @service and @method, or %NULL
188 camel_network_service_get_service_name (CamelNetworkService *service,
189 CamelNetworkSecurityMethod method)
191 CamelNetworkServiceInterface *interface;
192 const gchar *service_name = NULL;
194 g_return_val_if_fail (CAMEL_IS_NETWORK_SERVICE (service), NULL);
196 interface = CAMEL_NETWORK_SERVICE_GET_INTERFACE (service);
198 if (interface->get_service_name != NULL)
199 service_name = interface->get_service_name (service, method);
205 * camel_network_service_get_default_port:
206 * @service: a #CamelNetworkService
207 * @method: a #CamelNetworkSecurityMethod
209 * Returns the default network port number for @service and the security
210 * method @method, as defined in /etc/services. For example, the default
211 * port for unencrypted IMAP or encrypted IMAP using STARTTLS is 143, but
212 * the default port for IMAP over SSL is 993.
214 * Returns: the default port number for @service and @method
219 camel_network_service_get_default_port (CamelNetworkService *service,
220 CamelNetworkSecurityMethod method)
222 CamelNetworkServiceInterface *interface;
223 guint16 default_port = 0;
225 g_return_val_if_fail (CAMEL_IS_NETWORK_SERVICE (service), 0);
227 interface = CAMEL_NETWORK_SERVICE_GET_INTERFACE (service);
229 if (interface->get_default_port != NULL)
230 default_port = interface->get_default_port (service, method);
236 * camel_network_service_connect_sync:
237 * @service: a #CamelNetworkService
238 * @cancellable: optional #GCancellable object, or %NULL
239 * @error: return location for a #GError, or %NULL
241 * Attempts to establish a network connection to the server described by
242 * @service, using the preferred #CamelNetworkSettings:security-method to
243 * secure the connection. If a connection cannot be established, or the
244 * connection attempt is cancelled, the function sets @error and returns
247 * Returns: a #CamelStream, or %NULL
252 camel_network_service_connect_sync (CamelNetworkService *service,
253 GCancellable *cancellable,
256 CamelNetworkServiceInterface *interface;
258 g_return_val_if_fail (CAMEL_IS_NETWORK_SERVICE (service), NULL);
260 interface = CAMEL_NETWORK_SERVICE_GET_INTERFACE (service);
261 g_return_val_if_fail (interface->connect_sync != NULL, NULL);
263 return interface->connect_sync (service, cancellable, error);