version 0.2.9
[fms.git] / src / nntp / nntpconnection.cpp
index cc5cffe..b3eeecc 100644 (file)
@@ -28,6 +28,7 @@ NNTPConnection::NNTPConnection(SOCKET sock)
        m_status.m_boardid=-1;\r
        m_status.m_messageid=-1;\r
        m_status.m_mode=MODE_NONE;\r
+       m_status.m_authenticated=false;\r
 \r
        Option::Instance()->Get("NNTPAllowPost",tempval);\r
        if(tempval=="true")\r
@@ -68,6 +69,58 @@ const bool NNTPConnection::HandleArticleCommand(const NNTPCommand &command)
        return true;\r
 }\r
 \r
+const bool NNTPConnection::HandleAuthInfoCommand(const NNTPCommand &command)\r
+{\r
+       if(command.m_arguments.size()<2)\r
+       {\r
+               SendBufferedLine("501 Syntax error");\r
+       }\r
+       else if(m_status.m_authenticated==true)\r
+       {\r
+               SendBufferedLine("502 Command unavailable");            // not available when already authenticated\r
+       }\r
+       else\r
+       {\r
+               std::string arg=command.m_arguments[0];\r
+               StringFunctions::UpperCase(arg,arg);\r
+               std::string name="";\r
+               // get remaining args as part of the name since a name might have a space and the args are split on spaces\r
+               for(std::vector<std::string>::const_iterator i=command.m_arguments.begin()+1; i!=command.m_arguments.end(); i++)\r
+               {\r
+                       // we split on the space, so add it back\r
+                       if(i!=command.m_arguments.begin()+1)\r
+                       {\r
+                               name+=" ";\r
+                       }       \r
+                       name+=(*i);\r
+               }\r
+               if(arg=="USER")\r
+               {\r
+                       LocalIdentity localid;\r
+                       if(localid.Load(name))\r
+                       {\r
+                               m_status.m_authuser=localid;\r
+                               m_status.m_authenticated=true;\r
+                               SendBufferedLine("281 Authentication accepted");\r
+                       }\r
+                       else\r
+                       {\r
+                               SendBufferedLine("481 Authentication failed");\r
+                       }\r
+               }\r
+               else if(arg=="PASS")\r
+               {\r
+                       SendBufferedLine("482 Authentication commands issued out of sequence"); // only require username\r
+               }\r
+               else\r
+               {\r
+                       SendBufferedLine("501 Syntax error");\r
+               }\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
 const bool NNTPConnection::HandleBodyCommand(const NNTPCommand &command)\r
 {\r
        SendArticleParts(command);\r
@@ -80,7 +133,10 @@ const bool NNTPConnection::HandleCapabilitiesCommand(const NNTPCommand &command)
        \r
        SendBufferedLine("101 Capability list :");\r
        SendBufferedLine("VERSION 2");\r
-       SendBufferedLine("MODE-READER");\r
+       if(m_status.m_authenticated==false)             // RFC 4643 2.2 0 - don't advertise MODE-READER after authentication\r
+       {\r
+               SendBufferedLine("MODE-READER");\r
+       }\r
        SendBufferedLine("READER");\r
        SendBufferedLine("LIST OVERVIEW.FMT");\r
        SendBufferedLine("OVER MSGID");\r
@@ -88,6 +144,10 @@ const bool NNTPConnection::HandleCapabilitiesCommand(const NNTPCommand &command)
        {\r
                SendBufferedLine("POST");\r
        }\r
+       if(m_status.m_authenticated==false)\r
+       {\r
+               SendBufferedLine("AUTHINFO USER");\r
+       }\r
        SendBufferedLine(".");\r
        \r
        return true;\r
@@ -163,6 +223,10 @@ const bool NNTPConnection::HandleCommand(const NNTPCommand &command)
        {\r
                return HandleOverCommand(command);\r
        }\r
+       if(command.m_command=="AUTHINFO")\r
+       {\r
+               return HandleAuthInfoCommand(command);\r
+       }\r
 \r
        return false;\r
 }\r
@@ -783,6 +847,12 @@ void NNTPConnection::HandlePostedMessage(const std::string &message)
 \r
        if(mess.ParseNNTPMessage(message))\r
        {\r
+               // if we authenticated, set the username to the authenticated user\r
+               if(m_status.m_authenticated)\r
+               {\r
+                       mess.SetFromName(m_status.m_authuser.GetName());\r
+               }\r
+               // handle a messages posted to an adminboard\r
                if(mess.PostedToAdministrationBoard()==true)\r
                {\r
                        mess.HandleAdministrationMessage();\r