mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-23 13:45:04 +02:00
parent
acc9393c8a
commit
a01fb6d6e6
@ -18,5 +18,7 @@
|
|||||||
#define ICINGA_LOCALSTATEDIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}"
|
#define ICINGA_LOCALSTATEDIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}"
|
||||||
#define ICINGA_PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/icinga2"
|
#define ICINGA_PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/icinga2"
|
||||||
#define ICINGA_INCLUDECONFDIR "${CMAKE_INSTALL_FULL_DATADIR}/icinga2/include"
|
#define ICINGA_INCLUDECONFDIR "${CMAKE_INSTALL_FULL_DATADIR}/icinga2/include"
|
||||||
|
#define ICINGA_USER "${ICINGA2_USER}"
|
||||||
|
#define ICINGA_GROUP "${ICINGA2_GROUP}"
|
||||||
|
|
||||||
#endif /* CONFIG_H */
|
#endif /* CONFIG_H */
|
||||||
|
7
debian/icinga2-common.icinga2.init
vendored
7
debian/icinga2-common.icinga2.init
vendored
@ -17,7 +17,6 @@ PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
|||||||
DESC="icinga2 monitoring daemon"
|
DESC="icinga2 monitoring daemon"
|
||||||
NAME=icinga2
|
NAME=icinga2
|
||||||
DAEMON=/usr/sbin/icinga2
|
DAEMON=/usr/sbin/icinga2
|
||||||
DAEMON_CONFIG="/etc/icinga2/icinga2.conf"
|
|
||||||
DAEMON_USER=nagios
|
DAEMON_USER=nagios
|
||||||
DAEMON_GROUP=nagios
|
DAEMON_GROUP=nagios
|
||||||
DAEMON_CMDGROUP=www-data
|
DAEMON_CMDGROUP=www-data
|
||||||
@ -53,7 +52,7 @@ check_run () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_config () {
|
check_config () {
|
||||||
$DAEMON daemon --validate -u "$DAEMON_USER" -g "$DAEMON_GROUP" -c "$DAEMON_CONFIG"
|
$DAEMON daemon --validate
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -69,7 +68,7 @@ do_start()
|
|||||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||||
|| return 1
|
|| return 1
|
||||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
||||||
daemon -c "$DAEMON_CONFIG" -u "$DAEMON_USER" -g "$DAEMON_GROUP" -d $DAEMON_ARGS \
|
daemon -d $DAEMON_ARGS \
|
||||||
|| return 2
|
|| return 2
|
||||||
# Add code here, if necessary, that waits for the process to be ready
|
# Add code here, if necessary, that waits for the process to be ready
|
||||||
# to handle requests from services started subsequently which depend
|
# to handle requests from services started subsequently which depend
|
||||||
@ -84,7 +83,7 @@ do_foreground()
|
|||||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test \
|
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test \
|
||||||
|| return 1
|
|| return 1
|
||||||
start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON -- \
|
start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON -- \
|
||||||
daemon -c "$DAEMON_CONFIG" -u "$DAEMON_USER" -g "$DAEMON_GROUP" $DAEMON_ARGS \
|
daemon $DAEMON_ARGS \
|
||||||
|| return 2
|
|| return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
include(InstallConfig)
|
include(InstallConfig)
|
||||||
|
|
||||||
configure_file(icinga/icinga-classic-apache.conf.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga/icinga-classic-apache.conf @ONLY)
|
configure_file(icinga/icinga-classic-apache.conf.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga/icinga-classic-apache.conf @ONLY)
|
||||||
|
configure_file(icinga2/init.conf.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga2/init.conf @ONLY)
|
||||||
configure_file(icinga2/constants.conf.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga2/constants.conf @ONLY)
|
configure_file(icinga2/constants.conf.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga2/constants.conf @ONLY)
|
||||||
configure_file(logrotate.d/icinga2.cmake ${CMAKE_CURRENT_BINARY_DIR}/logrotate.d/icinga2 @ONLY)
|
configure_file(logrotate.d/icinga2.cmake ${CMAKE_CURRENT_BINARY_DIR}/logrotate.d/icinga2 @ONLY)
|
||||||
|
|
||||||
|
install_if_not_exists(${CMAKE_CURRENT_BINARY_DIR}/icinga2/init.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
||||||
install_if_not_exists(icinga2/icinga2.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
install_if_not_exists(icinga2/icinga2.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
||||||
install_if_not_exists(${CMAKE_CURRENT_BINARY_DIR}/icinga2/constants.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
install_if_not_exists(${CMAKE_CURRENT_BINARY_DIR}/icinga2/constants.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
||||||
install_if_not_exists(icinga2/zones.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
install_if_not_exists(icinga2/zones.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
||||||
|
2
etc/icinga2/init.conf.cmake
Normal file
2
etc/icinga2/init.conf.cmake
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
const RunAsUser = "@ICINGA2_USER@"
|
||||||
|
const RunAsGroup = "@ICINGA2_GROUP@"
|
@ -48,7 +48,7 @@ start() {
|
|||||||
printf "Starting Icinga 2: "
|
printf "Starting Icinga 2: "
|
||||||
@CMAKE_INSTALL_FULL_SBINDIR@/icinga2-prepare-dirs $SYSCONFIGFILE
|
@CMAKE_INSTALL_FULL_SBINDIR@/icinga2-prepare-dirs $SYSCONFIGFILE
|
||||||
|
|
||||||
if ! $DAEMON daemon -c $ICINGA2_CONFIG_FILE -d -e $ICINGA2_ERROR_LOG -u $ICINGA2_USER -g $ICINGA2_GROUP > $ICINGA2_STARTUP_LOG 2>&1; then
|
if ! $DAEMON daemon -c $ICINGA2_CONFIG_FILE -d -e $ICINGA2_ERROR_LOG > $ICINGA2_STARTUP_LOG 2>&1; then
|
||||||
echo "Error starting Icinga. Check '$ICINGA2_STARTUP_LOG' for details."
|
echo "Error starting Icinga. Check '$ICINGA2_STARTUP_LOG' for details."
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
@ -111,7 +111,7 @@ reload() {
|
|||||||
checkconfig() {
|
checkconfig() {
|
||||||
printf "Checking configuration: "
|
printf "Checking configuration: "
|
||||||
|
|
||||||
if ! $DAEMON daemon -c $ICINGA2_CONFIG_FILE -C -u $ICINGA2_USER -g $ICINGA2_GROUP > $ICINGA2_STARTUP_LOG 2>&1; then
|
if ! $DAEMON daemon -c $ICINGA2_CONFIG_FILE -C > $ICINGA2_STARTUP_LOG 2>&1; then
|
||||||
if [ "x$1" = "x" ]; then
|
if [ "x$1" = "x" ]; then
|
||||||
cat $ICINGA2_STARTUP_LOG
|
cat $ICINGA2_STARTUP_LOG
|
||||||
echo "Icinga 2 detected configuration errors. Check '$ICINGA2_STARTUP_LOG' for details."
|
echo "Icinga 2 detected configuration errors. Check '$ICINGA2_STARTUP_LOG' for details."
|
||||||
|
@ -34,6 +34,12 @@
|
|||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <pwd.h>
|
||||||
|
# include <grp.h>
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
@ -110,6 +116,8 @@ int Main(void)
|
|||||||
|
|
||||||
Application::DeclareZonesDir(Application::GetSysconfDir() + "/icinga2/zones.d");
|
Application::DeclareZonesDir(Application::GetSysconfDir() + "/icinga2/zones.d");
|
||||||
Application::DeclareApplicationType("icinga/IcingaApplication");
|
Application::DeclareApplicationType("icinga/IcingaApplication");
|
||||||
|
Application::DeclareRunAsUser(ICINGA_USER);
|
||||||
|
Application::DeclareRunAsGroup(ICINGA_GROUP);
|
||||||
|
|
||||||
LogSeverity logLevel = Logger::GetConsoleLogSeverity();
|
LogSeverity logLevel = Logger::GetConsoleLogSeverity();
|
||||||
Logger::SetConsoleLogSeverity(LogWarning);
|
Logger::SetConsoleLogSeverity(LogWarning);
|
||||||
@ -124,8 +132,12 @@ int Main(void)
|
|||||||
("define,D", po::value<std::vector<std::string> >(), "define a constant")
|
("define,D", po::value<std::vector<std::string> >(), "define a constant")
|
||||||
("library,l", po::value<std::vector<std::string> >(), "load a library")
|
("library,l", po::value<std::vector<std::string> >(), "load a library")
|
||||||
("include,I", po::value<std::vector<std::string> >(), "add include search directory")
|
("include,I", po::value<std::vector<std::string> >(), "add include search directory")
|
||||||
("log-level,x", po::value<std::string>(), "specify the log level for the console log");
|
("log-level,x", po::value<std::string>(), "specify the log level for the console log")
|
||||||
|
#ifndef _WIN32
|
||||||
|
("user,u", po::value<std::string>(), "user to run Icinga as")
|
||||||
|
("group,g", po::value<std::string>(), "group to run Icinga as")
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
;
|
||||||
|
|
||||||
po::options_description hiddenDesc("Hidden options");
|
po::options_description hiddenDesc("Hidden options");
|
||||||
|
|
||||||
@ -145,6 +157,13 @@ int Main(void)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String initconfig = Application::GetSysconfDir() + "/icinga2/init.conf";
|
||||||
|
|
||||||
|
if (Utility::PathExists(initconfig)) {
|
||||||
|
ConfigCompilerContext::GetInstance()->Reset();
|
||||||
|
ConfigCompiler::CompileFile(initconfig);
|
||||||
|
}
|
||||||
|
|
||||||
if (vm.count("define")) {
|
if (vm.count("define")) {
|
||||||
BOOST_FOREACH(const String& define, vm["define"].as<std::vector<std::string> >()) {
|
BOOST_FOREACH(const String& define, vm["define"].as<std::vector<std::string> >()) {
|
||||||
String key, value;
|
String key, value;
|
||||||
@ -160,6 +179,85 @@ int Main(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vm.count("group"))
|
||||||
|
ScriptVariable::Set("RunAsGroup", String(vm["group"].as<std::string>()));
|
||||||
|
|
||||||
|
if (vm.count("user"))
|
||||||
|
ScriptVariable::Set("RunAsUser", String(vm["user"].as<std::string>()));
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
String group = Application::GetRunAsGroup();
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
struct group *gr = getgrnam(group.CStr());
|
||||||
|
|
||||||
|
if (!gr) {
|
||||||
|
if (errno == 0) {
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "Invalid group specified: " + group;
|
||||||
|
Log(LogCritical, "cli", msgbuf.str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
} else {
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "getgrnam() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
||||||
|
Log(LogCritical, "cli", msgbuf.str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getgid() != gr->gr_gid) {
|
||||||
|
if (!vm.count("reload-internal") && setgroups(0, NULL) < 0) {
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "setgroups() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
||||||
|
Log(LogCritical, "cli", msgbuf.str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setgid(gr->gr_gid) < 0) {
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "setgid() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
||||||
|
Log(LogCritical, "cli", msgbuf.str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String user = Application::GetRunAsUser();
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
struct passwd *pw = getpwnam(user.CStr());
|
||||||
|
|
||||||
|
if (!pw) {
|
||||||
|
if (errno == 0) {
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "Invalid user specified: " + user;
|
||||||
|
Log(LogCritical, "cli", msgbuf.str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
} else {
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "getpwnam() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
||||||
|
Log(LogCritical, "cli", msgbuf.str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// also activate the additional groups the configured user is member of
|
||||||
|
if (getuid() != pw->pw_uid) {
|
||||||
|
if (!vm.count("reload-internal") && initgroups(user.CStr(), pw->pw_gid) < 0) {
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "initgroups() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
||||||
|
Log(LogCritical, "cli", msgbuf.str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setuid(pw->pw_uid) < 0) {
|
||||||
|
std::ostringstream msgbuf;
|
||||||
|
msgbuf << "setuid() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
||||||
|
Log(LogCritical, "cli", msgbuf.str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
Application::DeclareStatePath(Application::GetLocalStateDir() + "/lib/icinga2/icinga2.state");
|
Application::DeclareStatePath(Application::GetLocalStateDir() + "/lib/icinga2/icinga2.state");
|
||||||
Application::DeclareObjectsPath(Application::GetLocalStateDir() + "/cache/icinga2/icinga2.debug");
|
Application::DeclareObjectsPath(Application::GetLocalStateDir() + "/cache/icinga2/icinga2.debug");
|
||||||
Application::DeclarePidPath(Application::GetRunDir() + "/icinga2/icinga2.pid");
|
Application::DeclarePidPath(Application::GetRunDir() + "/icinga2/icinga2.pid");
|
||||||
|
@ -1051,6 +1051,45 @@ void Application::DeclareApplicationType(const String& type)
|
|||||||
ScriptVariable::Set("ApplicationType", type, false);
|
ScriptVariable::Set("ApplicationType", type, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the name of the user.
|
||||||
|
*
|
||||||
|
* @returns The name.
|
||||||
|
*/
|
||||||
|
String Application::GetRunAsUser(void)
|
||||||
|
{
|
||||||
|
return ScriptVariable::Get("RunAsUser");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name of the user.
|
||||||
|
*
|
||||||
|
* @param path The new user name.
|
||||||
|
*/
|
||||||
|
void Application::DeclareRunAsUser(const String& user)
|
||||||
|
{
|
||||||
|
ScriptVariable::Set("RunAsUser", user, false);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Retrieves the name of the group.
|
||||||
|
*
|
||||||
|
* @returns The name.
|
||||||
|
*/
|
||||||
|
String Application::GetRunAsGroup(void)
|
||||||
|
{
|
||||||
|
return ScriptVariable::Get("RunAsGroup");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name of the group.
|
||||||
|
*
|
||||||
|
* @param path The new group name.
|
||||||
|
*/
|
||||||
|
void Application::DeclareRunAsGroup(const String& group)
|
||||||
|
{
|
||||||
|
ScriptVariable::Set("RunAsGroup", group, false);
|
||||||
|
}
|
||||||
|
|
||||||
void Application::MakeVariablesConstant(void)
|
void Application::MakeVariablesConstant(void)
|
||||||
{
|
{
|
||||||
ScriptVariable::GetByName("PrefixDir")->SetConstant(true);
|
ScriptVariable::GetByName("PrefixDir")->SetConstant(true);
|
||||||
@ -1062,6 +1101,8 @@ void Application::MakeVariablesConstant(void)
|
|||||||
ScriptVariable::GetByName("ObjectsPath")->SetConstant(true);
|
ScriptVariable::GetByName("ObjectsPath")->SetConstant(true);
|
||||||
ScriptVariable::GetByName("PidPath")->SetConstant(true);
|
ScriptVariable::GetByName("PidPath")->SetConstant(true);
|
||||||
ScriptVariable::GetByName("ApplicationType")->SetConstant(true);
|
ScriptVariable::GetByName("ApplicationType")->SetConstant(true);
|
||||||
|
ScriptVariable::GetByName("RunAsUser")->SetConstant(true);
|
||||||
|
ScriptVariable::GetByName("RunAsGroup")->SetConstant(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,6 +113,12 @@ public:
|
|||||||
static String GetApplicationType(void);
|
static String GetApplicationType(void);
|
||||||
static void DeclareApplicationType(const String& type);
|
static void DeclareApplicationType(const String& type);
|
||||||
|
|
||||||
|
static String GetRunAsUser(void);
|
||||||
|
static void DeclareRunAsUser(const String& user);
|
||||||
|
|
||||||
|
static String GetRunAsGroup(void);
|
||||||
|
static void DeclareRunAsGroup(const String& group);
|
||||||
|
|
||||||
static void MakeVariablesConstant(void);
|
static void MakeVariablesConstant(void);
|
||||||
|
|
||||||
static ThreadPool& GetTP(void);
|
static ThreadPool& GetTP(void);
|
||||||
|
@ -270,8 +270,6 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
|||||||
|
|
||||||
EVP_PKEY *key = EVP_PKEY_new();
|
EVP_PKEY *key = EVP_PKEY_new();
|
||||||
EVP_PKEY_assign_RSA(key, rsa);
|
EVP_PKEY_assign_RSA(key, rsa);
|
||||||
X509_REQ_set_version(req, 0);
|
|
||||||
X509_REQ_set_pubkey(req, key);
|
|
||||||
|
|
||||||
if (!certfile.IsEmpty()) {
|
if (!certfile.IsEmpty()) {
|
||||||
X509 *cert = X509_new();
|
X509 *cert = X509_new();
|
||||||
@ -295,13 +293,15 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
|||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!csrfile.IsEmpty()) {
|
||||||
|
X509_REQ_set_version(req, 0);
|
||||||
|
X509_REQ_set_pubkey(req, key);
|
||||||
|
|
||||||
X509_NAME *name = X509_REQ_get_subject_name(req);
|
X509_NAME *name = X509_REQ_get_subject_name(req);
|
||||||
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0);
|
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0);
|
||||||
|
|
||||||
X509_REQ_sign(req, key, EVP_sha1());
|
X509_REQ_sign(req, key, EVP_sha1());
|
||||||
|
|
||||||
EVP_PKEY_free(key);
|
|
||||||
|
|
||||||
Log(LogInformation, "base", "Writing certificate signing request to '" + certfile + "'.");
|
Log(LogInformation, "base", "Writing certificate signing request to '" + certfile + "'.");
|
||||||
|
|
||||||
bio = BIO_new(BIO_s_file());
|
bio = BIO_new(BIO_s_file());
|
||||||
@ -310,6 +310,9 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
|
|||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
|
|
||||||
X509_REQ_free(req);
|
X509_REQ_free(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY_free(key);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ shared_ptr<SSL_CTX> I2_BASE_API MakeSSLContext(const String& pubkey, const Strin
|
|||||||
void I2_BASE_API AddCRLToSSLContext(const shared_ptr<SSL_CTX>& context, const String& crlPath);
|
void I2_BASE_API AddCRLToSSLContext(const shared_ptr<SSL_CTX>& context, const String& crlPath);
|
||||||
String I2_BASE_API GetCertificateCN(const shared_ptr<X509>& certificate);
|
String I2_BASE_API GetCertificateCN(const shared_ptr<X509>& certificate);
|
||||||
shared_ptr<X509> I2_BASE_API GetX509Certificate(const String& pemfile);
|
shared_ptr<X509> I2_BASE_API GetX509Certificate(const String& pemfile);
|
||||||
int I2_BASE_API MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile, const String& certfile = String());
|
int I2_BASE_API MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile = String(), const String& certfile = String());
|
||||||
String I2_BASE_API SHA256(const String& s);
|
String I2_BASE_API SHA256(const String& s);
|
||||||
|
|
||||||
class I2_BASE_API openssl_error : virtual public std::exception, virtual public boost::exception { };
|
class I2_BASE_API openssl_error : virtual public std::exception, virtual public boost::exception { };
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
set(cli_SOURCES
|
set(cli_SOURCES
|
||||||
pkiinitcacommand.cpp pkinewcsrcommand.cpp daemoncommand.cpp
|
pkinewcacommand.cpp pkinewcertcommand.cpp daemoncommand.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ICINGA2_UNITY_BUILD)
|
if(ICINGA2_UNITY_BUILD)
|
||||||
|
@ -37,12 +37,6 @@
|
|||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <pwd.h>
|
|
||||||
# include <grp.h>
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
@ -291,8 +285,6 @@ void DaemonCommand::InitParameters(boost::program_options::options_description&
|
|||||||
("errorlog,e", po::value<std::string>(), "log fatal errors to the specified log file (only works in combination with --daemonize)")
|
("errorlog,e", po::value<std::string>(), "log fatal errors to the specified log file (only works in combination with --daemonize)")
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
("daemonize,d", "detach from the controlling terminal")
|
("daemonize,d", "detach from the controlling terminal")
|
||||||
("user,u", po::value<std::string>(), "user to run Icinga as")
|
|
||||||
("group,g", po::value<std::string>(), "group to run Icinga as")
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -309,79 +301,6 @@ void DaemonCommand::InitParameters(boost::program_options::options_description&
|
|||||||
*/
|
*/
|
||||||
int DaemonCommand::Run(const po::variables_map& vm) const
|
int DaemonCommand::Run(const po::variables_map& vm) const
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
|
||||||
if (vm.count("group")) {
|
|
||||||
String group = vm["group"].as<std::string>();
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
struct group *gr = getgrnam(group.CStr());
|
|
||||||
|
|
||||||
if (!gr) {
|
|
||||||
if (errno == 0) {
|
|
||||||
std::ostringstream msgbuf;
|
|
||||||
msgbuf << "Invalid group specified: " + group;
|
|
||||||
Log(LogCritical, "cli", msgbuf.str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
} else {
|
|
||||||
std::ostringstream msgbuf;
|
|
||||||
msgbuf << "getgrnam() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
|
||||||
Log(LogCritical, "cli", msgbuf.str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vm.count("reload-internal") && setgroups(0, NULL) < 0) {
|
|
||||||
std::ostringstream msgbuf;
|
|
||||||
msgbuf << "setgroups() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
|
||||||
Log(LogCritical, "cli", msgbuf.str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setgid(gr->gr_gid) < 0) {
|
|
||||||
std::ostringstream msgbuf;
|
|
||||||
msgbuf << "setgid() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
|
||||||
Log(LogCritical, "cli", msgbuf.str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vm.count("user")) {
|
|
||||||
String user = vm["user"].as<std::string>();
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
struct passwd *pw = getpwnam(user.CStr());
|
|
||||||
|
|
||||||
if (!pw) {
|
|
||||||
if (errno == 0) {
|
|
||||||
std::ostringstream msgbuf;
|
|
||||||
msgbuf << "Invalid user specified: " + user;
|
|
||||||
Log(LogCritical, "cli", msgbuf.str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
} else {
|
|
||||||
std::ostringstream msgbuf;
|
|
||||||
msgbuf << "getpwnam() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
|
||||||
Log(LogCritical, "cli", msgbuf.str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// also activate the additional groups the configured user is member of
|
|
||||||
if (!vm.count("reload-internal") && initgroups(user.CStr(), pw->pw_gid) < 0) {
|
|
||||||
std::ostringstream msgbuf;
|
|
||||||
msgbuf << "initgroups() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
|
||||||
Log(LogCritical, "cli", msgbuf.str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setuid(pw->pw_uid) < 0) {
|
|
||||||
std::ostringstream msgbuf;
|
|
||||||
msgbuf << "setuid() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
|
||||||
Log(LogCritical, "cli", msgbuf.str());
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
ScriptVariable::Set("UseVfork", true, false, true);
|
ScriptVariable::Set("UseVfork", true, false, true);
|
||||||
|
|
||||||
Application::MakeVariablesConstant();
|
Application::MakeVariablesConstant();
|
||||||
|
@ -17,39 +17,62 @@
|
|||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "cli/pkiinitcacommand.hpp"
|
#include "cli/pkinewcacommand.hpp"
|
||||||
#include "base/logger_fwd.hpp"
|
#include "base/logger_fwd.hpp"
|
||||||
#include "base/clicommand.hpp"
|
#include "base/clicommand.hpp"
|
||||||
|
#include "base/application.hpp"
|
||||||
|
#include "base/tlsutility.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_CLICOMMAND("pki/init-ca", PKIInitCACommand);
|
REGISTER_CLICOMMAND("pki/new-ca", PKINewCACommand);
|
||||||
|
|
||||||
String PKIInitCACommand::GetDescription(void) const
|
String PKINewCACommand::GetDescription(void) const
|
||||||
{
|
{
|
||||||
return "Sets up a new Certificate Authority.";
|
return "Sets up a new Certificate Authority.";
|
||||||
}
|
}
|
||||||
|
|
||||||
String PKIInitCACommand::GetShortDescription(void) const
|
String PKINewCACommand::GetShortDescription(void) const
|
||||||
{
|
{
|
||||||
return "sets up a new CA";
|
return "sets up a new CA";
|
||||||
}
|
}
|
||||||
|
|
||||||
void PKIInitCACommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
void PKINewCACommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||||
boost::program_options::options_description& hiddenDesc) const
|
boost::program_options::options_description& hiddenDesc) const
|
||||||
{
|
{
|
||||||
/* Command doesn't support any parameters. */
|
/* Command doesn't support any parameters. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The entry point for the "ca init" CLI command.
|
* The entry point for the "pki new-ca" CLI command.
|
||||||
*
|
*
|
||||||
* @returns An exit status.
|
* @returns An exit status.
|
||||||
*/
|
*/
|
||||||
int PKIInitCACommand::Run(const boost::program_options::variables_map& vm) const
|
int PKINewCACommand::Run(const boost::program_options::variables_map& vm) const
|
||||||
{
|
{
|
||||||
Log(LogNotice, "cli", "Test!");
|
String cadir = Application::GetLocalStateDir() + "/lib/icinga2/ca";
|
||||||
Log(LogInformation, "cli", "Hello World!");
|
|
||||||
|
if (Utility::PathExists(cadir)) {
|
||||||
|
Log(LogCritical, "base", "CA directory '" + cadir + "' already exists.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Utility::MkDirP(cadir, 0700)) {
|
||||||
|
Log(LogCritical, "base", "Could not create CA directory '" + cadir + "'.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MakeX509CSR("Icinga CA", cadir + "/ca.key", String(), cadir + "/ca.crt");
|
||||||
|
|
||||||
|
String serialpath = cadir + "/serial.txt";
|
||||||
|
|
||||||
|
Log(LogInformation, "cli", "Initializing serial file in '" + serialpath + "'.");
|
||||||
|
|
||||||
|
std::ofstream fp;
|
||||||
|
fp.open(serialpath.CStr());
|
||||||
|
fp << "01";
|
||||||
|
fp.close();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -17,8 +17,8 @@
|
|||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifndef PKIINITCACOMMAND_H
|
#ifndef PKINEWCACOMMAND_H
|
||||||
#define PKIINITCACOMMAND_H
|
#define PKINEWCACOMMAND_H
|
||||||
|
|
||||||
#include "base/qstring.hpp"
|
#include "base/qstring.hpp"
|
||||||
#include "base/clicommand.hpp"
|
#include "base/clicommand.hpp"
|
||||||
@ -27,14 +27,14 @@ namespace icinga
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "pki init-ca" command.
|
* The "pki new-ca" command.
|
||||||
*
|
*
|
||||||
* @ingroup cli
|
* @ingroup cli
|
||||||
*/
|
*/
|
||||||
class PKIInitCACommand : public CLICommand
|
class PKINewCACommand : public CLICommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DECLARE_PTR_TYPEDEFS(PKIInitCACommand);
|
DECLARE_PTR_TYPEDEFS(PKINewCACommand);
|
||||||
|
|
||||||
virtual String GetDescription(void) const;
|
virtual String GetDescription(void) const;
|
||||||
virtual String GetShortDescription(void) const;
|
virtual String GetShortDescription(void) const;
|
||||||
@ -46,4 +46,4 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* PKIINITCACOMMAND_H */
|
#endif /* PKINEWCACOMMAND_H */
|
@ -17,7 +17,7 @@
|
|||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "cli/pkinewcsrcommand.hpp"
|
#include "cli/pkinewcertcommand.hpp"
|
||||||
#include "base/logger_fwd.hpp"
|
#include "base/logger_fwd.hpp"
|
||||||
#include "base/clicommand.hpp"
|
#include "base/clicommand.hpp"
|
||||||
#include "base/tlsutility.hpp"
|
#include "base/tlsutility.hpp"
|
||||||
@ -25,34 +25,34 @@
|
|||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
REGISTER_CLICOMMAND("pki/new-csr", PKINewCSRCommand);
|
REGISTER_CLICOMMAND("pki/new-cert", PKINewCertCommand);
|
||||||
|
|
||||||
String PKINewCSRCommand::GetDescription(void) const
|
String PKINewCertCommand::GetDescription(void) const
|
||||||
{
|
{
|
||||||
return "Creates a new Certificate Signing Request and optionally a self-signed X509 certificate.";
|
return "Creates a new Certificate Signing Request, a self-signed X509 certificate or both.";
|
||||||
}
|
}
|
||||||
|
|
||||||
String PKINewCSRCommand::GetShortDescription(void) const
|
String PKINewCertCommand::GetShortDescription(void) const
|
||||||
{
|
{
|
||||||
return "creates a new CSR";
|
return "creates a new CSR";
|
||||||
}
|
}
|
||||||
|
|
||||||
void PKINewCSRCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
void PKINewCertCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||||
boost::program_options::options_description& hiddenDesc) const
|
boost::program_options::options_description& hiddenDesc) const
|
||||||
{
|
{
|
||||||
visibleDesc.add_options()
|
visibleDesc.add_options()
|
||||||
("cn", po::value<std::string>(), "Common Name")
|
("cn", po::value<std::string>(), "Common Name")
|
||||||
("keyfile", po::value<std::string>(), "Key file path")
|
("keyfile", po::value<std::string>(), "Key file path")
|
||||||
("csrfile", po::value<std::string>(), "CSR file path")
|
("csrfile", po::value<std::string>(), "CSR file path (optional)")
|
||||||
("certfile", po::value<std::string>(), "Certificate file path (optional)");
|
("certfile", po::value<std::string>(), "Certificate file path (optional)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The entry point for the "ca init" CLI command.
|
* The entry point for the "pki new-cert" CLI command.
|
||||||
*
|
*
|
||||||
* @returns An exit status.
|
* @returns An exit status.
|
||||||
*/
|
*/
|
||||||
int PKINewCSRCommand::Run(const boost::program_options::variables_map& vm) const
|
int PKINewCertCommand::Run(const boost::program_options::variables_map& vm) const
|
||||||
{
|
{
|
||||||
if (!vm.count("cn")) {
|
if (!vm.count("cn")) {
|
||||||
Log(LogCritical, "cli", "Common name (--cn) must be specified.");
|
Log(LogCritical, "cli", "Common name (--cn) must be specified.");
|
||||||
@ -64,17 +64,15 @@ int PKINewCSRCommand::Run(const boost::program_options::variables_map& vm) const
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vm.count("csrfile")) {
|
String csrfile, certfile;
|
||||||
Log(LogCritical, "cli", "CSR file path (--csrfile) must be specified.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
String certfile;
|
if (vm.count("csrfile"))
|
||||||
|
csrfile = vm["csrfile"].as<std::string>();
|
||||||
|
|
||||||
if (vm.count("certfile"))
|
if (vm.count("certfile"))
|
||||||
certfile = vm["certfile"].as<std::string>();
|
certfile = vm["certfile"].as<std::string>();
|
||||||
|
|
||||||
MakeX509CSR(vm["cn"].as<std::string>(), vm["keyfile"].as<std::string>(), vm["csrfile"].as<std::string>(), certfile);
|
MakeX509CSR(vm["cn"].as<std::string>(), vm["keyfile"].as<std::string>(), csrfile, certfile);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -17,8 +17,8 @@
|
|||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifndef PKINEWCSRCOMMAND_H
|
#ifndef PKINEWCERTCOMMAND_H
|
||||||
#define PKINEWCSRCOMMAND_H
|
#define PKINEWCERTCOMMAND_H
|
||||||
|
|
||||||
#include "base/qstring.hpp"
|
#include "base/qstring.hpp"
|
||||||
#include "base/clicommand.hpp"
|
#include "base/clicommand.hpp"
|
||||||
@ -27,14 +27,14 @@ namespace icinga
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "pki new-csr" command.
|
* The "pki new-cert" command.
|
||||||
*
|
*
|
||||||
* @ingroup cli
|
* @ingroup cli
|
||||||
*/
|
*/
|
||||||
class PKINewCSRCommand : public CLICommand
|
class PKINewCertCommand : public CLICommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DECLARE_PTR_TYPEDEFS(PKINewCSRCommand);
|
DECLARE_PTR_TYPEDEFS(PKINewCertCommand);
|
||||||
|
|
||||||
virtual String GetDescription(void) const;
|
virtual String GetDescription(void) const;
|
||||||
virtual String GetShortDescription(void) const;
|
virtual String GetShortDescription(void) const;
|
||||||
@ -46,4 +46,4 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* PKINEWCSRCOMMAND_H */
|
#endif /* PKINEWCERTCOMMAND_H */
|
Loading…
x
Reference in New Issue
Block a user