/** * @file session-initialize-bincimap-up.cc * @brief bincimap-up requires sslserver * @author Andreas Aardal Hanssen, Erwin Hoffmann * @date 2002-2005, 2023 */ #include "broker.h" #include "convert.h" #include "globals.h" #include "iodevice.h" #include "iofactory.h" #include "multilogdevice.h" #include "operators.h" #include "session.h" #include "stdiodevice.h" #include "syslogdevice.h" #include "tools.h" #include #include #include #include #include using namespace Binc; using std::string; bool Session::initialize(int argc, char *argv[]) { IOFactory &ioFactory = IOFactory::getInstance(); auto stdioDevice = new StdIODevice(IODevice::IsEnabled); stdioDevice->setFlags(IODevice::HasOutputLimit); stdioDevice->setMaxOutputBufferSize(TRANSFER_BUFFER_SIZE); ioFactory.addDevice(std::unique_ptr(stdioDevice)); Session &session = Session::getInstance(); IOFactory::getLogger().clearFlags(IODevice::FlushesOnEndl); // Read command line arguments if (!session.parseCommandLine(argc, argv)) return false; // Show help if asked for it if (session.command.help) { printf("%s\n", session.args.usageString().c_str()); return false; } // Show version if asked for it if (session.command.version) { printf("Binc IMAP v" BINC_VERSION "\n"); return false; } // Let the command line args override the global settings. session.assignCommandLineArgs(); // for log input string ip = Tools::getenv("TCP6REMOTEIP") .value_or(Tools::getenv("TCPREMOTEIP").value_or("?")); session.setIP(ip); string logtype = session.getEnv("LOG_TYPE"); lowercase(logtype); trim(logtype); if (logtype == "" || logtype == "multilog") { auto device = new MultilogDevice(IODevice::IsEnabled | IODevice::FlushesOnEndl); ioFactory.addDevice(std::unique_ptr(device)); } else if (logtype == "syslog") { const string f = session.getEnv("SYSLOG_FACILITY"); int facility = 0; auto fcr = std::from_chars(f.c_str(), f.c_str() + f.size(), facility); if (fcr.ec != std::errc{}) { if (f == "LOG_USER") facility = LOG_USER; else if (f == "LOG_LOCAL0") facility = LOG_LOCAL0; else if (f == "LOG_LOCAL1") facility = LOG_LOCAL1; else if (f == "LOG_LOCAL2") facility = LOG_LOCAL2; else if (f == "LOG_LOCAL3") facility = LOG_LOCAL3; else if (f == "LOG_LOCAL4") facility = LOG_LOCAL4; else if (f == "LOG_LOCAL5") facility = LOG_LOCAL5; else if (f == "LOG_LOCAL6") facility = LOG_LOCAL6; else if (f == "LOG_LOCAL7") facility = LOG_LOCAL7; else facility = LOG_DAEMON; } auto device = new SyslogDevice(IODevice::IsEnabled | IODevice::FlushesOnEndl, "bincimap-up", LOG_NDELAY | LOG_PID, facility); ioFactory.addDevice(std::unique_ptr(device)); } // Now that we know the log type, we can flush. IOFactory::getLogger().setFlags(IODevice::FlushesOnEndl); IOFactory::getLogger().setOutputLevelLimit(IODevice::LogLevel::InfoLevel); // imaps (port 993) -- requires sslserver with option -e int stls = 0; if (Tools::getenv("SSL_SESSION_ID")) { session.command.ssl = true; stls = -1; // else we will do starttls - requires new FDs } else if (Tools::getenv("UCSPITLS")) { string ucspitls = session.getEnv("UCSPITLS"); if (ucspitls == "+") stls = 1; if (ucspitls == "-") stls = 0; if (ucspitls == "!") stls = 2; } BrokerFactory &brokerfactory = BrokerFactory::getInstance(); brokerfactory.assign("AUTHENTICATE", std::shared_ptr(new AuthenticateOperator())); brokerfactory.assign("CAPABILITY", std::shared_ptr(new CapabilityOperator())); brokerfactory.assign("LOGIN", std::shared_ptr(new LoginOperator())); brokerfactory.assign("LOGOUT", std::shared_ptr(new LogoutOperator())); brokerfactory.assign("NOOP", std::shared_ptr(new NoopOperator())); brokerfactory.assign("ID", std::shared_ptr(new IdOperator())); if (stls > 0) brokerfactory.assign("STARTTLS", std::shared_ptr(new StarttlsOperator())); bincClient.setTimeout(AUTH_TIMEOUT); session.setState(Session::NONAUTHENTICATED); // If the depot was not initialized properly, return false. return true; }