📄 telnet.cpp
字号:
m_iMode = CONFIG_MODE; break; } case TELOPT_OUTMRK: { // Telnet special chars// printf("output marking: %x %x\n", cData[iPos+1], cData[iPos+2]); m_cBuffer[0] = TELOPT_OUTMRK; m_cBuffer.SetSize(1); m_iMode = CONTROL_MODE; break; } case '\r': { // End of line sent: handle the corresponding data HandleLine(); // Send prompt for next line m_cStream << "\r\n" << m_strPrompt; break; } default: { HandleByte(cData[iPos]); break; } } // Go to next char in input iPos++; } } catch(E_Stream<C_Socket> e) { throw E_Telnet("Connection error", e); }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_TelnetSession::HandleLine(){ switch(m_iPhase) { case LOGIN_PHASE: { // Execute first login phase ExecLogin(); // Drop line since we don't have to remember login m_cCmdLine.DropLine(); break; } case PASSWD_PHASE: { // Check login ExecLogin(); // Drop line since we don't have to remember passwd m_cCmdLine.DropLine(); break; } default: { ASSERT(m_iPhase == COMMAND_PHASE); // Execute command ExecCommand(); // Start a new line m_cCmdLine.StartNewLine(); break; } }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_TelnetSession::HandleByte(byte bByte){ //printf("char: '%c' (%x)\n", bByte, bByte); switch(m_iMode) { case CONFIG_MODE: { ASSERT(m_cBuffer[0] == IAC); unsigned int iSize = m_cBuffer.GetSize(); m_cBuffer[iSize] = bByte; iSize++; m_cBuffer.SetSize(iSize); if(iSize == 3) { m_cStream << m_cOptions.Answer(m_cBuffer); m_cBuffer.SetSize(0); m_iMode = INTERACTIVE_MODE; } break; } case CONTROL_MODE: { ASSERT(m_cBuffer[0] == TELOPT_OUTMRK); unsigned int iSize = m_cBuffer.GetSize(); m_cBuffer[iSize] = bByte; iSize++; m_cBuffer.SetSize(iSize); if(iSize == 3) { m_cStream << m_cCmdLine.Edit(m_cBuffer); m_cBuffer.SetSize(0); m_iMode = INTERACTIVE_MODE; } break; } default: { ASSERT(m_iMode == INTERACTIVE_MODE); // Drop all characters before init is completed int iStatus = m_cOptions.GetOptionStatus(); if(iStatus == YES) { // Remote echo C_String cRemoteCmdLine = m_cCmdLine.Append(bByte); if(m_iPhase != PASSWD_PHASE) m_cStream << cRemoteCmdLine; } else if(iStatus == NO) throw E_Telnet("Client not supported"); //printf("char: %c\n", bByte); break; } }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_TelnetSession::ExecLogin(){ ASSERT(m_iPhase == LOGIN_PHASE || m_iPhase == PASSWD_PHASE); if(m_iPhase == LOGIN_PHASE) { // This is the login which has just been entered m_strLogin = m_cCmdLine.GetCmdLine(); m_strPrompt = PASSWD; m_iPhase = PASSWD_PHASE; } else { // Login has been entered before, this is the passwd C_String strPasswd = m_cCmdLine.GetCmdLine(); // Authentication (to do) int iRc = Authenticate(m_strLogin, strPasswd); if(!iRc) { m_strPrompt = m_strLogin + "@" + PROMPT; m_iPhase = COMMAND_PHASE; } else { m_strPrompt = LOGIN; m_iPhase = LOGIN_PHASE; } m_cStream << "\r\n"; }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_TelnetSession::ExecCommand(){ ASSERT(m_iPhase == COMMAND_PHASE); C_String strCmd = m_cCmdLine.GetCmdLine(); C_Request cRequest(""); C_Answer cAdminAnswer = m_pAdmin->ParseCmdLine(this, strCmd, cRequest); switch(cAdminAnswer.GetStatus()) { case ADMIN_WELLFORMED_COMMAND: if(cRequest.GetCmd() == "logout") { throw E_Telnet("logout requested"); } else { C_Answer cAnswer = m_pAdmin->HandleRequest(cRequest); SendAnswer(cAnswer); } break; case ADMIN_COMMAND_NOT_VALID: case ADMIN_UNKNOWN_COMMAND: case ADMIN_COMMAND_DENIED: SendAnswer(cAdminAnswer); break; case ADMIN_EMPTY_COMMAND: // Nothing to do break; default: ASSERT(false); break; }}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Send a C_Answer in human readable format//------------------------------------------------------------------------------void C_TelnetSession::SendAnswer(const C_Answer& cAnswer, const C_String& strPrefix){ if(cAnswer.GetProvider() != "") { m_cStream << "\r\n"; m_cStream << strPrefix + "Provider: " + cAnswer.GetProvider() + "\r\n"; int iStatus = cAnswer.GetStatus(); if(iStatus >= 0) m_cStream << strPrefix + "Status: " + iStatus + "\r\n"; else m_cStream << strPrefix + "Error: " + iStatus + "\r\n"; C_List<C_String> cMessageList = cAnswer.GetMessages(); unsigned int iSize = cMessageList.Size(); for(unsigned int i = 0; i < iSize; i++) { m_cStream << strPrefix + "Info: " + cMessageList[i] + "\r\n"; } C_List<C_Answer> cAnswerList = cAnswer.GetSubAnswers(); iSize = cAnswerList.Size(); for (unsigned int j = 0; j < iSize; j++) { SendAnswer(cAnswerList[j], strPrefix+" "); } }}/******************************************************************************** C_Telnet class********************************************************************************* *******************************************************************************///------------------------------------------------------------------------------// Constructor//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_Telnet::C_Telnet(handle hLog, C_Admin *pAdmin) : C_ConnectionsHandler<C_TelnetSession>(hLog, pAdmin){ ASSERT(hLog); ASSERT(pAdmin); m_hLog = hLog; m_pAdmin = pAdmin;}//------------------------------------------------------------------------------// Initialization//------------------------------------------------------------------------------int C_Telnet::Init(){ C_Application* pApp = C_Application::GetApp(); ASSERT(pApp); int iRc = NO_ERR; // Get config C_String strDomain = pApp->GetSetting("Telnet.Domain", "Inet4").ToLower(); int iDomain; C_String strDefaultHost; if(strDomain == "inet4") { iDomain = AF_INET; strDefaultHost = "0.0.0.0"; }#ifdef HAVE_IPV6 else if(strDomain == "inet6") { iDomain = AF_INET6; strDefaultHost = "0::0"; }#endif else { Log(m_hLog, LOG_ERROR, "Unknown domain:\n" + strDomain); iRc = GEN_ERR; } if(!iRc) { C_String strAddr = pApp->GetSetting("Telnet.LocalAddress", strDefaultHost); C_String strPort = pApp->GetSetting("Telnet.LocalPort", "9999"); // Init the socket try { C_ConnectionsHandler<C_TelnetSession>::Init(iDomain, strAddr, strPort); } catch(E_Exception e) { Log(m_hLog, LOG_ERROR, "Telnet server initialisation failed:\n" + e.Dump()); iRc = GEN_ERR; } } if(!iRc) Log(m_hLog, LOG_NOTE, "Telnet server initialised"); return iRc;}//------------------------------------------------------------------------------// Execution//------------------------------------------------------------------------------int C_Telnet::Run(){ int iRc = NO_ERR; try { C_ConnectionsHandler<C_TelnetSession>::Run(); } catch(E_Exception e) { iRc = GEN_ERR; Log(m_hLog, LOG_ERROR, "Telnet server launch failed:\n" + e.Dump()); } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Telnet::Stop(){ int iRc = NO_ERR; try { C_ConnectionsHandler<C_TelnetSession>::Stop(); } catch(E_Exception e) { Log(m_hLog, LOG_ERROR, "Could not stop telnet server:\n" + e.Dump()); iRc = GEN_ERR; } if(!iRc) Log(m_hLog, LOG_NOTE, "Telnet server stopped"); return iRc;}//------------------------------------------------------------------------------// Destruction//------------------------------------------------------------------------------int C_Telnet::Destroy(){ int iRc = NO_ERR; try { C_ConnectionsHandler<C_TelnetSession>::Destroy(); } catch(E_Exception e) { Log(m_hLog, LOG_ERROR, "Error during telnet server destruction:\n" + e.Dump()); iRc = GEN_ERR; } if(!iRc) Log(m_hLog, LOG_NOTE, "Telnet server destroyed"); return iRc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -