Skip to content
API Documentation
BastionGuard™
proxy_config.hpp
Go to the documentation of this file.
1/*
2 * BastionGuard™
3 * Copyright (C) 2025–2026 Calogero Scarnà
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, version 3.
8 *
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
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 *
17 * BastionGuard™ is a trademark of Calogero Scarnà.
18 * The BastionGuard™ name and branding are not licensed under the GPL.
19 */
20
21#pragma once
22
23#include <string>
24#include <vector>
25#include <cstdlib>
26#include <iostream>
27#include <fstream>
28#include <sstream>
29#include <filesystem>
30#include <algorithm>
31#include <cctype>
32
33#include <glib/gi18n.h>
34#include "../SafeProcess.hpp"
35namespace BrowserProxy {
36
37namespace fs = std::filesystem;
38
39struct Settings {
40 std::string host;
41 int port;
42};
43
44// =============================================================================
45// Bypass list LAN — in vari formati richiesti da browser e desktop env.
46//
47// Copre tutto quanto rilevato anche da DomainFilter::is_local_network():
48// - localhost / *.local / *.lan / *.intranet / *.home.arpa / ...
49// - 127.0.0.0/8, 10.0.0.0/8, 172.16/12, 192.168/16, 169.254/16, 100.64/10
50// - ::1, fe80::/10, fc00::/7
51//
52// Note sui formati:
53// - Firefox `network.proxy.no_proxies_on`: stringa CSV, supporta CIDR e
54// pattern *.suffix.
55// - Chromium `ProxyBypassList`: CSV, supporta CIDR + il magic <-loopback>.
56// - GNOME `org.gnome.system.proxy.ignore-hosts`: array GVariant di stringhe,
57// supporta CIDR e domini.
58// - KDE `NoProxyFor`: CSV.
59// - Variabili d'ambiente `no_proxy` / `NO_PROXY`: CSV "tradizionale", non
60// supporta CIDR ma supporta hostname e suffissi `.example.com`.
61// =============================================================================
62
63// CSV completo con CIDR (per Firefox / Chromium / GNOME / KDE)
64static constexpr const char* LAN_BYPASS_CIDR =
65 "localhost,"
66 "127.0.0.0/8,"
67 "10.0.0.0/8,"
68 "172.16.0.0/12,"
69 "192.168.0.0/16,"
70 "169.254.0.0/16,"
71 "100.64.0.0/10,"
72 "::1,"
73 "fe80::/10,"
74 "fc00::/7,"
75 "*.local,*.lan,*.intranet,*.internal,*.home.arpa,*.corp,*.private";
76
77// Versione "no-CIDR" per env vars (no_proxy classico). Niente CIDR (non
78// supportato da curl/wget/glibc), ma copriamo i prefissi più comuni.
79static constexpr const char* LAN_BYPASS_NOCIDR =
80 "localhost,"
81 "127.0.0.1,"
82 "::1,"
83 "10.,"
84 "192.168.,"
85 "172.16.,172.17.,172.18.,172.19.,"
86 "172.20.,172.21.,172.22.,172.23.,"
87 "172.24.,172.25.,172.26.,172.27.,"
88 "172.28.,172.29.,172.30.,172.31.,"
89 "169.254.,"
90 ".local,.lan,.intranet,.internal,.home.arpa,.corp,.private";
91
92// Array GVariant per GNOME gsettings: "['x','y',...]" — usa virgolette singole.
93static constexpr const char* LAN_BYPASS_GVARIANT =
94 "['localhost',"
95 "'127.0.0.0/8',"
96 "'10.0.0.0/8',"
97 "'172.16.0.0/12',"
98 "'192.168.0.0/16',"
99 "'169.254.0.0/16',"
100 "'100.64.0.0/10',"
101 "'::1','fe80::/10','fc00::/7',"
102 "'*.local','*.lan','*.intranet','*.internal','*.home.arpa']";
103
104static std::string home_dir() {
105 const char* h = std::getenv("HOME");
106 return h ? h : "";
107}
108
109static void write_file(const fs::path& p, const std::string& content) {
110 std::ofstream f(p);
111 if (f) f << content;
112}
113
114static void remove_lines_containing(const fs::path& p, const std::string& needle) {
115 if (!fs::exists(p)) return;
116 std::ifstream in(p);
117 std::ostringstream out;
118 std::string line;
119 while (std::getline(in, line))
120 if (line.find(needle) == std::string::npos)
121 out << line << "\n";
122 in.close();
123 write_file(p, out.str());
124}
125
126static constexpr const char* FF_MARKER = "// BastionGuard-proxy";
127
128static fs::path firefox_active_profile(const fs::path& profiles_dir) {
129
130 const fs::path ini = profiles_dir / "profiles.ini";
131 if (!fs::exists(ini)) return {};
132
133 struct Profile {
134 std::string path;
135 bool is_relative = true;
136 bool is_default = false;
137 };
138
139 std::vector<Profile> profiles;
140 std::string install_default;
141 bool in_install = false;
142 bool in_profile = false;
143
144 std::ifstream f(ini);
145 std::string line;
146
147 while (std::getline(f, line)) {
148 line.erase(0, line.find_first_not_of(" \t\r\n"));
149 if (!line.empty()) line.erase(line.find_last_not_of(" \t\r\n") + 1);
150 if (line.empty() || line[0] == ';') continue;
151
152 if (line[0] == '[') {
153 in_install = (line.rfind("[Install", 0) == 0);
154 in_profile = (line.rfind("[Profile", 0) == 0);
155 if (in_profile) profiles.push_back({});
156 } else if (in_install) {
157 if (line.rfind("Default=", 0) == 0)
158 install_default = line.substr(8);
159 } else if (in_profile && !profiles.empty()) {
160 auto& p = profiles.back();
161 if (line.rfind("Default=1", 0) == 0) p.is_default = true;
162 else if (line.rfind("Path=", 0) == 0) p.path = line.substr(5);
163 else if (line.rfind("IsRelative=0", 0) == 0) p.is_relative = false;
164 }
165 }
166 if (!install_default.empty()) {
167 for (const auto& p : profiles) {
168 if (p.path == install_default) {
169 fs::path full = p.is_relative
170 ? profiles_dir / p.path
171 : fs::path(p.path);
172 if (fs::exists(full)) return full;
173 }
174 }
175
176 fs::path full = profiles_dir / install_default;
177 if (fs::exists(full)) return full;
178 }
179 for (const auto& p : profiles) {
180 if (!p.path.empty() && p.path.find("default-release") != std::string::npos) {
181 fs::path full = p.is_relative ? profiles_dir / p.path : fs::path(p.path);
182 if (fs::exists(full)) return full;
183 }
184 }
185
186 for (const auto& p : profiles) {
187 if (p.is_default && !p.path.empty()) {
188 fs::path full = p.is_relative ? profiles_dir / p.path : fs::path(p.path);
189 if (fs::exists(full)) return full;
190 }
191 }
192
193 std::error_code ec;
194 for (auto& e : fs::directory_iterator(profiles_dir, ec))
195 if (e.is_directory() && e.path().filename().string().find('.') != std::string::npos)
196 return e.path();
197
198 return {};
199}
200
201static void firefox_set_profile(const fs::path& profile, const Settings& s) {
202 if (profile.empty() || !fs::exists(profile)) return;
203
204 const fs::path user_js = profile / "user.js";
206
207 std::ofstream f(user_js, std::ios::app);
208 if (!f) return;
209
210 f << "\n" << FF_MARKER << "\n"
211 << "user_pref(\"network.proxy.type\", 1); " << FF_MARKER << "\n"
212 << "user_pref(\"network.proxy.http\", \"" << s.host << "\"); " << FF_MARKER << "\n"
213 << "user_pref(\"network.proxy.http_port\", " << s.port << "); " << FF_MARKER << "\n"
214 << "user_pref(\"network.proxy.ssl\", \"" << s.host << "\"); " << FF_MARKER << "\n"
215 << "user_pref(\"network.proxy.ssl_port\", " << s.port << "); " << FF_MARKER << "\n"
216 << "user_pref(\"network.proxy.no_proxies_on\", \"" << LAN_BYPASS_CIDR << "\"); " << FF_MARKER << "\n"
217 // Importante: Firefox di default proxy-a anche le risoluzioni DNS, e
218 // questo rompe Avahi/mDNS. Forziamo le LAN a NON essere proxate.
219 << "user_pref(\"network.proxy.allow_hijacking_localhost\", false); " << FF_MARKER << "\n";
220
221 char buf[256];
222 std::snprintf(buf, sizeof(buf),
223 _("[browser-proxy] Firefox profile configured: %s\n"), profile.c_str());
224 std::cerr << buf;
225}
226
227static void firefox_clear_profile(const fs::path& profile) {
228 if (profile.empty()) return;
229 remove_lines_containing(profile / "user.js", FF_MARKER);
230}
231
232static void configure_firefox_family(const Settings& s, bool clear) {
233 const std::string home = home_dir();
234 if (home.empty()) return;
235
236 const std::vector<fs::path> roots = {
237 fs::path(home) / ".mozilla/firefox",
238 fs::path(home) / ".librewolf",
239 fs::path(home) / ".waterfox",
240 fs::path(home) / "snap/firefox/common/.mozilla/firefox",
241 fs::path(home) / ".var/app/org.mozilla.firefox/.mozilla/firefox",
242 fs::path(home) / ".var/app/io.gitlab.librewolf-community/.librewolf",
243 };
244
245 for (const auto& root : roots) {
246 if (!fs::exists(root)) continue;
247 const fs::path profile = firefox_active_profile(root);
248 if (profile.empty()) continue;
249 if (clear) firefox_clear_profile(profile);
250 else firefox_set_profile(profile, s);
251 }
252}
253
254static std::string make_chromium_policy(const Settings& s) {
255 return "{\n"
256 " \"ProxyMode\": \"fixed_servers\",\n"
257 " \"ProxyServer\": \"http://" + s.host + ":" + std::to_string(s.port) + "\",\n"
258 " \"ProxyBypassList\": \"<-loopback>," + std::string(LAN_BYPASS_CIDR) + "\"\n"
259 "}\n";
260}
261
262static void chromium_set_policy(const fs::path& dir, const Settings& s) {
263 std::error_code ec;
264 fs::create_directories(dir, ec);
265 if (ec) return;
266
267 write_file(dir / "bastionguard_proxy.json", make_chromium_policy(s));
268
269 char buf[256];
270 std::snprintf(buf, sizeof(buf),
271 _("[browser-proxy] Chromium policy written: %s\n"), dir.c_str());
272 std::cerr << buf;
273}
274
275static void chromium_clear_policy(const fs::path& dir) {
276 std::error_code ec;
277 fs::remove(dir / "bastionguard_proxy.json", ec);
278}
279
280static void configure_chromium_family(const Settings& s, bool clear) {
281 const std::string home = home_dir();
282 if (home.empty()) return;
283
284 const std::vector<fs::path> dirs = {
285 fs::path(home) / ".config/chromium/policies/managed",
286 fs::path(home) / ".config/google-chrome/policies/managed",
287 fs::path(home) / ".config/BraveSoftware/Brave-Browser/policies/managed",
288 fs::path(home) / ".config/microsoft-edge/policies/managed",
289 fs::path(home) / ".config/vivaldi/policies/managed",
290 fs::path(home) / ".config/opera/policies/managed",
291 fs::path(home) / ".var/app/org.chromium.Chromium/config/chromium/policies/managed",
292 fs::path(home) / ".var/app/com.google.Chrome/config/google-chrome/policies/managed",
293 fs::path(home) / ".var/app/com.brave.Browser/config/BraveSoftware/Brave-Browser/policies/managed",
294 fs::path(home) / "snap/chromium/current/.config/chromium/policies/managed",
295 };
296
297 for (const auto& dir : dirs) {
298 if (clear) {
300 } else {
301 if (fs::exists(dir.parent_path().parent_path()))
302 chromium_set_policy(dir, s);
303 }
304 }
305}
306
307static constexpr const char* BG_CA_CERT = "/etc/BastionGuard/certs/BastionGuard-ca.crt.pem";
308static constexpr const char* BG_CA_NICK = "BastionGuard-CA";
309
310
311static bool nss_contains_ca(const std::string& database) {
312 const auto list = bg_process::run({"certutil", "-L", "-d", database});
313 return list.ok() && list.output.find(BG_CA_NICK) != std::string::npos;
314}
315
316static void install_ca_firefox_profile(const fs::path& profile) {
317 if (profile.empty() || !fs::exists(profile) || !fs::exists(BG_CA_CERT)) return;
318 if (nss_contains_ca(profile.string())) return;
319 (void)bg_process::run({"certutil", "-A", "-d", profile.string(),
320 "-n", BG_CA_NICK, "-t", "CT,C,C", "-i", BG_CA_CERT});
321}
322
324 const std::string home = home_dir();
325 if (home.empty()) return;
326
327 const std::vector<fs::path> roots = {
328 fs::path(home) / ".mozilla/firefox",
329 fs::path(home) / ".librewolf",
330 fs::path(home) / ".waterfox",
331 fs::path(home) / "snap/firefox/common/.mozilla/firefox",
332 fs::path(home) / ".var/app/org.mozilla.firefox/.mozilla/firefox",
333 fs::path(home) / ".var/app/io.gitlab.librewolf-community/.librewolf",
334 };
335
336 for (const auto& root : roots) {
337 if (!fs::exists(root)) continue;
338 const fs::path profile = firefox_active_profile(root);
339 if (!profile.empty())
341 }
342}
343
344static void install_ca_nssdb() {
345 if (!fs::exists(BG_CA_CERT)) return;
346 const std::string home = home_dir();
347 if (home.empty()) return;
348
349 const fs::path nssdb = fs::path(home) / ".pki/nssdb";
350 if (!fs::exists(nssdb)) {
351 std::error_code ec;
352 fs::create_directories(nssdb, ec);
353 if (!ec) (void)bg_process::run({"certutil", "-N", "--empty-password", "-d", nssdb.string()});
354 }
355 for (const fs::path& database : {nssdb,
356 fs::path(home) / "snap/chromium/current/.pki/nssdb"}) {
357 if (fs::exists(database) && !nss_contains_ca(database.string())) {
358 (void)bg_process::run({"certutil", "-A", "-d", database.string(),
359 "-n", BG_CA_NICK, "-t", "CT,C,C", "-i", BG_CA_CERT});
360 }
361 }
362}
363
365 if (!fs::exists(BG_CA_CERT)) {
366 std::cerr << _("[ca-install] CA cert not found, skipping\n");
367 return;
368 }
369
370 std::cerr << _("[ca-install] installing BastionGuard CA in browsers\n");
373}
374
375static void apply(const Settings& s) {
376 std::cerr << _("[browser-proxy] configuring browsers\n");
377 configure_firefox_family(s, false);
379}
380
381static void restore() {
382 std::cerr << _("[browser-proxy] restoring browser proxy settings\n");
383 configure_firefox_family({}, true);
385}
386
387} // namespace BrowserProxy
388
389
390namespace ProxyConfig {
391
392struct Settings {
393 std::string host;
394 int port;
395};
396
397static bool run(const std::vector<std::string>& args, bool silent = false) {
398 const auto result = bg_process::run(args, true, 256U * 1024U);
399 if (!result.ok() && !silent)
400 std::cerr << "[proxy-config] command failed: " << args.front() << " ("
401 << result.exit_code << ")\n";
402 return result.ok();
403}
404
405enum class DE { GNOME, KDE, XFCE, MATE, CINNAMON, LXQT, OTHER };
406
407static DE detect() {
408 const char* xdg = std::getenv("XDG_CURRENT_DESKTOP");
409 if (xdg) {
410 std::string d(xdg);
411 for (auto& c : d) c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
412 if (d.find("GNOME") != std::string::npos) return DE::GNOME;
413 if (d.find("KDE") != std::string::npos) return DE::KDE;
414 if (d.find("XFCE") != std::string::npos) return DE::XFCE;
415 if (d.find("MATE") != std::string::npos) return DE::MATE;
416 if (d.find("CINNAMON") != std::string::npos) return DE::CINNAMON;
417 if (d.find("LXQT") != std::string::npos) return DE::LXQT;
418 }
419 if (std::getenv("KDE_FULL_SESSION")) return DE::KDE;
420 if (std::getenv("GNOME_DESKTOP_SESSION_ID")) return DE::GNOME;
421 return DE::OTHER;
422}
423
424static void gnome_set(const Settings& s) {
425 const std::string port = std::to_string(s.port);
426 run({"gsettings", "set", "org.gnome.system.proxy", "mode", "manual"});
427 for (const char* scheme : {"http", "https"}) {
428 const std::string schema = std::string("org.gnome.system.proxy.") + scheme;
429 run({"gsettings", "set", schema, "host", s.host});
430 run({"gsettings", "set", schema, "port", port});
431 }
432 run({"gsettings", "set", "org.gnome.system.proxy.socks", "host", ""});
433 run({"gsettings", "set", "org.gnome.system.proxy.socks", "port", "0"});
434 run({"gsettings", "set", "org.gnome.system.proxy", "ignore-hosts",
436}
437
438static void gnome_clear() {
439 run({"gsettings", "set", "org.gnome.system.proxy", "mode", "none"});
440}
441
442static void kde_refresh() {
443 // Either kioclient version may be installed; failures are harmless.
444 if (!run({"kioclient6", "clear"}, true))
445 (void)run({"kioclient5", "clear"}, true);
446}
447
448static void kde_set(const Settings& s) {
449 const std::string hp = "http://" + s.host + ":" + std::to_string(s.port);
450 for (const char* bin : {"kwriteconfig6", "kwriteconfig5"}) {
451 const std::vector<std::string> common = {bin, "--file", "kioslaverc", "--group", "Proxy Settings"};
452 auto set = [&](const std::string& key, const std::string& val) {
453 std::vector<std::string> args = common;
454 args.insert(args.end(), {"--key", key, val});
455 (void)run(args, true);
456 };
457 set("ProxyType", "1");
458 set("httpProxy", hp);
459 set("httpsProxy", hp);
460 set("NoProxyFor", BrowserProxy::LAN_BYPASS_CIDR);
461 set("ReversedException", "false");
462 }
463 kde_refresh();
464}
465
466static void kde_clear() {
467 for (const char* bin : {"kwriteconfig6", "kwriteconfig5"})
468 (void)run({bin, "--file", "kioslaverc", "--group", "Proxy Settings",
469 "--key", "ProxyType", "0"}, true);
470 kde_refresh();
471}
472
473static void xfce_set(const Settings& s) {
474 const std::string port = std::to_string(s.port);
475 (void)run({"xfconf-query", "-c", "xfce4-settings-editor", "-p", "/Net/ProxyMode", "-s", "manual"}, true);
476 for (const char* scheme : {"http", "https"}) {
477 const std::string key = std::string("/Net/") + scheme + "-proxy/";
478 (void)run({"xfconf-query", "-c", "xfce4-settings-editor", "-p", key + "host", "-s", s.host}, true);
479 (void)run({"xfconf-query", "-c", "xfce4-settings-editor", "-p", key + "port", "-s", port}, true);
480 }
481 (void)run({"gsettings", "set", "org.gnome.system.proxy", "ignore-hosts",
483}
484
485static void xfce_clear() {
486 (void)run({"xfconf-query", "-c", "xfce4-settings-editor", "-p", "/Net/ProxyMode", "-s", "none"}, true);
487}
488
489static void mate_set(const Settings& s) {
490 const std::string port = std::to_string(s.port);
491 for (const auto& [key, value] : std::vector<std::pair<std::string, std::string>>{
492 {"proxy-mode", "manual"}, {"http-host", s.host}, {"http-port", port},
493 {"https-host", s.host}, {"https-port", port},
494 {"ignore-hosts", BrowserProxy::LAN_BYPASS_GVARIANT}}) {
495 (void)run({"gsettings", "set", "org.mate.network-preferences", key, value}, true);
496 }
497}
498
499static void mate_clear() {
500 (void)run({"gsettings", "set", "org.mate.network-preferences", "proxy-mode", "none"}, true);
501}
502
503static void lxqt_set(const Settings& s) {
504 const char* home = std::getenv("HOME");
505 if (!home) return;
506
507 namespace fs = std::filesystem;
508 std::ofstream f(fs::path(home) / ".config/lxqt/session.conf", std::ios::app);
509 if (f) {
510 const std::string val = "http://" + s.host + ":" + std::to_string(s.port);
511 f << "\n[Environment]\n"
512 << "http_proxy=" << val << "\n"
513 << "https_proxy=" << val << "\n"
514 << "no_proxy=" << BrowserProxy::LAN_BYPASS_NOCIDR << "\n";
515 }
516}
517
518static void env_set(const Settings& s) {
519 const std::string val = "http://" + s.host + ":" + std::to_string(s.port);
520 const char* nopx = BrowserProxy::LAN_BYPASS_NOCIDR;
521
522 setenv("http_proxy", val.c_str(), 1);
523 setenv("HTTP_PROXY", val.c_str(), 1);
524 setenv("https_proxy", val.c_str(), 1);
525 setenv("HTTPS_PROXY", val.c_str(), 1);
526 setenv("all_proxy", val.c_str(), 1);
527 setenv("ALL_PROXY", val.c_str(), 1);
528 setenv("no_proxy", nopx, 1);
529 setenv("NO_PROXY", nopx, 1);
530
531 const char* home = std::getenv("HOME");
532 if (home) {
533 namespace fs = std::filesystem;
534 const fs::path conf_dir = fs::path(home) / ".config/environment.d";
535 std::error_code ec;
536 fs::create_directories(conf_dir, ec);
537 if (!ec) {
538 std::ofstream f(conf_dir / "bastionguard-proxy.conf");
539 if (f) {
540 f << "http_proxy=" << val << "\n"
541 << "HTTP_PROXY=" << val << "\n"
542 << "https_proxy=" << val << "\n"
543 << "HTTPS_PROXY=" << val << "\n"
544 << "all_proxy=" << val << "\n"
545 << "ALL_PROXY=" << val << "\n"
546 << "no_proxy=" << nopx << "\n"
547 << "NO_PROXY=" << nopx << "\n";
548 }
549 }
550 }
551}
552
553static void env_clear() {
554 unsetenv("http_proxy");
555 unsetenv("HTTP_PROXY");
556 unsetenv("https_proxy");
557 unsetenv("HTTPS_PROXY");
558 unsetenv("all_proxy");
559 unsetenv("ALL_PROXY");
560 unsetenv("no_proxy");
561 unsetenv("NO_PROXY");
562
563 const char* home = std::getenv("HOME");
564 if (home) {
565 std::error_code ec;
566 std::filesystem::remove(
567 std::filesystem::path(home) / ".config/environment.d/bastionguard-proxy.conf", ec);
568 }
569}
570
571static void apply(const Settings& s) {
572 // Validate addresses before persisting them to configuration files.
573 const bool valid_host = !s.host.empty() && s.host.size() <= 253 &&
574 std::all_of(s.host.begin(), s.host.end(), [](unsigned char c) {
575 return std::isalnum(c) || c == '.' || c == '-' || c == ':' || c == '[' || c == ']';
576 });
577 if (!valid_host || s.port < 1 || s.port > 65535) {
578 std::cerr << "[proxy-config] refusing unsafe host or port\n";
579 return;
580 }
581 char msg[256];
582 std::snprintf(msg, sizeof(msg), _("[proxy-config] setting system proxy → %s:%d\n"),
583 s.host.c_str(), s.port);
584 std::cerr << msg;
585
586 env_set(s);
587
588 switch (detect()) {
589 case DE::GNOME:
590 case DE::CINNAMON: gnome_set(s); break;
591 case DE::KDE: kde_set(s); break;
592 case DE::XFCE: xfce_set(s); break;
593 case DE::MATE: gnome_set(s); mate_set(s); break;
594 case DE::LXQT: lxqt_set(s); break;
595 case DE::OTHER: break;
596 }
598
599 BrowserProxy::apply({ s.host, s.port });
600}
601
602static void restore() {
603 std::cerr << _("[proxy-config] restoring system proxy\n");
604
605 env_clear();
606
607 switch (detect()) {
608 case DE::GNOME:
609 case DE::CINNAMON: gnome_clear(); break;
610 case DE::KDE: kde_clear(); break;
611 case DE::XFCE: xfce_clear(); break;
612 case DE::MATE: gnome_clear(); mate_clear(); break;
613 case DE::LXQT: break;
614 case DE::OTHER: break;
615 }
616
618}
619
620} // namespace ProxyConfig
#define _(s)
static void configure_firefox_family(const Settings &s, bool clear)
static bool nss_contains_ca(const std::string &database)
static std::string home_dir()
static constexpr const char * BG_CA_CERT
static void chromium_clear_policy(const fs::path &dir)
static void install_ca_firefox_family()
static void install_ca_firefox_profile(const fs::path &profile)
static void install_ca_all_browsers()
static constexpr const char * LAN_BYPASS_NOCIDR
static constexpr const char * LAN_BYPASS_CIDR
static void install_ca_nssdb()
static void configure_chromium_family(const Settings &s, bool clear)
static void remove_lines_containing(const fs::path &p, const std::string &needle)
static void chromium_set_policy(const fs::path &dir, const Settings &s)
static std::string make_chromium_policy(const Settings &s)
static constexpr const char * LAN_BYPASS_GVARIANT
static void restore()
static fs::path firefox_active_profile(const fs::path &profiles_dir)
static constexpr const char * BG_CA_NICK
static constexpr const char * FF_MARKER
static void apply(const Settings &s)
static void firefox_clear_profile(const fs::path &profile)
static void firefox_set_profile(const fs::path &profile, const Settings &s)
static void write_file(const fs::path &p, const std::string &content)
static void xfce_clear()
static void lxqt_set(const Settings &s)
static void mate_set(const Settings &s)
static void gnome_clear()
static void env_set(const Settings &s)
static DE detect()
static bool run(const std::vector< std::string > &args, bool silent=false)
static void xfce_set(const Settings &s)
static void mate_clear()
static void env_clear()
static void kde_refresh()
static void gnome_set(const Settings &s)
static void apply(const Settings &s)
static void kde_clear()
static void kde_set(const Settings &s)
static void restore()
Result run(const std::vector< std::string > &args, bool merge_stderr=false, std::size_t limit=8U *1024U *1024U, const std::map< std::string, std::string > &environment={}, const std::function< bool(const std::string &)> &on_line={})