Update changelog
[manu/suphp.git] / src / Configuration.cpp
1 /*
2     suPHP - (c)2002-2008 Sebastian Marsching <sebastian@marsching.com>
3
4     This file is part of suPHP.
5
6     suPHP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     suPHP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with suPHP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include <string>
22 #include <vector>
23
24 #include "IniFile.hpp"
25 #include "Util.hpp"
26
27 #include "Configuration.hpp"
28
29 using namespace suPHP;
30
31 bool suPHP::Configuration::strToBool(const std::string& bstr) const
32     throw (ParsingException) {
33     std::string str = bstr;
34     // Convert upper characters to lower characters
35     for (int i=0; i<str.size(); i++) {
36         if (str[i] >= 65 && str[i] <= 90)
37             str[i] += 32;
38     }
39
40     if (str == std::string("true")) {
41         return true;
42     } else if (str == std::string("yes")) {
43         return true;
44     } else if (str == std::string("on")) {
45         return true;
46     } else if (str == std::string("enabled")) {
47         return true;
48     } else if (str == std::string("1")) {
49         return true;
50     } else if (str == std::string("false")) {
51         return false;
52     } else if (str == std::string("no")) {
53         return false;
54     } else if (str == std::string("off")) {
55         return false;
56     } else if (str == std::string("disabled")) {
57         return false;
58     } else if (str == std::string("0")) {
59         return false;
60     } else {
61         throw ParsingException("\"" + str + "\" is not a valid boolean value",
62                                __FILE__, __LINE__);
63     }
64         
65 }
66
67
68 LogLevel suPHP::Configuration::strToLogLevel(const std::string& str) const
69     throw (ParsingException) {
70     if (str == "none")
71         return LOGLEVEL_NONE;
72     else if (str == "error")
73         return LOGLEVEL_ERROR;
74     else if (str == "warn")
75         return LOGLEVEL_WARN;
76     else if (str == "info")
77         return LOGLEVEL_INFO;
78     else
79         throw ParsingException("\"" + str + "\" is not a valid log level",
80                                __FILE__, __LINE__);
81 }
82
83 suPHP::Configuration::Configuration() {
84     this->logfile = "/var/log/suphp.log";
85 #ifdef OPT_APACHE_USER
86     this->webserver_user = OPT_APACHE_USER;
87 #else
88     this->webserver_user = "wwwrun";
89 #endif
90     this->docroots.push_back("/");
91     this->allow_file_group_writeable = false;
92     this->allow_directory_group_writeable = false;
93     this->allow_file_others_writeable = false;
94     this->allow_directory_others_writeable = false;
95 #ifdef OPT_DISABLE_CHECKPATH
96     this->check_vhost_docroot = false;
97 #else
98     this->check_vhost_docroot = true;
99 #endif
100     this->errors_to_browser = false;
101     this->env_path = "/bin:/usr/bin";
102     this->loglevel = LOGLEVEL_INFO;
103 #ifdef OPT_MIN_UID
104     this->min_uid = OPT_MIN_UID;
105 #else
106     this->min_uid = 1;
107 #endif
108 #ifdef OPT_MIN_GID
109     this->min_gid = OPT_MIN_GID;
110 #else
111     this->min_gid = 1;
112 #endif
113     this->umask = 0077;
114     this->chroot_path = "";
115 }
116
117 void suPHP::Configuration::readFromFile(File& file) 
118     throw (IOException, ParsingException) {
119     IniFile ini;
120     ini.parse(file);
121     if (ini.hasSection("global")) {
122         const IniSection& sect = ini.getSection("global");
123         const std::vector<std::string> keys = sect.getKeys();
124         std::vector<std::string>::const_iterator i;
125         for (i = keys.begin(); i < keys.end(); i++) {
126             std::string key = *i;
127             std::string value = sect.getValue(key);
128
129             if (key == "logfile")
130                 this->logfile = value;
131             else if (key == "webserver_user")
132                 this->webserver_user = value;
133             else if (key == "docroot") {
134                 this->docroots = sect.getValues(key);
135             } else if (key == "allow_file_group_writeable")
136                 this->allow_file_group_writeable = this->strToBool(value);
137             else if (key == "allow_directory_group_writeable")
138                 this->allow_directory_group_writeable = this->strToBool(value);
139             else if (key == "allow_file_others_writeable")
140                 this->allow_file_others_writeable = this->strToBool(value);
141             else if (key == "allow_directory_others_writeable")
142                 this->allow_directory_others_writeable = 
143                     this->strToBool(value);
144             else if (key == "check_vhost_docroot")
145                 this->check_vhost_docroot = this->strToBool(value);
146             else if (key == "errors_to_browser")
147                 this->errors_to_browser = this->strToBool(value);
148             else if (key == "env_path")
149                 this->env_path = value;
150             else if (key == "loglevel")
151                 this->loglevel = this->strToLogLevel(value);
152             else if (key == "min_uid")
153                 this->min_uid = Util::strToInt(value);
154             else if (key == "min_gid")
155                 this->min_gid = Util::strToInt(value);
156             else if (key == "umask")
157                 this->umask = Util::octalStrToInt(value);
158             else if (key == "chroot")
159                 this->chroot_path = value;
160             else 
161                 throw ParsingException("Unknown option \"" + key + 
162                                        "\" in section [global]", 
163                                        __FILE__, __LINE__);
164         }
165     }
166     
167     // Get handlers / interpreters
168     if (ini.hasSection("handlers")) {
169         IniSection sect = ini.getSection("handlers");
170         const std::vector<std::string> keys = sect.getKeys();
171         std::vector<std::string>::const_iterator i;
172         for (i = keys.begin(); i < keys.end(); i++) {
173             std::string key = *i;
174             std::string value = sect.getValue(key);
175             std::pair<std::string, std::string> p;
176             p.first = key;
177             p.second = value;
178             this->handlers.insert(p);
179         }
180     }
181     
182 }
183
184 std::string suPHP::Configuration::getLogfile() const {
185     return this->logfile;
186 }
187
188 LogLevel suPHP::Configuration::getLogLevel() const {
189     return this->loglevel;
190 }
191
192 std::string suPHP::Configuration::getWebserverUser() const {
193     return this->webserver_user;
194 }
195
196 const std::vector<std::string>& suPHP::Configuration::getDocroots() const {
197     return this->docroots;
198 }
199
200 bool suPHP::Configuration::getCheckVHostDocroot() const {
201     return this->check_vhost_docroot;
202 }
203
204 bool suPHP::Configuration::getAllowFileGroupWriteable() const {
205     return this->allow_file_group_writeable;
206 }
207
208 bool suPHP::Configuration::getAllowDirectoryGroupWriteable() const {
209     return this->allow_directory_group_writeable;
210 }
211
212 bool suPHP::Configuration::getAllowFileOthersWriteable() const {
213     return this->allow_file_others_writeable;
214 }
215
216 bool suPHP::Configuration::getAllowDirectoryOthersWriteable() const {
217     return this->allow_directory_others_writeable;
218 }
219
220 bool suPHP::Configuration::getErrorsToBrowser() const {
221     return this->errors_to_browser;
222 }
223
224 std::string suPHP::Configuration::getEnvPath() const {
225     return this->env_path;
226 }
227
228 std::string suPHP::Configuration::getInterpreter(std::string handler) const 
229     throw (KeyNotFoundException) {
230     if (this->handlers.find(handler) != this->handlers.end()) {
231         return this->handlers.find(handler) -> second;
232     } else {
233         throw KeyNotFoundException("Handler \"" + handler + "\" not found",
234                                    __FILE__, __LINE__);
235     }
236 }
237
238 int suPHP::Configuration::getMinUid() const {
239     return this->min_uid;
240 }
241
242 int suPHP::Configuration::getMinGid() const {
243     return this->min_gid;
244 }
245
246 int suPHP::Configuration::getUmask() const {
247     return this->umask;
248 }
249
250 std::string suPHP::Configuration::getChrootPath() const {
251     return this->chroot_path;
252 }