0.6.0-1 release
[manu/suphp.git] / src / Configuration.cpp
1 /*
2     suPHP - (c)2002-2005 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->docroot = "/";
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_vhos_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 }
115
116 void suPHP::Configuration::readFromFile(File& file) 
117     throw (IOException, ParsingException) {
118     IniFile ini;
119     ini.parse(file);
120     if (ini.hasSection("global")) {
121         IniSection& sect = ini.getSection("global");
122         std::vector<std::string> keys = sect.getKeys();
123         std::vector<std::string>::iterator i;
124         for (i = keys.begin(); i < keys.end(); i++) {
125             std::string key = *i;
126             std::string value = sect.getValue(key);
127
128             if (key == "logfile")
129                 this->logfile = value;
130             else if (key == "webserver_user")
131                 this->webserver_user = value;
132             else if (key == "docroot")
133                 this->docroot = value;
134             else if (key == "allow_file_group_writeable")
135                 this->allow_file_group_writeable = this->strToBool(value);
136             else if (key == "allow_directory_group_writeable")
137                 this->allow_directory_group_writeable = this->strToBool(value);
138             else if (key == "allow_file_others_writeable")
139                 this->allow_file_others_writeable = this->strToBool(value);
140             else if (key == "allow_directory_others_writeable")
141                 this->allow_directory_others_writeable = 
142                     this->strToBool(value);
143             else if (key == "check_vhost_docroot")
144                 this->check_vhost_docroot = this->strToBool(value);
145             else if (key == "errors_to_browser")
146                 this->errors_to_browser = this->strToBool(value);
147             else if (key == "env_path")
148                 this->env_path = value;
149             else if (key == "loglevel")
150                 this->loglevel = this->strToLogLevel(value);
151             else if (key == "min_uid")
152                 this->min_uid = Util::strToInt(value);
153             else if (key == "min_gid")
154                 this->min_gid = Util::strToInt(value);
155             else if (key == "umask")
156                 this->umask = Util::octalStrToInt(value);
157             else 
158                 throw ParsingException("Unknown option \"" + key + 
159                                        "\" in section [global]", 
160                                        __FILE__, __LINE__);
161         }
162     }
163     
164     // Get handlers / interpreters
165     if (ini.hasSection("handlers")) {
166         IniSection sect = ini.getSection("handlers");
167         std::vector<std::string> keys = sect.getKeys();
168         std::vector<std::string>::iterator i;
169         for (i = keys.begin(); i < keys.end(); i++) {
170             std::string key = *i;
171             std::string value = sect.getValue(key);
172             std::pair<std::string, std::string> p;
173             p.first = key;
174             p.second = value;
175             this->handlers.insert(p);
176         }
177     }
178     
179 }
180
181 std::string suPHP::Configuration::getLogfile() const {
182     return this->logfile;
183 }
184
185 LogLevel suPHP::Configuration::getLogLevel() const {
186     return this->loglevel;
187 }
188
189 std::string suPHP::Configuration::getWebserverUser() const {
190     return this->webserver_user;
191 }
192
193 std::string suPHP::Configuration::getDocroot() const {
194     return this->docroot;
195 }
196
197 bool suPHP::Configuration::getCheckVHostDocroot() const {
198     return this->check_vhost_docroot;
199 }
200
201 bool suPHP::Configuration::getAllowFileGroupWriteable() const {
202     return this->allow_file_group_writeable;
203 }
204
205 bool suPHP::Configuration::getAllowDirectoryGroupWriteable() const {
206     return this->allow_directory_group_writeable;
207 }
208
209 bool suPHP::Configuration::getAllowFileOthersWriteable() const {
210     return this->allow_file_others_writeable;
211 }
212
213 bool suPHP::Configuration::getAllowDirectoryOthersWriteable() const {
214     return this->allow_directory_others_writeable;
215 }
216
217 bool suPHP::Configuration::getErrorsToBrowser() const {
218     return this->errors_to_browser;
219 }
220
221 std::string suPHP::Configuration::getEnvPath() const {
222     return this->env_path;
223 }
224
225 std::string suPHP::Configuration::getInterpreter(std::string handler) const 
226     throw (KeyNotFoundException) {
227     if (this->handlers.find(handler) != this->handlers.end()) {
228         return this->handlers.find(handler) -> second;
229     } else {
230         throw KeyNotFoundException("Handler \"" + handler + "\" not found",
231                                    __FILE__, __LINE__);
232     }
233 }
234
235 int suPHP::Configuration::getMinUid() const {
236     return this->min_uid;
237 }
238
239 int suPHP::Configuration::getMinGid() const {
240     return this->min_gid;
241 }
242
243 int suPHP::Configuration::getUmask() const {
244     return this->umask;
245 }