1 //=============================================================================
2 //
3 //   File : OptionsWidget_connection.cpp
4 //   Creation date : Sat Nov 24 04:25:16 2001 GMT by Szymon Stefanek
5 //
6 //   This file is part of the KVIrc IRC client distribution
7 //   Copyright (C) 2001 Szymon Stefanek (pragma at kvirc dot net)
8 //   copyright (C) 2008 Elvio Basello (hellvis69 at netsons dot org)
9 //
10 //   This program is FREE software. You can redistribute it and/or
11 //   modify it under the terms of the GNU General Public License
12 //   as published by the Free Software Foundation; either version 2
13 //   of the License, or (at your option) any later version.
14 //
15 //   This program is distributed in the HOPE that it will be USEFUL,
16 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 //   See the GNU General Public License for more details.
19 //
20 //   You should have received a copy of the GNU General Public License
21 //   along with this program. If not, write to the Free Software Foundation,
22 //   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 //
24 //=============================================================================
25 
26 #include "OptionsWidget_connection.h"
27 
28 #include "kvi_settings.h"
29 #include "KviLocale.h"
30 #include "KviOptions.h"
31 #include "KviIconManager.h"
32 
33 #include <QRadioButton>
34 
OptionsWidget_connection(QWidget * parent)35 OptionsWidget_connection::OptionsWidget_connection(QWidget * parent)
36     : KviOptionsWidget(parent)
37 {
38 	setObjectName("connection_options_widget");
39 	createLayout();
40 
41 	KviBoolSelector * b1;
42 	KviBoolSelector * b;
43 
44 	KviTalGroupBox * gbox = addGroupBox(0, 0, 0, 0, Qt::Horizontal, __tr2qs_ctx("On Disconnect", "options"));
45 
46 	b1 = addBoolSelector(gbox, __tr2qs_ctx("Keep channels open", "options"), KviOption_boolKeepChannelsOpenOnDisconnect, true);
47 	mergeTip(b1, __tr2qs_ctx("This option will cause KVIrc to keep channels open after disconnect.", "options"));
48 
49 	b1 = addBoolSelector(gbox, __tr2qs_ctx("Keep queries open", "options"), KviOption_boolKeepQueriesOpenOnDisconnect, true);
50 	mergeTip(b1, __tr2qs_ctx("This option will cause KVIrc to keep queries open after disconnect.", "options"));
51 
52 	gbox = addGroupBox(0, 1, 0, 1, Qt::Horizontal, __tr2qs_ctx("On Unexpected Disconnect", "options"));
53 
54 	b1 = addBoolSelector(gbox, __tr2qs_ctx("Keep channels open", "options"), KviOption_boolKeepChannelsOpenOnUnexpectedDisconnect, true);
55 	mergeTip(b1, __tr2qs_ctx("This option will cause KVIrc to keep channels open after an unexpected disconnect.", "options"));
56 
57 	b1 = addBoolSelector(gbox, __tr2qs_ctx("Keep queries open", "options"), KviOption_boolKeepQueriesOpenOnUnexpectedDisconnect, true);
58 	mergeTip(b1, __tr2qs_ctx("This option will cause KVIrc to keep queries open after an unexpected disconnect.", "options"));
59 
60 	b1 = addBoolSelector(gbox, __tr2qs_ctx("Rejoin channels after reconnect", "options"), KviOption_boolRejoinChannelsAfterReconnect, true);
61 	mergeTip(b1, __tr2qs_ctx("This option will cause KVIrc to rejoin channels after a successful reconnect attempt.", "options"));
62 
63 	b1 = addBoolSelector(gbox, __tr2qs_ctx("Reopen queries after reconnect", "options"), KviOption_boolReopenQueriesAfterReconnect, true);
64 	mergeTip(b1, __tr2qs_ctx("This option will cause KVIrc to reopen query windows after a successful reconnect attempt.", "options"));
65 
66 	b = addBoolSelector(gbox, __tr2qs_ctx("Automatically reconnect", "options"), KviOption_boolAutoReconnectOnUnexpectedDisconnect);
67 	mergeTip(b, __tr2qs_ctx("This option will enable auto-reconnecting after an unexpected disconnect. "
68 	                        "An unexpected disconnect is the <b>termination</b> of a <b>fully connected IRC session</b> "
69 	                        "that was <b>not requested by the user</b> by the means of the QUIT message."
70 	                        "<p><b>Warning:</b> If you use /RAW to send a QUIT message to the server, "
71 	                        "this option will not behave correctly, since does not detect the outgoing "
72 	                        "QUIT message and will attempt to reconnect after the server has closed the connection. "
73 	                        "For this reason, always use the /QUIT command to close your connections. "
74 	                        "This option may also behave incorrectly with bouncers that support "
75 	                        "detaching, in this case a solution could be to prepare an alias that sends the "
76 	                        "bouncer \"detach\" command immediately before the \"quit\" command.<br>"
77 	                        "<tt>alias(bncdetach){ raw bouncer detach; quit; }</tt></p>",
78 	                "options"));
79 
80 	KviUIntSelector * u = addUIntSelector(gbox, __tr2qs_ctx("Maximum attempts (0 = unlimited):", "options"),
81 	    KviOption_uintMaxAutoReconnectAttempts, 0, 100, 5, KVI_OPTION_BOOL(KviOption_boolAutoReconnectOnUnexpectedDisconnect));
82 	connect(b, SIGNAL(toggled(bool)), u, SLOT(setEnabled(bool)));
83 
84 	u = addUIntSelector(gbox, __tr2qs_ctx("Delay between attempts:", "options"), KviOption_uintAutoReconnectDelay, 0, 86400, 5,
85 	    KVI_OPTION_BOOL(KviOption_boolAutoReconnectOnUnexpectedDisconnect));
86 	u->setSuffix(__tr2qs_ctx(" sec", "options"));
87 	connect(b, SIGNAL(toggled(bool)), u, SLOT(setEnabled(bool)));
88 
89 	mergeTip(u, __tr2qs_ctx("Minimum value: <b>0 sec</b><br>Maximum value: <b>86400 sec</b>", "options"));
90 
91 	addRowSpacer(0, 3, 4, 3);
92 }
93 
94 OptionsWidget_connection::~OptionsWidget_connection()
95     = default;
96 
OptionsWidget_connectionSsl(QWidget * parent)97 OptionsWidget_connectionSsl::OptionsWidget_connectionSsl(QWidget * parent)
98     : KviOptionsWidget(parent)
99 {
100 	setObjectName("ssl_options_widget");
101 	createLayout();
102 
103 #ifdef COMPILE_SSL_SUPPORT
104 
105 	KviBoolSelector * b;
106 	KviFileSelector * f;
107 	KviPasswordSelector * p;
108 
109 	KviTalGroupBox * gbox = addGroupBox(0, 0, 0, 0, Qt::Horizontal, __tr2qs_ctx("Certificate", "options"));
110 
111 	b = addBoolSelector(gbox, __tr2qs_ctx("Use SSL certificate (PEM format only)", "options"),
112 	    &(KVI_OPTION_BOOL(KviOption_boolUseSSLCertificate)), true);
113 
114 	f = addFileSelector(gbox, __tr2qs_ctx("Certificate location:", "options"), &(KVI_OPTION_STRING(KviOption_stringSSLCertificatePath)),
115 	    KVI_OPTION_BOOL(KviOption_boolUseSSLCertificate));
116 	connect(b, SIGNAL(toggled(bool)), f, SLOT(setEnabled(bool)));
117 
118 	p = new KviPasswordSelector(gbox, __tr2qs_ctx("Certificate password:", "options"), &(KVI_OPTION_STRING(KviOption_stringSSLCertificatePass)),
119 	    KVI_OPTION_BOOL(KviOption_boolUseSSLCertificate));
120 	connect(b, SIGNAL(toggled(bool)), p, SLOT(setEnabled(bool)));
121 
122 	gbox = addGroupBox(0, 1, 0, 1, Qt::Horizontal, __tr2qs_ctx("Private Key", "options"));
123 
124 	b = addBoolSelector(gbox, __tr2qs_ctx("Use SSL private key", "options"), &(KVI_OPTION_BOOL(KviOption_boolUseSSLPrivateKey)), true);
125 	f = addFileSelector(gbox, __tr2qs_ctx("Private key location:", "options"), &(KVI_OPTION_STRING(KviOption_stringSSLPrivateKeyPath)),
126 	    KVI_OPTION_BOOL(KviOption_boolUseSSLPrivateKey));
127 	connect(b, SIGNAL(toggled(bool)), f, SLOT(setEnabled(bool)));
128 
129 	p = addPasswordSelector(gbox, __tr2qs_ctx("Private key password:", "options"), &(KVI_OPTION_STRING(KviOption_stringSSLPrivateKeyPass)),
130 	    KVI_OPTION_BOOL(KviOption_boolUseSSLPrivateKey));
131 	connect(b, SIGNAL(toggled(bool)), p, SLOT(setEnabled(bool)));
132 
133 	addRowSpacer(0, 3, 0, 3);
134 #else
135 	addLabel(0, 0, 0, 0, __tr2qs_ctx("This executable has no SSL support.", "options"));
136 #endif
137 }
138 
139 OptionsWidget_connectionSsl::~OptionsWidget_connectionSsl()
140     = default;
141 
OptionsWidget_connectionSocket(QWidget * parent)142 OptionsWidget_connectionSocket::OptionsWidget_connectionSocket(QWidget * parent)
143     : KviOptionsWidget(parent)
144 {
145 	setObjectName("transport_options_widget");
146 	createLayout();
147 
148 	KviUIntSelector * u;
149 	KviTalGroupBox * g;
150 	KviBoolSelector * b;
151 	KviStringSelector * s;
152 
153 	g = addGroupBox(0, 0, 0, 0, Qt::Horizontal, __tr2qs_ctx("Timeout Values", "options"));
154 	u = addUIntSelector(g, __tr2qs_ctx("Connect timeout:", "options"), KviOption_uintIrcSocketTimeout, 5, 6000, 60);
155 	u->setSuffix(__tr2qs_ctx(" sec", "options"));
156 	u = addUIntSelector(g, __tr2qs_ctx("Outgoing data queue flush timeout:", "options"), KviOption_uintSocketQueueFlushTimeout, 100, 2000, 500);
157 	u->setSuffix(__tr2qs_ctx(" msec", "options"));
158 	b = addBoolSelector(0, 1, 0, 1, __tr2qs_ctx("Limit outgoing traffic per connection", "options"), KviOption_boolLimitOutgoingTraffic);
159 	u = addUIntSelector(0, 2, 0, 2, __tr2qs_ctx("Limit to 1 message every:", "options"),
160 	    KviOption_uintOutgoingTrafficLimitUSeconds, 10000, 2000000, 10000001, KVI_OPTION_BOOL(KviOption_boolLimitOutgoingTraffic));
161 	u->setSuffix(__tr2qs_ctx(" usec", "options"));
162 	mergeTip(u, __tr2qs_ctx("Minimum value: <b>10000 usec</b><br>Maximum value: <b>10000000 usec</b>", "options"));
163 	connect(b, SIGNAL(toggled(bool)), u, SLOT(setEnabled(bool)));
164 
165 	g = addGroupBox(0, 3, 0, 3, Qt::Horizontal, __tr2qs_ctx("Network Interfaces", "options"));
166 
167 	b = addBoolSelector(g, __tr2qs_ctx("Bind IPv4 connections to:", "options"), KviOption_boolBindIrcIPv4ConnectionsToSpecifiedAddress);
168 	s = addStringSelector(g, "", KviOption_stringIPv4ConnectionBindAddress, KVI_OPTION_BOOL(KviOption_boolBindIrcIPv4ConnectionsToSpecifiedAddress));
169 	connect(b, SIGNAL(toggled(bool)), s, SLOT(setEnabled(bool)));
170 #ifdef COMPILE_IPV6_SUPPORT
171 	b = addBoolSelector(g, __tr2qs_ctx("Bind IPv6 connections to:", "options"), KviOption_boolBindIrcIPv6ConnectionsToSpecifiedAddress);
172 	s = addStringSelector(g, "", KviOption_stringIPv6ConnectionBindAddress, KVI_OPTION_BOOL(KviOption_boolBindIrcIPv6ConnectionsToSpecifiedAddress));
173 	connect(b, SIGNAL(toggled(bool)), s, SLOT(setEnabled(bool)));
174 #endif //!COMPILE_IPV6_SUPPORT
175 
176 	b = addBoolSelector(0, 4, 0, 4, __tr2qs_ctx("Pick random IP address for round-robin servers", "options"), KviOption_boolPickRandomIpAddressForRoundRobinServers);
177 	mergeTip(b, __tr2qs_ctx("This option will cause the KVIrc networking stack to pick up "
178 	                        "a random entry when multiple IP address are retrieved for a server "
179 	                        "DNS lookup. This is harmless and can fix some problems with caching "
180 	                        "DNS servers that do not properly rotate the records as the authoritative "
181 	                        "ones would do. On the other hand, you might want to disable it if "
182 	                        "you want to rely on the DNS server to provide the best choice.",
183 	                "options"));
184 
185 	b = addBoolSelector(0, 5, 0, 5, __tr2qs_ctx("Drop connection on SASL authentication failure", "options"), KviOption_boolDropConnectionOnSaslFailure);
186 	mergeTip(b, __tr2qs_ctx("This option will close the socket if no SASL authentication or any SASL fallback had succeeded.", "options"));
187 
188 	addRowSpacer(0, 6, 0, 6);
189 }
190 
191 OptionsWidget_connectionSocket::~OptionsWidget_connectionSocket()
192     = default;
193 
OptionsWidget_identService(QWidget * parent)194 OptionsWidget_identService::OptionsWidget_identService(QWidget * parent)
195     : KviOptionsWidget(parent)
196 {
197 	setObjectName("ident_options_widget");
198 	createLayout();
199 
200 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
201 	m_pEnableIdent = addBoolSelector(0, 0, 0, 0, __tr2qs_ctx("Enable Ident service", "options"), KviOption_boolUseIdentService);
202 #else
203 	m_pEnableIdent = addBoolSelector(0, 0, 0, 0, __tr2qs_ctx("Enable Ident service (bad practice on UNIX!)", "options"), KviOption_boolUseIdentService);
204 #endif
205 	connect(m_pEnableIdent, SIGNAL(toggled(bool)), this, SLOT(enableIpv4InIpv6(bool)));
206 
207 	KviTalGroupBox * gbox = addGroupBox(0, 1, 0, 1, Qt::Horizontal, __tr2qs_ctx("Output Verbosity", "options"), KVI_OPTION_BOOL(KviOption_boolUseIdentService));
208 	connect(m_pEnableIdent, SIGNAL(toggled(bool)), gbox, SLOT(setEnabled(bool)));
209 
210 	addLabel(gbox, __tr2qs_ctx("Output Ident service messages to:", "options"));
211 
212 	m_pActiveRadio = new QRadioButton(__tr2qs_ctx("Active window", "options"), gbox);
213 	m_pConsoleRadio = new QRadioButton(__tr2qs_ctx("Console", "options"), gbox);
214 	m_pQuietRadio = new QRadioButton(__tr2qs_ctx("Do not show any Ident service messages", "options"), gbox);
215 
216 	switch(KVI_OPTION_UINT(KviOption_uintIdentdOutputMode))
217 	{
218 		case KviIdentdOutputMode::Quiet:
219 			m_pQuietRadio->setChecked(true);
220 			break;
221 		case KviIdentdOutputMode::ToConsole:
222 			m_pConsoleRadio->setChecked(true);
223 			break;
224 		case KviIdentdOutputMode::ToActiveWindow:
225 			m_pActiveRadio->setChecked(true);
226 			break;
227 	}
228 
229 	KviBoolSelector * b;
230 	KviStringSelector * s;
231 	KviUIntSelector * u;
232 
233 	gbox = addGroupBox(0, 2, 0, 2, Qt::Horizontal, __tr2qs_ctx("Configuration", "options"), KVI_OPTION_BOOL(KviOption_boolUseIdentService));
234 
235 	b = addBoolSelector(gbox, __tr2qs_ctx("Enable Ident service only while connecting to server", "options"), KviOption_boolUseIdentServiceOnlyOnConnect);
236 	connect(m_pEnableIdent, SIGNAL(toggled(bool)), b, SLOT(setEnabled(bool)));
237 
238 	s = addStringSelector(gbox, __tr2qs_ctx("Ident username:", "options"), KviOption_stringIdentdUser, KVI_OPTION_BOOL(KviOption_boolUseIdentService));
239 	connect(m_pEnableIdent, SIGNAL(toggled(bool)), s, SLOT(setEnabled(bool)));
240 
241 	u = addUIntSelector(gbox, __tr2qs_ctx("Service port:", "options"), KviOption_uintIdentdPort, 0, 65535, 113, KVI_OPTION_BOOL(KviOption_boolUseIdentService));
242 	connect(m_pEnableIdent, SIGNAL(toggled(bool)), u, SLOT(setEnabled(bool)));
243 	connect(m_pEnableIdent, SIGNAL(toggled(bool)), gbox, SLOT(setEnabled(bool)));
244 
245 	gbox = addGroupBox(0, 3, 0, 3, Qt::Horizontal, __tr2qs_ctx("IPv6 Settings", "options"), KVI_OPTION_BOOL(KviOption_boolUseIdentService));
246 
247 	m_pEnableIpv6 = addBoolSelector(gbox, __tr2qs_ctx("Enable service for IPv6", "options"), KviOption_boolIdentdEnableIPv6,
248 	    KVI_OPTION_BOOL(KviOption_boolUseIdentService));
249 #ifdef COMPILE_IPV6_SUPPORT
250 	connect(m_pEnableIdent, SIGNAL(toggled(bool)), m_pEnableIpv6, SLOT(setEnabled(bool)));
251 	connect(m_pEnableIpv6, SIGNAL(toggled(bool)), this, SLOT(enableIpv4InIpv6(bool)));
252 #else
253 	m_pEnableIpv6->setEnabled(false);
254 #endif
255 	m_pIpv4InIpv6 = addBoolSelector(gbox, __tr2qs_ctx("IP stack treats IPv4 as part of IPv6 namespace", "options"), KviOption_boolIdentdIPv6ContainsIPv4,
256 	    KVI_OPTION_BOOL(KviOption_boolUseIdentService) && KVI_OPTION_BOOL(KviOption_boolIdentdEnableIPv6));
257 	connect(m_pEnableIdent, SIGNAL(toggled(bool)), gbox, SLOT(setEnabled(bool)));
258 
259 	addLabel(0, 4, 0, 4,
260 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
261 	    __tr2qs_ctx("<p><b>Warning:</b><br>"
262 	                "This is a <b>non RFC 1413 compliant</b> Ident daemon that implements "
263 	                "only a limited subset of the Identification Protocol specifications. If it is possible, install a "
264 	                "real Ident daemon.</p>",
265 	             "options")
266 #else
267 	    __tr2qs_ctx("<p><b>Warning:</b><br>"
268 	                "This is a <b>non RFC 1413 compliant</b> Ident daemon that implements "
269 	                "only a limited subset of the <b>Identification Protocol</b> specifications.<br>"
270 	                "On UNIX, you may also need root privileges to bind to the auth port (113).<br>"
271 	                "It is <b>highly recommended</b> that a <b>real</b> system-wide Ident daemon be used instead, "
272 	                "or none at all if Ident is not required.</p>",
273 	             "options")
274 #endif
275 	        );
276 
277 	addRowSpacer(0, 5, 0, 5);
278 }
279 
280 OptionsWidget_identService::~OptionsWidget_identService()
281     = default;
282 
commit()283 void OptionsWidget_identService::commit()
284 {
285 	KviOptionsWidget::commit();
286 	if(m_pConsoleRadio->isChecked())
287 		KVI_OPTION_UINT(KviOption_uintIdentdOutputMode) = KviIdentdOutputMode::ToConsole;
288 	if(m_pActiveRadio->isChecked())
289 		KVI_OPTION_UINT(KviOption_uintIdentdOutputMode) = KviIdentdOutputMode::ToActiveWindow;
290 	if(m_pQuietRadio->isChecked())
291 		KVI_OPTION_UINT(KviOption_uintIdentdOutputMode) = KviIdentdOutputMode::Quiet;
292 }
293 
enableIpv4InIpv6(bool)294 void OptionsWidget_identService::enableIpv4InIpv6(bool)
295 {
296 #ifdef COMPILE_IPV6_SUPPORT
297 	m_pIpv4InIpv6->setEnabled(m_pEnableIdent->isChecked() && m_pEnableIpv6->isChecked());
298 #endif
299 }
300 
OptionsWidget_connectionAdvanced(QWidget * parent)301 OptionsWidget_connectionAdvanced::OptionsWidget_connectionAdvanced(QWidget * parent)
302     : KviOptionsWidget(parent)
303 {
304 	setObjectName("connection_advanced_options_widget");
305 }
306 
307 OptionsWidget_connectionAdvanced::~OptionsWidget_connectionAdvanced()
308     = default;
309