Added SOCKS proxy support.
[claws.git] / src / prefs_proxy.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2018 the Claws Mail team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program 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
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19
20 #include <glib.h>
21 #include <glib/gi18n.h>
22 #include <gtk/gtk.h>
23
24 #include "common/defs.h"
25 #include "common/proxy.h"
26
27 #include "gtk/menu.h"
28
29 #include "prefs_common.h"
30 #include "prefs_gtk.h"
31 #include "passwordstore.h"
32
33 typedef struct _ProxyPage
34 {
35         PrefsPage page;
36
37         GtkWidget *proxy_checkbtn;
38         GtkWidget *socks4_radiobtn;
39         GtkWidget *socks5_radiobtn;
40         GtkWidget *proxy_host_entry;
41         GtkWidget *proxy_port_spinbtn;
42         GtkWidget *proxy_auth_checkbtn;
43         GtkWidget *proxy_name_entry;
44         GtkWidget *proxy_pass_entry;
45 } ProxyPage;
46
47
48 static void prefs_proxy_create_widget(PrefsPage *_page, GtkWindow *window,
49                 gpointer data)
50 {
51         ProxyPage *page = (ProxyPage *)_page;
52
53         GtkWidget *vbox0, *vbox1, *vbox2;
54         GtkWidget *hbox;
55         GtkWidget *label;
56         GtkWidget *proxy_checkbtn;
57         GtkWidget *socks4_radiobtn, *socks5_radiobtn;
58         GtkWidget *proxy_auth_checkbtn;
59         GtkWidget *proxy_frame;
60         GtkWidget *proxy_host_entry;
61         GtkWidget *proxy_port_spinbtn;
62         GtkWidget *proxy_name_entry;
63         GtkWidget *proxy_pass_entry;
64         GtkWidget *button;
65         gchar *buf;
66
67         vbox0 = gtk_vbox_new(FALSE, VSPACING);
68         gtk_container_set_border_width(GTK_CONTAINER(vbox0), VBOX_BORDER);
69
70         proxy_checkbtn = gtk_check_button_new_with_label(_("Use proxy server"));
71         PACK_FRAME(vbox0, proxy_frame, NULL);
72         gtk_frame_set_label_widget(GTK_FRAME(proxy_frame), proxy_checkbtn);
73
74         vbox1 = gtk_vbox_new(FALSE, VSPACING_NARROW);
75         gtk_container_set_border_width(GTK_CONTAINER(vbox1), 8);
76         gtk_container_add(GTK_CONTAINER(proxy_frame), vbox1);
77
78         hbox = gtk_hbox_new(FALSE, 8);
79         gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 0);
80
81         socks4_radiobtn = gtk_radio_button_new_with_label(NULL, "SOCKS4");
82         gtk_box_pack_start(GTK_BOX(hbox), socks4_radiobtn, FALSE, FALSE, 0);
83         g_object_set_data(G_OBJECT(socks4_radiobtn), MENU_VAL_ID,
84                         GINT_TO_POINTER(PROXY_SOCKS4));
85
86         socks5_radiobtn = gtk_radio_button_new_with_label_from_widget(
87                         GTK_RADIO_BUTTON(socks4_radiobtn), "SOCKS5");
88         gtk_box_pack_start(GTK_BOX(hbox), socks5_radiobtn, FALSE, FALSE, 0);
89         g_object_set_data(G_OBJECT(socks5_radiobtn), MENU_VAL_ID,
90                         GINT_TO_POINTER(PROXY_SOCKS5));
91
92         hbox = gtk_hbox_new(FALSE, 8);
93         gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 0);
94
95         label = gtk_label_new(_("Hostname"));
96         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
97
98         proxy_host_entry = gtk_entry_new();
99         gtk_widget_set_size_request(proxy_host_entry, DEFAULT_ENTRY_WIDTH, -1);
100         gtk_box_pack_start(GTK_BOX(hbox), proxy_host_entry, TRUE, TRUE, 0);
101
102         label = gtk_label_new(_("Port"));
103         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
104
105         proxy_port_spinbtn = gtk_spin_button_new_with_range(0, 65535, 1080);
106         gtk_widget_set_size_request(proxy_port_spinbtn, 64, -1);
107         gtk_box_pack_start(GTK_BOX(hbox), proxy_port_spinbtn, FALSE, FALSE, 0);
108
109         vbox2 = gtk_vbox_new(FALSE, VSPACING_NARROW);
110         gtk_box_pack_start(GTK_BOX(vbox1), vbox2, FALSE, FALSE, 0);
111
112         PACK_CHECK_BUTTON(vbox2, proxy_auth_checkbtn, _("Use authentication"));
113
114         hbox = gtk_hbox_new(FALSE, 0);
115         gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
116
117         label = gtk_label_new(_("Username"));
118         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
119
120         proxy_name_entry = gtk_entry_new();
121         gtk_widget_set_size_request(proxy_name_entry, DEFAULT_ENTRY_WIDTH, -1);
122         gtk_box_pack_start(GTK_BOX(hbox), proxy_name_entry, TRUE, TRUE, 0);
123
124         label = gtk_label_new(_("Password"));
125         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
126
127         proxy_pass_entry = gtk_entry_new();
128         gtk_widget_set_size_request(proxy_pass_entry, DEFAULT_ENTRY_WIDTH, -1);
129         gtk_entry_set_visibility(GTK_ENTRY(proxy_pass_entry), FALSE);
130         gtk_box_pack_start(GTK_BOX(hbox), proxy_pass_entry, TRUE, TRUE, 0);
131
132         gtk_widget_show_all(vbox0);
133
134         SET_TOGGLE_SENSITIVITY(proxy_checkbtn, vbox1);
135         SET_TOGGLE_SENSITIVITY(proxy_auth_checkbtn, hbox);
136         SET_TOGGLE_SENSITIVITY(socks5_radiobtn, vbox2);
137
138         /* Set widgets to their correct states, based on prefs. */
139         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(proxy_checkbtn),
140                         prefs_common.use_proxy);
141         if (prefs_common.proxy_info.proxy_type == PROXY_SOCKS4)
142                 button = socks4_radiobtn;
143         else
144                 button = socks5_radiobtn;
145         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
146         gtk_entry_set_text(GTK_ENTRY(proxy_host_entry),
147                         prefs_common.proxy_info.proxy_host);
148         gtk_spin_button_set_value(GTK_SPIN_BUTTON(proxy_port_spinbtn),
149                         (gdouble)prefs_common.proxy_info.proxy_port);
150         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(proxy_auth_checkbtn),
151                         prefs_common.proxy_info.use_proxy_auth);
152         gtk_entry_set_text(GTK_ENTRY(proxy_name_entry),
153                         prefs_common.proxy_info.proxy_name);
154
155         buf =
156                 passwd_store_get(PWS_CORE, PWS_CORE_PROXY, PWS_CORE_PROXY_PASS);
157         gtk_entry_set_text(GTK_ENTRY(proxy_pass_entry), buf != NULL ? buf : "");
158         if (buf != NULL) {
159                 memset(buf, 0, strlen(buf));
160                 g_free(buf);
161         }
162
163         page->proxy_checkbtn = proxy_checkbtn;
164         page->socks4_radiobtn = socks4_radiobtn;
165         page->socks5_radiobtn = socks5_radiobtn;
166         page->proxy_host_entry = proxy_host_entry;
167         page->proxy_port_spinbtn = proxy_port_spinbtn;
168         page->proxy_auth_checkbtn = proxy_auth_checkbtn;
169         page->proxy_name_entry = proxy_name_entry;
170         page->proxy_pass_entry = proxy_pass_entry;
171         page->page.widget = vbox0;
172 }
173
174
175 static void prefs_proxy_destroy_widget(PrefsPage *_page)
176 {
177 }
178
179
180 static void prefs_proxy_save(PrefsPage *_page)
181 {
182         ProxyPage *page = (ProxyPage *)_page;
183
184         prefs_common.use_proxy = gtk_toggle_button_get_active(
185                         GTK_TOGGLE_BUTTON(page->proxy_checkbtn));
186
187         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->socks4_radiobtn)))
188                 prefs_common.proxy_info.proxy_type = PROXY_SOCKS4;
189         else
190                 prefs_common.proxy_info.proxy_type = PROXY_SOCKS5;
191
192         g_free(prefs_common.proxy_info.proxy_host);
193         prefs_common.proxy_info.proxy_host = g_strdup(gtk_entry_get_text(
194                                 GTK_ENTRY(page->proxy_host_entry)));
195
196         prefs_common.proxy_info.proxy_port = gtk_spin_button_get_value_as_int(
197                         GTK_SPIN_BUTTON(page->proxy_port_spinbtn));
198
199         prefs_common.proxy_info.use_proxy_auth = gtk_toggle_button_get_active(
200                         GTK_TOGGLE_BUTTON(page->proxy_auth_checkbtn));
201
202         g_free(prefs_common.proxy_info.proxy_name);
203         prefs_common.proxy_info.proxy_name = g_strdup(gtk_entry_get_text(
204                                 GTK_ENTRY(page->proxy_name_entry)));
205
206         passwd_store_set(PWS_CORE, PWS_CORE_PROXY, PWS_CORE_PROXY_PASS,
207                         gtk_entry_get_text(GTK_ENTRY(page->proxy_pass_entry)), FALSE);
208 }
209
210
211 ProxyPage *prefs_proxy;
212
213 void prefs_proxy_init(void)
214 {
215         ProxyPage *page;
216         static gchar *path[3];
217
218         path[0] = _("Other");
219         path[1] = _("Proxy");
220         path[2] = NULL;
221
222         page = g_new0(ProxyPage, 1);
223         page->page.path = path;
224         page->page.create_widget = prefs_proxy_create_widget;
225         page->page.destroy_widget = prefs_proxy_destroy_widget;
226         page->page.save_page = prefs_proxy_save;
227         page->page.weight = 5.0;
228
229         prefs_gtk_register_page((PrefsPage *)page);
230         prefs_proxy = page;
231 }
232
233 void prefs_proxy_done(void)
234 {
235         prefs_gtk_unregister_page((PrefsPage *)prefs_proxy);
236         g_free(prefs_proxy);
237 }