├── NEWS ├── AUTHORS ├── Makefile.am ├── .gitmodules ├── tests ├── googlemock-library.cpp ├── googletest-library.cpp ├── test.cpp ├── Makefile.am └── PathMatcher_test.cpp ├── doc ├── apache │ ├── README │ ├── CONFIG │ └── INSTALL ├── README ├── suphp.conf-example ├── INSTALL └── CONFIG ├── .gitignore ├── src ├── apache2 │ └── Makefile.am ├── API.cpp ├── API_Helper.cpp ├── Makefile.am ├── Util.hpp ├── API_Helper.hpp ├── IOException.cpp ├── GroupInfo.cpp ├── SoftException.cpp ├── Logger.cpp ├── LookupException.cpp ├── SystemException.cpp ├── ParsingException.cpp ├── API_Linux_Logger.hpp ├── SecurityException.cpp ├── IOException.hpp ├── OutOfRangeException.cpp ├── KeyNotFoundException.cpp ├── PathMatcher.hpp ├── SystemException.hpp ├── SecurityException.hpp ├── ParsingException.hpp ├── OutOfRangeException.hpp ├── SoftException.hpp ├── KeyNotFoundException.hpp ├── LookupException.hpp ├── GroupInfo.hpp ├── Util.cpp ├── IniFile.hpp ├── CommandLine.hpp ├── Exception.hpp ├── UserInfo.cpp ├── IniSection.hpp ├── Environment.hpp ├── UserInfo.hpp ├── Exception.cpp ├── Logger.hpp ├── CommandLine.cpp ├── Environment.cpp ├── IniSection.cpp ├── API_Linux_Logger.cpp ├── File.cpp ├── File.hpp ├── PathMatcher.cpp ├── Application.hpp ├── API.hpp ├── API_Linux.hpp ├── Configuration.hpp ├── IniFile.cpp └── Configuration.cpp ├── .gitlab-ci.yml ├── m4 ├── ax_cxx_compile_stdcxx_11.m4 ├── ax_cxx_compile_stdcxx_0x.m4 └── find_apr.m4 ├── README ├── .project ├── ChangeLog ├── configure.ac └── INSTALL /NEWS: -------------------------------------------------------------------------------- 1 | See ChangeLog -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Sebastian Marsching 2 | John Lightsey -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = src tests 2 | EXTRA_DIST = doc googletest 3 | ACLOCAL_AMFLAGS = -I m4 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "googletest"] 2 | path = googletest 3 | url = https://github.com/google/googletest.git 4 | -------------------------------------------------------------------------------- /tests/googlemock-library.cpp: -------------------------------------------------------------------------------- 1 | // This stub avoids dirtying the googletest directory 2 | 3 | #include "src/gmock-all.cc" 4 | -------------------------------------------------------------------------------- /tests/googletest-library.cpp: -------------------------------------------------------------------------------- 1 | // This stub avoids dirtying the googletest directory 2 | 3 | #include "src/gtest-all.cc" 4 | -------------------------------------------------------------------------------- /tests/test.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "gmock/gmock.h" 3 | 4 | int main(int argc, char **argv) { 5 | ::testing::InitGoogleMock(&argc, argv); 6 | 7 | return RUN_ALL_TESTS(); 8 | } 9 | -------------------------------------------------------------------------------- /doc/apache/README: -------------------------------------------------------------------------------- 1 | =========================== 2 | == suPHP Apache module == 3 | =========================== 4 | 5 | For help on installation see INSTALL in this directory. 6 | 7 | 8 | =================================== 9 | (c)2002-2013 by Sebastian Marsching 10 | 11 | Please see LICENSE for 12 | additional information 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Autotools generated files 2 | Makefile.in 3 | src/config.h.in 4 | src/config.h.in~ 5 | configure 6 | autom4te.cache/ 7 | config/ 8 | aclocal.m4 9 | m4/ 10 | 11 | # Generated by configure 12 | Makefile 13 | config.log 14 | config.status 15 | libtool 16 | .deps 17 | src/config.h 18 | src/stamp-h1 19 | 20 | # Compiled files 21 | *.o 22 | *.la 23 | *.lo 24 | .libs 25 | src/suphp 26 | tests/test 27 | tests/*.log 28 | tests/*.trs 29 | 30 | # Tarballs 31 | *.tar.gz 32 | -------------------------------------------------------------------------------- /src/apache2/Makefile.am: -------------------------------------------------------------------------------- 1 | if COND_APUSERGROUP 2 | DEFINE_USERGROUP = -DSUPHP_USE_USERGROUP 3 | endif 4 | 5 | AM_CFLAGS=-I@APXS_INCLUDEDIR@ -I@APR_INCLUDEDIR@ @APXS_EXTRA_CFLAGS@ 6 | AM_CFLAGS+=-DSUPHP_PATH_TO_SUPHP=\"${sbindir}/suphp\" $(DEFINE_USERGROUP) 7 | 8 | AM_CPPFLAGS=@APR_CPPFLAGS@ 9 | 10 | noinst_LTLIBRARIES = mod_suphp.la 11 | mod_suphp_la_SOURCES = mod_suphp.c 12 | 13 | mod_suphp_la_LDFLAGS = -module -rpath '@APXS_LIBEXECDIR@' 14 | 15 | install-data-local: 16 | ${INSTALL_SCRIPT} -d ${DESTDIR}'@APXS_LIBEXECDIR@' 17 | ${INSTALL_SCRIPT} -m 0755 .libs/mod_suphp.so ${DESTDIR}'@APXS_LIBEXECDIR@'/mod_suphp.so 18 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | check_LTLIBRARIES = libgtest.la libgmock.la 2 | 3 | libgtest_la_SOURCES = googletest-library.cpp 4 | libgtest_la_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest -I$(top_srcdir)/googletest/googlemock/include 5 | libgtest_la_LDFLAGS = -pthread 6 | 7 | libgmock_la_SOURCES = googlemock-library.cpp 8 | libgmock_la_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googlemock/include -I$(top_srcdir)/googletest/googlemock 9 | libgmock_la_LDFLAGS = -pthread 10 | 11 | 12 | check_PROGRAMS = test 13 | 14 | test_SOURCES = test.cpp PathMatcher_test.cpp 15 | test_LDADD = libgtest.la libgmock.la ../src/libsuphp.la 16 | test_LDFLAGS = -pthread 17 | test_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest -I$(top_srcdir)/googletest/googlemock/include -I$(top_srcdir)/googletest/googlemock 18 | 19 | TESTS = test 20 | -------------------------------------------------------------------------------- /src/API.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "API.hpp" 23 | 24 | extern char **environ; 25 | 26 | using namespace suPHP; 27 | -------------------------------------------------------------------------------- /src/API_Helper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "API.hpp" 23 | 24 | #include "API_Helper.hpp" 25 | 26 | using namespace suPHP; 27 | 28 | API_Linux suPHP::API_Helper::api; 29 | 30 | API& suPHP::API_Helper::getSystemAPI() { return API_Helper::api; } 31 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CXXFLAGS=-DOPT_CONFIGFILE=\"${sysconfdir}/suphp.conf\" 2 | 3 | SUBDIRS = apache2 4 | DIST_SUBDIRS = apache2 5 | 6 | sbin_PROGRAMS = suphp 7 | 8 | suphp_SOURCES = Application.cpp 9 | suphp_LDADD = libsuphp.la 10 | 11 | noinst_LTLIBRARIES = libsuphp.la 12 | libsuphp_la_SOURCES = API.cpp API.hpp API_Helper.cpp API_Helper.hpp API_Linux.cpp API_Linux.hpp API_Linux_Logger.cpp API_Linux_Logger.hpp Application.hpp CommandLine.cpp CommandLine.hpp Configuration.cpp Configuration.hpp Environment.cpp Environment.hpp Exception.cpp Exception.hpp File.cpp File.hpp GroupInfo.cpp GroupInfo.hpp IOException.cpp IOException.hpp IniFile.cpp IniFile.hpp IniSection.cpp IniSection.hpp KeyNotFoundException.cpp KeyNotFoundException.hpp Logger.cpp Logger.hpp LookupException.cpp LookupException.hpp OutOfRangeException.cpp OutOfRangeException.hpp PathMatcher.hpp PathMatcher.cpp ParsingException.cpp ParsingException.hpp SecurityException.cpp SecurityException.hpp SoftException.cpp SoftException.hpp SystemException.cpp SystemException.hpp UserInfo.cpp UserInfo.hpp Util.cpp Util.hpp 13 | libsuphp_la_LDFLAGS = -static 14 | 15 | install-exec-hook: 16 | chmod u+s $(DESTDIR)$(sbindir)/suphp$(EXEEXT) 17 | -------------------------------------------------------------------------------- /doc/README: -------------------------------------------------------------------------------- 1 | =========================== 2 | == suPHP == 3 | =========================== 4 | 5 | suPHP - (c)2002-2013 Sebastian Marsching 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 20 | USA 21 | 22 | 23 | For help on installation see INSTALL in this directory. 24 | 25 | 26 | =================================== 27 | (c)2002-2013 by Sebastian Marsching 28 | 29 | Please see LICENSE for 30 | additional information 31 | -------------------------------------------------------------------------------- /src/Util.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_UTIL_H 23 | #define SUPHP_UTIL_H 24 | 25 | #include 26 | 27 | namespace suPHP { 28 | /** 29 | * Class containing useful utility functions 30 | */ 31 | class Util { 32 | public: 33 | static std::string intToStr(const int i); 34 | static int strToInt(const std::string istr); 35 | static int octalStrToInt(const std::string istr); 36 | }; 37 | } 38 | 39 | #endif // SUPHP_UTIL_H 40 | -------------------------------------------------------------------------------- /src/API_Helper.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_API_HELPER_H 23 | #define SUPHP_API_HELPER_H 24 | 25 | #include "API.hpp" 26 | #include "API_Linux.hpp" 27 | 28 | namespace suPHP { 29 | /** 30 | * Class encapsulating system-specific API. 31 | */ 32 | class API_Helper { 33 | private: 34 | static API_Linux api; 35 | 36 | public: 37 | /** 38 | * Get system API 39 | */ 40 | static API& getSystemAPI(); 41 | }; 42 | } 43 | 44 | #endif // SUPHP_API_HELPER_H 45 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | GIT_SUBMODULE_STRATEGY: normal 3 | 4 | debian10_build: 5 | image: debian:10 6 | script: 7 | - apt-get update 8 | - apt-get -y install build-essential autoconf automake libtool apache2 apache2-dev 9 | - autoreconf -i 10 | - CFLAGS="-Wall -Wpedantic -Werror" CXXFLAGS="-Wall -Wpedantic -Werror" ./configure 11 | - make 12 | - make check 13 | 14 | debian9_build: 15 | image: debian:9 16 | script: 17 | - apt-get update 18 | - apt-get -y install build-essential autoconf automake libtool apache2 apache2-dev 19 | - autoreconf -i 20 | - CFLAGS="-Wall -Wpedantic -Werror" CXXFLAGS="-Wall -Wpedantic -Werror" ./configure 21 | - make 22 | - make check 23 | 24 | centos6_build: 25 | image: centos:6 26 | script: 27 | - yum makecache fast 28 | - yum -y install autoconf automake libtool make gcc gcc-c++ httpd-devel which 29 | - autoreconf -i 30 | - CFLAGS="-Wall -pedantic -Werror" CXXFLAGS="-Wall -pedantic -Werror" ./configure 31 | - make 32 | - make CXXFLAGS="-Wall -Werror" check 33 | 34 | centos7_build: 35 | image: centos:7 36 | script: 37 | - yum makecache fast 38 | - yum -y install autoconf automake libtool make gcc gcc-c++ httpd-devel which 39 | - autoreconf -i 40 | - CFLAGS="-std=gnu99 -Wall -Wpedantic -Werror" CXXFLAGS="-Wall -Wpedantic -Werror" ./configure 41 | - make 42 | - make check 43 | -------------------------------------------------------------------------------- /doc/suphp.conf-example: -------------------------------------------------------------------------------- 1 | [global] 2 | ;Path to logfile 3 | logfile=/var/log/suphp.log 4 | 5 | ;Loglevel 6 | loglevel=info 7 | 8 | ;User Apache is running as 9 | ;webserver_user=apache 10 | 11 | ;Path all scripts have to be in 12 | docroot=/var/www:${HOME}/public_html 13 | 14 | ;Path to chroot() to before executing script 15 | ;chroot=/mychroot 16 | 17 | ; Security options 18 | allow_file_group_writeable=false 19 | allow_file_others_writeable=false 20 | allow_directory_group_writeable=false 21 | allow_directory_others_writeable=false 22 | 23 | ; Security mode 24 | ;mode=paranoid 25 | 26 | ; Paranoid mode modifiers 27 | paranoid_uid_check=true 28 | paranoid_gid_check=true 29 | 30 | ;Check whether script is within DOCUMENT_ROOT 31 | check_vhost_docroot=true 32 | 33 | ;Send minor error messages to browser 34 | errors_to_browser=false 35 | 36 | ;PATH environment variable 37 | env_path="/bin:/usr/bin" 38 | 39 | ;Umask to set, specify in octal notation 40 | umask=0077 41 | 42 | ; Minimum UID 43 | min_uid=100 44 | 45 | ; Minimum GID 46 | min_gid=100 47 | 48 | ;Ignore suPHP_UserGroup for userdir requests. 49 | userdir_overrides_usergroup=true 50 | 51 | ;Include script being executed in command arguments 52 | full_php_process_display=false 53 | 54 | [handlers] 55 | ;Handler for php-scripts 56 | x-httpd-php="php:/usr/bin/php" 57 | 58 | ;Handler for CGI-scripts 59 | x-suphp-cgi="execute:!self" 60 | 61 | [phprc_paths] 62 | ;Force a specific php.ini through PHPRC 63 | ;x-httpd-php=/etc/php/php.ini -------------------------------------------------------------------------------- /src/IOException.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "IOException.hpp" 23 | 24 | using namespace suPHP; 25 | 26 | std::string suPHP::IOException::getName() const { return "IOException"; } 27 | 28 | suPHP::IOException::IOException(std::string file, int line) 29 | : Exception(file, line) {} 30 | 31 | suPHP::IOException::IOException(std::string message, std::string file, int line) 32 | : Exception(message, file, line) {} 33 | 34 | suPHP::IOException::IOException(Exception& cause, std::string file, int line) 35 | : Exception(cause, file, line) {} 36 | 37 | suPHP::IOException::IOException(std::string message, Exception& cause, 38 | std::string file, int line) 39 | : Exception(message, cause, file, line) {} 40 | -------------------------------------------------------------------------------- /src/GroupInfo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | 24 | #include "API.hpp" 25 | #include "API_Helper.hpp" 26 | 27 | #include "GroupInfo.hpp" 28 | 29 | using namespace suPHP; 30 | 31 | suPHP::GroupInfo::GroupInfo() { this->gid = -1; } 32 | 33 | suPHP::GroupInfo::GroupInfo(int gid) { this->gid = gid; } 34 | 35 | std::string suPHP::GroupInfo::getGroupname() const { 36 | API& api = API_Helper::getSystemAPI(); 37 | return api.GroupInfo_getGroupname(*this); 38 | } 39 | 40 | int suPHP::GroupInfo::getGid() const { return this->gid; } 41 | 42 | bool suPHP::GroupInfo::operator==(const GroupInfo& ginfo) const { 43 | if (this->getGid() == ginfo.getGid()) 44 | return true; 45 | else 46 | return false; 47 | } 48 | 49 | bool suPHP::GroupInfo::operator!=(const GroupInfo& ginfo) const { 50 | return !this->operator==(ginfo); 51 | } 52 | -------------------------------------------------------------------------------- /src/SoftException.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "SoftException.hpp" 23 | 24 | using namespace suPHP; 25 | 26 | std::string suPHP::SoftException::getName() const { return "SoftException"; } 27 | 28 | suPHP::SoftException::SoftException(std::string file, int line) 29 | : Exception(file, line) {} 30 | 31 | suPHP::SoftException::SoftException(std::string message, std::string file, 32 | int line) 33 | : Exception(message, file, line) {} 34 | 35 | suPHP::SoftException::SoftException(Exception& cause, std::string file, 36 | int line) 37 | : Exception(cause, file, line) {} 38 | 39 | suPHP::SoftException::SoftException(std::string message, Exception& cause, 40 | std::string file, int line) 41 | : Exception(message, cause, file, line) {} 42 | -------------------------------------------------------------------------------- /src/Logger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "Logger.hpp" 23 | 24 | using namespace suPHP; 25 | 26 | LogLevel suPHP::Logger::getLogLevel() { return this->logLevel; } 27 | 28 | void suPHP::Logger::setLogLevel(LogLevel level) { this->logLevel = level; } 29 | 30 | void suPHP::Logger::logInfo(const std::string& message) { 31 | if (this->getLogLevel() == LOGLEVEL_INFO) this->log("info", message); 32 | } 33 | 34 | void suPHP::Logger::logWarning(const std::string& message) { 35 | if (this->getLogLevel() == LOGLEVEL_WARN || 36 | this->getLogLevel() == LOGLEVEL_INFO) 37 | this->log("warn", message); 38 | } 39 | 40 | void suPHP::Logger::logError(const std::string& message) { 41 | if (this->getLogLevel() == LOGLEVEL_ERROR || 42 | this->getLogLevel() == LOGLEVEL_WARN || 43 | this->getLogLevel() == LOGLEVEL_INFO) 44 | this->log("error", message); 45 | } 46 | -------------------------------------------------------------------------------- /src/LookupException.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "LookupException.hpp" 23 | 24 | using namespace suPHP; 25 | 26 | std::string suPHP::LookupException::getName() const { 27 | return "LookupException"; 28 | } 29 | 30 | suPHP::LookupException::LookupException(std::string file, int line) 31 | : Exception(file, line) {} 32 | 33 | suPHP::LookupException::LookupException(std::string message, std::string file, 34 | int line) 35 | : Exception(message, file, line) {} 36 | 37 | suPHP::LookupException::LookupException(Exception& cause, std::string file, 38 | int line) 39 | : Exception(cause, file, line) {} 40 | 41 | suPHP::LookupException::LookupException(std::string message, Exception& cause, 42 | std::string file, int line) 43 | : Exception(message, cause, file, line) {} 44 | -------------------------------------------------------------------------------- /src/SystemException.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "SystemException.hpp" 23 | 24 | using namespace suPHP; 25 | 26 | std::string suPHP::SystemException::getName() const { 27 | return "SystemException"; 28 | } 29 | 30 | suPHP::SystemException::SystemException(std::string file, int line) 31 | : Exception(file, line) {} 32 | 33 | suPHP::SystemException::SystemException(std::string message, std::string file, 34 | int line) 35 | : Exception(message, file, line) {} 36 | 37 | suPHP::SystemException::SystemException(Exception& cause, std::string file, 38 | int line) 39 | : Exception(cause, file, line) {} 40 | 41 | suPHP::SystemException::SystemException(std::string message, Exception& cause, 42 | std::string file, int line) 43 | : Exception(message, cause, file, line) {} 44 | -------------------------------------------------------------------------------- /src/ParsingException.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "ParsingException.hpp" 23 | 24 | using namespace suPHP; 25 | 26 | std::string suPHP::ParsingException::getName() const { 27 | return "ParsingException"; 28 | } 29 | 30 | suPHP::ParsingException::ParsingException(std::string file, int line) 31 | : Exception(file, line) {} 32 | 33 | suPHP::ParsingException::ParsingException(std::string message, std::string file, 34 | int line) 35 | : Exception(message, file, line) {} 36 | 37 | suPHP::ParsingException::ParsingException(Exception& cause, std::string file, 38 | int line) 39 | : Exception(cause, file, line) {} 40 | 41 | suPHP::ParsingException::ParsingException(std::string message, Exception& cause, 42 | std::string file, int line) 43 | : Exception(message, cause, file, line) {} 44 | -------------------------------------------------------------------------------- /src/API_Linux_Logger.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_API_LINUX_LOGGER_H 23 | #define SUPHP_API_LINUX_LOGGER_H 24 | 25 | #include "Logger.hpp" 26 | 27 | namespace suPHP { 28 | /** 29 | * Class containing logging facility. 30 | * Implementation for Linux API. 31 | */ 32 | class API_Linux_Logger : public Logger { 33 | private: 34 | int logFd; 35 | bool ready; 36 | 37 | /** 38 | * Internal log function - implementation 39 | */ 40 | virtual void log(const std::string& classification, 41 | const std::string& message); 42 | 43 | public: 44 | /** 45 | * Constructor 46 | */ 47 | API_Linux_Logger(); 48 | 49 | /** 50 | * Initialize (open logfile) - implementation 51 | */ 52 | virtual void init(const Configuration& config); 53 | /** 54 | * Is Logger initialized? 55 | */ 56 | virtual bool isInitialized(); 57 | }; 58 | } // namespace suPHP 59 | 60 | #endif // SUPHP_API_LINUX_LOGGER_H 61 | -------------------------------------------------------------------------------- /m4/ax_cxx_compile_stdcxx_11.m4: -------------------------------------------------------------------------------- 1 | # ============================================================================ 2 | # http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html 3 | # ============================================================================ 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_CXX_COMPILE_STDCXX_11([ext|noext], [mandatory|optional]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # Check for baseline language coverage in the compiler for the C++11 12 | # standard; if necessary, add switches to CXX and CXXCPP to enable 13 | # support. 14 | # 15 | # This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX 16 | # macro with the version set to C++11. The two optional arguments are 17 | # forwarded literally as the second and third argument respectively. 18 | # Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for 19 | # more information. If you want to use this macro, you also need to 20 | # download the ax_cxx_compile_stdcxx.m4 file. 21 | # 22 | # LICENSE 23 | # 24 | # Copyright (c) 2008 Benjamin Kosnik 25 | # Copyright (c) 2012 Zack Weinberg 26 | # Copyright (c) 2013 Roy Stogner 27 | # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov 28 | # Copyright (c) 2015 Paul Norman 29 | # Copyright (c) 2015 Moritz Klammler 30 | # 31 | # Copying and distribution of this file, with or without modification, are 32 | # permitted in any medium without royalty provided the copyright notice 33 | # and this notice are preserved. This file is offered as-is, without any 34 | # warranty. 35 | 36 | #serial 17 37 | 38 | AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) 39 | AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])]) 40 | -------------------------------------------------------------------------------- /src/SecurityException.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "SecurityException.hpp" 23 | 24 | using namespace suPHP; 25 | 26 | std::string suPHP::SecurityException::getName() const { 27 | return "SecurityException"; 28 | } 29 | 30 | suPHP::SecurityException::SecurityException(std::string file, int line) 31 | : Exception(file, line) {} 32 | 33 | suPHP::SecurityException::SecurityException(std::string message, 34 | std::string file, int line) 35 | : Exception(message, file, line) {} 36 | 37 | suPHP::SecurityException::SecurityException(Exception& cause, std::string file, 38 | int line) 39 | : Exception(cause, file, line) {} 40 | 41 | suPHP::SecurityException::SecurityException(std::string message, 42 | Exception& cause, std::string file, 43 | int line) 44 | : Exception(message, cause, file, line) {} 45 | -------------------------------------------------------------------------------- /src/IOException.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_IOEXCEPTION_H 23 | #define SUPHP_IOEXCEPTION_H 24 | 25 | #include 26 | #include 27 | 28 | #include "Exception.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Exception showing problems during I/O operation 33 | */ 34 | class IOException : public Exception { 35 | private: 36 | std::string getName() const; 37 | 38 | public: 39 | /** 40 | * Constructor without message. 41 | */ 42 | IOException(std::string file, int line); 43 | 44 | /** 45 | * Constructor with message. 46 | */ 47 | IOException(std::string message, std::string file, int line); 48 | 49 | /** 50 | * Constructor without message but with cause. 51 | */ 52 | IOException(Exception& cause, std::string file, int line); 53 | 54 | /** 55 | * Constructor with message and cause. 56 | */ 57 | IOException(std::string message, Exception& cause, std::string file, 58 | int line); 59 | }; 60 | } 61 | 62 | #endif // SUPHP_IOEXCEPTION_H 63 | -------------------------------------------------------------------------------- /src/OutOfRangeException.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "OutOfRangeException.hpp" 23 | 24 | using namespace suPHP; 25 | 26 | std::string suPHP::OutOfRangeException::getName() const { 27 | return "OutOfRangeException"; 28 | } 29 | 30 | suPHP::OutOfRangeException::OutOfRangeException(std::string file, int line) 31 | : Exception(file, line) {} 32 | 33 | suPHP::OutOfRangeException::OutOfRangeException(std::string message, 34 | std::string file, int line) 35 | : Exception(message, file, line) {} 36 | 37 | suPHP::OutOfRangeException::OutOfRangeException(Exception& cause, 38 | std::string file, int line) 39 | : Exception(cause, file, line) {} 40 | 41 | suPHP::OutOfRangeException::OutOfRangeException(std::string message, 42 | Exception& cause, 43 | std::string file, int line) 44 | : Exception(message, cause, file, line) {} 45 | -------------------------------------------------------------------------------- /src/KeyNotFoundException.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "KeyNotFoundException.hpp" 23 | 24 | using namespace suPHP; 25 | 26 | std::string suPHP::KeyNotFoundException::getName() const { 27 | return "KeyNotFoundException"; 28 | } 29 | 30 | suPHP::KeyNotFoundException::KeyNotFoundException(std::string file, int line) 31 | : Exception(file, line) {} 32 | 33 | suPHP::KeyNotFoundException::KeyNotFoundException(std::string message, 34 | std::string file, int line) 35 | : Exception(message, file, line) {} 36 | 37 | suPHP::KeyNotFoundException::KeyNotFoundException(Exception& cause, 38 | std::string file, int line) 39 | : Exception(cause, file, line) {} 40 | 41 | suPHP::KeyNotFoundException::KeyNotFoundException(std::string message, 42 | Exception& cause, 43 | std::string file, int line) 44 | : Exception(message, cause, file, line) {} 45 | -------------------------------------------------------------------------------- /src/PathMatcher.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_PATHMATCHER_H 23 | #define SUPHP_PATHMATCHER_H 24 | 25 | #include 26 | 27 | #include "GroupInfo.hpp" 28 | #include "KeyNotFoundException.hpp" 29 | #include "ParsingException.hpp" 30 | #include "UserInfo.hpp" 31 | 32 | namespace suPHP { 33 | 34 | template 35 | class PathMatcher { 36 | private: 37 | const TUserInfo& user; 38 | const TGroupInfo& group; 39 | std::string lookupVariable(std::string str); 40 | 41 | public: 42 | /** 43 | * Contructor 44 | */ 45 | PathMatcher(const TUserInfo& cuser, const TGroupInfo& cgroup) 46 | : user(cuser), group(cgroup){}; 47 | 48 | /** 49 | * Checks wheter a path matches a pattern 50 | */ 51 | bool matches(std::string pattern, std::string path); 52 | 53 | /** 54 | * Resolves variables in a string 55 | */ 56 | std::string resolveVariables(std::string str, bool unescape = true); 57 | }; 58 | } // namespace suPHP 59 | 60 | #endif // SUPHP_PATHMATCHER_H 61 | -------------------------------------------------------------------------------- /src/SystemException.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_SYSTEMEXCEPTION_H 23 | #define SUPHP_SYSTEMEXCEPTION_H 24 | 25 | #include 26 | #include 27 | 28 | #include "Exception.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Exception showing that some system-call failed 33 | */ 34 | class SystemException : public Exception { 35 | private: 36 | std::string getName() const; 37 | 38 | public: 39 | /** 40 | * Constructor without message. 41 | */ 42 | SystemException(std::string file, int line); 43 | 44 | /** 45 | * Constructor with message. 46 | */ 47 | SystemException(std::string message, std::string file, int line); 48 | 49 | /** 50 | * Constructor without message but with cause. 51 | */ 52 | SystemException(Exception& cause, std::string file, int line); 53 | 54 | /** 55 | * Constructor with message and cause. 56 | */ 57 | SystemException(std::string message, Exception& cause, std::string file, 58 | int line); 59 | }; 60 | } 61 | 62 | #endif // SUPHP_SYSTEMEXCEPTION_H 63 | -------------------------------------------------------------------------------- /src/SecurityException.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_SECURITYEXCEPTION_H 23 | #define SUPHP_SECURITYEXCEPTION_H 24 | 25 | #include 26 | #include 27 | 28 | #include "Exception.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Exception showing a security relevant problem. 33 | */ 34 | class SecurityException : public Exception { 35 | private: 36 | std::string getName() const; 37 | 38 | public: 39 | /** 40 | * Constructor without message. 41 | */ 42 | SecurityException(std::string file, int line); 43 | 44 | /** 45 | * Constructor with message. 46 | */ 47 | SecurityException(std::string message, std::string file, int line); 48 | 49 | /** 50 | * Constructor without message but with cause. 51 | */ 52 | SecurityException(Exception& cause, std::string file, int line); 53 | 54 | /** 55 | * Constructor with message and cause. 56 | */ 57 | SecurityException(std::string message, Exception& cause, std::string file, 58 | int line); 59 | }; 60 | } 61 | 62 | #endif // SUPHP_SECURITYEXCEPTION_H 63 | -------------------------------------------------------------------------------- /src/ParsingException.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_PARSINGEXCEPTION_H 23 | #define SUPHP_PARSINGEXCEPTION_H 24 | 25 | #include 26 | #include 27 | 28 | #include "Exception.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Exception showing that an error ocurred while parsing some input 33 | */ 34 | class ParsingException : public Exception { 35 | private: 36 | std::string getName() const; 37 | 38 | public: 39 | /** 40 | * Constructor without message. 41 | */ 42 | ParsingException(std::string file, int line); 43 | 44 | /** 45 | * Constructor with message. 46 | */ 47 | ParsingException(std::string message, std::string file, int line); 48 | 49 | /** 50 | * Constructor without message but with cause. 51 | */ 52 | ParsingException(Exception& cause, std::string file, int line); 53 | 54 | /** 55 | * Constructor with message and cause. 56 | */ 57 | ParsingException(std::string message, Exception& cause, std::string file, 58 | int line); 59 | }; 60 | } 61 | 62 | #endif // SUPHP_PARSINGEXCEPTION_H 63 | -------------------------------------------------------------------------------- /src/OutOfRangeException.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_OUTOFRANGEEXCEPTION_H 23 | #define SUPHP_OUTOFRANGEEXCEPTION_H 24 | 25 | #include 26 | #include 27 | 28 | #include "Exception.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Exception showing that value is not in expected range. 33 | */ 34 | class OutOfRangeException : public Exception { 35 | private: 36 | std::string getName() const; 37 | 38 | public: 39 | /** 40 | * Constructor without message. 41 | */ 42 | OutOfRangeException(std::string file, int line); 43 | 44 | /** 45 | * Constructor with message. 46 | */ 47 | OutOfRangeException(std::string message, std::string file, int line); 48 | 49 | /** 50 | * Constructor without message but with cause. 51 | */ 52 | OutOfRangeException(Exception& cause, std::string file, int line); 53 | 54 | /** 55 | * Constructor with message and cause. 56 | */ 57 | OutOfRangeException(std::string message, Exception& cause, std::string file, 58 | int line); 59 | }; 60 | } 61 | 62 | #endif // SUPHP_OUTOFRANGEEXCEPTION_H 63 | -------------------------------------------------------------------------------- /src/SoftException.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_SOFTEXCEPTION_H 23 | #define SUPHP_SOFTEXCEPTION_H 24 | 25 | #include 26 | #include 27 | 28 | #include "Exception.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Exception showing that an minor problem ocurred and the program 33 | * should simply exit without logging anything 34 | */ 35 | class SoftException : public Exception { 36 | private: 37 | std::string getName() const; 38 | 39 | public: 40 | /** 41 | * Constructor without message. 42 | */ 43 | SoftException(std::string file, int line); 44 | 45 | /** 46 | * Constructor with message. 47 | */ 48 | SoftException(std::string message, std::string file, int line); 49 | 50 | /** 51 | * Constructor without message but with cause. 52 | */ 53 | SoftException(Exception& cause, std::string file, int line); 54 | 55 | /** 56 | * Constructor with message and cause. 57 | */ 58 | SoftException(std::string message, Exception& cause, std::string file, 59 | int line); 60 | }; 61 | } 62 | 63 | #endif // SUPHP_SOFTEXCEPTION_H 64 | -------------------------------------------------------------------------------- /src/KeyNotFoundException.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_KEYNOTFOUNDEXCEPTION_H 23 | #define SUPHP_KEYNOTFOUNDEXCEPTION_H 24 | 25 | #include 26 | #include 27 | 28 | #include "Exception.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Exception showing that a specified key was not found within a list 33 | */ 34 | class KeyNotFoundException : public Exception { 35 | private: 36 | std::string getName() const; 37 | 38 | public: 39 | /** 40 | * Constructor without message. 41 | */ 42 | KeyNotFoundException(std::string file, int line); 43 | 44 | /** 45 | * Constructor with message. 46 | */ 47 | KeyNotFoundException(std::string message, std::string file, int line); 48 | 49 | /** 50 | * Constructor without message but with cause. 51 | */ 52 | KeyNotFoundException(Exception& cause, std::string file, int line); 53 | 54 | /** 55 | * Constructor with message and cause. 56 | */ 57 | KeyNotFoundException(std::string message, Exception& cause, std::string file, 58 | int line); 59 | }; 60 | } 61 | 62 | #endif // SUPHP_KEYNOTFOUNDEXCEPTION_H 63 | -------------------------------------------------------------------------------- /src/LookupException.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_LOOKUPEXCEPTION_H 23 | #define SUPHP_LOOKUPEXCEPTION_H 24 | 25 | #include 26 | #include 27 | 28 | #include "Exception.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Exception showing that an error ocurred during a lookup operation 33 | * (e.g. reading in the system's user database 34 | */ 35 | class LookupException : public Exception { 36 | private: 37 | std::string getName() const; 38 | 39 | public: 40 | /** 41 | * Constructor without message. 42 | */ 43 | LookupException(std::string file, int line); 44 | 45 | /** 46 | * Constructor with message. 47 | */ 48 | LookupException(std::string message, std::string file, int line); 49 | 50 | /** 51 | * Constructor without message but with cause. 52 | */ 53 | LookupException(Exception& cause, std::string file, int line); 54 | 55 | /** 56 | * Constructor with message and cause. 57 | */ 58 | LookupException(std::string message, Exception& cause, std::string file, 59 | int line); 60 | }; 61 | } 62 | 63 | #endif // SUPHP_LOOKUPEXCEPTION_H 64 | -------------------------------------------------------------------------------- /src/GroupInfo.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_GROUPINFO_H 23 | 24 | namespace suPHP { 25 | class GroupInfo; 26 | } 27 | 28 | #define SUPHP_GROUPINFO_H 29 | 30 | #include 31 | #include 32 | 33 | #include "LookupException.hpp" 34 | 35 | namespace suPHP { 36 | /** 37 | * Class encapsulating group information. 38 | */ 39 | class GroupInfo { 40 | private: 41 | int gid; 42 | 43 | public: 44 | /** 45 | * Constructor without arguments. 46 | * Does not create a "valid" object, since it has no well defined GID 47 | */ 48 | GroupInfo(); 49 | 50 | /** 51 | * Contructor (creates group object from GID) 52 | */ 53 | GroupInfo(int gid); 54 | 55 | /** 56 | * Returns groupname 57 | */ 58 | std::string getGroupname() const; 59 | 60 | /** 61 | * Returns GID 62 | */ 63 | int getGid() const; 64 | 65 | /** 66 | * Compares to GroupInfo objects for equality 67 | */ 68 | bool operator==(const GroupInfo& ginfo) const; 69 | 70 | /** 71 | * Overloaded operator != 72 | */ 73 | bool operator!=(const GroupInfo& ginfo) const; 74 | }; 75 | } // namespace suPHP 76 | 77 | #endif // SUPHP_GROUPINFO_H 78 | -------------------------------------------------------------------------------- /src/Util.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | 24 | #include "Util.hpp" 25 | 26 | using namespace suPHP; 27 | 28 | std::string suPHP::Util::intToStr(const int i) { 29 | std::ostringstream ostr; 30 | ostr << i; 31 | return ostr.str(); 32 | } 33 | 34 | int suPHP::Util::strToInt(const std::string str) { 35 | int i = 0; 36 | std::istringstream istr; 37 | istr.str(str); 38 | istr >> i; 39 | return i; 40 | } 41 | 42 | int suPHP::Util::octalStrToInt(const std::string str) { 43 | int result = 0; 44 | for (std::string::size_type i = 0; i < str.length(); i++) { 45 | int d; 46 | result *= 8; 47 | switch (str[i]) { 48 | case '0': 49 | d = 0; 50 | break; 51 | case '1': 52 | d = 1; 53 | break; 54 | case '2': 55 | d = 2; 56 | break; 57 | case '3': 58 | d = 3; 59 | break; 60 | case '4': 61 | d = 4; 62 | break; 63 | case '5': 64 | d = 5; 65 | break; 66 | case '6': 67 | d = 6; 68 | break; 69 | case '7': 70 | d = 7; 71 | break; 72 | default: 73 | // Should not happen 74 | continue; 75 | } 76 | result += d; 77 | } 78 | return result; 79 | } 80 | -------------------------------------------------------------------------------- /src/IniFile.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_INIFILE_H 23 | #define SUPHP_INIFILE_H 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "File.hpp" 30 | #include "IOException.hpp" 31 | #include "IniSection.hpp" 32 | #include "KeyNotFoundException.hpp" 33 | #include "ParsingException.hpp" 34 | 35 | namespace suPHP { 36 | /** 37 | * Class providing access to configuration in a INI file. 38 | */ 39 | class IniFile { 40 | private: 41 | std::map sections; 42 | 43 | std::string parseValue(const std::string& value) const; 44 | 45 | public: 46 | /** 47 | * Reads values from INI file 48 | */ 49 | void parse(const File& file); 50 | 51 | /** 52 | * Returns section 53 | */ 54 | const IniSection& getSection(const std::string& name) const; 55 | 56 | /** 57 | * Index operator 58 | */ 59 | const IniSection& operator[](const std::string& name) const; 60 | 61 | /** 62 | * Returns vector containing names of all sections 63 | */ 64 | const std::vector getSections(); 65 | 66 | /** 67 | * Checks wheter a section is existing 68 | */ 69 | bool hasSection(const std::string& name) const; 70 | }; 71 | } // namespace suPHP 72 | 73 | #endif // SUPHP_INIFILE_H 74 | -------------------------------------------------------------------------------- /src/CommandLine.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_COMMANDLINE_H 23 | #define SUPHP_COMMANDLINE_H 24 | 25 | #include 26 | #include 27 | 28 | #include "OutOfRangeException.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Class containing command-line arguments. 33 | */ 34 | class CommandLine { 35 | private: 36 | std::vector arguments; 37 | 38 | public: 39 | /** 40 | * Size typedef 41 | */ 42 | typedef std::vector::size_type size_type; 43 | 44 | /** 45 | * Constructer 46 | */ 47 | CommandLine(); 48 | 49 | /** 50 | * Return number of arguments 51 | */ 52 | size_type count() const; 53 | 54 | /** 55 | * Returns (copy of) argument at at position 56 | */ 57 | std::string getArgument(size_type pos) const; 58 | 59 | /** 60 | * Set argument at position 61 | */ 62 | void setArgument(size_type pos, std::string arg); 63 | 64 | /** 65 | * Add argument at the end of commandline 66 | */ 67 | void putArgument(std::string arg); 68 | 69 | /** 70 | * Returns reference to string at index 71 | */ 72 | std::string& operator[](size_type index); 73 | 74 | /** 75 | * Returns number of elements 76 | */ 77 | size_type size() const; 78 | }; 79 | } // namespace suPHP 80 | 81 | #endif // SUPHP_COMMANDLINE_H 82 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | =========================== 2 | == suPHP == 3 | =========================== 4 | 5 | What is it? 6 | ----------- 7 | 8 | The suPHP project combines an Apache handler module and a setuid 9 | binary. Together, they allow PHP scripts to safely run as the script 10 | owner rather than the Apache webserver user. 11 | 12 | suPHP validates that the requested PHP script has appropriate ownership 13 | and permissions. It also verifies that the filesystem paths leading to 14 | the PHP script have safe ownership and permissions. 15 | 16 | 17 | Documentation 18 | ------------- 19 | 20 | Documentation for mod_suphp is available in the "doc" directory. 21 | 22 | The "doc/INSTALL" file details the installation process of mod_suphp. 23 | 24 | The "doc/CONFIG" file contains instructions for configuring the setuid 25 | suphp binary. 26 | 27 | The "doc/apache/CONFIG" file contains instructions for configuring 28 | the mod_suphp Apache handler module. 29 | 30 | 31 | Reporting Bugs 32 | -------------- 33 | 34 | If you encounter bugs while using mod_suphp, please open an issue 35 | at the github repo: 36 | 37 | https://github.com/lightsey/mod_suphp 38 | 39 | If you believe you have found a security flaw in mod_suphp, please 40 | email the details directly to john@nixnuts.net 41 | 42 | 43 | License 44 | ------- 45 | 46 | suPHP - (c)2002-2013 Sebastian Marsching 47 | (c)2018 John Lightsey 48 | 49 | suPHP is free software; you can redistribute it and/or modify 50 | it under the terms of the GNU General Public License as published by 51 | the Free Software Foundation; either version 2 of the License, or 52 | (at your option) any later version. 53 | 54 | suPHP is distributed in the hope that it will be useful, 55 | but WITHOUT ANY WARRANTY; without even the implied warranty of 56 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 57 | GNU General Public License for more details. 58 | 59 | You should have received a copy of the GNU General Public License 60 | along with suPHP; if not, write to the Free Software 61 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 62 | USA 63 | 64 | =================================== 65 | -------------------------------------------------------------------------------- /src/Exception.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_EXCEPTION_H 23 | #define SUPHP_EXCEPTION_H 24 | 25 | #include 26 | #include 27 | 28 | namespace suPHP { 29 | /** 30 | * Parent class for exceptions. 31 | * All exceptions are derived from this class. 32 | */ 33 | class Exception { 34 | private: 35 | std::string message; 36 | std::string backtrace; 37 | int line; 38 | std::string file; 39 | virtual std::string getName() const = 0; 40 | 41 | public: 42 | /** 43 | * Constructor without message. 44 | */ 45 | Exception(std::string file, int line); 46 | 47 | /** 48 | * Constructor with message. 49 | */ 50 | Exception(std::string message, std::string file, int line); 51 | 52 | /** 53 | * Constructor without message but with cause. 54 | */ 55 | Exception(Exception& cause, std::string file, int line); 56 | 57 | /** 58 | * Constructor with message and cause. 59 | */ 60 | Exception(std::string message, Exception& cause, std::string file, int line); 61 | 62 | /** 63 | * Get the message 64 | */ 65 | std::string getMessage(); 66 | 67 | /** 68 | * Get string representing the exception 69 | */ 70 | std::string toString() const; 71 | }; 72 | 73 | std::ostream& operator<<(std::ostream& os, const Exception& e); 74 | } 75 | 76 | #endif // SUPHP_EXCEPTION_H 77 | -------------------------------------------------------------------------------- /src/UserInfo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "API.hpp" 30 | #include "API_Helper.hpp" 31 | 32 | #include "UserInfo.hpp" 33 | 34 | using namespace suPHP; 35 | 36 | suPHP::UserInfo::UserInfo() { this->uid = -1; } 37 | 38 | suPHP::UserInfo::UserInfo(int uid) { this->uid = uid; } 39 | 40 | std::string suPHP::UserInfo::getUsername() const { 41 | API& api = API_Helper::getSystemAPI(); 42 | return api.UserInfo_getUsername(*this); 43 | } 44 | 45 | int suPHP::UserInfo::getUid() const { return this->uid; } 46 | 47 | GroupInfo suPHP::UserInfo::getGroupInfo() const { 48 | API& api = API_Helper::getSystemAPI(); 49 | return api.UserInfo_getGroupInfo(*this); 50 | } 51 | 52 | std::string suPHP::UserInfo::getHomeDirectory() const { 53 | API& api = API_Helper::getSystemAPI(); 54 | return api.UserInfo_getHomeDirectory(*this); 55 | } 56 | 57 | bool suPHP::UserInfo::isSuperUser() { 58 | return API_Helper::getSystemAPI().UserInfo_isSuperUser(*this); 59 | } 60 | 61 | bool suPHP::UserInfo::operator==(const UserInfo& uinfo) const { 62 | if (this->getUid() == uinfo.getUid()) 63 | return true; 64 | else 65 | return false; 66 | } 67 | 68 | bool suPHP::UserInfo::operator!=(const UserInfo& uinfo) const { 69 | return !this->operator==(uinfo); 70 | } 71 | -------------------------------------------------------------------------------- /src/IniSection.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_INISECTION_H 23 | #define SUPHP_INISECTION_H 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "KeyNotFoundException.hpp" 30 | 31 | namespace suPHP { 32 | 33 | class IniFile; 34 | 35 | /** 36 | * Class providing access to configuration in a INI file. 37 | */ 38 | class IniSection { 39 | private: 40 | std::multimap entries; 41 | void putValue(const std::string key, const std::string value); 42 | void removeValues(const std::string& key); 43 | 44 | public: 45 | /** 46 | * Returns values corresponding to key 47 | */ 48 | const std::vector getValues(const std::string& key) const; 49 | 50 | /** 51 | * Returns first value corresponding to a key 52 | */ 53 | std::string getValue(const std::string& key) const; 54 | 55 | /** 56 | * Returns keys appearing in this section 57 | */ 58 | const std::vector getKeys() const; 59 | /** 60 | * Overloaded index operator, calls getValues() 61 | */ 62 | const std::vector operator[](const std::string& key) const; 63 | 64 | friend class IniFile; 65 | 66 | /** 67 | * Check wheter key is existing within section 68 | */ 69 | bool hasKey(const std::string& name) const; 70 | }; 71 | } // namespace suPHP 72 | 73 | #endif // SUPHP_INISECTION_H 74 | -------------------------------------------------------------------------------- /src/Environment.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_ENVIRONMENT_H 23 | #define SUPHP_ENVIRONMENT_H 24 | 25 | #include 26 | #include 27 | 28 | #include "KeyNotFoundException.hpp" 29 | 30 | namespace suPHP { 31 | /** 32 | * Class containing environment variables. 33 | */ 34 | class Environment { 35 | private: 36 | std::map vars; 37 | 38 | public: 39 | /** 40 | * Returns (copy of) variable content 41 | */ 42 | std::string getVar(const std::string& name) const; 43 | 44 | /** 45 | * Sets variable content 46 | */ 47 | void setVar(const std::string name, const std::string content); 48 | 49 | /** 50 | * Adds variable to environment 51 | */ 52 | void putVar(const std::string name, const std::string content); 53 | 54 | /** 55 | * Deletes variable from environment if it is set 56 | */ 57 | void deleteVar(const std::string& name); 58 | 59 | /** 60 | * Checks whether a variable is set 61 | */ 62 | bool hasVar(const std::string& name) const; 63 | 64 | /** 65 | * Returns reference to variable with name 66 | */ 67 | std::string& operator[](const std::string& name); 68 | 69 | /** 70 | * Returns const reference to the map which stores the variables 71 | */ 72 | const std::map& getBackendMap() const; 73 | }; 74 | } // namespace suPHP 75 | 76 | #endif // SUPHP_ENVIRONMENT_H 77 | -------------------------------------------------------------------------------- /doc/apache/CONFIG: -------------------------------------------------------------------------------- 1 | =========================== 2 | == suPHP Apache module == 3 | =========================== 4 | 5 | Configuration 6 | ------------- 7 | 8 | mod_suphp knows the following configuration directives: 9 | 10 | suPHP_Engine (can either be turned "on" or "off") 11 | 12 | This option tells mod_suphp if a PHP-script requested on this server (or 13 | VirtualHost) should be run with the PHP-interpreter or returned to the 14 | browser "as it is". 15 | 16 | This directive can be used in the global context or in a 17 | ""-directive. 18 | 19 | 20 | suPHP_ConfigPath (expects a path name) 21 | 22 | This option tells mod_suphp which path to pass on to the PHP-interpreter 23 | (by setting the PHPRC environment variable). 24 | Do *NOT* refer to a file but to the directory the file resists in. 25 | 26 | E.g.: If you want to use "/path/to/server/config/php.ini", use 27 | "suPHP_ConfigPath /path/to/server/config". 28 | 29 | If you don't use this option, PHP will use its compiled in default path. 30 | 31 | 32 | suPHP_UserGroup (expects user- and groupname) 33 | 34 | * Only supported when compiled with setid-mode "force" or "paranoid" * 35 | Specify the user- and groupname to run PHP-scripts with. This setting 36 | can only be used within a or context. 37 | Example: suPHP_UserGroup foouser bargroup 38 | 39 | 40 | suPHP_AddHandler 41 | 42 | Tells mod_suphp to handle requests with the type . 43 | Please note this only works, if an action for the handler is specified 44 | in the suPHP configuration file. Settings on per-directory level supersede 45 | settings made on per-server level. 46 | 47 | 48 | suPHP_RemoveHandler 49 | 50 | Tells mod_suphp NOT to handle requests with the type . This will 51 | override the suPHP_AddHandler setting made on a higher configuration level. 52 | 53 | 54 | suPHP_PHPPath (expects a path name) 55 | 56 | Sets the path to the PHP binary that is used to render files with the 57 | "x-httpd-php" or "application/x-httpd-php" type. This setting does 58 | *NOT* affect the PHP binary used for serving script requests, which is 59 | still configured in suphp.conf. 60 | 61 | =================================== 62 | (c)2002-2007 by Sebastian Marsching 63 | 64 | Please see LICENSE for 65 | additional information 66 | -------------------------------------------------------------------------------- /src/UserInfo.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_USERINFO_H 23 | 24 | namespace suPHP { 25 | class UserInfo; 26 | } 27 | 28 | #define SUPHP_USERINFO_H 29 | 30 | #include 31 | #include 32 | 33 | #include "GroupInfo.hpp" 34 | #include "LookupException.hpp" 35 | 36 | namespace suPHP { 37 | /** 38 | * Class encapsulating user information. 39 | */ 40 | class UserInfo { 41 | private: 42 | int uid; 43 | 44 | public: 45 | /** 46 | * Constructor without arguments. 47 | * Does not create a "valid" object, since it has no well defined UID 48 | */ 49 | UserInfo(); 50 | 51 | /** 52 | * Constructor (takes UID) 53 | */ 54 | UserInfo(int uid); 55 | 56 | /** 57 | * Returns username 58 | */ 59 | std::string getUsername() const; 60 | 61 | /** 62 | * Returns UID 63 | */ 64 | int getUid() const; 65 | 66 | /** 67 | * Returns primary group 68 | */ 69 | GroupInfo getGroupInfo() const; 70 | 71 | /** 72 | * Returns home directory 73 | */ 74 | std::string getHomeDirectory() const; 75 | 76 | /** 77 | * Checks wheter user is super-user 78 | */ 79 | bool isSuperUser(); 80 | 81 | /** 82 | * Compares to UserInfo objects for equality (same UID) 83 | */ 84 | bool operator==(const UserInfo& uinfo) const; 85 | 86 | /** 87 | * Overloaded operator 88 | */ 89 | bool operator!=(const UserInfo& uinfo) const; 90 | }; 91 | } // namespace suPHP 92 | 93 | #endif // SUPHP_USERINFO_H 94 | -------------------------------------------------------------------------------- /src/Exception.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | 24 | #include "Exception.hpp" 25 | 26 | using namespace suPHP; 27 | 28 | std::string suPHP::Exception::getName() const { return "Exception"; } 29 | 30 | suPHP::Exception::Exception(std::string file, int line) { 31 | this->file = file; 32 | this->line = line; 33 | } 34 | 35 | suPHP::Exception::Exception(std::string message, std::string file, int line) { 36 | this->message = message; 37 | this->file = file; 38 | this->line = line; 39 | } 40 | 41 | suPHP::Exception::Exception(Exception& cause, std::string file, int line) { 42 | this->backtrace = cause.toString(); 43 | this->file = file; 44 | this->line = line; 45 | } 46 | 47 | suPHP::Exception::Exception(std::string message, Exception& cause, 48 | std::string file, int line) { 49 | this->message = message; 50 | this->backtrace = cause.toString(); 51 | this->file = file; 52 | this->line = line; 53 | } 54 | 55 | std::string suPHP::Exception::getMessage() { return this->message; } 56 | 57 | std::string suPHP::Exception::toString() const { 58 | std::ostringstream ostr; 59 | ostr << std::string(this->getName()) << " in " << this->file << ":" 60 | << this->line << ": " << this->message << "\n"; 61 | if (this->backtrace.length() > 0) { 62 | ostr << "Caused by " << this->backtrace; 63 | } 64 | return ostr.str(); 65 | } 66 | 67 | std::ostream& suPHP::operator<<(std::ostream& os, const Exception& e) { 68 | os << e.toString(); 69 | return os; 70 | } 71 | -------------------------------------------------------------------------------- /src/Logger.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_LOGGER_H 23 | 24 | namespace suPHP { 25 | class Logger; 26 | 27 | enum LogLevel { LOGLEVEL_NONE, LOGLEVEL_ERROR, LOGLEVEL_WARN, LOGLEVEL_INFO }; 28 | } // namespace suPHP 29 | 30 | #define SUPHP_LOGGER_H 31 | 32 | #include "Configuration.hpp" 33 | 34 | namespace suPHP { 35 | /** 36 | * Class containing logging facility. 37 | * This is only an interface class. 38 | * It contains the code doing the formatting 39 | * but the API implementation has to provide 40 | * the file access code. 41 | */ 42 | class Logger { 43 | private: 44 | LogLevel logLevel; 45 | 46 | /** 47 | * Internal log function 48 | */ 49 | virtual void log(const std::string& classification, 50 | const std::string& message) = 0; 51 | 52 | protected: 53 | /** 54 | * Set log level 55 | */ 56 | virtual void setLogLevel(LogLevel level); 57 | 58 | public: 59 | /** 60 | * Virtual destructor so that derived class destructors are invoked 61 | */ 62 | virtual ~Logger() = default; 63 | 64 | /*** 65 | * Get log level 66 | */ 67 | virtual LogLevel getLogLevel(); 68 | 69 | /** 70 | * Initialize (open logfile) 71 | */ 72 | virtual void init(const Configuration& config) = 0; 73 | 74 | /** 75 | * Check wheter Logger has been initialized 76 | */ 77 | virtual bool isInitialized() = 0; 78 | 79 | /** 80 | * Logs info message 81 | */ 82 | virtual void logInfo(const std::string& message); 83 | 84 | /** 85 | * Logs warning 86 | */ 87 | virtual void logWarning(const std::string& message); 88 | 89 | /** 90 | * Logs error 91 | */ 92 | virtual void logError(const std::string& message); 93 | }; 94 | } // namespace suPHP 95 | 96 | #endif // SUPHP_LOGGER_H 97 | -------------------------------------------------------------------------------- /src/CommandLine.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "OutOfRangeException.hpp" 26 | 27 | #include "CommandLine.hpp" 28 | 29 | using namespace suPHP; 30 | 31 | suPHP::CommandLine::CommandLine() { /* do nothing */ 32 | } 33 | 34 | suPHP::CommandLine::size_type suPHP::CommandLine::count() const { 35 | return this->arguments.size(); 36 | } 37 | 38 | std::string suPHP::CommandLine::getArgument( 39 | suPHP::CommandLine::size_type pos) const { 40 | if (pos >= this->arguments.size()) { 41 | throw OutOfRangeException("Index out of range", __FILE__, __LINE__); 42 | } 43 | try { 44 | return this->arguments[pos]; 45 | } catch (std::out_of_range& e) { 46 | throw OutOfRangeException("Index out of range", __FILE__, __LINE__); 47 | } 48 | } 49 | 50 | void suPHP::CommandLine::setArgument(suPHP::CommandLine::size_type pos, 51 | std::string arg) { 52 | if (pos >= this->arguments.size()) { 53 | for (suPHP::CommandLine::size_type i = 0; 54 | i < (this->arguments.size() - pos); i++) { 55 | this->arguments.push_back(std::string("")); 56 | } 57 | } 58 | this->arguments[pos] = arg; 59 | } 60 | 61 | void suPHP::CommandLine::putArgument(std::string arg) { 62 | this->arguments.push_back(arg); 63 | } 64 | 65 | std::string& suPHP::CommandLine::operator[]( 66 | suPHP::CommandLine::size_type index) { 67 | if (index >= this->arguments.size()) { 68 | throw OutOfRangeException("Index out of range", __FILE__, __LINE__); 69 | } 70 | try { 71 | return this->arguments[index]; 72 | } catch (std::out_of_range& ex) { 73 | throw OutOfRangeException("Index out of range", __FILE__, __LINE__); 74 | } 75 | } 76 | 77 | suPHP::CommandLine::size_type suPHP::CommandLine::size() const { 78 | return this->arguments.size(); 79 | } 80 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | suphp 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | -j5 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.buildLocation 34 | ${workspace_loc:/suphp/build} 35 | 36 | 37 | org.eclipse.cdt.make.core.cleanBuildTarget 38 | clean 39 | 40 | 41 | org.eclipse.cdt.make.core.contents 42 | org.eclipse.cdt.make.core.activeConfigSettings 43 | 44 | 45 | org.eclipse.cdt.make.core.enableAutoBuild 46 | false 47 | 48 | 49 | org.eclipse.cdt.make.core.enableCleanBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.enableFullBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.fullBuildTarget 58 | all 59 | 60 | 61 | org.eclipse.cdt.make.core.stopOnError 62 | true 63 | 64 | 65 | org.eclipse.cdt.make.core.useDefaultBuildCmd 66 | true 67 | 68 | 69 | 70 | 71 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 72 | 73 | 74 | 75 | 76 | 77 | org.eclipse.cdt.core.ccnature 78 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 79 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 80 | org.eclipse.cdt.core.cnature 81 | 82 | 83 | -------------------------------------------------------------------------------- /src/Environment.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "KeyNotFoundException.hpp" 26 | 27 | #include "Environment.hpp" 28 | 29 | using namespace suPHP; 30 | 31 | std::string suPHP::Environment::getVar(const std::string& name) const { 32 | auto found = this->vars.find(name); 33 | if (found != this->vars.end()) { 34 | return found->second; 35 | } else { 36 | throw KeyNotFoundException("Key " + name + " not found", __FILE__, 37 | __LINE__); 38 | } 39 | } 40 | 41 | void suPHP::Environment::setVar(const std::string name, 42 | const std::string content) { 43 | auto found = this->vars.find(name); 44 | if (found != this->vars.end()) { 45 | found->second = content; 46 | } else { 47 | throw KeyNotFoundException("Key " + name + " not found", __FILE__, 48 | __LINE__); 49 | } 50 | } 51 | 52 | void suPHP::Environment::putVar(const std::string name, 53 | const std::string content) { 54 | auto inserted = this->vars.insert( 55 | std::map::value_type(name, content)); 56 | if (!inserted.second) { 57 | inserted.first->second = content; 58 | } 59 | } 60 | 61 | void suPHP::Environment::deleteVar(const std::string& name) { 62 | this->vars.erase(name); 63 | } 64 | 65 | bool suPHP::Environment::hasVar(const std::string& name) const { 66 | if (this->vars.find(name) != this->vars.end()) { 67 | return true; 68 | } else { 69 | return false; 70 | } 71 | } 72 | 73 | std::string& suPHP::Environment::operator[](const std::string& name) { 74 | auto found = this->vars.find(name); 75 | if (found != this->vars.end()) { 76 | return found->second; 77 | } else { 78 | throw KeyNotFoundException("Key " + name + " not found", __FILE__, 79 | __LINE__); 80 | } 81 | } 82 | 83 | const std::map& suPHP::Environment::getBackendMap() 84 | const { 85 | return this->vars; 86 | } 87 | -------------------------------------------------------------------------------- /src/IniSection.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | 24 | #include "KeyNotFoundException.hpp" 25 | 26 | #include "IniSection.hpp" 27 | 28 | using namespace suPHP; 29 | 30 | void suPHP::IniSection::putValue(const std::string key, 31 | const std::string value) { 32 | std::pair p; 33 | p.first = key; 34 | p.second = value; 35 | this->entries.insert(p); 36 | } 37 | 38 | const std::vector suPHP::IniSection::getValues( 39 | const std::string& key) const { 40 | std::vector values; 41 | std::pair::const_iterator, 42 | std::multimap::const_iterator> 43 | range = this->entries.equal_range(key); 44 | for (std::multimap::const_iterator pos = 45 | range.first; 46 | pos != range.second; pos++) { 47 | values.push_back(pos->second); 48 | } 49 | if (values.size() == 0) { 50 | throw KeyNotFoundException("No value for key " + key + " found", __FILE__, 51 | __LINE__); 52 | } 53 | return values; 54 | } 55 | 56 | std::string suPHP::IniSection::getValue(const std::string& key) const { 57 | std::vector values; 58 | if (this->entries.find(key) != this->entries.end()) { 59 | return this->entries.find(key)->second; 60 | } else { 61 | throw KeyNotFoundException("No value for key " + key + " found", __FILE__, 62 | __LINE__); 63 | } 64 | } 65 | 66 | const std::vector suPHP::IniSection::getKeys() const { 67 | std::vector keys; 68 | for (std::multimap::const_iterator pos = 69 | this->entries.begin(); 70 | pos != this->entries.end(); pos++) { 71 | keys.push_back(pos->first); 72 | } 73 | return keys; 74 | } 75 | 76 | bool suPHP::IniSection::hasKey(const std::string& key) const { 77 | if (this->entries.find(key) != this->entries.end()) { 78 | return true; 79 | } else { 80 | return false; 81 | } 82 | } 83 | 84 | const std::vector suPHP::IniSection::operator[]( 85 | const std::string& key) const { 86 | return this->getValues(key); 87 | } 88 | 89 | void suPHP::IniSection::removeValues(const std::string& key) { 90 | this->entries.erase(key); 91 | } 92 | -------------------------------------------------------------------------------- /src/API_Linux_Logger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "API_Linux_Logger.hpp" 32 | 33 | using namespace suPHP; 34 | 35 | suPHP::API_Linux_Logger::API_Linux_Logger() { 36 | this->ready = false; 37 | this->logFd = -1; 38 | } 39 | 40 | void suPHP::API_Linux_Logger::log(const std::string& classification, 41 | const std::string& message) { 42 | ::time_t ts; 43 | struct ::tm* now; 44 | char timestr[64] = {0}; 45 | std::string logline; 46 | 47 | ts = ::time(NULL); 48 | now = ::localtime(&ts); 49 | 50 | // Do not check for error when running strftime - 51 | // we couldn't handle it anyway :-) 52 | ::strftime(timestr, 64, "[%a %b %d %H:%M:%S %Y]", now); 53 | 54 | // Construct logline 55 | logline = 56 | std::string(timestr) + " [" + classification + "] " + message + "\n"; 57 | 58 | // Check wheter we have an uninitialized logfile 59 | // or write to the logfile failed 60 | if (!this->isInitialized() || 61 | (write(this->logFd, logline.c_str(), logline.size()) == -1)) { 62 | // Print message to stderr 63 | std::cerr << "Could not write to logfile:" 64 | << std::endl 65 | // << ::strerror(::errno) << std::endl 66 | << "Printing message to stderr:" << std::endl 67 | << logline << std::endl; 68 | } 69 | } 70 | 71 | void suPHP::API_Linux_Logger::init(const Configuration& config) { 72 | // Open logfile in append mode, create if not existing. 73 | this->logFd = 74 | ::open(config.getLogfile().c_str(), 75 | O_WRONLY | O_CREAT | O_APPEND | O_NOCTTY, S_IRUSR | S_IWUSR); 76 | 77 | // Check wheter something failed 78 | if (this->logFd == -1) { 79 | throw IOException("Could not open logfile " + config.getLogfile(), __FILE__, 80 | __LINE__); 81 | } 82 | 83 | // Set close-on-exec flag, because we do not want 84 | // the user to write to our logfile 85 | if (::fcntl(this->logFd, F_SETFD, FD_CLOEXEC)) { 86 | // Ooops, something went wrong 87 | throw IOException("Could not set close-on-exec flag on logfile", __FILE__, 88 | __LINE__); 89 | } 90 | 91 | // Get log level from configuration 92 | this->setLogLevel(config.getLogLevel()); 93 | 94 | // We got here, so nothing failed 95 | this->ready = true; 96 | } 97 | 98 | bool suPHP::API_Linux_Logger::isInitialized() { return this->ready; } 99 | -------------------------------------------------------------------------------- /m4/ax_cxx_compile_stdcxx_0x.m4: -------------------------------------------------------------------------------- 1 | # ============================================================================ 2 | # http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_0x.html 3 | # ============================================================================ 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_CXX_COMPILE_STDCXX_0X 8 | # 9 | # DESCRIPTION 10 | # 11 | # Check for baseline language coverage in the compiler for the C++0x 12 | # standard. 13 | # 14 | # This macro is deprecated and has been superseded by the 15 | # AX_CXX_COMPILE_STDCXX_11 macro which should be used instead. 16 | # 17 | # LICENSE 18 | # 19 | # Copyright (c) 2008 Benjamin Kosnik 20 | # 21 | # Copying and distribution of this file, with or without modification, are 22 | # permitted in any medium without royalty provided the copyright notice 23 | # and this notice are preserved. This file is offered as-is, without any 24 | # warranty. 25 | 26 | #serial 10 27 | 28 | AU_ALIAS([AC_CXX_COMPILE_STDCXX_0X], [AX_CXX_COMPILE_STDCXX_0X]) 29 | AC_DEFUN([AX_CXX_COMPILE_STDCXX_0X], [ 30 | AC_OBSOLETE([$0], [; use AX_CXX_COMPILE_STDCXX_11 instead]) 31 | AC_CACHE_CHECK(if g++ supports C++0x features without additional flags, 32 | ax_cv_cxx_compile_cxx0x_native, 33 | [AC_LANG_SAVE 34 | AC_LANG_CPLUSPLUS 35 | AC_TRY_COMPILE([ 36 | template 37 | struct check 38 | { 39 | static_assert(sizeof(int) <= sizeof(T), "not big enough"); 40 | }; 41 | 42 | typedef check> right_angle_brackets; 43 | 44 | int a; 45 | decltype(a) b; 46 | 47 | typedef check check_type; 48 | check_type c; 49 | check_type&& cr = static_cast(c);],, 50 | ax_cv_cxx_compile_cxx0x_native=yes, ax_cv_cxx_compile_cxx0x_native=no) 51 | AC_LANG_RESTORE 52 | ]) 53 | 54 | AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x, 55 | ax_cv_cxx_compile_cxx0x_cxx, 56 | [AC_LANG_SAVE 57 | AC_LANG_CPLUSPLUS 58 | ac_save_CXX="$CXX" 59 | CXX="$CXX -std=c++0x" 60 | AC_TRY_COMPILE([ 61 | template 62 | struct check 63 | { 64 | static_assert(sizeof(int) <= sizeof(T), "not big enough"); 65 | }; 66 | 67 | typedef check> right_angle_brackets; 68 | 69 | int a; 70 | decltype(a) b; 71 | 72 | typedef check check_type; 73 | check_type c; 74 | check_type&& cr = static_cast(c);],, 75 | ax_cv_cxx_compile_cxx0x_cxx=yes, ax_cv_cxx_compile_cxx0x_cxx=no) 76 | CXX="$ac_save_CXX" 77 | AC_LANG_RESTORE 78 | ]) 79 | 80 | AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x, 81 | ax_cv_cxx_compile_cxx0x_gxx, 82 | [AC_LANG_SAVE 83 | AC_LANG_CPLUSPLUS 84 | ac_save_CXX="$CXX" 85 | CXX="$CXX -std=gnu++0x" 86 | AC_TRY_COMPILE([ 87 | template 88 | struct check 89 | { 90 | static_assert(sizeof(int) <= sizeof(T), "not big enough"); 91 | }; 92 | 93 | typedef check> right_angle_brackets; 94 | 95 | int a; 96 | decltype(a) b; 97 | 98 | typedef check check_type; 99 | check_type c; 100 | check_type&& cr = static_cast(c);],, 101 | ax_cv_cxx_compile_cxx0x_gxx=yes, ax_cv_cxx_compile_cxx0x_gxx=no) 102 | CXX="$ac_save_CXX" 103 | AC_LANG_RESTORE 104 | ]) 105 | 106 | if test "$ax_cv_cxx_compile_cxx0x_native" = yes || 107 | test "$ax_cv_cxx_compile_cxx0x_cxx" = yes || 108 | test "$ax_cv_cxx_compile_cxx0x_gxx" = yes; then 109 | AC_DEFINE(HAVE_STDCXX_0X,,[Define if g++ supports C++0x features. ]) 110 | fi 111 | ]) 112 | -------------------------------------------------------------------------------- /src/File.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include "API_Helper.hpp" 23 | 24 | #include "File.hpp" 25 | 26 | using namespace suPHP; 27 | using namespace std; 28 | 29 | bool suPHP::File::hasPermissionBit(FileMode perm) const { 30 | return API_Helper::getSystemAPI().File_hasPermissionBit(*this, perm); 31 | } 32 | 33 | suPHP::File::File(string path) { this->path = path; } 34 | 35 | string suPHP::File::getPath() const { return this->path; } 36 | 37 | unique_ptr suPHP::File::getInputStream() const { 38 | unique_ptr infile(new ifstream(this->path.c_str())); 39 | if (infile->fail()) { 40 | throw IOException("Could not open file " + this->path + " for reading", 41 | __FILE__, __LINE__); 42 | } 43 | return infile; 44 | } 45 | 46 | bool suPHP::File::exists() const { 47 | return API_Helper::getSystemAPI().File_exists(*this); 48 | } 49 | 50 | string suPHP::File::getRealPath() const { 51 | return API_Helper::getSystemAPI().File_getRealPath(*this); 52 | } 53 | 54 | File suPHP::File::getParentDirectory() const { 55 | string path = this->getPath(); 56 | path = path.substr(0, path.rfind('/')); 57 | if (path.length() == 0) { 58 | path = "/"; 59 | } 60 | return File(path); 61 | } 62 | 63 | bool suPHP::File::hasUserReadBit() const { 64 | return this->hasPermissionBit(FILEMODE_USER_READ); 65 | } 66 | 67 | bool suPHP::File::hasUserWriteBit() const { 68 | return this->hasPermissionBit(FILEMODE_USER_WRITE); 69 | } 70 | 71 | bool suPHP::File::hasUserExecuteBit() const { 72 | return this->hasPermissionBit(FILEMODE_USER_EXEC); 73 | } 74 | 75 | bool suPHP::File::hasGroupReadBit() const { 76 | return this->hasPermissionBit(FILEMODE_GROUP_READ); 77 | } 78 | 79 | bool suPHP::File::hasGroupWriteBit() const { 80 | return this->hasPermissionBit(FILEMODE_GROUP_WRITE); 81 | } 82 | 83 | bool suPHP::File::hasGroupExecuteBit() const { 84 | return this->hasPermissionBit(FILEMODE_GROUP_EXEC); 85 | } 86 | 87 | bool suPHP::File::hasOthersReadBit() const { 88 | return this->hasPermissionBit(FILEMODE_OTHERS_READ); 89 | } 90 | 91 | bool suPHP::File::hasOthersWriteBit() const { 92 | return this->hasPermissionBit(FILEMODE_OTHERS_WRITE); 93 | } 94 | 95 | bool suPHP::File::hasOthersExecuteBit() const { 96 | return this->hasPermissionBit(FILEMODE_OTHERS_EXEC); 97 | } 98 | 99 | UserInfo suPHP::File::getUser() const { 100 | return API_Helper::getSystemAPI().File_getUser(*this); 101 | } 102 | 103 | GroupInfo suPHP::File::getGroup() const { 104 | return API_Helper::getSystemAPI().File_getGroup(*this); 105 | } 106 | 107 | bool suPHP::File::isSymlink() const { 108 | return API_Helper::getSystemAPI().File_isSymlink(*this); 109 | } 110 | -------------------------------------------------------------------------------- /src/File.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_FILE_H 23 | 24 | namespace suPHP { 25 | class File; 26 | 27 | enum FileMode { 28 | FILEMODE_USER_READ, 29 | FILEMODE_USER_WRITE, 30 | FILEMODE_USER_EXEC, 31 | FILEMODE_GROUP_READ, 32 | FILEMODE_GROUP_WRITE, 33 | FILEMODE_GROUP_EXEC, 34 | FILEMODE_OTHERS_READ, 35 | FILEMODE_OTHERS_WRITE, 36 | FILEMODE_OTHERS_EXEC 37 | }; 38 | } // namespace suPHP 39 | 40 | #define SUPHP_FILE_H 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | #include "GroupInfo.hpp" 48 | #include "IOException.hpp" 49 | #include "SystemException.hpp" 50 | #include "UserInfo.hpp" 51 | 52 | namespace suPHP { 53 | /** 54 | * Class encapsulating file information and access. 55 | */ 56 | class File { 57 | private: 58 | std::string path; 59 | bool hasPermissionBit(FileMode perm) const; 60 | 61 | public: 62 | /** 63 | * Constructor 64 | */ 65 | File(std::string path); 66 | 67 | /** 68 | * Returns path to file 69 | */ 70 | std::string getPath() const; 71 | 72 | /** 73 | * Returns input stream to read from file 74 | */ 75 | std::unique_ptr getInputStream() const; 76 | 77 | /** 78 | * Does file exists? 79 | */ 80 | bool exists() const; 81 | 82 | /** 83 | * Returns real path to file (without symlinks in path) 84 | */ 85 | std::string getRealPath() const; 86 | 87 | /** 88 | * Returns File object representing parent directory 89 | */ 90 | File getParentDirectory() const; 91 | 92 | /** 93 | * Returns permission bit 94 | */ 95 | bool hasUserReadBit() const; 96 | 97 | /** 98 | * Returns permission bit 99 | */ 100 | bool hasUserWriteBit() const; 101 | 102 | /** 103 | * Returns permission bit 104 | */ 105 | bool hasUserExecuteBit() const; 106 | 107 | /** 108 | * Returns permission bit 109 | */ 110 | bool hasGroupReadBit() const; 111 | 112 | /** 113 | * Returns permission bit 114 | */ 115 | bool hasGroupWriteBit() const; 116 | 117 | /** 118 | * Returns permission bit 119 | */ 120 | bool hasGroupExecuteBit() const; 121 | 122 | /** 123 | * Returns permission bit 124 | */ 125 | bool hasOthersReadBit() const; 126 | 127 | /** 128 | * Returns permission bit 129 | */ 130 | bool hasOthersWriteBit() const; 131 | 132 | /** 133 | * Returns permission bit 134 | */ 135 | bool hasOthersExecuteBit() const; 136 | 137 | /** 138 | * Returns owner (user) of file 139 | */ 140 | UserInfo getUser() const; 141 | 142 | /** 143 | * Returns owning group of file 144 | */ 145 | GroupInfo getGroup() const; 146 | 147 | /** 148 | * Checks whether this file is a symlink 149 | */ 150 | bool isSymlink() const; 151 | }; 152 | } // namespace suPHP 153 | 154 | #endif // SUPHP_FILE_H 155 | -------------------------------------------------------------------------------- /src/PathMatcher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include "PathMatcher.hpp" 24 | #include "Util.hpp" 25 | 26 | namespace suPHP { 27 | 28 | template 29 | bool PathMatcher::matches(std::string pattern, 30 | std::string path) { 31 | std::string interpolatedPattern = resolveVariables(pattern, false); 32 | if (interpolatedPattern.length() == 0) { 33 | return true; 34 | } 35 | if (interpolatedPattern.at(interpolatedPattern.length() - 1) == '/') { 36 | interpolatedPattern.append("*"); 37 | } 38 | if (fnmatch(interpolatedPattern.c_str(), path.c_str(), 39 | FNM_FILE_NAME | FNM_LEADING_DIR) == 0) { 40 | return true; 41 | } 42 | return false; 43 | } 44 | 45 | template 46 | std::string PathMatcher::lookupVariable( 47 | std::string str) { 48 | std::string rv; 49 | if (str == "USERNAME") { 50 | rv = user.getUsername(); 51 | } else if (str == "UID") { 52 | rv = Util::intToStr(user.getUid()); 53 | } else if (str == "HOME") { 54 | rv = user.getHomeDirectory(); 55 | } else if (str == "GROUPNAME") { 56 | rv = group.getGroupname(); 57 | } else if (str == "GID") { 58 | rv = Util::intToStr(group.getGid()); 59 | } else { 60 | throw KeyNotFoundException( 61 | "Key \"" + str + "\" does not represent a valid variable name", 62 | __FILE__, __LINE__); 63 | } 64 | return rv; 65 | } 66 | 67 | template 68 | std::string PathMatcher::resolveVariables( 69 | std::string str, bool unescape) { 70 | std::string out; 71 | bool escapeNext = false; 72 | for (std::string::size_type i = 0; i < str.length(); i++) { 73 | char c = str.at(i); 74 | if (escapeNext) { 75 | escapeNext = false; 76 | if (unescape && (c == '\\' || c == '$')) { 77 | // Backslash was used as an escape character 78 | out += c; 79 | } else { 80 | out += '\\'; 81 | out += c; 82 | } 83 | } else { 84 | if (c == '\\') { 85 | escapeNext = true; 86 | } else if (c == '$') { 87 | if (str.length() < i + 3) { 88 | throw ParsingException( 89 | "Incorrect use of $ in string \"" + str + "\".", __FILE__, 90 | __LINE__); 91 | } 92 | if (str.at(i + 1) != '{') { 93 | throw ParsingException( 94 | "Incorrect use of $ in string \"" + str + "\".", __FILE__, 95 | __LINE__); 96 | } 97 | std::string::size_type closingBrace = str.find('}', i); 98 | if (closingBrace == std::string::npos) { 99 | throw ParsingException( 100 | "Incorrect use of $ in string \"" + str + "\".", __FILE__, 101 | __LINE__); 102 | } 103 | std::string varName = str.substr(i + 2, closingBrace - i - 2); 104 | out += lookupVariable(varName); 105 | i = closingBrace; 106 | } else { 107 | out += c; 108 | } 109 | } 110 | } 111 | return out; 112 | } 113 | 114 | template class PathMatcher; 115 | } // namespace suPHP 116 | -------------------------------------------------------------------------------- /doc/INSTALL: -------------------------------------------------------------------------------- 1 | =========================== 2 | == suPHP == 3 | =========================== 4 | 5 | Installation 6 | ------------ 7 | 8 | 1. Introduction 9 | 10 | The suPHP Apache module together with suPHP itself provides an easy way to 11 | run PHP scripts with different users on the same server. 12 | 13 | It provides security, because the PHP scripts are not run with the rights of 14 | the webserver's user. 15 | In addition to that you probably won't have to use PHP's "safe mode", which 16 | applies many restrictions on the scripts. 17 | 18 | Please note that the suPHP binary has to be installed setuid-root to work, 19 | so a security bug in suPHP probably will allow atackers to run commands with 20 | root privileges. Although I currently don't know any bug in suPHP I can't 21 | guarantee that there aren't any. 22 | 23 | 2. Installation 24 | 25 | Run ./configure with the appropriate paramters for your system. 26 | 27 | On most systems a 28 | ./configure --prefix=/usr 29 | will suffice. 30 | 31 | The configure script can take the familar GNU autoconf arguments plus the 32 | following suPHP specific ones: 33 | 34 | --disable-checkpath: With this compile time option suPHP does not check, 35 | whether a script (or a symink to it)is inside the 36 | DOCUMENT_ROOT. You may want to activate this option 37 | if you are working with "Alias"-directives. 38 | 39 | --disable-checkuid: You may specify this option to make suPHP work with 40 | scripts whose UIDs are not listed in /etc/passwd. 41 | 42 | --disable-checkgid: You may specify this option to make suPHP work with 43 | scripts whose GIDs are not listed in /etc/group. 44 | 45 | --with-apxs=FILE: Path to "apxs" of your Apache installation. If not 46 | specified, configure will look for apxs in your PATH. 47 | Without apxs the Apache module mod_suphp will not be 48 | built. It will not be built either, if your Apache has 49 | been compiled without DSO support. Please make sure you 50 | specify the right path to apxs, because suPHP will use 51 | apxs to check whether to build mod_suphp for Apache 1 52 | or Apache 2. 53 | 54 | --with-min-uid=UID: The minium UID that suPHP will allow PHP to run scripts 55 | with (defaults to 100). 56 | 57 | --with-min-gid=GID: The minium GID that suPHP will allow PHP to run scripts 58 | with (defaults to 100). 59 | 60 | --with-apache-user=USERNAME: 61 | Username (not UID) Apache is running as (defaults to 62 | wwwrun). 63 | 64 | --with-logfile=FILE Path to the suPHP logfile (defaults to 65 | /var/log/httpd/suphp_log). 66 | 67 | --with-setid-mode=MODE: 68 | MODE has to be one of: 69 | "owner": Run scripts with owner UID/GID 70 | "force": Run scripts with UID/GID specified in Apache 71 | configuration 72 | "paranoid": Run scripts with owner UID/GID but also check 73 | if they match the UID/GID specified in the 74 | Apache configuration 75 | The default is "paranoid" mode. 76 | You should *NEVER* use "force" mode as it is very 77 | dangerous. 78 | While "owner" mode is not as dangerous as "force" mode 79 | its use is disadvised and "paranoid" mode should be 80 | preferred. 81 | 82 | Now compile suPHP using "make" and if no error occured install it using 83 | "make install". Be sure to be root, when you try to install it. 84 | 85 | If your Apache is running with DSO support and "apxs" was found during the 86 | build process, you are done. Otherwise you have to rebuilt your Apache 87 | server with "mod_suphp.c" included. If you used another prefix during the 88 | suPHP build than "/usr", you have to modify "mod_suphp.c" to set the path to 89 | the suPHP executable (which you can find in $exec_prefix/sbin/suphp). 90 | 91 | Details on how to compile your Apache webserver with mod_suphp can be found 92 | in apache/INSTALL. 93 | 94 | Now, you have to modify your "httpd.conf" to activate suPHP for specific 95 | VHosts. See apache/CONFIG for details on this. 96 | 97 | Please note that in order to make suPHP work, you have to specify at least 98 | one handler in the suPHP configuration file. Read CONFIG for additonal 99 | information about how to configure suPHP. 100 | 101 | =================================== 102 | (c)2002-2013 by Sebastian Marsching 103 | 104 | Please see LICENSE for 105 | additional information 106 | -------------------------------------------------------------------------------- /doc/apache/INSTALL: -------------------------------------------------------------------------------- 1 | =========================== 2 | == suPHP Apache module == 3 | =========================== 4 | 5 | Installation 6 | ------------ 7 | 8 | 1. Introduction 9 | 10 | The suPHP Apache module together with suPHP itself provides an easy way to 11 | run PHP scripts with different users on the same server. 12 | 13 | It provides security, because the PHP scripts are not run with the rights of 14 | the webserver's user. 15 | In addition to that you probably won't have to use PHP's "safe mode", which 16 | applies many restrictions on the scripts. 17 | 18 | Please be sure to have read the README file in this directory and both the 19 | README and the INSTALL file in the main directory of the suPHP distribution. 20 | 21 | 22 | 2. The simple facts 23 | 24 | In this part, I'll give the most important information for people who know 25 | how to compile the Apache Server with additional modules. 26 | If you aren't familiar with doing this, you'll find a step-by-step guide in 27 | the third part of this manual. 28 | 29 | mod_suphp only consists of one file, called "mod_suphp.c". 30 | If the suphp binary is not in the default path (/usr/sbin/suphp) you'll have 31 | to modify the corresponding line in mod_suphp.c before adding it to your 32 | Apache sources with the "configure" script of Apache. 33 | 34 | The easiest way to install mod_suphp is to compile it as a dynamically 35 | loadable module (DSO). If your Apache was compiled with DSO support and 36 | "apxs" is either in your path or you specified the path to it when running 37 | "configure", mod_suphp will automatically be compiled when doing "make" and 38 | installed to your Apache server (when doing "make install"). 39 | 40 | Information on how to configure mod_suphp can be found in the "CONFIG" file 41 | in this directory. 42 | 43 | Please note that mod_suphp was developped for Apache 1.3.2x and Apache 44 | 2.0.x. It might not work with other version. 45 | 46 | suPHP was developped for Linux, perhaps it'll also work with some other 47 | *NIX-systems. I have heard that there is a suPHP port for FreeBSD, however 48 | as I do not have running FreeBSD on any system at the moment I cannot test 49 | which modifications have to be made to the current version to run it on 50 | suPHP. If you know, tell me and a will try to modify the GNU autoconf 51 | scripts to make decisions automatically. 52 | 53 | If you have tested it with another system and it works, please tell me. 54 | 55 | 56 | 3. Step-by-step guide 57 | 58 | If you have already running Apache with mod_so (DSO-support), mod_suphp 59 | should have been installed to your Apache server automatically. 60 | 61 | It it is not working look for the two lines 62 | LoadModule suphp_module /usr/lib/httpd/mod_suphp.so 63 | and 64 | AddModule mod_suphp.c 65 | in your "httpd.conf". 66 | 67 | Sometimes "apxs" adds this lines at the wrong locations. In this case you 68 | will have to move them to the appropriate position (see the Apache 69 | documentation for details). 70 | 71 | To compile Apache from scratch with mod_suphp (statically) proceed with the 72 | following steps: 73 | 74 | If necessary change the path to the suPHP executable in "mod_suphp.c". 75 | 76 | Get the Apache sources from http://www.apache.org and unpack them. 77 | Now go into the newly created directory. And run "./configure --help" which 78 | will output some really useful information about the configure-script. 79 | 80 | Now run the configure script with the parameters that match your needs but 81 | add the option "--add-module=/path/to/mod_suphp.c". 82 | 83 | This will copy mod_suphp.c to the Apache sources and activate it. 84 | 85 | Now you can "make" Apache and install it using "make install". 86 | 87 | Please note that suPHP will probably not work if you also compile in mod_php. 88 | 89 | To use suPHP to parse PHP-Files add a line like 90 | 91 | AddType application/x-httpd-php .php 92 | 93 | to your Apache configuration and to activate mod_suphp for the appropriate 94 | VHosts. 95 | 96 | You can turn mod_suphp on by adding the line 97 | 98 | suPHP_Engine on 99 | 100 | to your global Apache-configuration. 101 | This will activate mod_suphp for all VirtualHosts. 102 | 103 | Please note that you have to specify at least one suPHP_AddHandler 104 | directive, because mod_suphp by default handles no mime-type. 105 | 106 | Example: 107 | 108 | suPHP_AddHandler application/x-httpd-php 109 | 110 | If you are using "paranoid" or "force" mode, you have to specify 111 | at least one suPHP_UserGroup directive. 112 | 113 | Information about additional options can be found in the "CONFIG"-Readme. 114 | 115 | 4. Additional information 116 | 117 | Please note, that running mod_suphp and mod_php concurrently can be 118 | *VERY DANGEROUS* and should be avoided. The same applies to CGI 119 | scripts which are run with webserver privileges. 120 | 121 | suPHP should only be used if you are using no CGI scripts or if all CGI 122 | scripts are run using suExec. 123 | 124 | 125 | =================================== 126 | (c)2002-2007 by Sebastian Marsching 127 | 128 | Please see LICENSE for 129 | additional information 130 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | * Version 0.8.0-pre (4 February 2018) 2 | - Remove Apache 1.3 support. 3 | - Add Apache 2.4 support. 4 | - Update copyright files and dates. 5 | - Fix compiler warnings. 6 | - Add support for "userdir_overrides_usergroup" option 7 | - Add support for "full_php_process_display" option 8 | - Add suphp.conf options to disable paranoid UID and GID checks 9 | - Add support for phprc_paths section in suphp.conf 10 | 11 | * Version 0.7.2 (20 May 2013) 12 | - Use empty environment when forking a process for PHP source rendering. 13 | - Ignore PHPRC environment variable, to force use of suPHP_ConfigPath directive 14 | instead of SetEnv directive. 15 | 16 | * Version 0.7.1 (14 March 2009) 17 | - Fixed bug causing problems when a symlink was present in the script path. 18 | 19 | * Version 0.7.0 (25 December 2008) 20 | - Fixed "underquoted definition" warning in acinclude.m4 21 | - mod_suphp (Apache 1.3) checks explicitly for r->content_type 22 | thus allowing to use AddType instead of AddHandler 23 | - Added support for application/x-httpd-php-source: 24 | The PHP binary used to parse render the code can be set using the 25 | suPHP_PHPPath directive. 26 | - Made suPHP_AddHandler and suPHP_RemoveHandler directives 27 | available on server level. 28 | - Added support for multiple docroots (using patterns). 29 | - Added support for variable substitution in chroot path. 30 | 31 | * Version 0.6.3 (30 March 2008) 32 | - Fixed a possible race condition concerning the check for the 33 | right symlink owner. 34 | - Added checks for the owner of the parent directories were added. 35 | 36 | * Version 0.6.2 (19 November 2006) 37 | - Made mod_suphp compatible with Apache 2.2 38 | - Modified SmartPtr implementation (hopefully) fixing 39 | double free problem 40 | - Fixed problem that caused the process to block 41 | when more than 4096 were written to stderr 42 | - Implemented userdir support 43 | - Fixed problem with PATH_INFO and PHP scripts 44 | 45 | * Version 0.6.1 (26 November 2005) 46 | - Changed usage of STL to gain better compatibility with old GCC versions 47 | (credits to Jeremy Chadwick for finding the relevant code) 48 | - Fixed typos in mod_suphp.c (Apache 1.3) 49 | (credits to Johan Ekenberg for finding these typos) 50 | - Fixed potential buffer overflow in function suphp_bucket_read() in 51 | src/apache2/mod_suphp.c 52 | - Fix problems with scripts sending "Last-Modified" headers 53 | - Extended autoconf script to look for an installation of APR 54 | and to use its includedir when building mod_suphp for Apache 2 55 | - Added support for chroot() call before execution of script 56 | 57 | * Version 0.6.0 (27 May 2005) 58 | ++ The development of this version was sponsored by Techno-vi - Wanix. ++ 59 | ++ Thanks to the sponsor! ++ 60 | - Ported suPHP to C++ 61 | - Ported build system to automake 62 | - Added runtime configuration support 63 | - Made writeable by group/others check optional 64 | - Rewrote Apache 1.3.x module completely, thus now supporting all 65 | setid-modes with Apache 1.3 and Apache 2.0 66 | - Added support for multiple interpreters 67 | - Added support for runtime-configurable loglevel 68 | 69 | * Version 0.5.2 (13 July 2004) 70 | - Added support for UIDs/GIDs not listed in system configuration when using 71 | "force" or "paranoid" mode 72 | - Fixed bug in configure script that caused autoconf to assume wrong values 73 | - Changed behaviour for setting "REDIRECT_STATUS": Now it is only set to 74 | "200" when it has not already been set by Apache 75 | - Fixed bug causing environment variables with values ending with a '=' 76 | sign to be unset 77 | 78 | * Version 0.5.1 (24 February 2004) 79 | - Empty environment variables now are deleted from the environment instead 80 | of being set to "no value" 81 | - Fixed bug causing a segmentation fault when using different suPHP_Engine 82 | settings in vhosts (special thanks to Matthias Brunner for tracking down 83 | this problem) 84 | 85 | * Version 0.5 (10 January 2004) 86 | - Apache 2.x support 87 | - Portability to other *NIX systems improved by using more compatible 88 | system calls 89 | - Improved logging 90 | - Added "--with-setid-mode" compile time option (see doc/INSTALL for 91 | details) 92 | - Apache 2.x version now supports direct header output 93 | (like "HTTP/1.0 401 ...") 94 | 95 | * Version 0.3 (23 August 2003) 96 | - Changed build system to GNU autoconf 97 | - Supplementary groups are set correctly 98 | - Optional support for environments with UIDs/GIDs not in the system's 99 | configuration files 100 | 101 | * Version 0.2.3 (25 December 2002) 102 | - Fixed handling of symlinks 103 | 104 | * Version 0.2.2 (24 October 2002) 105 | - Added missing file "suphp.h" 106 | 107 | * Version 0.2.1 (20 October 2002) 108 | - Fixed problems with "suPHP_ConfigPath"-option on some systems 109 | - Added German documentation 110 | 111 | * Version 0.2 (13 July 2002) 112 | - Added support for VirtualHost based (de-)activation of suPHP 113 | - Added support for concurrent use of different PHP configuration files 114 | 115 | * Version 0.1 (04 June 2002) 116 | - First release of suPHP 117 | -------------------------------------------------------------------------------- /src/Application.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_APPLICATION_H 23 | #define SUPHP_APPLICATION_H 24 | 25 | #include 26 | #include 27 | 28 | #include "CommandLine.hpp" 29 | #include "Environment.hpp" 30 | #include "GroupInfo.hpp" 31 | #include "SecurityException.hpp" 32 | #include "SoftException.hpp" 33 | #include "SystemException.hpp" 34 | #include "UserInfo.hpp" 35 | 36 | namespace suPHP { 37 | 38 | enum TargetMode { TARGETMODE_PHP, TARGETMODE_SELFEXECUTE }; 39 | 40 | /** 41 | * Main application class. 42 | * Contains the main() function. 43 | */ 44 | class Application { 45 | private: 46 | /** 47 | * Print message containing version information 48 | */ 49 | void printAboutMessage(); 50 | 51 | /** 52 | * Checks wheter process has root privileges 53 | * and calling user is webserver user 54 | */ 55 | void checkProcessPermissions(Configuration& config); 56 | 57 | /** 58 | * Checks scriptfile (first stage). 59 | * Includes check for VHost docroot, symbollink and permissions. 60 | */ 61 | void checkScriptFileStage1(const File& scriptFile, const File& realScriptFile, 62 | const Configuration& config, 63 | const Environment& environment) const; 64 | 65 | /** 66 | * Checks scriptfile. 67 | * Includes check for paths which might be user specific 68 | */ 69 | void checkScriptFileStage2(const File& scriptFile, const File& realScriptFile, 70 | const Configuration& config, 71 | const Environment& environment, 72 | const UserInfo& targetUser, 73 | const GroupInfo& targetGroup) const; 74 | 75 | /** 76 | * Determines target user and group that is to be used for script execution. 77 | * Uses preprocessor macros to distinguish between modes 78 | */ 79 | void checkProcessPermissions(const File& scriptFile, 80 | const File& realScriptFile, 81 | const Configuration& config, 82 | const Environment& environment, 83 | UserInfo& targetUser, 84 | GroupInfo& targetGroup) const; 85 | 86 | /** 87 | * Changes process permission (user and group). 88 | * Uses preprocessor macros to distinguish between modes 89 | */ 90 | void changeProcessPermissions(const Configuration& config, 91 | const UserInfo& targetUser, 92 | const GroupInfo& targetGroup) const; 93 | 94 | /** 95 | * Prepares the environment before invoking the script 96 | */ 97 | Environment prepareEnvironment(const Environment& sourceEnv, 98 | const Configuration& config, TargetMode mode); 99 | 100 | /** 101 | * Returns the php.ini path defined in the config for script being executed 102 | */ 103 | std::string getPHPRCPath(const Environment& env, const Configuration& config); 104 | 105 | /** 106 | * Returns interpreter for script being executed 107 | */ 108 | std::string getInterpreter(const Environment& env, 109 | const Configuration& config); 110 | 111 | /** 112 | * Returns mode interpreter is using 113 | */ 114 | TargetMode getTargetMode(const std::string& interpreter); 115 | 116 | /** 117 | * Runs script 118 | */ 119 | void executeScript(const std::string& scriptFilename, 120 | const std::string& interpreter, TargetMode mode, 121 | const Environment& env, const Configuration& config) const; 122 | 123 | /** 124 | * Checks ownership and permissions for parent directories 125 | */ 126 | void checkParentDirectories(const File& file, const UserInfo& owner, 127 | const Configuration& config) const; 128 | 129 | public: 130 | /** 131 | * Constructer 132 | */ 133 | Application(); 134 | 135 | /** 136 | * Function called by the main() function 137 | */ 138 | int run(CommandLine& cmdline, const Environment& env); 139 | }; 140 | } // namespace suPHP 141 | 142 | int main(int argc, char** argv); 143 | 144 | #endif // SUPHP_APPLICATION_H 145 | -------------------------------------------------------------------------------- /src/API.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_API_H 23 | 24 | namespace suPHP { 25 | class API; 26 | } 27 | 28 | #define SUPHP_API_H 29 | 30 | #include 31 | #include "CommandLine.hpp" 32 | #include "Environment.hpp" 33 | #include "File.hpp" 34 | #include "GroupInfo.hpp" 35 | #include "Logger.hpp" 36 | #include "UserInfo.hpp" 37 | 38 | namespace suPHP { 39 | /** 40 | * Class encapsulating system-specific API. 41 | */ 42 | class API { 43 | public: 44 | /** 45 | * Get environment variable 46 | */ 47 | virtual Environment getProcessEnvironment() = 0; 48 | 49 | /** 50 | * Get UserInfo from username 51 | */ 52 | virtual UserInfo getUserInfo(const std::string username) = 0; 53 | 54 | /** 55 | * Get UserInfo from UID 56 | */ 57 | virtual UserInfo getUserInfo(const int uid) = 0; 58 | 59 | /** 60 | * Get GroupInfo from groupname 61 | */ 62 | virtual GroupInfo getGroupInfo(const std::string groupname) = 0; 63 | 64 | /** 65 | * Get GroupInfo from GID 66 | */ 67 | virtual GroupInfo getGroupInfo(const int gid) = 0; 68 | 69 | /** 70 | * Get UserInfo for effective UID 71 | */ 72 | virtual UserInfo getEffectiveProcessUser() = 0; 73 | 74 | /** 75 | * Get UserInfo for real UID 76 | */ 77 | virtual UserInfo getRealProcessUser() = 0; 78 | 79 | /** 80 | * Get GroupInfo for effective GID 81 | */ 82 | virtual GroupInfo getEffectiveProcessGroup() = 0; 83 | 84 | /** 85 | * Get GroupInfo for real GID 86 | */ 87 | virtual GroupInfo getRealProcessGroup() = 0; 88 | 89 | /** 90 | * Get Logger implementation 91 | */ 92 | virtual Logger& getSystemLogger() = 0; 93 | 94 | /** 95 | * Set UID of current process 96 | */ 97 | virtual void setProcessUser(const UserInfo& user) const = 0; 98 | 99 | /** 100 | * Set GID of current process 101 | */ 102 | virtual void setProcessGroup(const GroupInfo& group) const = 0; 103 | 104 | /** 105 | * Returns username from UserInfo 106 | */ 107 | virtual std::string UserInfo_getUsername(const UserInfo& uinfo) const = 0; 108 | 109 | /** 110 | * Returns group from UserInfo 111 | */ 112 | virtual GroupInfo UserInfo_getGroupInfo(const UserInfo& uinfo) const = 0; 113 | 114 | /** 115 | * Returns home directory from UserInfo 116 | */ 117 | virtual std::string UserInfo_getHomeDirectory( 118 | const UserInfo& uinfo) const = 0; 119 | 120 | /** 121 | * Checks whether UserInfo objects represents the super-user 122 | */ 123 | virtual bool UserInfo_isSuperUser(const UserInfo& uinfo) const = 0; 124 | 125 | /** 126 | * Returns groupname from GroupInfo 127 | */ 128 | virtual std::string GroupInfo_getGroupname(const GroupInfo& ginfo) const = 0; 129 | 130 | /** 131 | * Checks whether file exists 132 | */ 133 | virtual bool File_exists(const File& file) const = 0; 134 | 135 | /** 136 | * Returns real path to file 137 | */ 138 | virtual std::string File_getRealPath(const File& file) const = 0; 139 | 140 | /** 141 | * Checks for a permission bit 142 | */ 143 | virtual bool File_hasPermissionBit(const File& file, FileMode perm) const = 0; 144 | 145 | /** 146 | * Returns UID of file 147 | */ 148 | virtual UserInfo File_getUser(const File& file) const = 0; 149 | 150 | /** 151 | * Returns GID of file 152 | */ 153 | virtual GroupInfo File_getGroup(const File& file) const = 0; 154 | 155 | /** 156 | * Checks whether a file is a symlink 157 | */ 158 | virtual bool File_isSymlink(const File& file) const = 0; 159 | 160 | /** 161 | * Runs another program (replaces current process) 162 | */ 163 | virtual void execute(std::string program, const CommandLine& cline, 164 | const Environment& env) const = 0; 165 | 166 | /** 167 | * Returns current working directory 168 | */ 169 | virtual std::string getCwd() const = 0; 170 | 171 | /** 172 | * Sets current working directory 173 | */ 174 | virtual void setCwd(const std::string& dir) const = 0; 175 | 176 | /** 177 | * Sets umask 178 | */ 179 | virtual void setUmask(int umask) const = 0; 180 | 181 | /** 182 | * Changes root directory for the current process 183 | */ 184 | virtual void chroot(const std::string& dir) const = 0; 185 | }; 186 | } // namespace suPHP 187 | 188 | #endif // SUPHP_API_H 189 | -------------------------------------------------------------------------------- /src/API_Linux.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_API_LINUX_H 23 | #define SUPHP_API_LINUX_H 24 | 25 | #include 26 | 27 | #include "API.hpp" 28 | #include "API_Linux_Logger.hpp" 29 | #include "Environment.hpp" 30 | #include "File.hpp" 31 | 32 | namespace suPHP { 33 | /** 34 | * Class encapsulating system-specific API for Linux. 35 | */ 36 | class API_Linux : public API { 37 | private: 38 | /** 39 | * Internal function for checking wheter path 40 | * points to a symlink 41 | */ 42 | bool isSymlink(const std::string path) const; 43 | 44 | /** 45 | * Internal function to read the target of a symlink 46 | */ 47 | std::string readSymlink(const std::string path) const; 48 | 49 | public: 50 | /** 51 | * Get environment variable 52 | */ 53 | virtual Environment getProcessEnvironment(); 54 | 55 | /** 56 | * Get UserInfo from username 57 | */ 58 | virtual UserInfo getUserInfo(const std::string username); 59 | 60 | /** 61 | * Get UserInfo from UID 62 | */ 63 | virtual UserInfo getUserInfo(const int uid); 64 | 65 | /** 66 | * Get GroupInfo from groupname 67 | */ 68 | virtual GroupInfo getGroupInfo(const std::string groupname); 69 | 70 | /** 71 | * Get GroupInfo from GID 72 | */ 73 | virtual GroupInfo getGroupInfo(const int gid); 74 | 75 | /** 76 | * Get UserInfo for effective UID 77 | */ 78 | virtual UserInfo getEffectiveProcessUser(); 79 | 80 | /** 81 | * Get UserInfo for real UID 82 | */ 83 | virtual UserInfo getRealProcessUser(); 84 | 85 | /** 86 | * Get GroupInfo for effective GID 87 | */ 88 | virtual GroupInfo getEffectiveProcessGroup(); 89 | 90 | /** 91 | * Get GroupInfo for real GID 92 | */ 93 | virtual GroupInfo getRealProcessGroup(); 94 | 95 | virtual Logger& getSystemLogger(); 96 | 97 | /** 98 | * Set UID of current process 99 | */ 100 | virtual void setProcessUser(const UserInfo& user) const; 101 | 102 | /** 103 | * Set GID of current process 104 | */ 105 | virtual void setProcessGroup(const GroupInfo& group) const; 106 | 107 | /** 108 | * Returns username from UserInfo 109 | */ 110 | virtual std::string UserInfo_getUsername(const UserInfo& uinfo) const; 111 | 112 | /** 113 | * Returns group from UserInfo 114 | */ 115 | virtual GroupInfo UserInfo_getGroupInfo(const UserInfo& uinfo) const; 116 | 117 | /** 118 | * Returns home directory from UserInfo 119 | */ 120 | virtual std::string UserInfo_getHomeDirectory(const UserInfo& uinfo) const; 121 | 122 | /** 123 | * Checks whether UserInfo objects represents the super-user 124 | */ 125 | virtual bool UserInfo_isSuperUser(const UserInfo& uinfo) const; 126 | 127 | /** 128 | * Returns groupname from GroupInfo 129 | */ 130 | std::string GroupInfo_getGroupname(const GroupInfo& ginfo) const; 131 | 132 | /** 133 | * Checks whether file exists 134 | */ 135 | virtual bool File_exists(const File& file) const; 136 | 137 | /** 138 | * Returns real path to file 139 | */ 140 | virtual std::string File_getRealPath(const File& file) const; 141 | 142 | /** 143 | * Checks for a permission bit 144 | */ 145 | virtual bool File_hasPermissionBit(const File& file, FileMode perm) const; 146 | 147 | /** 148 | * Returns UID of file 149 | */ 150 | virtual UserInfo File_getUser(const File& file) const; 151 | 152 | /** 153 | * Returns GID of file 154 | */ 155 | virtual GroupInfo File_getGroup(const File& file) const; 156 | 157 | /** 158 | * Checks whether a file is a symlink 159 | */ 160 | virtual bool File_isSymlink(const File& file) const; 161 | 162 | /** 163 | * Runs another program (replaces current process) 164 | */ 165 | virtual void execute(std::string program, const CommandLine& cline, 166 | const Environment& env) const; 167 | 168 | /** 169 | * Returns current working directory 170 | */ 171 | virtual std::string getCwd() const; 172 | 173 | /** 174 | * Sets current working directory 175 | */ 176 | virtual void setCwd(const std::string& dir) const; 177 | 178 | /** 179 | * Sets umask 180 | */ 181 | virtual void setUmask(int umask) const; 182 | 183 | /** 184 | * Sets new root directory for current process 185 | */ 186 | virtual void chroot(const std::string& dir) const; 187 | }; 188 | } // namespace suPHP 189 | 190 | #endif // SUPHP_API_LINUX_H 191 | -------------------------------------------------------------------------------- /src/Configuration.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef SUPHP_CONFIGURATION_H 23 | 24 | namespace suPHP { 25 | class Configuration; 26 | } 27 | 28 | #define SUPHP_CONFIGURATION_H 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include "config.h" 35 | #include "File.hpp" 36 | #include "IOException.hpp" 37 | #include "KeyNotFoundException.hpp" 38 | #include "Logger.hpp" 39 | #include "ParsingException.hpp" 40 | 41 | namespace suPHP { 42 | 43 | enum SetidMode { OWNER_MODE, FORCE_MODE, PARANOID_MODE }; 44 | 45 | /** 46 | * Class encapsulating run-time configuration. 47 | */ 48 | class Configuration { 49 | private: 50 | std::string logfile; 51 | std::string webserver_user; 52 | std::vector docroots; 53 | bool allow_file_group_writeable; 54 | bool allow_directory_group_writeable; 55 | bool allow_file_others_writeable; 56 | bool allow_directory_others_writeable; 57 | bool check_vhost_docroot; 58 | bool userdir_overrides_usergroup; 59 | bool errors_to_browser; 60 | std::string env_path; 61 | std::map handlers; 62 | std::map phprc_paths; 63 | LogLevel loglevel; 64 | int min_uid; 65 | int min_gid; 66 | int umask; 67 | std::string chroot_path; 68 | bool full_php_process_display; 69 | SetidMode mode; 70 | bool paranoid_uid_check; 71 | bool paranoid_gid_check; 72 | 73 | /** 74 | * Converts string to bool 75 | */ 76 | bool strToBool(const std::string& str) const; 77 | 78 | /** 79 | * Converts string to LogLevel 80 | */ 81 | LogLevel strToLogLevel(const std::string& str) const; 82 | 83 | /** 84 | * Converts string to SetidMode 85 | */ 86 | SetidMode strToMode(const std::string& str) const; 87 | 88 | public: 89 | /** 90 | * Constructor, initializes configuration with default values. 91 | */ 92 | Configuration(); 93 | 94 | /** 95 | * Reads values from INI file 96 | */ 97 | void readFromFile(File& file); 98 | 99 | /** 100 | * Return path to logfile; 101 | */ 102 | std::string getLogfile() const; 103 | 104 | /** 105 | Return log level 106 | */ 107 | LogLevel getLogLevel() const; 108 | 109 | /** 110 | * Return username of user the webserver is running as 111 | */ 112 | std::string getWebserverUser() const; 113 | 114 | /** 115 | * Return document root (list of directories, scripts may be within) 116 | */ 117 | const std::vector& getDocroots() const; 118 | 119 | /** 120 | * Returns wheter suPHP should check if scripts in within the 121 | * document root of the VHost 122 | */ 123 | bool getCheckVHostDocroot() const; 124 | 125 | /** 126 | * Returns wheter suPHP should use the user and group provided 127 | * by Apache on userdir requests in preference to suPHP_UserGroup 128 | */ 129 | bool getUserdirOverridesUsergroup() const; 130 | 131 | /** 132 | * Returns wheter suPHP should ignore the group write bit of 133 | * the script file 134 | */ 135 | bool getAllowFileGroupWriteable() const; 136 | 137 | /** 138 | * Returns wheter suPHP should ignore the group write bit of 139 | * the directory the is script in 140 | */ 141 | bool getAllowDirectoryGroupWriteable() const; 142 | 143 | /** 144 | * Returns wheter suPHP should ignore the others write bit of the 145 | * script file 146 | */ 147 | bool getAllowFileOthersWriteable() const; 148 | 149 | /** 150 | * Returns wheter suPHP should ignore the others write bit of 151 | * the directory the is script in 152 | */ 153 | bool getAllowDirectoryOthersWriteable() const; 154 | 155 | /** 156 | * Returns whether suPHP should include the SCRIPT_FILENAME in the 157 | * command line arguments so that it is visible to ps. 158 | */ 159 | bool getFullPHPProcessDisplay() const; 160 | 161 | /** 162 | * Returns the configured mode for UID/GID determination and 163 | * ownership checks 164 | */ 165 | SetidMode getMode() const; 166 | 167 | /** 168 | * Returns whether suPHP should check the target script GID in 169 | * paranoid mode 170 | */ 171 | bool getParanoidGIDCheck() const; 172 | 173 | /** 174 | * Returns whether suPHP should check the target script UID in 175 | * paranoid mode 176 | */ 177 | bool getParanoidUIDCheck() const; 178 | 179 | /** 180 | * Returns whether (minor) error message should be sent to browser 181 | */ 182 | bool getErrorsToBrowser() const; 183 | 184 | /** 185 | * Returns the content for the PATH environment variable 186 | */ 187 | std::string getEnvPath() const; 188 | 189 | /** 190 | * Returns phprc_path string for the specified handler 191 | */ 192 | std::string getPHPRCPath(std::string handler) const; 193 | 194 | /** 195 | * Returns interpreter string for specified handler 196 | */ 197 | std::string getInterpreter(std::string handler) const; 198 | 199 | /** 200 | * Returns minimum UID allowed for scripts 201 | */ 202 | int getMinUid() const; 203 | 204 | /** 205 | * Returns minimum GID allowed for scripts 206 | */ 207 | int getMinGid() const; 208 | 209 | /** 210 | * Returns umask to set 211 | */ 212 | int getUmask() const; 213 | 214 | /** 215 | * Return chroot path 216 | */ 217 | std::string getChrootPath() const; 218 | }; 219 | } // namespace suPHP 220 | 221 | #endif // SUPHP_CONFIGURATION_H 222 | -------------------------------------------------------------------------------- /tests/PathMatcher_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "gmock/gmock.h" 3 | #include "gtest/gtest.h" 4 | 5 | /* 6 | Import the PathMatcher method declarations AND definitions 7 | since we're mocking the injected dependencies 8 | */ 9 | #include "ParsingException.hpp" 10 | #include "PathMatcher.cpp" 11 | #include "PathMatcher.hpp" 12 | 13 | namespace { 14 | using ::testing::Return; 15 | 16 | class MockUserInfo { 17 | public: 18 | MOCK_CONST_METHOD0(getUsername, std::string()); 19 | MOCK_CONST_METHOD0(getUid, int()); 20 | MOCK_CONST_METHOD0(getHomeDirectory, std::string()); 21 | }; 22 | 23 | class MockGroupInfo { 24 | public: 25 | MOCK_CONST_METHOD0(getGroupname, std::string()); 26 | MOCK_CONST_METHOD0(getGid, int()); 27 | }; 28 | 29 | class PathMatcherTest : public ::testing::Test { 30 | protected: 31 | PathMatcherTest() : path_matcher(mock_userinfo, mock_groupinfo){}; 32 | MockUserInfo mock_userinfo; 33 | MockGroupInfo mock_groupinfo; 34 | suPHP::PathMatcher path_matcher; 35 | }; 36 | 37 | TEST_F(PathMatcherTest, StaticPathsEndingSlash) { 38 | ASSERT_TRUE(path_matcher.matches("/", "/home/foo")); 39 | ASSERT_TRUE(path_matcher.matches("/home/", "/home/foo")); 40 | ASSERT_TRUE(path_matcher.matches("/home/", "/home/bar")); 41 | ASSERT_TRUE(path_matcher.matches("/home/", "/home/foo/bar/baz")); 42 | } 43 | 44 | TEST_F(PathMatcherTest, StaticPathsEmptyPattern) { 45 | ASSERT_TRUE(path_matcher.matches("", "")); 46 | ASSERT_TRUE(path_matcher.matches("", "/home/foo")); 47 | ASSERT_TRUE(path_matcher.matches("", "abcd")); 48 | } 49 | TEST_F(PathMatcherTest, StaticPathsEmptyPath) { 50 | ASSERT_TRUE(path_matcher.matches("", "")); 51 | ASSERT_TRUE(path_matcher.matches("*", "")); 52 | ASSERT_FALSE(path_matcher.matches("/", "")); 53 | } 54 | TEST_F(PathMatcherTest, StaticPathsImplicitPatternSlash) { 55 | // A pattern that does not end in '/' can match either a file 56 | // or directory of the same name. 57 | ASSERT_TRUE(path_matcher.matches("/xyzzy", "/xyzzy")); 58 | ASSERT_TRUE(path_matcher.matches("/xyzzy", "/xyzzy/")); 59 | ASSERT_TRUE(path_matcher.matches("/xyzzy", "/xyzzy/abcde")); 60 | ASSERT_FALSE(path_matcher.matches("/xyzzy", "/xyzzyabcde")); 61 | ASSERT_FALSE(path_matcher.matches("/xyzzy", "/abcde")); 62 | } 63 | 64 | TEST_F(PathMatcherTest, StaticPathsImplicitPathSlash) { 65 | // A path that does not end in '/' is treated as a filename 66 | ASSERT_FALSE(path_matcher.matches("/", "")); 67 | ASSERT_FALSE(path_matcher.matches("/home/", "/home")); 68 | ASSERT_FALSE(path_matcher.matches("/./", "/.")); 69 | } 70 | 71 | TEST_F(PathMatcherTest, EscapedPatternEndingSlash) { 72 | ASSERT_TRUE(path_matcher.matches("/home/\\*/", "/home/*/")); 73 | ASSERT_TRUE(path_matcher.matches("/home/\\*/", "/home/*/x")); 74 | ASSERT_FALSE(path_matcher.matches("/home/\\*/", "/home/*")); 75 | } 76 | 77 | TEST_F(PathMatcherTest, EscapedPatternImplicitSlash) { 78 | ASSERT_TRUE(path_matcher.matches("/home/\\*", "/home/*/")); 79 | ASSERT_TRUE(path_matcher.matches("/home/\\*", "/home/*/x")); 80 | ASSERT_TRUE(path_matcher.matches("/home/\\*", "/home/*/x")); 81 | ASSERT_FALSE(path_matcher.matches("/home/\\*", "/home/*x")); 82 | ASSERT_FALSE(path_matcher.matches("/home/\\*", "/home/X")); 83 | ASSERT_TRUE(path_matcher.matches("/\\\\", "/\\")); 84 | ASSERT_TRUE(path_matcher.matches("/\\\\", "/\\/")); 85 | ASSERT_TRUE(path_matcher.matches("/abc\\\\def\\$ghi", "/abc\\def$ghi/")); 86 | } 87 | 88 | TEST_F(PathMatcherTest, FaultyEscapes) { 89 | // Backslash in an invalid escape sequence is discarded 90 | ASSERT_TRUE(path_matcher.matches("/home/\\a", "/home/a/bc")); 91 | ASSERT_FALSE(path_matcher.matches("/home/\\a", "/home/\\a/bc")); 92 | ASSERT_FALSE(path_matcher.matches("/home/\\b", "/home/")); 93 | // At the end of the match expression it counts as a literal 94 | ASSERT_TRUE(path_matcher.matches("/home/\\", "/home/\\/")); 95 | ASSERT_FALSE(path_matcher.matches("/home/\\/", "/home/\\/")); 96 | 97 | // No support for printf style escape sequences 98 | ASSERT_FALSE(path_matcher.matches("/home/\\ndef/", "/home/\ndef/")); 99 | } 100 | 101 | TEST_F(PathMatcherTest, InterpolatedVar) { 102 | EXPECT_CALL(mock_userinfo, getUsername()) 103 | .Times(4) 104 | .WillRepeatedly(Return("foo")); 105 | ASSERT_TRUE(path_matcher.matches("/home/${USERNAME}", "/home/foo/bar")); 106 | ASSERT_TRUE(path_matcher.matches("/home/${USERNAME}/", "/home/foo/bar")); 107 | ASSERT_TRUE(path_matcher.matches("/home/\\$${USERNAME}", "/home/$foo/")); 108 | ASSERT_FALSE(path_matcher.matches("/home/${USERNAME}/", "/home/bar/baz")); 109 | EXPECT_THROW(path_matcher.matches("/home/$USER{NAME}", "/home/$USER{NAME}/"), 110 | suPHP::ParsingException); 111 | } 112 | 113 | TEST_F(PathMatcherTest, DoubleInterpolation) { 114 | EXPECT_CALL(mock_userinfo, getUsername()) 115 | .Times(2) 116 | .WillRepeatedly(Return("${UID}")); 117 | ASSERT_TRUE(path_matcher.matches("/home/${USERNAME}", "/home/${UID}/")); 118 | ASSERT_TRUE(path_matcher.matches("/home/${USERNAME}/", "/home/${UID}/")); 119 | } 120 | 121 | TEST_F(PathMatcherTest, ClosingBracePosition) { 122 | EXPECT_CALL(mock_userinfo, getHomeDirectory()) 123 | .Times(2) 124 | .WillRepeatedly(Return("/home/foo")); 125 | ASSERT_FALSE( 126 | path_matcher.matches("${HOME}q/some/path", "/home/foo/some/path")); 127 | ASSERT_TRUE(path_matcher.matches("${HOME}/DEF", "/home/foo/DEF")); 128 | } 129 | 130 | TEST_F(PathMatcherTest, WildCards) { 131 | EXPECT_CALL(mock_userinfo, getUsername()) 132 | .Times(3) 133 | .WillRepeatedly(Return("foo")); 134 | ASSERT_TRUE(path_matcher.matches("/*/${USERNAME}", "/home/foo/")); 135 | ASSERT_TRUE(path_matcher.matches("/home/${USERNAME}/*", "/home/foo/bar/")); 136 | ASSERT_TRUE(path_matcher.matches("/home/${USERNAME}/*", "/home/foo/bar")); 137 | ASSERT_TRUE(path_matcher.matches("/home/f*o/*", "/home/foo/bar")); 138 | ASSERT_TRUE(path_matcher.matches("/home/*o/*", "/home/foo/bar")); 139 | ASSERT_TRUE(path_matcher.matches("/home/f*/*", "/home/foo/bar")); 140 | ASSERT_FALSE(path_matcher.matches("/home/f*/z*", "/home/foo/bar")); 141 | ASSERT_FALSE(path_matcher.matches("/home/*z*/*", "/home/foo/bar")); 142 | ASSERT_TRUE(path_matcher.matches("/home/*\\*", "/home/foo*/bar")); 143 | ASSERT_TRUE(path_matcher.matches("/home/*\\*/", "/home/foo*/bar")); 144 | ASSERT_TRUE(path_matcher.matches("/home/\\**", "/home/*foo/bar")); 145 | ASSERT_TRUE(path_matcher.matches("/home/\\**/", "/home/*foo/bar")); 146 | ASSERT_TRUE(path_matcher.matches("/home/\\**", "/home/*/bar")); 147 | ASSERT_TRUE(path_matcher.matches("/home/\\**/", "/home/*/bar")); 148 | ASSERT_TRUE(path_matcher.matches("/home/*\\*", "/home/*/bar")); 149 | ASSERT_TRUE(path_matcher.matches("/home/*\\*/", "/home/*/bar")); 150 | // PathMatcher can't handle simple path traversal 151 | // ASSERT_FALSE(path_matcher.matches("/home/*/", "/home/./")); 152 | } 153 | } // namespace 154 | -------------------------------------------------------------------------------- /doc/CONFIG: -------------------------------------------------------------------------------- 1 | =========================== 2 | == suPHP == 3 | =========================== 4 | 5 | Configuration 6 | ------------- 7 | 8 | 1. General notes 9 | 10 | The suPHP configuration file resides in $sysconfdir/suphp.conf (which will 11 | resolve e.g. to /etc/suphp.conf). 12 | 13 | It has the usual "INI-file" syntax. 14 | 15 | Section names are encapsulated in square brackets (e.g. [global]). 16 | Configuration options are key value pairs, separated by a "=" sign (e.g. 17 | umask=0077). 18 | 19 | Comment lines start with a ";". 20 | 21 | You can find a sample configuration in suphp.conf-example 22 | 23 | 24 | 2. Multiple values and escaping 25 | 26 | For a setting that allows multiple values, you can either seperate the 27 | values using the colon (":") character or you can use multiple lines. 28 | If you use multiple lines any line following the first has to use the "+=" 29 | assignment, otherwise preceding values will be discarded. 30 | 31 | If you want to use the ":" character in a value, you have to escape it 32 | using a backslash ("\"). The backslash itself is escaped by prepending 33 | another backslash. 34 | 35 | For patterns the asterisk ("*") has to be escaped, too. 36 | 37 | 38 | 3. Variables 39 | 40 | Certain configuration values may contain variables. Valid variables are: 41 | 42 | ${USERNAME} - is replaced by the name of the target user 43 | ${UID} - is replaced by the numerical UID of the target user 44 | ${GROUPNAME} - is replaced by the name of the target group 45 | ${GID} - is replaced by the numerical GID of the target group 46 | ${HOME} - is replaced by the path to the home directory of the target user 47 | 48 | Dollar ("$") characters that are not meant to represent variables, have to 49 | be escape using a backslash ("\"), if used in a value that allows 50 | variables. 51 | 52 | 53 | 4. Global options 54 | 55 | This options have to be specified in the [global] section. 56 | All this options are facultative. 57 | 58 | logfile: 59 | Specifies path to logfile. If not specified, the compile-time value is 60 | used. 61 | 62 | loglevel: 63 | One of "info", "warn", "error", "none". 64 | Specifies messages of which classification should be logged. 65 | Defaults to "info". 66 | 67 | webserver_user: 68 | Username of UID webserver is running as. If not specified, the 69 | compile-time value is used. 70 | 71 | docroot: 72 | Patterns matching all allowed script directories. This is an 73 | additional security check, especially when 74 | check_vhost_docroot is disabled. Defaults to "/*" thus 75 | allowing scripts in any location being run. May contain the 76 | "*" character which matches zero to n characters excluding 77 | the "/" character. Multiple values are allowed for this 78 | setting. May contain variables as described above. 79 | 80 | chroot: 81 | Path to change the process's root directory to before executing the 82 | script. Has to be specified without a trailing slash. 83 | If not specified, no chroot() call is performed. May contain variables 84 | as described above. 85 | 86 | allow_file_group_writeable: 87 | Allow files to be group writeable. Is disabled by default. 88 | 89 | allow_directory_group_writeable: 90 | Allow directories scripts are residing in to be group writeable. 91 | Is disabled by default. 92 | 93 | allow_file_others_writeable: 94 | Allow files to be writeable by world. Is disabled by default: 95 | WARNING: Enabling this option is very dangerous and causes major 96 | security issues, especially the danger of arbitrary code execution! 97 | 98 | allow_directoy_others_writeable: 99 | Allow directories scripts are residing in to be writeable by world. 100 | Is disabled by default: 101 | WARNING: Enabling this option is dangerous! 102 | 103 | check_vhost_docroot: 104 | Checks wheter the script is within DOCUMENT_ROOT specified by the 105 | webserver. This option is intended to avoid symbol links outside of the 106 | webpage directory. You may want to disable it, when you are using 107 | mod_vhost_alias or the Alias-directive. 108 | This option is disabled by default, if at compile-time the 109 | "--disable-check-docroot" option has been specified, otherwise it is 110 | enabled by default. 111 | 112 | errors_to_browser: 113 | Enable this option to sent information about minor problems during script 114 | invocation to the browser. This option is disabled by default. 115 | 116 | env_path: 117 | Content of the "PATH" environment variable. Set this to a safe value. 118 | The value has to be enclosed in quotes or colons have to be escaped with 119 | the backslash character. 120 | The default value is "/bin:/usr/bin". 121 | 122 | umask: 123 | umask to set before script execution. 124 | Has to be specified in octal notation (e.g. 0077). 125 | 126 | min_uid: 127 | Minimum UID allowed to execute scripts. 128 | Defaults to compile-time value. 129 | 130 | min_gid: 131 | Minimum GID allowed to execute scripts. 132 | Defaults to compile-time value. 133 | 134 | userdir_overrides_usergroup: 135 | When processing a userdir request that enters a context with 136 | suPHP_UserGroup set, use the userdir user rather than the 137 | suPHP_UserGroup setting. 138 | Defaults to true. 139 | 140 | full_php_process_display: 141 | Include the full PHP script path in the arguments to the PHP 142 | interpreter so that it is visible in ps output. This can 143 | help with determining which scripts are misbehaving but does 144 | reveal the script path to local users. 145 | Defaults to false. 146 | 147 | mode: 148 | Mode to use for setting UID/GID and verifying the integrity of the 149 | target PHP script. The mode can be one of "owner", "config" 150 | or "paranoid". The default is set based on the compile-time flags. 151 | 152 | paranoid_uid_check: 153 | While running in "paranoid" mode, confirm that the script being 154 | executed is owned by the same user ID that it will be executed as. 155 | In other modes, this option has no effect. 156 | Defaults to true. 157 | 158 | paranoid_gid_check: 159 | While running in "paranoid" mode, confirm that the script being 160 | executed is owned by the same group ID that it will be executed as. 161 | In other modes, this option has no effect. 162 | Defaults to true. 163 | 164 | 5. Handlers 165 | 166 | In the [handlers] section you specify a mapping between mime-types and 167 | interpreters to be used. 168 | 169 | Example: 170 | x-httpd-php=php\:/usr/bin/php 171 | 172 | The "key" is the mime-type. The "value" consists of to parts seperated by a 173 | colon. This colon has to be escaped by a backslash if the value is not 174 | enclosed by quotes. 175 | 176 | The first part is the "mode". The second part is the path to the 177 | interpreter. 178 | 179 | At the moment two modes are supported: 180 | 181 | "php"-mode: Use this mode for PHP scripts. Specify the PHP-interpreter you 182 | want to use. 183 | 184 | "execute"-mode: Must be specified as "execute:!self". Does not take any 185 | interpreter as the script itself is executed. Use this option for 186 | CGI-scripts. 187 | 188 | 6. PHPRC Paths 189 | 190 | In the [phprc_paths] section you specify an optional mapping between PHP 191 | mime-types and php.ini files that should be used via the PHPRC environmental 192 | variable. 193 | 194 | Example: 195 | x-httpd-php=/etc/php/php.ini 196 | 197 | =================================== 198 | (c)2002-2013 by Sebastian Marsching 199 | (c)2018 by John Lightsey 200 | 201 | Please see LICENSE for 202 | additional information 203 | -------------------------------------------------------------------------------- /m4/find_apr.m4: -------------------------------------------------------------------------------- 1 | dnl ======================================================================== 2 | dnl | BEGIN CODE FROM find_apr.m4 | 3 | dnl ======================================================================== 4 | dnl -------------------------------------------------------- -*- autoconf -*- 5 | dnl Licensed to the Apache Software Foundation (ASF) under one or more 6 | dnl contributor license agreements. See the NOTICE file distributed with 7 | dnl this work for additional information regarding copyright ownership. 8 | dnl The ASF licenses this file to You under the Apache License, Version 2.0 9 | dnl (the "License"); you may not use this file except in compliance with 10 | dnl the License. You may obtain a copy of the License at 11 | dnl 12 | dnl http://www.apache.org/licenses/LICENSE-2.0 13 | dnl 14 | dnl Unless required by applicable law or agreed to in writing, software 15 | dnl distributed under the License is distributed on an "AS IS" BASIS, 16 | dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | dnl See the License for the specific language governing permissions and 18 | dnl limitations under the License. 19 | 20 | dnl 21 | dnl find_apr.m4 : locate the APR include files and libraries 22 | dnl 23 | dnl This macro file can be used by applications to find and use the APR 24 | dnl library. It provides a standardized mechanism for using APR. It supports 25 | dnl embedding APR into the application source, or locating an installed 26 | dnl copy of APR. 27 | dnl 28 | dnl APR_FIND_APR(srcdir, builddir, implicit-install-check, acceptable-majors, 29 | dnl detailed-check) 30 | dnl 31 | dnl where srcdir is the location of the bundled APR source directory, or 32 | dnl empty if source is not bundled. 33 | dnl 34 | dnl where builddir is the location where the bundled APR will will be built, 35 | dnl or empty if the build will occur in the srcdir. 36 | dnl 37 | dnl where implicit-install-check set to 1 indicates if there is no 38 | dnl --with-apr option specified, we will look for installed copies. 39 | dnl 40 | dnl where acceptable-majors is a space separated list of acceptable major 41 | dnl version numbers. Often only a single major version will be acceptable. 42 | dnl If multiple versions are specified, and --with-apr=PREFIX or the 43 | dnl implicit installed search are used, then the first (leftmost) version 44 | dnl in the list that is found will be used. Currently defaults to [0 1]. 45 | dnl 46 | dnl where detailed-check is an M4 macro which sets the apr_acceptable to 47 | dnl either "yes" or "no". The macro will be invoked for each installed 48 | dnl copy of APR found, with the apr_config variable set appropriately. 49 | dnl Only installed copies of APR which are considered acceptable by 50 | dnl this macro will be considered found. If no installed copies are 51 | dnl considered acceptable by this macro, apr_found will be set to either 52 | dnl either "no" or "reconfig". 53 | dnl 54 | dnl Sets the following variables on exit: 55 | dnl 56 | dnl apr_found : "yes", "no", "reconfig" 57 | dnl 58 | dnl apr_config : If the apr-config tool exists, this refers to it. If 59 | dnl apr_found is "reconfig", then the bundled directory 60 | dnl should be reconfigured *before* using apr_config. 61 | dnl 62 | dnl Note: this macro file assumes that apr-config has been installed; it 63 | dnl is normally considered a required part of an APR installation. 64 | dnl 65 | dnl If a bundled source directory is available and needs to be (re)configured, 66 | dnl then apr_found is set to "reconfig". The caller should reconfigure the 67 | dnl (passed-in) source directory, placing the result in the build directory, 68 | dnl as appropriate. 69 | dnl 70 | dnl If apr_found is "yes" or "reconfig", then the caller should use the 71 | dnl value of apr_config to fetch any necessary build/link information. 72 | dnl 73 | 74 | AC_DEFUN([APR_FIND_APR], [ 75 | apr_found="no" 76 | 77 | if test "$target_os" = "os2-emx"; then 78 | # Scripts don't pass test -x on OS/2 79 | TEST_X="test -f" 80 | else 81 | TEST_X="test -x" 82 | fi 83 | 84 | ifelse([$4], [], [ 85 | ifdef(AC_WARNING,AC_WARNING([$0: missing argument 4 (acceptable-majors): Defaulting to APR 0.x then APR 1.x])) 86 | acceptable_majors="0 1"], 87 | [acceptable_majors="$4"]) 88 | 89 | apr_temp_acceptable_apr_config="" 90 | for apr_temp_major in $acceptable_majors 91 | do 92 | case $apr_temp_major in 93 | 0) 94 | apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-config" 95 | ;; 96 | *) 97 | apr_temp_acceptable_apr_config="$apr_temp_acceptable_apr_config apr-$apr_temp_major-config" 98 | ;; 99 | esac 100 | done 101 | 102 | AC_MSG_CHECKING(for APR) 103 | AC_ARG_WITH(apr, 104 | [ --with-apr=PATH prefix for installed APR or the full path to 105 | apr-config], 106 | [ 107 | if test "$withval" = "no" || test "$withval" = "yes"; then 108 | AC_MSG_ERROR([--with-apr requires a directory or file to be provided]) 109 | fi 110 | 111 | for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config 112 | do 113 | for lookdir in "$withval/bin" "$withval" 114 | do 115 | if $TEST_X "$lookdir/$apr_temp_apr_config_file"; then 116 | apr_config="$lookdir/$apr_temp_apr_config_file" 117 | ifelse([$5], [], [], [ 118 | apr_acceptable="yes" 119 | $5 120 | if test "$apr_acceptable" != "yes"; then 121 | AC_MSG_WARN([Found APR in $apr_config, but we think it is considered unacceptable]) 122 | continue 123 | fi]) 124 | apr_found="yes" 125 | break 2 126 | fi 127 | done 128 | done 129 | 130 | if test "$apr_found" != "yes" && $TEST_X "$withval" && $withval --help > /dev/null 2>&1 ; then 131 | apr_config="$withval" 132 | ifelse([$5], [], [apr_found="yes"], [ 133 | apr_acceptable="yes" 134 | $5 135 | if test "$apr_acceptable" = "yes"; then 136 | apr_found="yes" 137 | fi]) 138 | fi 139 | 140 | dnl if --with-apr is used, it is a fatal error for its argument 141 | dnl to be invalid 142 | if test "$apr_found" != "yes"; then 143 | AC_MSG_ERROR([the --with-apr parameter is incorrect. It must specify an install prefix, a build directory, or an apr-config file.]) 144 | fi 145 | ],[ 146 | dnl If we allow installed copies, check those before using bundled copy. 147 | if test -n "$3" && test "$3" = "1"; then 148 | for apr_temp_apr_config_file in $apr_temp_acceptable_apr_config 149 | do 150 | if $apr_temp_apr_config_file --help > /dev/null 2>&1 ; then 151 | apr_config="$apr_temp_apr_config_file" 152 | ifelse([$5], [], [], [ 153 | apr_acceptable="yes" 154 | $5 155 | if test "$apr_acceptable" != "yes"; then 156 | AC_MSG_WARN([skipped APR at $apr_config, version not acceptable]) 157 | continue 158 | fi]) 159 | apr_found="yes" 160 | break 161 | else 162 | dnl look in some standard places 163 | for lookdir in /usr /usr/local /usr/local/apr /opt/apr; do 164 | if $TEST_X "$lookdir/bin/$apr_temp_apr_config_file"; then 165 | apr_config="$lookdir/bin/$apr_temp_apr_config_file" 166 | ifelse([$5], [], [], [ 167 | apr_acceptable="yes" 168 | $5 169 | if test "$apr_acceptable" != "yes"; then 170 | AC_MSG_WARN([skipped APR at $apr_config, version not acceptable]) 171 | continue 172 | fi]) 173 | apr_found="yes" 174 | break 2 175 | fi 176 | done 177 | fi 178 | done 179 | fi 180 | dnl if we have not found anything yet and have bundled source, use that 181 | if test "$apr_found" = "no" && test -d "$1"; then 182 | apr_temp_abs_srcdir="`cd \"$1\" && pwd`" 183 | apr_found="reconfig" 184 | apr_bundled_major="`sed -n '/#define.*APR_MAJOR_VERSION/s/^[^0-9]*\([0-9]*\).*$/\1/p' \"$1/include/apr_version.h\"`" 185 | case $apr_bundled_major in 186 | "") 187 | AC_MSG_ERROR([failed to find major version of bundled APR]) 188 | ;; 189 | 0) 190 | apr_temp_apr_config_file="apr-config" 191 | ;; 192 | *) 193 | apr_temp_apr_config_file="apr-$apr_bundled_major-config" 194 | ;; 195 | esac 196 | if test -n "$2"; then 197 | apr_config="$2/$apr_temp_apr_config_file" 198 | else 199 | apr_config="$1/$apr_temp_apr_config_file" 200 | fi 201 | fi 202 | ]) 203 | 204 | AC_MSG_RESULT($apr_found) 205 | ]) 206 | -------------------------------------------------------------------------------- /src/IniFile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "KeyNotFoundException.hpp" 28 | 29 | #include "IniFile.hpp" 30 | 31 | using namespace suPHP; 32 | using namespace std; 33 | 34 | const IniSection& suPHP::IniFile::getSection(const string& name) const { 35 | if (this->sections.find(name) != this->sections.end()) { 36 | return this->sections.find(name)->second; 37 | } else { 38 | throw KeyNotFoundException("Section " + name + " not found", __FILE__, 39 | __LINE__); 40 | } 41 | } 42 | 43 | bool suPHP::IniFile::hasSection(const string& name) const { 44 | if (this->sections.find(name) != this->sections.end()) { 45 | return true; 46 | } else { 47 | return false; 48 | } 49 | } 50 | 51 | const IniSection& suPHP::IniFile::operator[](const string& name) const { 52 | return this->getSection(name); 53 | } 54 | 55 | void suPHP::IniFile::parse(const File& file) { 56 | auto is = file.getInputStream(); 57 | IniSection* current_section = NULL; 58 | while (!is->eof() && !is->fail()) { 59 | string line; 60 | string tstr; 61 | string::size_type startpos = 0; 62 | string::size_type endpos = 0; 63 | 64 | // Read line from file 65 | getline(*is, line); 66 | 67 | tstr = line; 68 | 69 | // Find first char not being space or tab 70 | startpos = tstr.find_first_not_of(" \t"); 71 | // Find last char not being space or tab 72 | endpos = tstr.find_last_not_of(" \t"); 73 | 74 | // Skip empty line, only containing whitespace 75 | if (startpos == string::npos) continue; 76 | 77 | // Get trimmed string 78 | tstr = tstr.substr(startpos, endpos - startpos + 1); 79 | 80 | // Is line a comment (starting with ";")? 81 | if (tstr[0] == ';') { 82 | // Comments are not interessting => skip 83 | continue; 84 | 85 | // Is line a section mark ("[section]")? 86 | } else if (tstr[0] == '[' && tstr[tstr.size() - 1] == ']') { 87 | // Extract name of section 88 | string name = tstr.substr(1, tstr.size() - 2); 89 | // If section is not yet existing, create it 90 | if (!this->hasSection(name)) { 91 | pair p; 92 | IniSection sect; 93 | p.first = name; 94 | p.second = sect; 95 | this->sections.insert(p); 96 | } 97 | // Set current section 98 | current_section = &(this->sections.find(name)->second); 99 | 100 | // Is the line a key-value pair? 101 | } else if (tstr.find_first_of('=') != string::npos) { 102 | string name; 103 | vector values; 104 | bool append_mode = false; 105 | 106 | string::size_type eqpos = 0; 107 | 108 | // Check wheter we already have a section 109 | if (current_section == NULL) { 110 | throw ParsingException( 111 | "Option line \"" + tstr + "\" before first section", __FILE__, 112 | __LINE__); 113 | } 114 | 115 | // Extract name 116 | eqpos = tstr.find_first_of('='); 117 | if (eqpos == string::npos || eqpos < 1 || eqpos == tstr.length() - 1) { 118 | throw ParsingException("Malformed line: " + tstr, __FILE__, __LINE__); 119 | } 120 | if (tstr[eqpos - 1] == '+') { 121 | append_mode = true; 122 | name = tstr.substr(0, eqpos - 1); 123 | } else { 124 | name = tstr.substr(0, eqpos); 125 | } 126 | 127 | string::size_type temppos; 128 | temppos = name.find_first_not_of(" \t"); 129 | if (temppos == string::npos) { 130 | throw ParsingException("Malformed line: " + tstr, __FILE__, __LINE__); 131 | } 132 | name = name.substr(0, name.find_last_not_of(" \t") + 1); 133 | 134 | bool in_quotes = false; 135 | bool last_was_backslash = false; 136 | string::size_type token_start = eqpos + 1; 137 | 138 | for (string::size_type i = eqpos + 1; i < tstr.length(); i++) { 139 | bool current_is_backslash = false; 140 | if (tstr[i] == '"') { 141 | if (!last_was_backslash) { 142 | in_quotes = !in_quotes; 143 | } 144 | } else if (tstr[i] == '\\') { 145 | if (!last_was_backslash) { 146 | current_is_backslash = true; 147 | } 148 | } else if (tstr[i] == ':') { 149 | if (!in_quotes && !last_was_backslash) { 150 | // Save token and begin new one 151 | string token = tstr.substr(token_start, i - token_start); 152 | try { 153 | token = parseValue(token); 154 | } catch (ParsingException&) { 155 | throw ParsingException("Malformed line: " + tstr, __FILE__, 156 | __LINE__); 157 | } 158 | if (token.length() == 0) { 159 | throw ParsingException("Malformed line: " + tstr, __FILE__, 160 | __LINE__); 161 | } 162 | values.push_back(token); 163 | token_start = i + 1; 164 | } 165 | } 166 | if (i == tstr.length() - 1) { 167 | if (in_quotes) { 168 | throw ParsingException("Unended quotes in line: " + tstr, __FILE__, 169 | __LINE__); 170 | } else if (last_was_backslash) { 171 | throw ParsingException( 172 | "Multiline values are not supported in line: " + tstr, __FILE__, 173 | __LINE__); 174 | } 175 | string token = tstr.substr(token_start, i + 1 - token_start); 176 | try { 177 | token = parseValue(token); 178 | } catch (ParsingException&) { 179 | throw ParsingException("Malformed line: " + tstr, __FILE__, 180 | __LINE__); 181 | } 182 | if (token.length() == 0) { 183 | throw ParsingException("Malformed line: " + tstr, __FILE__, 184 | __LINE__); 185 | } 186 | values.push_back(token); 187 | } 188 | last_was_backslash = current_is_backslash; 189 | } 190 | 191 | if (!append_mode) { 192 | current_section->removeValues(name); 193 | } 194 | for (auto i = values.begin(); i != values.end(); i++) { 195 | current_section->putValue(name, *i); 196 | } 197 | 198 | // Line is something we do not know 199 | } else { 200 | throw ParsingException("Malformed line \"" + tstr + "\"", __FILE__, 201 | __LINE__); 202 | } 203 | } 204 | is->close(); 205 | } 206 | 207 | string suPHP::IniFile::parseValue(const string& value) const { 208 | bool in_quotes = false; 209 | bool last_was_backslash = false; 210 | string tempvalue; 211 | string output; 212 | 213 | string::size_type startpos = value.find_first_not_of(" \t"); 214 | string::size_type endpos = value.find_last_not_of(" \t"); 215 | if (startpos == string::npos) { 216 | return ""; 217 | } 218 | if (endpos == string::npos) { 219 | tempvalue = value; 220 | } else { 221 | tempvalue = value.substr(startpos, endpos - startpos + 1); 222 | } 223 | 224 | for (string::size_type i = 0; i < value.length(); i++) { 225 | bool current_is_backslash = false; 226 | 227 | if (tempvalue[i] == '"') { 228 | if (last_was_backslash) { 229 | output.append("\""); 230 | } else { 231 | if (!in_quotes && i != 0) { 232 | throw ParsingException("Content preceding quoted content", __FILE__, 233 | __LINE__); 234 | } 235 | if (in_quotes && i != tempvalue.length() - 1) { 236 | throw ParsingException("Content following quoted content", __FILE__, 237 | __LINE__); 238 | } 239 | in_quotes = !in_quotes; 240 | } 241 | } else if (tempvalue[i] == '\\') { 242 | if (last_was_backslash) { 243 | output.append("\\"); 244 | } else { 245 | current_is_backslash = true; 246 | } 247 | } else if (tempvalue[i] == ':') { 248 | output.append(":"); 249 | } else { 250 | if (last_was_backslash) { 251 | throw ParsingException("Illegal character after backslash", __FILE__, 252 | __LINE__); 253 | } 254 | output.append(tempvalue.substr(i, 1)); 255 | } 256 | 257 | last_was_backslash = current_is_backslash; 258 | } 259 | 260 | return output; 261 | } 262 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Process this file with autoconf to produce a configure script. 2 | 3 | # Initialize 4 | AC_INIT([suPHP], [0.8.0-pre], [john@nixnuts.net], [suphp]) 5 | 6 | # Auxiliary tools 7 | AC_CONFIG_AUX_DIR([config]) 8 | AC_CONFIG_MACRO_DIR([m4]) 9 | 10 | # Check for right directory 11 | AC_CONFIG_SRCDIR([src/Application.cpp]) 12 | # Config headers for automake 13 | AM_CONFIG_HEADER([src/config.h]) 14 | 15 | AM_INIT_AUTOMAKE([-Wall -Werror subdir-objects]) 16 | 17 | # Build time sanity check 18 | AM_SANITY_CHECK 19 | 20 | # Look for install program 21 | AC_PROG_INSTALL 22 | 23 | # Look for compiler 24 | AC_PROG_CC 25 | AC_PROG_CC_C99 26 | AC_PROG_CXX 27 | 28 | AX_CXX_COMPILE_STDCXX_11(,optional) 29 | if test "$HAVE_CXX11" != "1"; then 30 | # G++ 4.4 fails the full c++11 test but includes the features 31 | # that are actually being used (auto and unique_ptr). 32 | # The older autoconf STDCXX_0X will pass it. 33 | AX_CXX_COMPILE_STDCXX_0X 34 | if test "x$ax_cv_cxx_compile_cxx0x_native" != xyes; then 35 | if test "x$ax_cv_cxx_compile_cxx0x_gxx" = xyes; then 36 | CXX+=" -std=gnu++0x -DGTEST_LANG_CXX11=0" 37 | CXXCPP+=" -std=gnu++0x -DGTEST_LANG_CXX11=0" 38 | elif test "x$ax_cv_cxx_compile_cxx0x_cxx" = xyes; then 39 | CXX+=" -std=c++0x -DGTEST_LANG_CXX11=0" 40 | CXXCPP+=" -std=c++0x -DGTEST_LANG_CXX11=0" 41 | else 42 | AC_MSG_ERROR([A compiler with C++11 or C++0x support is required to build mod_suphp]) 43 | fi 44 | fi 45 | fi 46 | 47 | # Libtool 48 | m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) 49 | AM_PROG_LIBTOOL 50 | 51 | # Checks for header files. 52 | AC_HEADER_STDC 53 | AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h]) 54 | 55 | # Find apr-config 56 | 57 | APR_FIND_APR([], [], [1], [1]) 58 | 59 | # Determine Apache version and find apxs 60 | 61 | AC_MSG_CHECKING([for dynamic Apache module support (via APXS)]) 62 | AC_ARG_WITH(apxs, 63 | AC_HELP_STRING([--with-apxs=FILE], 64 | [Build shared Apache module. FILE is the optional pathname to the Apache apxs tool; defaults to "apxs".]), 65 | [ 66 | if test "$withval" = "yes"; then 67 | APXS=apxs 68 | else 69 | APXS="$withval" 70 | fi 71 | ]) 72 | 73 | if test -z "$APXS"; then 74 | APXS=`which apxs` 75 | fi 76 | 77 | if test "$BINNAME" = "" -a "$APXS" = "" -a "$FAIL_STATIC" = ""; then 78 | for i in /usr/sbin /usr/local/apache/bin ; do 79 | if test -f "$i/apxs"; then 80 | APXS="$i/apxs" 81 | fi 82 | done 83 | fi 84 | 85 | if test -n "$APXS"; then 86 | AC_SUBST(APXS) 87 | 88 | APACHE_VERSION=`\`$APXS -q SBINDIR\`/\`$APXS -q TARGET\` -v \ 89 | | grep "Server version" \ 90 | | cut -f2 -d":" \ 91 | | cut -f2 -d"/" \ 92 | | cut -f1 -d" "` 93 | major_version=`echo $APACHE_VERSION|cut -f1 -d.` 94 | minor_version=`echo $APACHE_VERSION|cut -f2 -d.` 95 | if test "$major_version" -ge "2" -a "$minor_version" -ge "2"; then 96 | APXS_EXTRA_CFLAGS=`$APXS -q CFLAGS` 97 | else 98 | AC_MSG_ERROR([Apache must be version 2.2 or later]) 99 | fi 100 | APXS_INCLUDEDIR=`$APXS -q INCLUDEDIR` 101 | APXS_LIBEXECDIR=`$APXS -q LIBEXECDIR` 102 | AC_SUBST([APXS_INCLUDEDIR]) 103 | AC_SUBST([APXS_LIBEXECDIR]) 104 | AC_SUBST([APXS_EXTRA_CFLAGS]) 105 | 106 | AC_MSG_RESULT(found at $APXS (version $APACHE_VERSION)) 107 | else 108 | APXS="/notfound/" 109 | AC_SUBST(APXS) 110 | 111 | AC_MSG_RESULT(no) 112 | fi 113 | 114 | dnl For Apache 2.x APR is needed 115 | if test x"${apr_found}" = xyes ; then \ 116 | APR_INCLUDEDIR=`${apr_config} --includedir` 117 | AC_SUBST([APR_INCLUDEDIR]) 118 | APR_CPPFLAGS=`${apr_config} --cppflags` 119 | AC_SUBST([APR_CPPFLAGS]) 120 | else 121 | AC_MSG_ERROR([APR is needed to build mod_suphp for Apache 2.x but was not found]) 122 | fi 123 | 124 | # Get uid/gid mode 125 | 126 | AC_MSG_CHECKING([for set-UID/set-GID mode]) 127 | AC_ARG_WITH(setid-mode, 128 | AC_HELP_STRING([--with-setid-mode=MODE], 129 | [Mode to use for setting UID/GID. MODE can be one of "owner", "config" or "paranoid"; defaults to "paranoid".]), 130 | [ 131 | if test "$withval" = "yes"; then 132 | SETID_MODE="paranoid" 133 | else 134 | SETID_MODE="$withval" 135 | fi 136 | ]) 137 | 138 | if test -z "$SETID_MODE" ; then 139 | SETID_MODE="paranoid" 140 | fi 141 | 142 | if test -n "$SETID_MODE"; then 143 | case "$SETID_MODE" in 144 | owner) 145 | OPT_APACHEMOD_USERGROUP_DEF="" 146 | AC_SUBST(OPT_APACHEMOD_USERGROUP_DEF) 147 | AC_DEFINE(OPT_USERGROUP_OWNER, 1, 148 | [Define if you want to set UID/GID to the owner of the script]) 149 | ;; 150 | force) 151 | OPT_APACHEMOD_USERGROUP_DEF=-DSUPHP_USE_USERGROUP 152 | AC_SUBST(OPT_APACHEMOD_USERGROUP_DEF) 153 | AC_DEFINE(OPT_USERGROUP_FORCE, 1, 154 | [Define if you want to set UID/GID to the user/group specified in the Apache configuration]) 155 | ;; 156 | paranoid) 157 | OPT_APACHEMOD_USERGROUP_DEF=-DSUPHP_USE_USERGROUP 158 | AC_SUBST(OPT_APACHEMOD_USERGROUP_DEF) 159 | AC_DEFINE(OPT_USERGROUP_PARANOID, 1, 160 | [Define if you want to set UID/GID to the user/group specified in the Apache configuration AND check if these settings match the UID/GID of the script]) 161 | ;; 162 | *) 163 | AC_MSG_ERROR([--with-setid-mode has to be set to one of "owner", "force" or "paranoid"]) 164 | ;; 165 | esac 166 | AC_MSG_RESULT([ok - using $SETID_MODE]) 167 | fi 168 | 169 | 170 | # Checkpath (docroot) option 171 | 172 | checkpath=yes 173 | AC_ARG_ENABLE([checkpath], 174 | AC_HELP_STRING([--enable-checkpath], 175 | [Check if script resides in DOCUMENT_ROOT (default is ENABLED)]), 176 | [ 177 | if test "$enableval" = "no"; then 178 | checkpath=no 179 | AC_DEFINE(OPT_DISABLE_CHECKPATH, 1, [Define if you want to disable the check, wether script resides in DOCUMENT_ROOT]) 180 | fi 181 | ]) 182 | 183 | 184 | # Minimum UID 185 | 186 | AC_ARG_WITH([min-uid], 187 | AC_HELP_STRING([--with-min-uid=UID], 188 | [Minimum UID, which is allowed to run scripts 189 | (default=100)]), 190 | [ 191 | if test "$withval" -a ! "$withval" = "yes" ; then 192 | AC_DEFINE_UNQUOTED(OPT_MIN_UID, $withval, [Defines the min UID 193 | allowed to run scripts]) 194 | fi 195 | ], 196 | [ 197 | AC_DEFINE(OPT_MIN_UID, 100, [Defines the min UID 198 | allowed to run scripts]) 199 | ]) 200 | 201 | # Minimum GID 202 | 203 | AC_ARG_WITH([min-gid], 204 | AC_HELP_STRING([--with-min-gid=GID], 205 | [Minimum GID, which is allowed to run scripts 206 | (default=100)]), 207 | [ 208 | if test "$withval" -a ! "$withval" = "yes" ; then 209 | AC_DEFINE_UNQUOTED(OPT_MIN_GID, $withval, [Defines the min GID 210 | allowed to run scripts]) 211 | fi 212 | ], 213 | [ 214 | AC_DEFINE(OPT_MIN_GID, 100, [Defines the min GID 215 | allowed to run scripts]) 216 | ]) 217 | 218 | 219 | # Webserver user 220 | AC_ARG_WITH([apache-user], 221 | AC_HELP_STRING([--with-apache-user=USERNAME], 222 | [Name of the user Apache is running as 223 | (default is "www-data" on Debian, "apache" on RedHat, and "wwwrun" on other systems)]), 224 | [ 225 | if test "$withval" -a ! "$withval" = "yes" ; then 226 | webserver_user="$withval" 227 | fi 228 | ]) 229 | 230 | if test -z "$webserver_user"; then 231 | if test -e "/etc/redhat-release" ; then 232 | webserver_user="apache" 233 | elif test -e "/etc/debian_version" ; then 234 | webserver_user="www-data" 235 | else 236 | webserver_user="wwwrun" 237 | fi 238 | fi 239 | 240 | AC_DEFINE_UNQUOTED(OPT_APACHE_USER, "$webserver_user", [Defines the username of the Apache user]) 241 | 242 | # Path to logfile 243 | 244 | AC_ARG_WITH([logfile], 245 | AC_HELP_STRING([--with-logfile=FILE], 246 | [Path to suPHP logfile (default is "/var/log/suphp.log"]), 247 | [ 248 | if test "$withval" -a ! "$withval" = "yes" ; then 249 | AC_DEFINE_UNQUOTED(OPT_LOGFILE, "$withval", [Defines 250 | path to logfile]) 251 | fi 252 | ], 253 | [ 254 | AC_DEFINE_UNQUOTED(OPT_LOGFILE, "/var/log/suphp.log", [Defines path to logfile]) 255 | ]) 256 | 257 | 258 | # Conditionally include UserGroup support 259 | AM_CONDITIONAL([COND_APUSERGROUP], [test \( x"$SETID_MODE" = xparanoid \) -o \( x"$SETID_MODE" = xforce \) ]) 260 | 261 | # Verify submodules are installed when building from a git checkout 262 | AM_CONDITIONAL([SUBMODULES_INSTALLED], [test -e googletest/googletest/src/gtest-all.cc]) 263 | 264 | AM_COND_IF([SUBMODULES_INSTALLED],,[AC_MSG_WARN([The "check" target uses submodules. The unit tests will not function until you run "git submodule update".])]) 265 | 266 | AC_CONFIG_FILES([Makefile src/Makefile src/apache2/Makefile tests/Makefile]) 267 | 268 | AC_OUTPUT 269 | 270 | if test "$APXS" = "/notfound/"; then 271 | AC_MSG_WARN([ 272 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 273 | !!*** APXS was not found, so mod_suphp will not be built! ***!! 274 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 275 | ]) 276 | fi 277 | 278 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 5 | 2006 Free Software Foundation, Inc. 6 | 7 | This file is free documentation; the Free Software Foundation gives 8 | unlimited permission to copy, distribute and modify it. 9 | 10 | Basic Installation 11 | ================== 12 | 13 | Briefly, the shell commands `./configure; make; make install' should 14 | configure, build, and install this package. The following 15 | more-detailed instructions are generic; see the `README' file for 16 | instructions specific to this package. 17 | 18 | The `configure' shell script attempts to guess correct values for 19 | various system-dependent variables used during compilation. It uses 20 | those values to create a `Makefile' in each directory of the package. 21 | It may also create one or more `.h' files containing system-dependent 22 | definitions. Finally, it creates a shell script `config.status' that 23 | you can run in the future to recreate the current configuration, and a 24 | file `config.log' containing compiler output (useful mainly for 25 | debugging `configure'). 26 | 27 | It can also use an optional file (typically called `config.cache' 28 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 29 | the results of its tests to speed up reconfiguring. Caching is 30 | disabled by default to prevent problems with accidental use of stale 31 | cache files. 32 | 33 | If you need to do unusual things to compile the package, please try 34 | to figure out how `configure' could check whether to do them, and mail 35 | diffs or instructions to the address given in the `README' so they can 36 | be considered for the next release. If you are using the cache, and at 37 | some point `config.cache' contains results you don't want to keep, you 38 | may remove or edit it. 39 | 40 | The file `configure.ac' (or `configure.in') is used to create 41 | `configure' by a program called `autoconf'. You need `configure.ac' if 42 | you want to change it or regenerate `configure' using a newer version 43 | of `autoconf'. 44 | 45 | The simplest way to compile this package is: 46 | 47 | 1. `cd' to the directory containing the package's source code and type 48 | `./configure' to configure the package for your system. 49 | 50 | Running `configure' might take a while. While running, it prints 51 | some messages telling which features it is checking for. 52 | 53 | 2. Type `make' to compile the package. 54 | 55 | 3. Optionally, type `make check' to run any self-tests that come with 56 | the package. 57 | 58 | 4. Type `make install' to install the programs and any data files and 59 | documentation. 60 | 61 | 5. You can remove the program binaries and object files from the 62 | source code directory by typing `make clean'. To also remove the 63 | files that `configure' created (so you can compile the package for 64 | a different kind of computer), type `make distclean'. There is 65 | also a `make maintainer-clean' target, but that is intended mainly 66 | for the package's developers. If you use it, you may have to get 67 | all sorts of other programs in order to regenerate files that came 68 | with the distribution. 69 | 70 | Compilers and Options 71 | ===================== 72 | 73 | Some systems require unusual options for compilation or linking that the 74 | `configure' script does not know about. Run `./configure --help' for 75 | details on some of the pertinent environment variables. 76 | 77 | You can give `configure' initial values for configuration parameters 78 | by setting variables in the command line or in the environment. Here 79 | is an example: 80 | 81 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 82 | 83 | *Note Defining Variables::, for more details. 84 | 85 | Compiling For Multiple Architectures 86 | ==================================== 87 | 88 | You can compile the package for more than one kind of computer at the 89 | same time, by placing the object files for each architecture in their 90 | own directory. To do this, you can use GNU `make'. `cd' to the 91 | directory where you want the object files and executables to go and run 92 | the `configure' script. `configure' automatically checks for the 93 | source code in the directory that `configure' is in and in `..'. 94 | 95 | With a non-GNU `make', it is safer to compile the package for one 96 | architecture at a time in the source code directory. After you have 97 | installed the package for one architecture, use `make distclean' before 98 | reconfiguring for another architecture. 99 | 100 | Installation Names 101 | ================== 102 | 103 | By default, `make install' installs the package's commands under 104 | `/usr/local/bin', include files under `/usr/local/include', etc. You 105 | can specify an installation prefix other than `/usr/local' by giving 106 | `configure' the option `--prefix=PREFIX'. 107 | 108 | You can specify separate installation prefixes for 109 | architecture-specific files and architecture-independent files. If you 110 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 111 | PREFIX as the prefix for installing programs and libraries. 112 | Documentation and other data files still use the regular prefix. 113 | 114 | In addition, if you use an unusual directory layout you can give 115 | options like `--bindir=DIR' to specify different values for particular 116 | kinds of files. Run `configure --help' for a list of the directories 117 | you can set and what kinds of files go in them. 118 | 119 | If the package supports it, you can cause programs to be installed 120 | with an extra prefix or suffix on their names by giving `configure' the 121 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 122 | 123 | Optional Features 124 | ================= 125 | 126 | Some packages pay attention to `--enable-FEATURE' options to 127 | `configure', where FEATURE indicates an optional part of the package. 128 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 129 | is something like `gnu-as' or `x' (for the X Window System). The 130 | `README' should mention any `--enable-' and `--with-' options that the 131 | package recognizes. 132 | 133 | For packages that use the X Window System, `configure' can usually 134 | find the X include and library files automatically, but if it doesn't, 135 | you can use the `configure' options `--x-includes=DIR' and 136 | `--x-libraries=DIR' to specify their locations. 137 | 138 | Specifying the System Type 139 | ========================== 140 | 141 | There may be some features `configure' cannot figure out automatically, 142 | but needs to determine by the type of machine the package will run on. 143 | Usually, assuming the package is built to be run on the _same_ 144 | architectures, `configure' can figure that out, but if it prints a 145 | message saying it cannot guess the machine type, give it the 146 | `--build=TYPE' option. TYPE can either be a short name for the system 147 | type, such as `sun4', or a canonical name which has the form: 148 | 149 | CPU-COMPANY-SYSTEM 150 | 151 | where SYSTEM can have one of these forms: 152 | 153 | OS KERNEL-OS 154 | 155 | See the file `config.sub' for the possible values of each field. If 156 | `config.sub' isn't included in this package, then this package doesn't 157 | need to know the machine type. 158 | 159 | If you are _building_ compiler tools for cross-compiling, you should 160 | use the option `--target=TYPE' to select the type of system they will 161 | produce code for. 162 | 163 | If you want to _use_ a cross compiler, that generates code for a 164 | platform different from the build platform, you should specify the 165 | "host" platform (i.e., that on which the generated programs will 166 | eventually be run) with `--host=TYPE'. 167 | 168 | Sharing Defaults 169 | ================ 170 | 171 | If you want to set default values for `configure' scripts to share, you 172 | can create a site shell script called `config.site' that gives default 173 | values for variables like `CC', `cache_file', and `prefix'. 174 | `configure' looks for `PREFIX/share/config.site' if it exists, then 175 | `PREFIX/etc/config.site' if it exists. Or, you can set the 176 | `CONFIG_SITE' environment variable to the location of the site script. 177 | A warning: not all `configure' scripts look for a site script. 178 | 179 | Defining Variables 180 | ================== 181 | 182 | Variables not defined in a site shell script can be set in the 183 | environment passed to `configure'. However, some packages may run 184 | configure again during the build, and the customized values of these 185 | variables may be lost. In order to avoid this problem, you should set 186 | them in the `configure' command line, using `VAR=value'. For example: 187 | 188 | ./configure CC=/usr/local2/bin/gcc 189 | 190 | causes the specified `gcc' to be used as the C compiler (unless it is 191 | overridden in the site shell script). 192 | 193 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 194 | an Autoconf bug. Until the bug is fixed you can use this workaround: 195 | 196 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 197 | 198 | `configure' Invocation 199 | ====================== 200 | 201 | `configure' recognizes the following options to control how it operates. 202 | 203 | `--help' 204 | `-h' 205 | Print a summary of the options to `configure', and exit. 206 | 207 | `--version' 208 | `-V' 209 | Print the version of Autoconf used to generate the `configure' 210 | script, and exit. 211 | 212 | `--cache-file=FILE' 213 | Enable the cache: use and save the results of the tests in FILE, 214 | traditionally `config.cache'. FILE defaults to `/dev/null' to 215 | disable caching. 216 | 217 | `--config-cache' 218 | `-C' 219 | Alias for `--cache-file=config.cache'. 220 | 221 | `--quiet' 222 | `--silent' 223 | `-q' 224 | Do not print messages saying which checks are being made. To 225 | suppress all normal output, redirect it to `/dev/null' (any error 226 | messages will still be shown). 227 | 228 | `--srcdir=DIR' 229 | Look for the package's source code in directory DIR. Usually 230 | `configure' can determine that directory automatically. 231 | 232 | `configure' also accepts some other, not widely useful, options. Run 233 | `configure --help' for more details. 234 | 235 | -------------------------------------------------------------------------------- /src/Configuration.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | suPHP - (c)2002-2013 Sebastian Marsching 3 | (c)2018 John Lightsey 4 | 5 | This file is part of suPHP. 6 | 7 | suPHP is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | suPHP is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with suPHP; if not, write to the Free Software Foundation, Inc., 19 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "IniFile.hpp" 26 | #include "Util.hpp" 27 | 28 | #include "Configuration.hpp" 29 | 30 | using namespace suPHP; 31 | 32 | bool suPHP::Configuration::strToBool(const std::string& bstr) const { 33 | std::string str = bstr; 34 | // Convert upper characters to lower characters 35 | for (std::string::size_type i = 0; i < str.size(); i++) { 36 | if (str[i] >= 65 && str[i] <= 90) str[i] += 32; 37 | } 38 | 39 | if (str == std::string("true")) { 40 | return true; 41 | } else if (str == std::string("yes")) { 42 | return true; 43 | } else if (str == std::string("on")) { 44 | return true; 45 | } else if (str == std::string("enabled")) { 46 | return true; 47 | } else if (str == std::string("1")) { 48 | return true; 49 | } else if (str == std::string("false")) { 50 | return false; 51 | } else if (str == std::string("no")) { 52 | return false; 53 | } else if (str == std::string("off")) { 54 | return false; 55 | } else if (str == std::string("disabled")) { 56 | return false; 57 | } else if (str == std::string("0")) { 58 | return false; 59 | } else { 60 | throw ParsingException("\"" + str + "\" is not a valid boolean value", 61 | __FILE__, __LINE__); 62 | } 63 | } 64 | 65 | LogLevel suPHP::Configuration::strToLogLevel(const std::string& str) const { 66 | if (str == "none") 67 | return LOGLEVEL_NONE; 68 | else if (str == "error") 69 | return LOGLEVEL_ERROR; 70 | else if (str == "warn") 71 | return LOGLEVEL_WARN; 72 | else if (str == "info") 73 | return LOGLEVEL_INFO; 74 | else 75 | throw ParsingException("\"" + str + "\" is not a valid log level", __FILE__, 76 | __LINE__); 77 | } 78 | 79 | SetidMode suPHP::Configuration::strToMode(const std::string& str) const { 80 | if (str == "owner") 81 | return OWNER_MODE; 82 | else if (str == "force") 83 | return FORCE_MODE; 84 | else if (str == "paranoid") 85 | return PARANOID_MODE; 86 | else 87 | throw ParsingException("\"" + str + "\" is not a valid mode", __FILE__, 88 | __LINE__); 89 | } 90 | 91 | suPHP::Configuration::Configuration() 92 | : 93 | #ifdef OPT_LOGFILE 94 | logfile{OPT_LOGFILE}, 95 | #else 96 | logfile{"/var/log/suphp.log"}, 97 | #endif 98 | #ifdef OPT_APACHE_USER 99 | webserver_user{OPT_APACHE_USER}, 100 | #else 101 | webserver_user{"wwwrun"}, 102 | #endif 103 | docroots(1, "/"), 104 | allow_file_group_writeable{false}, 105 | allow_directory_group_writeable{false}, 106 | allow_file_others_writeable{false}, 107 | allow_directory_others_writeable{false}, 108 | #ifdef OPT_DISABLE_CHECKPATH 109 | check_vhost_docroot{false}, 110 | #else 111 | check_vhost_docroot{true}, 112 | #endif 113 | userdir_overrides_usergroup{false}, 114 | errors_to_browser{false}, 115 | env_path{"/bin:/usr/bin"}, 116 | loglevel{LOGLEVEL_INFO}, 117 | #ifdef OPT_MIN_UID 118 | min_uid{OPT_MIN_UID}, 119 | #else 120 | min_uid{1}, 121 | #endif 122 | #ifdef OPT_MIN_GID 123 | min_gid{OPT_MIN_GID}, 124 | #else 125 | min_gid{1}, 126 | #endif 127 | umask{0077}, 128 | chroot_path{""}, 129 | full_php_process_display{false}, 130 | #if defined OPT_USERGROUP_OWNER 131 | mode{OWNER_MODE}, 132 | #elif defined OPT_USERGROUP_FORCE 133 | mode{FORCE_MODE}, 134 | #else 135 | mode{PARANOID_MODE}, 136 | #endif 137 | paranoid_uid_check{true}, 138 | paranoid_gid_check{true} { 139 | } 140 | 141 | void suPHP::Configuration::readFromFile(File& file) { 142 | IniFile ini; 143 | ini.parse(file); 144 | if (ini.hasSection("global")) { 145 | const IniSection& sect = ini.getSection("global"); 146 | const std::vector keys = sect.getKeys(); 147 | std::vector::const_iterator i; 148 | for (i = keys.begin(); i < keys.end(); i++) { 149 | std::string key = *i; 150 | std::string value = sect.getValue(key); 151 | 152 | if (key == "logfile") 153 | this->logfile = value; 154 | else if (key == "webserver_user") 155 | this->webserver_user = value; 156 | else if (key == "docroot") { 157 | this->docroots = sect.getValues(key); 158 | } else if (key == "allow_file_group_writeable") 159 | this->allow_file_group_writeable = this->strToBool(value); 160 | else if (key == "allow_directory_group_writeable") 161 | this->allow_directory_group_writeable = this->strToBool(value); 162 | else if (key == "allow_file_others_writeable") 163 | this->allow_file_others_writeable = this->strToBool(value); 164 | else if (key == "allow_directory_others_writeable") 165 | this->allow_directory_others_writeable = this->strToBool(value); 166 | else if (key == "check_vhost_docroot") 167 | this->check_vhost_docroot = this->strToBool(value); 168 | else if (key == "userdir_overrides_usergroup") 169 | this->userdir_overrides_usergroup = this->strToBool(value); 170 | else if (key == "errors_to_browser") 171 | this->errors_to_browser = this->strToBool(value); 172 | else if (key == "env_path") 173 | this->env_path = value; 174 | else if (key == "loglevel") 175 | this->loglevel = this->strToLogLevel(value); 176 | else if (key == "min_uid") 177 | this->min_uid = Util::strToInt(value); 178 | else if (key == "min_gid") 179 | this->min_gid = Util::strToInt(value); 180 | else if (key == "umask") 181 | this->umask = Util::octalStrToInt(value); 182 | else if (key == "chroot") 183 | this->chroot_path = value; 184 | else if (key == "full_php_process_display") 185 | this->full_php_process_display = this->strToBool(value); 186 | else if (key == "mode") 187 | this->mode = this->strToMode(value); 188 | else if (key == "paranoid_gid_check") 189 | this->paranoid_gid_check = this->strToBool(value); 190 | else if (key == "paranoid_uid_check") 191 | this->paranoid_uid_check = this->strToBool(value); 192 | else 193 | throw ParsingException( 194 | "Unknown option \"" + key + "\" in section [global]", __FILE__, 195 | __LINE__); 196 | } 197 | } 198 | 199 | // Get handlers / interpreters 200 | if (ini.hasSection("handlers")) { 201 | IniSection sect = ini.getSection("handlers"); 202 | const std::vector keys = sect.getKeys(); 203 | std::vector::const_iterator i; 204 | for (i = keys.begin(); i < keys.end(); i++) { 205 | std::string key = *i; 206 | std::string value = sect.getValue(key); 207 | std::pair p; 208 | p.first = key; 209 | p.second = value; 210 | this->handlers.insert(p); 211 | } 212 | } 213 | 214 | // Get configured phprc_paths 215 | if (ini.hasSection("phprc_paths")) { 216 | IniSection sect = ini.getSection("phprc_paths"); 217 | std::vector keys = sect.getKeys(); 218 | std::vector::iterator i; 219 | for (i = keys.begin(); i < keys.end(); i++) { 220 | std::string key = *i; 221 | std::string value = sect.getValue(key); 222 | std::pair p; 223 | p.first = key; 224 | p.second = value; 225 | this->phprc_paths.insert(p); 226 | } 227 | } 228 | } 229 | 230 | std::string suPHP::Configuration::getLogfile() const { return this->logfile; } 231 | 232 | LogLevel suPHP::Configuration::getLogLevel() const { return this->loglevel; } 233 | 234 | std::string suPHP::Configuration::getWebserverUser() const { 235 | return this->webserver_user; 236 | } 237 | 238 | const std::vector& suPHP::Configuration::getDocroots() const { 239 | return this->docroots; 240 | } 241 | 242 | bool suPHP::Configuration::getCheckVHostDocroot() const { 243 | return this->check_vhost_docroot; 244 | } 245 | 246 | bool suPHP::Configuration::getUserdirOverridesUsergroup() const { 247 | return this->userdir_overrides_usergroup; 248 | } 249 | 250 | bool suPHP::Configuration::getAllowFileGroupWriteable() const { 251 | return this->allow_file_group_writeable; 252 | } 253 | 254 | bool suPHP::Configuration::getAllowDirectoryGroupWriteable() const { 255 | return this->allow_directory_group_writeable; 256 | } 257 | 258 | bool suPHP::Configuration::getAllowFileOthersWriteable() const { 259 | return this->allow_file_others_writeable; 260 | } 261 | 262 | bool suPHP::Configuration::getAllowDirectoryOthersWriteable() const { 263 | return this->allow_directory_others_writeable; 264 | } 265 | 266 | bool suPHP::Configuration::getFullPHPProcessDisplay() const { 267 | return this->full_php_process_display; 268 | } 269 | 270 | SetidMode suPHP::Configuration::getMode() const { return this->mode; } 271 | 272 | bool suPHP::Configuration::getParanoidUIDCheck() const { 273 | return this->paranoid_uid_check; 274 | } 275 | 276 | bool suPHP::Configuration::getParanoidGIDCheck() const { 277 | return this->paranoid_gid_check; 278 | } 279 | 280 | bool suPHP::Configuration::getErrorsToBrowser() const { 281 | return this->errors_to_browser; 282 | } 283 | 284 | std::string suPHP::Configuration::getEnvPath() const { return this->env_path; } 285 | 286 | std::string suPHP::Configuration::getInterpreter(std::string handler) const { 287 | if (this->handlers.find(handler) != this->handlers.end()) { 288 | return this->handlers.find(handler)->second; 289 | } else { 290 | throw KeyNotFoundException("Handler \"" + handler + "\" not found", 291 | __FILE__, __LINE__); 292 | } 293 | } 294 | 295 | std::string suPHP::Configuration::getPHPRCPath(std::string handler) const { 296 | if (this->phprc_paths.find(handler) != this->phprc_paths.end()) { 297 | return this->phprc_paths.find(handler)->second; 298 | } else { 299 | return std::string(); 300 | } 301 | } 302 | 303 | int suPHP::Configuration::getMinUid() const { return this->min_uid; } 304 | 305 | int suPHP::Configuration::getMinGid() const { return this->min_gid; } 306 | 307 | int suPHP::Configuration::getUmask() const { return this->umask; } 308 | 309 | std::string suPHP::Configuration::getChrootPath() const { 310 | return this->chroot_path; 311 | } 312 | --------------------------------------------------------------------------------