ConsoleSession's login flow never actually checked anything: the entered username was discarded and the password was never compared, so any input (including blank) reached the command prompt. Confirmed live via an unauthenticated login against BARANTMail's admin console on port 1027, which was reachable externally. ConsoleServer now takes an optional credentialChecker callback consulted by the WAIT_PASSWORD state; omitting it preserves the old accept-anything behavior for any other use of this class. Separately, the console never prompted until the client's first line arrived - that line was silently discarded just to kick the state machine off, shifting every subsequent line one slot early. Harmless under the old accept-anything login, but it broke real credential checking outright (the typed password was compared against the typed username, etc). ConsoleSession::onConnected() now starts the state machine immediately on connect instead. CommandList::processCommand() was a no-op stub - the intended "typing help lists the registered commands" body was commented out, and even referenced a Command::getName() that was never added to the base class. The map's own key from add() already is the registered name, so this just walks it directly.
66 lines
2.3 KiB
C++
66 lines
2.3 KiB
C++
#ifndef __ConsoleSession_h__
|
|
#define __ConsoleSession_h__
|
|
|
|
#include "TerminalSession.h"
|
|
//#include "TCPServer.h"
|
|
#include "CommandList.h"
|
|
|
|
namespace core {
|
|
|
|
class TCPServer;
|
|
|
|
///
|
|
/// ConsoleSession
|
|
///
|
|
/// Extends the session parameters for this TCPSocket derived object.
|
|
/// Extend the protocol() method in order to define the behavior and
|
|
/// protocol interaction for this socket which is a console session.
|
|
///
|
|
/// The User:/Password: exchange is a real login when the owning
|
|
/// ConsoleServer was constructed with a credentialChecker (see its
|
|
/// own doc comment) - previously the entered username was never
|
|
/// even stored and the password was never compared against
|
|
/// anything, so any input (including blank) reached the command
|
|
/// prompt. A ConsoleServer built without a credentialChecker still
|
|
/// accepts anything, matching that original behavior exactly.
|
|
///
|
|
|
|
class ConsoleSession : public TerminalSession {
|
|
|
|
public:
|
|
ConsoleSession(EPoll &ePoll, TCPServer *server);
|
|
~ConsoleSession();
|
|
|
|
void writeLog(std::string data);
|
|
|
|
protected:
|
|
void protocol(coreutils::ZString &data) override;
|
|
|
|
// Previously absent entirely, so the state machine only ever
|
|
// advanced on the CLIENT's first line of input - that line was
|
|
// consumed just to drive WELCOME->LOGIN and was never used as
|
|
// real content, meaning every subsequent line was shifted one
|
|
// slot early (what the user typed as their *username* actually
|
|
// got compared as nothing, their *password* got captured as
|
|
// enteredUser, and their first real command got compared as the
|
|
// password). Harmless before real credential checking existed -
|
|
// any input reached the prompt regardless - but it broke login
|
|
// outright once checkCredentials() started actually comparing
|
|
// values. Kicking the state machine off here instead means
|
|
// "User: " is sent immediately on connect, before the client
|
|
// has sent anything at all.
|
|
void onConnected() override;
|
|
|
|
private:
|
|
enum Status {WELCOME, LOGIN, WAIT_USER_PROFILE, PASSWORD, WAIT_PASSWORD, PROMPT, INPUT, PROCESS, DONE};
|
|
Status status = WELCOME;
|
|
void doCommand(coreutils::ZString &request);
|
|
coreutils::ZString command;
|
|
std::string enteredUser;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|