/** -------------------------------------------------------------------- * @file bincimapd-capability.cc * @brief Implementation of the CAPABILITY command * @author Andreas Aardal Hanssen, Erwin Hoffmann * @date 2002-2005, 2023 * ----------------------------------------------------------------- **/ #include #include "depot.h" #include "iodevice.h" #include "iofactory.h" #include "operators.h" #include "recursivedescent.h" #include "session.h" #include "globals.h" using namespace ::std; using namespace Binc; //---------------------------------------------------------------------- CapabilityOperator::CapabilityOperator(void) { } //---------------------------------------------------------------------- CapabilityOperator::~CapabilityOperator(void) { } //---------------------------------------------------------------------- const string CapabilityOperator::getName(void) const { return "CAPABILITY"; } //---------------------------------------------------------------------- int CapabilityOperator::getState(void) const { return Session::NONAUTHENTICATED | Session::AUTHENTICATED | Session::SELECTED; } //---------------------------------------------------------------------- void CapabilityOperator::addCapability(const string &cap) { capabilities.push_back(cap); } //---------------------------------------------------------------------- Operator::ProcessResult CapabilityOperator::process(Depot &depot, Request &command) { Session &session = Session::getInstance(); bincClient << "* CAPABILITY " << IMAP_VERSION ; if (session.getState() == Session::NONAUTHENTICATED) { if (getenv("UCSPITLS")) if (!session.command.ssl) bincClient << " STARTTLS"; const string authmethods = session.getEnv("BINCIMAP_LOGIN"); auto cram = authmethods.find("+CRAM-MD5"); if (session.command.ssl || session.hasEnv("ALLOW_NONSSL_PLAINTEXT_LOGINS")) { if (cram != string::npos) bincClient << " AUTH=LOGIN AUTH=PLAIN AUTH=CRAM-MD5"; else bincClient << " AUTH=LOGIN AUTH=PLAIN"; } else bincClient << " LOGINDISABLED"; } bincClient << " IDLE LITERAL+ NAMESPACE CHILDREN"; vector::const_iterator i = capabilities.begin(); while (i != capabilities.end()) { bincClient << " " << *i; ++i; } bincClient << endl; return OK; } //---------------------------------------------------------------------- Operator::ParseResult CapabilityOperator::parse(Request &c_in) const { Session &session = Session::getInstance(); if (c_in.getUidMode()) return REJECT; Operator::ParseResult res; if ((res = expectCRLF()) != ACCEPT) { session.setLastError("Expected CRLF after CAPABILITY"); return res; } c_in.setName("CAPABILITY"); return ACCEPT; }