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