1 /*******************************************************************************
2 * libproxy sysconfig module
3 * Copyright (C) 2010 Novell Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library 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 GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 ******************************************************************************/
19
20 #include <sys/stat.h>
21 #include <cstdlib>
22 #include <map>
23 #include <fstream>
24 #include <unistd.h>
25 #include <sys/types.h>
26
27
28 #include "../extension_config.hpp"
29 using namespace libproxy;
30 using std::map;
31
32 enum Trim {
33 NO_TRIM = 0x00,
34 L_TRIM = 0x01,
35 R_TRIM = 0x02,
36 TRIM = (L_TRIM|R_TRIM)
37 };
38
trim(const std::string & s,const Trim trim_r=TRIM)39 static std::string trim( const std::string & s, const Trim trim_r = TRIM ) {
40
41 if (s.empty() || trim_r == NO_TRIM)
42 return s;
43
44 std::string ret(s);
45
46 if (trim_r & L_TRIM) {
47 std::string::size_type p = ret.find_first_not_of(" \t\n");
48 if (p == std::string::npos)
49 return std::string();
50
51 ret = ret.substr(p);
52 }
53
54 if (trim_r & R_TRIM) {
55 std::string::size_type p = ret.find_last_not_of(" \t\n");
56 if (p == std::string::npos)
57 return std::string();
58
59 ret = ret.substr(0, p+1);
60 }
61
62 return ret;
63 }
64
sysconfig_read(const string & _path)65 static map<string,string> sysconfig_read(const string &_path) {
66
67 map<string,string> ret;
68 string line;
69
70 ifstream in(_path.c_str());
71 if (in.fail()) {
72 return ret;
73 }
74
75 while(getline( in, line)) {
76
77 if (*line.begin() != '#') {
78
79 string::size_type pos = line.find('=', 0);
80
81 if (pos != string::npos) {
82
83 string key = trim(line.substr(0, pos));
84 string value = trim(line.substr(pos + 1, line.length() - pos - 1));
85
86 if (value.length() >= 2
87 && *(value.begin()) == '"'
88 && *(value.rbegin()) == '"') {
89 value = value.substr( 1, value.length() - 2 );
90 }
91
92 if (value.length() >= 2
93 && *(value.begin()) == '\''
94 && *(value.rbegin()) == '\'' ) {
95 value = value.substr( 1, value.length() - 2 );
96 }
97 ret[key] = value;
98 } // '=' found
99
100 } // not comment
101
102 } // while getline
103 return ret;
104 }
105
should_use_sysconfig()106 static bool should_use_sysconfig()
107 {
108 struct stat st;
109 if (stat("/etc/sysconfig", &st) == 0)
110 return (getuid() == 0);
111 return false;
112 }
113
114 class sysconfig_config_extension : public config_extension {
115
116 map<string,string> _data;
117
118 public:
sysconfig_config_extension()119 sysconfig_config_extension()
120 : _data(sysconfig_read("/etc/sysconfig/proxy")) {
121
122 }
123
~sysconfig_config_extension()124 ~sysconfig_config_extension() {
125 }
126
get_config(const url & dst)127 vector<url> get_config(const url &dst) {
128 map<string,string>::const_iterator it = _data.find("PROXY_ENABLED");
129 vector<url> response;
130
131 if (it != _data.end() && it->second == "no") {
132 response.push_back(url("direct://"));
133 return response;
134 }
135
136 string key;
137 string proxy;
138
139 // If the URL is an ftp url, try to read the ftp proxy
140 if (dst.get_scheme() == "ftp")
141 key = "FTP_PROXY";
142 else if (dst.get_scheme() == "http")
143 key = "HTTP_PROXY";
144 else if (dst.get_scheme() == "https")
145 key = "HTTPS_PROXY";
146
147 it = _data.find(key);
148 if (it != _data.end())
149 proxy = it->second;
150
151 if (proxy.empty())
152 throw runtime_error("Unable to read configuration");
153
154 response.push_back(url(proxy));
155 return response;
156 }
157
get_ignore(const url &)158 string get_ignore(const url&) {
159 map<string,string>::const_iterator it = _data.find("NO_PROXY");
160 if (it != _data.end())
161 return it->second;
162 return "";
163 }
164
165 // if we are running as root, and the module is used, then
166 // make sure this is the first method tried
operator <(const base_extension &) const167 virtual bool operator<(const base_extension&) const {
168 return true;
169 }
170 };
171
172 MM_MODULE_INIT_EZ(sysconfig_config_extension, should_use_sysconfig(), NULL, NULL);
173
174