/** -------------------------------------------------------------------- * @file operator-login.cc * @brief Implementation of the rapid LOGIN command * @author Andreas Aardal Hanssen, Erwin Hoffmann * @date 2002-2005, 2023 * ----------------------------------------------------------------- **/ #include #include #include #include #include #include #include "authenticate.h" #include "depot.h" #include "iodevice.h" #include "iofactory.h" #include "globals.h" #include "operators.h" #include "recursivedescent.h" #include "session.h" using namespace ::std; using namespace Binc; //---------------------------------------------------------------------- LoginOperator::LoginOperator(void) { } //---------------------------------------------------------------------- LoginOperator::~LoginOperator(void) { } //---------------------------------------------------------------------- const string LoginOperator::getName(void) const { return "LOGIN"; } //---------------------------------------------------------------------- int LoginOperator::getState(void) const { return Session::NONAUTHENTICATED; } //------------------------------------------------------------------------ Operator::ProcessResult LoginOperator::process(Depot &depot, Request &command) { Session &session = Session::getInstance(); if (!session.command.ssl && !session.hasEnv("ALLOW_NONSSL_PLAINTEXT_LOGINS")) { session.setLastError("Plain text password authentication is disallowd. " "Please enable StartTLS or TLS in your mail client."); return NO; } session.setEnv("BINCIMAP_LOGIN", "LOGIN+" + command.getTag()); string challenge; switch (authenticate(depot, command.getUserID(), command.getPassword(), challenge)) { case 1: session.setLastError("An internal error occurred when you attempted " "to log in to the IMAP server. Please contact " "your system administrator."); return NO; case 2: session.setLastError("Login failed. Either your user name " "or your password was wrong. Please try again, " "and if the problem persists, please contact " "your system administrator."); return NO; case 3: bincClient << "* BYE Timeout after " << IDLE_TIMEOUT << " seconds of inactivity." << endl; break; case -1: bincClient << "* BYE The server died unexpectedly. Please contact " "your system administrator for more information." << endl; break; } // go to logout session.setState(Session::LOGOUT); return NOTHING; } //---------------------------------------------------------------------- Operator::ParseResult LoginOperator::parse(Request &c_in) const { Session &session = Session::getInstance(); if (c_in.getUidMode()) return REJECT; Operator::ParseResult res; if ((res = expectSPACE()) != ACCEPT) { session.setLastError("Expected single SPACE after LOGIN"); return res; } string userid; if ((res = expectAstring(userid)) != ACCEPT) { session.setLastError("Expected userid after LOGIN SPACE"); return res; } c_in.setUserID(userid); if ((res = expectSPACE()) != ACCEPT) { session.setLastError("Expected SPACE after LOGIN SPACE userid"); return res; } string password; if ((res = expectAstring(password)) != ACCEPT) { session.setLastError("Expected password after LOGIN " "SPACE userid SPACE"); return res; } if ((res = expectCRLF()) != ACCEPT) { session.setLastError("Expected CRLF after password"); return res; } c_in.setPassword(password); c_in.setName("LOGIN"); return ACCEPT; }