diff options
Diffstat (limited to 'libproxy/modules/config_gnome.cpp')
-rw-r--r-- | libproxy/modules/config_gnome.cpp | 307 |
1 files changed, 0 insertions, 307 deletions
diff --git a/libproxy/modules/config_gnome.cpp b/libproxy/modules/config_gnome.cpp deleted file mode 100644 index fcd9516..0000000 --- a/libproxy/modules/config_gnome.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/******************************************************************************* - * libproxy - A library for proxy configuration - * Copyright (C) 2006 Nathaniel McCallum <nathaniel@natemccallum.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - ******************************************************************************/ - -#include <cstdio> // For fileno(), fread(), pclose(), popen(), sscanf() -#include <sys/select.h> // For select() -#include <fcntl.h> // For fcntl() -#include <errno.h> // For errno stuff -#include <sys/types.h> // For stat() -#include <sys/stat.h> // For stat() -#include <unistd.h> // For pipe(), close(), vfork(), dup(), execl(), _exit() -#include <signal.h> // For kill() - -#include "../extension_config.hpp" -using namespace libproxy; - -#define BUFFERSIZE 10240 - -#define PROXY_MODE "/system/proxy/mode" -#define PROXY_USE_AUTHENTICATION "/system/http_proxy/use_authentication" -#define PROXY_AUTH_PASSWORD "/system/http_proxy/authentication_password" -#define PROXY_AUTH_USER "/system/http_proxy/authentication_user" -#define PROXY_AUTOCONFIG_URL "/system/proxy/autoconfig_url" -#define PROXY_IGNORE_HOSTS "/system/http_proxy/ignore_hosts" -#define PROXY_HTTP_HOST "/system/http_proxy/host" -#define PROXY_HTTP_PORT "/system/http_proxy/port" -#define PROXY_FTP_HOST "/system/proxy/ftp_host" -#define PROXY_FTP_PORT "/system/proxy/ftp_port" -#define PROXY_SECURE_HOST "/system/proxy/secure_host" -#define PROXY_SECURE_PORT "/system/proxy/secure_port" -#define PROXY_SOCKS_HOST "/system/proxy/socks_host" -#define PROXY_SOCKS_PORT "/system/proxy/socks_port" -#define PROXY_SAME_FOR_ALL "/system/http_proxy/use_same_proxy" - -static const char *all_keys[] = { - PROXY_MODE, - PROXY_USE_AUTHENTICATION, - PROXY_AUTH_PASSWORD, - PROXY_AUTH_USER, - PROXY_AUTOCONFIG_URL, - PROXY_IGNORE_HOSTS, - PROXY_HTTP_HOST, - PROXY_HTTP_PORT, - PROXY_FTP_HOST, - PROXY_FTP_PORT, - PROXY_SECURE_HOST, - PROXY_SECURE_PORT, - PROXY_SOCKS_HOST, - PROXY_SOCKS_PORT, - PROXY_SAME_FOR_ALL, - NULL -}; - -static int popen2(const char *program, FILE** read, FILE** write, pid_t* pid) { - if (!read || !write || !pid || !program || !*program) - return EINVAL; - *read = NULL; - *write = NULL; - *pid = 0; - - // Open the pipes - int rpipe[2]; - int wpipe[2]; - if (pipe(rpipe) < 0) - return errno; - if (pipe(wpipe) < 0) { - close(rpipe[0]); - close(rpipe[1]); - return errno; - } - - switch (*pid = vfork()) { - case -1: // Error - close(rpipe[0]); - close(rpipe[1]); - close(wpipe[0]); - close(wpipe[1]); - return errno; - - case 0: // Child - close(STDIN_FILENO); // Close stdin - close(STDOUT_FILENO); // Close stdout - - // Dup the read end of the write pipe to stdin - // Dup the write end of the read pipe to stdout - if (dup2(wpipe[0], STDIN_FILENO) != STDIN_FILENO) _exit(1); - if (dup2(rpipe[1], STDOUT_FILENO) != STDOUT_FILENO) _exit(2); - - // Close unneeded fds - for (int i = 3; i < sysconf(_SC_OPEN_MAX); i++) - close(i); - - // Exec - execl("/bin/sh", "sh", "-c", program, (char*) NULL); - _exit(127); // Whatever we do, don't return - - default: // Parent - close(rpipe[1]); - close(wpipe[0]); - *read = fdopen(rpipe[0], "r"); - *write = fdopen(wpipe[1], "w"); - if (*read == NULL || *write == NULL) { - if (*read != NULL) fclose(*read); - if (*write != NULL) fclose(*write); - return errno; - } - return 0; - } -} - -static inline uint16_t get_port(const string &port) -{ - uint16_t retval; - - if (sscanf(port.c_str(), "%hu", &retval) != 1) - retval = 0; - - return retval; -} - -void store_response(const string &type, - const string &host, - const string &port, - bool auth, - const string &username, - const string &password, - vector<url> &response) { - if (host != "" && get_port(port) != 0) { - string tmp = type + "://"; - if (auth) - tmp += username + ":" + password + "@"; - tmp += host + ":" + port; - response.push_back(url(tmp)); - } -} - -class gnome_config_extension : public config_extension { -public: - gnome_config_extension() { - // Build the command - int count; - struct stat st; - string cmd = LIBEXECDIR "/pxgconf"; - const char *pxgconf = getenv("PX_GCONF"); - - if (pxgconf) - cmd = string (pxgconf); - - if (stat(cmd.c_str(), &st)) - throw runtime_error ("Unable to open gconf helper!"); - - for (count=0 ; all_keys[count] ; count++) - cmd += string(" ", 1) + all_keys[count]; - - // Get our pipes - if (popen2(cmd.c_str(), &this->read, &this->write, &this->pid) != 0) - throw runtime_error("Unable to run gconf helper!"); - - // Read in our initial data - this->read_data(count); - - // Set the read pipe to non-blocking - if (fcntl(fileno(this->read), F_SETFL, O_NONBLOCK) == -1) { - fclose(this->read); - fclose(this->write); - kill(this->pid, SIGTERM); - throw runtime_error("Unable to set pipe to non-blocking!"); - } - } - - ~gnome_config_extension() { - fclose(this->read); - fclose(this->write); - kill(this->pid, SIGTERM); - } - - vector<url> get_config(const url &dest) { - // Check for changes in the config - fd_set rfds; - struct timeval timeout = { 0, 0 }; - vector<url> response; - - FD_ZERO(&rfds); - FD_SET(fileno(this->read), &rfds); - if (select(fileno(this->read)+1, &rfds, NULL, NULL, &timeout) > 0) - this->read_data(); - - // Mode is wpad:// or pac+http://... - if (this->data[PROXY_MODE] == "auto") { - string pac = this->data[PROXY_AUTOCONFIG_URL]; - response.push_back(url::is_valid(pac) ? url(string("pac+") + pac) : url("wpad://")); - return response; - } - - // Mode is http://... or socks://... - else if (this->data[PROXY_MODE] == "manual") { - bool auth = this->data[PROXY_USE_AUTHENTICATION] == "true"; - string username = url::encode(this->data[PROXY_AUTH_USER], URL_ALLOWED_IN_USERINFO_ELEMENT); - string password = url::encode(this->data[PROXY_AUTH_PASSWORD], URL_ALLOWED_IN_USERINFO_ELEMENT); - - // Get the per-scheme proxy settings - if (dest.get_scheme() == "http") - store_response("http", this->data[PROXY_HTTP_HOST], - this->data[PROXY_HTTP_PORT], auth, username, password, response); - else if (dest.get_scheme() == "https") - // It is expected that the configured server is an - // HTTP server that support CONNECT method. - store_response("http", this->data[PROXY_SECURE_HOST], - this->data[PROXY_SECURE_PORT], auth, username, password, response); - else if (dest.get_scheme() == "ftp") - // It is expected that the configured server is an - // HTTP server that handles proxying FTP URLs - // (e.g. request with header "Host: ftp://ftp.host.org") - store_response("http", this->data[PROXY_FTP_HOST], - this->data[PROXY_FTP_PORT], auth, username, password, response); - - store_response("socks", this->data[PROXY_SOCKS_HOST], - this->data[PROXY_SOCKS_PORT], auth, username, password, response); - - // In case nothing matched, try HTTP Connect and fallback to direct. - // If there is not secure HTTP proxy, this will only add direct:// to - // the response - if (response.size() == 0 && dest.get_scheme() != "http") { - store_response("http", this->data[PROXY_SECURE_HOST], - this->data[PROXY_SECURE_PORT], auth, username, password, response); - response.push_back(url("direct://")); - } - } - - return response; - } - - string get_ignore(const url&) { - return this->data[PROXY_IGNORE_HOSTS]; - } - - virtual bool set_creds(url /*proxy*/, string username, string password) { - string auth = PROXY_USE_AUTHENTICATION "\ttrue\n"; - string user = string(PROXY_AUTH_USER "\t") + username + "\n"; - string pass = string(PROXY_AUTH_PASSWORD "\t") + password + "\n"; - - return (fwrite(auth.c_str(), 1, auth.size(), this->write) == auth.size() && - fwrite(user.c_str(), 1, user.size(), this->write) == user.size() && - fwrite(pass.c_str(), 1, pass.size(), this->write) == pass.size()); - } - -private: - FILE* read; - FILE* write; - pid_t pid; - map<string, string> data; - - bool read_data(int num=-1) { - if (num == 0) return true; - if (!this->read) return false; // We need the pipe to be open - - for (char l[BUFFERSIZE] ; num != 0 && fgets(l, BUFFERSIZE, this->read) != NULL ; ) { - string line = l; - line = line.substr(0, line.rfind('\n')); - string key = line.substr(0, line.find("\t")); - string val = line.substr(line.find("\t")+1); - this->data[key] = val; - if (num > 0) num--; - } - - return (num <= 0); - } -}; - -static base_extension** gnome_config_extension_init() { - base_extension** retval = new base_extension*[2]; - retval[1] = NULL; - try { - retval[0] = new gnome_config_extension(); - return retval; - } - catch (runtime_error) { - delete[] retval; - return NULL; - } -} - -static bool gnome_config_extension_test() { - return (getenv("GNOME_DESKTOP_SESSION_ID") - || (getenv("DESKTOP_SESSION") - && string(getenv("DESKTOP_SESSION")) == "gnome")); -} - -MM_MODULE_INIT(gnome_config_extension, - gnome_config_extension_init, - gnome_config_extension_test, - NULL, NULL); |