1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2010 Collabora, Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  *
18  * Authors: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
19  */
20 
21 #include <config.h>
22 #include <glib.h>
23 #include <string.h>
24 
25 #include <gio/gsocketaddress.h>
26 
27 #include "gproxyaddress.h"
28 #include "glibintl.h"
29 
30 /**
31  * SECTION:gproxyaddress
32  * @short_description: An internet address with proxy information
33  * @include: gio/gio.h
34  *
35  * Support for proxied #GInetSocketAddress.
36  */
37 
38 /**
39  * GProxyAddress:
40  *
41  * A #GInetSocketAddress representing a connection via a proxy server
42  *
43  * Since: 2.26
44  **/
45 
46 /**
47  * GProxyAddressClass:
48  *
49  * Class structure for #GProxyAddress.
50  *
51  * Since: 2.26
52  **/
53 
54 enum
55 {
56   PROP_0,
57   PROP_PROTOCOL,
58   PROP_DESTINATION_PROTOCOL,
59   PROP_DESTINATION_HOSTNAME,
60   PROP_DESTINATION_PORT,
61   PROP_USERNAME,
62   PROP_PASSWORD,
63   PROP_URI
64 };
65 
66 struct _GProxyAddressPrivate
67 {
68   gchar 	 *uri;
69   gchar 	 *protocol;
70   gchar		 *username;
71   gchar		 *password;
72   gchar 	 *dest_protocol;
73   gchar 	 *dest_hostname;
74   guint16 	  dest_port;
75 };
76 
G_DEFINE_TYPE_WITH_PRIVATE(GProxyAddress,g_proxy_address,G_TYPE_INET_SOCKET_ADDRESS)77 G_DEFINE_TYPE_WITH_PRIVATE (GProxyAddress, g_proxy_address, G_TYPE_INET_SOCKET_ADDRESS)
78 
79 static void
80 g_proxy_address_finalize (GObject *object)
81 {
82   GProxyAddress *proxy = G_PROXY_ADDRESS (object);
83 
84   g_free (proxy->priv->uri);
85   g_free (proxy->priv->protocol);
86   g_free (proxy->priv->username);
87   g_free (proxy->priv->password);
88   g_free (proxy->priv->dest_hostname);
89   g_free (proxy->priv->dest_protocol);
90 
91   G_OBJECT_CLASS (g_proxy_address_parent_class)->finalize (object);
92 }
93 
94 static void
g_proxy_address_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)95 g_proxy_address_set_property (GObject      *object,
96 			      guint         prop_id,
97 			      const GValue *value,
98 			      GParamSpec   *pspec)
99 {
100   GProxyAddress *proxy = G_PROXY_ADDRESS (object);
101 
102   switch (prop_id)
103     {
104     case PROP_PROTOCOL:
105       g_free (proxy->priv->protocol);
106       proxy->priv->protocol = g_value_dup_string (value);
107       break;
108 
109     case PROP_DESTINATION_PROTOCOL:
110       g_free (proxy->priv->dest_protocol);
111       proxy->priv->dest_protocol = g_value_dup_string (value);
112       break;
113 
114     case PROP_DESTINATION_HOSTNAME:
115       g_free (proxy->priv->dest_hostname);
116       proxy->priv->dest_hostname = g_value_dup_string (value);
117       break;
118 
119     case PROP_DESTINATION_PORT:
120       proxy->priv->dest_port = g_value_get_uint (value);
121       break;
122 
123     case PROP_USERNAME:
124       g_free (proxy->priv->username);
125       proxy->priv->username = g_value_dup_string (value);
126       break;
127 
128     case PROP_PASSWORD:
129       g_free (proxy->priv->password);
130       proxy->priv->password = g_value_dup_string (value);
131       break;
132 
133     case PROP_URI:
134       g_free (proxy->priv->uri);
135       proxy->priv->uri = g_value_dup_string (value);
136       break;
137 
138     default:
139       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
140     }
141 }
142 
143 static void
g_proxy_address_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)144 g_proxy_address_get_property (GObject    *object,
145 			      guint       prop_id,
146 			      GValue     *value,
147 			      GParamSpec *pspec)
148 {
149   GProxyAddress *proxy = G_PROXY_ADDRESS (object);
150 
151   switch (prop_id)
152     {
153       case PROP_PROTOCOL:
154 	g_value_set_string (value, proxy->priv->protocol);
155 	break;
156 
157       case PROP_DESTINATION_PROTOCOL:
158 	g_value_set_string (value, proxy->priv->dest_protocol);
159 	break;
160 
161       case PROP_DESTINATION_HOSTNAME:
162 	g_value_set_string (value, proxy->priv->dest_hostname);
163 	break;
164 
165       case PROP_DESTINATION_PORT:
166 	g_value_set_uint (value, proxy->priv->dest_port);
167 	break;
168 
169       case PROP_USERNAME:
170 	g_value_set_string (value, proxy->priv->username);
171 	break;
172 
173       case PROP_PASSWORD:
174 	g_value_set_string (value, proxy->priv->password);
175 	break;
176 
177       case PROP_URI:
178 	g_value_set_string (value, proxy->priv->uri);
179 	break;
180 
181       default:
182 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
183     }
184 }
185 
186 static void
g_proxy_address_class_init(GProxyAddressClass * klass)187 g_proxy_address_class_init (GProxyAddressClass *klass)
188 {
189   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
190 
191   gobject_class->finalize = g_proxy_address_finalize;
192   gobject_class->set_property = g_proxy_address_set_property;
193   gobject_class->get_property = g_proxy_address_get_property;
194 
195   g_object_class_install_property (gobject_class,
196 				   PROP_PROTOCOL,
197 				   g_param_spec_string ("protocol",
198 						       P_("Protocol"),
199 						       P_("The proxy protocol"),
200 						       NULL,
201 						       G_PARAM_READWRITE |
202 						       G_PARAM_CONSTRUCT_ONLY |
203 						       G_PARAM_STATIC_STRINGS));
204 
205   g_object_class_install_property (gobject_class,
206 				   PROP_USERNAME,
207 				   g_param_spec_string ("username",
208 						       P_("Username"),
209 						       P_("The proxy username"),
210 						       NULL,
211 						       G_PARAM_READWRITE |
212 						       G_PARAM_CONSTRUCT_ONLY |
213 						       G_PARAM_STATIC_STRINGS));
214 
215   g_object_class_install_property (gobject_class,
216 				   PROP_PASSWORD,
217 				   g_param_spec_string ("password",
218 						       P_("Password"),
219 						       P_("The proxy password"),
220 						       NULL,
221 						       G_PARAM_READWRITE |
222 						       G_PARAM_CONSTRUCT_ONLY |
223 						       G_PARAM_STATIC_STRINGS));
224 
225   /**
226    * GProxyAddress:destination-protocol:
227    *
228    * The protocol being spoke to the destination host, or %NULL if
229    * the #GProxyAddress doesn't know.
230    *
231    * Since: 2.34
232    */
233   g_object_class_install_property (gobject_class,
234 				   PROP_DESTINATION_PROTOCOL,
235 				   g_param_spec_string ("destination-protocol",
236 						       P_("Destination Protocol"),
237 						       P_("The proxy destination protocol"),
238 						       NULL,
239 						       G_PARAM_READWRITE |
240 						       G_PARAM_CONSTRUCT_ONLY |
241 						       G_PARAM_STATIC_STRINGS));
242 
243   g_object_class_install_property (gobject_class,
244 				   PROP_DESTINATION_HOSTNAME,
245 				   g_param_spec_string ("destination-hostname",
246 						       P_("Destination Hostname"),
247 						       P_("The proxy destination hostname"),
248 						       NULL,
249 						       G_PARAM_READWRITE |
250 						       G_PARAM_CONSTRUCT_ONLY |
251 						       G_PARAM_STATIC_STRINGS));
252 
253   g_object_class_install_property (gobject_class,
254 				   PROP_DESTINATION_PORT,
255 				   g_param_spec_uint ("destination-port",
256 						      P_("Destination Port"),
257 						      P_("The proxy destination port"),
258 						      0, 65535, 0,
259 						      G_PARAM_READWRITE |
260 						      G_PARAM_CONSTRUCT_ONLY |
261 						      G_PARAM_STATIC_STRINGS));
262 
263   /**
264    * GProxyAddress:uri:
265    *
266    * The URI string that the proxy was constructed from (or %NULL
267    * if the creator didn't specify this).
268    *
269    * Since: 2.34
270    */
271   g_object_class_install_property (gobject_class,
272 				   PROP_URI,
273 				   g_param_spec_string ("uri",
274 							P_("URI"),
275 							P_("The proxy’s URI"),
276 							NULL,
277 							G_PARAM_READWRITE |
278 							G_PARAM_CONSTRUCT_ONLY |
279 							G_PARAM_STATIC_STRINGS));
280 }
281 
282 static void
g_proxy_address_init(GProxyAddress * proxy)283 g_proxy_address_init (GProxyAddress *proxy)
284 {
285   proxy->priv = g_proxy_address_get_instance_private (proxy);
286   proxy->priv->protocol = NULL;
287   proxy->priv->username = NULL;
288   proxy->priv->password = NULL;
289   proxy->priv->dest_hostname = NULL;
290   proxy->priv->dest_port = 0;
291 }
292 
293 /**
294  * g_proxy_address_new:
295  * @inetaddr: The proxy server #GInetAddress.
296  * @port: The proxy server port.
297  * @protocol: The proxy protocol to support, in lower case (e.g. socks, http).
298  * @dest_hostname: The destination hostname the proxy should tunnel to.
299  * @dest_port: The destination port to tunnel to.
300  * @username: (nullable): The username to authenticate to the proxy server
301  *     (or %NULL).
302  * @password: (nullable): The password to authenticate to the proxy server
303  *     (or %NULL).
304  *
305  * Creates a new #GProxyAddress for @inetaddr with @protocol that should
306  * tunnel through @dest_hostname and @dest_port.
307  *
308  * (Note that this method doesn't set the #GProxyAddress:uri or
309  * #GProxyAddress:destination-protocol fields; use g_object_new()
310  * directly if you want to set those.)
311  *
312  * Returns: a new #GProxyAddress
313  *
314  * Since: 2.26
315  */
316 GSocketAddress *
g_proxy_address_new(GInetAddress * inetaddr,guint16 port,const gchar * protocol,const gchar * dest_hostname,guint16 dest_port,const gchar * username,const gchar * password)317 g_proxy_address_new (GInetAddress  *inetaddr,
318 		     guint16        port,
319 		     const gchar   *protocol,
320 		     const gchar   *dest_hostname,
321 		     guint16        dest_port,
322 		     const gchar   *username,
323 		     const gchar   *password)
324 {
325   return g_object_new (G_TYPE_PROXY_ADDRESS,
326 		       "address", inetaddr,
327 		       "port", port,
328 		       "protocol", protocol,
329 		       "destination-hostname", dest_hostname,
330 		       "destination-port", dest_port,
331 		       "username", username,
332 		       "password", password,
333 		       NULL);
334 }
335 
336 
337 /**
338  * g_proxy_address_get_protocol:
339  * @proxy: a #GProxyAddress
340  *
341  * Gets @proxy's protocol. eg, "socks" or "http"
342  *
343  * Returns: the @proxy's protocol
344  *
345  * Since: 2.26
346  */
347 const gchar *
g_proxy_address_get_protocol(GProxyAddress * proxy)348 g_proxy_address_get_protocol (GProxyAddress *proxy)
349 {
350   return proxy->priv->protocol;
351 }
352 
353 /**
354  * g_proxy_address_get_destination_protocol:
355  * @proxy: a #GProxyAddress
356  *
357  * Gets the protocol that is being spoken to the destination
358  * server; eg, "http" or "ftp".
359  *
360  * Returns: the @proxy's destination protocol
361  *
362  * Since: 2.34
363  */
364 const gchar *
g_proxy_address_get_destination_protocol(GProxyAddress * proxy)365 g_proxy_address_get_destination_protocol (GProxyAddress *proxy)
366 {
367   return proxy->priv->dest_protocol;
368 }
369 
370 /**
371  * g_proxy_address_get_destination_hostname:
372  * @proxy: a #GProxyAddress
373  *
374  * Gets @proxy's destination hostname; that is, the name of the host
375  * that will be connected to via the proxy, not the name of the proxy
376  * itself.
377  *
378  * Returns: the @proxy's destination hostname
379  *
380  * Since: 2.26
381  */
382 const gchar *
g_proxy_address_get_destination_hostname(GProxyAddress * proxy)383 g_proxy_address_get_destination_hostname (GProxyAddress *proxy)
384 {
385   return proxy->priv->dest_hostname;
386 }
387 
388 /**
389  * g_proxy_address_get_destination_port:
390  * @proxy: a #GProxyAddress
391  *
392  * Gets @proxy's destination port; that is, the port on the
393  * destination host that will be connected to via the proxy, not the
394  * port number of the proxy itself.
395  *
396  * Returns: the @proxy's destination port
397  *
398  * Since: 2.26
399  */
400 guint16
g_proxy_address_get_destination_port(GProxyAddress * proxy)401 g_proxy_address_get_destination_port (GProxyAddress *proxy)
402 {
403   return proxy->priv->dest_port;
404 }
405 
406 /**
407  * g_proxy_address_get_username:
408  * @proxy: a #GProxyAddress
409  *
410  * Gets @proxy's username.
411  *
412  * Returns: (nullable): the @proxy's username
413  *
414  * Since: 2.26
415  */
416 const gchar *
g_proxy_address_get_username(GProxyAddress * proxy)417 g_proxy_address_get_username (GProxyAddress *proxy)
418 {
419   return proxy->priv->username;
420 }
421 
422 /**
423  * g_proxy_address_get_password:
424  * @proxy: a #GProxyAddress
425  *
426  * Gets @proxy's password.
427  *
428  * Returns: (nullable): the @proxy's password
429  *
430  * Since: 2.26
431  */
432 const gchar *
g_proxy_address_get_password(GProxyAddress * proxy)433 g_proxy_address_get_password (GProxyAddress *proxy)
434 {
435   return proxy->priv->password;
436 }
437 
438 
439 /**
440  * g_proxy_address_get_uri:
441  * @proxy: a #GProxyAddress
442  *
443  * Gets the proxy URI that @proxy was constructed from.
444  *
445  * Returns: (nullable): the @proxy's URI, or %NULL if unknown
446  *
447  * Since: 2.34
448  */
449 const gchar *
g_proxy_address_get_uri(GProxyAddress * proxy)450 g_proxy_address_get_uri (GProxyAddress *proxy)
451 {
452   return proxy->priv->uri;
453 }
454