version 0.3.29
[fms.git] / src / nntp / nntpconnection.cpp
index d7eaa70..431c1e6 100644 (file)
@@ -1,26 +1,25 @@
 #include "../../include/nntp/nntpconnection.h"\r
 #include "../../include/nntp/uwildmat.h"\r
 #include "../../include/stringfunctions.h"\r
-#include "../../include/datetime.h"\r
 #include "../../include/boardlist.h"\r
 #include "../../include/message.h"\r
 #include "../../include/messagelist.h"\r
 #include "../../include/option.h"\r
+#include "../../include/nntp/extensiontrust.h"\r
+#include "../../include/threadwrapper/cancelablethread.h"\r
 \r
 #include <algorithm>\r
-\r
-//#include <zthread/Thread.h>\r
-#include "../../include/pthreadwrapper/thread.h"\r
+#include <Poco/DateTime.h>\r
+#include <Poco/DateTimeFormatter.h>\r
+#include <Poco/Timestamp.h>\r
 \r
 #ifdef XMEM\r
        #include <xmem.h>\r
 #endif\r
 \r
-NNTPConnection::NNTPConnection(SOCKET sock)\r
+NNTPConnection::NNTPConnection(SOCKET sock):m_socket(sock),m_status(0)\r
 {\r
-       std::string tempval;\r
 \r
-       m_socket=sock;\r
        m_tempbuffer.resize(32768);\r
        \r
        m_status.m_isposting=false;\r
@@ -28,12 +27,7 @@ NNTPConnection::NNTPConnection(SOCKET sock)
        m_status.m_boardid=-1;\r
        m_status.m_messageid=-1;\r
        m_status.m_mode=MODE_NONE;\r
-\r
-       Option::Instance()->Get("NNTPAllowPost",tempval);\r
-       if(tempval=="true")\r
-       {\r
-               m_status.m_allowpost=true;\r
-       }\r
+       m_status.m_authenticated=false;\r
 \r
 }\r
 \r
@@ -68,6 +62,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(m_db);\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 +126,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 +137,11 @@ 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("XFMSTRUST");\r
        SendBufferedLine(".");\r
        \r
        return true;\r
@@ -163,15 +217,185 @@ 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
+       if(command.m_command=="XGETTRUST")\r
+       {\r
+               return HandleGetTrustCommand(command);\r
+       }\r
+       if(command.m_command=="XSETTRUST")\r
+       {\r
+               return HandleSetTrustCommand(command);\r
+       }\r
+       if(command.m_command=="XGETTRUSTLIST")\r
+       {\r
+               return HandleGetTrustListCommand(command);\r
+       }\r
 \r
        return false;\r
 }\r
 \r
 const bool NNTPConnection::HandleDateCommand(const NNTPCommand &command)\r
 {\r
-       DateTime now;\r
-       now.SetToGMTime();\r
-       SendBufferedLine("111 "+now.Format("%Y%m%d%H%M%S"));\r
+       Poco::DateTime now;\r
+       SendBufferedLine("111 "+Poco::DateTimeFormatter::format(now,"%Y%m%d%H%M%S"));\r
+       return true;\r
+}\r
+\r
+const bool NNTPConnection::HandleGetTrustCommand(const NNTPCommand &command)\r
+{\r
+       if(command.m_arguments.size()>=2)\r
+       {\r
+               std::string type=command.m_arguments[0];\r
+               StringFunctions::UpperCase(type,type);\r
+               if(type=="MESSAGE" || type=="TRUSTLIST" || type=="PEERMESSAGE" || type=="PEERTRUSTLIST")\r
+               {\r
+                       if(m_status.m_authenticated)\r
+                       {\r
+                               bool found=false;\r
+                               int trust=-1;\r
+                               std::string nntpname="";\r
+                               for(int i=1; i<command.m_arguments.size(); i++)\r
+                               {\r
+                                       if(i!=1)\r
+                                       {\r
+                                               nntpname+=" ";\r
+                                       }\r
+                                       nntpname+=command.m_arguments[i];\r
+                               }\r
+\r
+                               TrustExtension tr(m_db,m_status.m_authuser.GetID());\r
+\r
+                               if(type=="MESSAGE")\r
+                               {\r
+                                       if(tr.GetMessageTrust(nntpname,trust))\r
+                                       {\r
+                                               found=true;\r
+                                       }\r
+                               }\r
+                               else if(type=="TRUSTLIST")\r
+                               {\r
+                                       if(tr.GetTrustListTrust(nntpname,trust))\r
+                                       {\r
+                                               found=true;\r
+                                       }\r
+                               }\r
+                               else if(type=="PEERMESSAGE")\r
+                               {\r
+                                       if(tr.GetPeerMessageTrust(nntpname,trust))\r
+                                       {\r
+                                               found=true;\r
+                                       }\r
+                               }\r
+                               else if(type=="PEERTRUSTLIST")\r
+                               {\r
+                                       if(tr.GetPeerTrustListTrust(nntpname,trust))\r
+                                       {\r
+                                               found=true;\r
+                                       }\r
+                               }\r
+\r
+                               if(trust>=0 && found)\r
+                               {\r
+                                       std::string truststr="";\r
+                                       StringFunctions::Convert(trust,truststr);\r
+                                       SendBufferedLine("280 "+truststr);\r
+                               }\r
+                               else if(found)\r
+                               {\r
+                                       SendBufferedLine("281 null");\r
+                               }\r
+                               else\r
+                               {\r
+                                       SendBufferedLine("480 Identity not found");\r
+                               }\r
+\r
+                       }\r
+                       else\r
+                       {\r
+                               SendBufferedLine("480 User not authenticated");\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       SendBufferedLine("501 Syntax error");\r
+               }\r
+       }\r
+       else\r
+       {\r
+               SendBufferedLine("501 Syntax error");\r
+       }\r
+       return true;\r
+}      \r
+\r
+const bool NNTPConnection::HandleGetTrustListCommand(const NNTPCommand &command)\r
+{\r
+       if(m_status.m_authenticated)\r
+       {\r
+               TrustExtension tr(m_db,m_status.m_authuser.GetID());\r
+               std::map<std::string,TrustExtension::trust> trustlist;\r
+               if(tr.GetTrustList(trustlist))\r
+               {\r
+                       SendBufferedLine("280 Trust list follows");\r
+                       for(std::map<std::string,TrustExtension::trust>::iterator i=trustlist.begin(); i!=trustlist.end(); i++)\r
+                       {\r
+                               std::ostringstream tempstr;\r
+                               tempstr << (*i).first << "\t";\r
+                               if((*i).second.m_localmessagetrust>-1)\r
+                               {\r
+                                       tempstr << (*i).second.m_localmessagetrust;\r
+                               } \r
+                               else\r
+                               {\r
+                                       tempstr << "null";\r
+                               }\r
+                               tempstr << "\t";\r
+                               if((*i).second.m_localtrustlisttrust>-1)\r
+                               {\r
+                                       tempstr << (*i).second.m_localtrustlisttrust;\r
+                               }\r
+                               else\r
+                               {\r
+                                       tempstr << "null";\r
+                               }\r
+                               tempstr << "\t";\r
+                               if((*i).second.m_peermessagetrust>-1)\r
+                               {\r
+                                       tempstr << (*i).second.m_peermessagetrust;\r
+                               }\r
+                               else\r
+                               {\r
+                                       tempstr << "null";\r
+                               }\r
+                               tempstr << "\t";\r
+                               if((*i).second.m_peertrustlisttrust>-1)\r
+                               {\r
+                                       tempstr << (*i).second.m_peertrustlisttrust;\r
+                               }\r
+                               else\r
+                               {\r
+                                       tempstr << "null";\r
+                               }\r
+                               tempstr << "\t";\r
+                               tempstr << (*i).second.m_messagetrustcomment;\r
+                               tempstr << "\t";\r
+                               tempstr << (*i).second.m_trustlisttrustcomment;\r
+\r
+                               SendBufferedLine(tempstr.str());\r
+                       }\r
+                       SendBufferedLine(".");\r
+               }\r
+               else\r
+               {\r
+                       SendBufferedLine("501 Syntax error");\r
+               }\r
+       }\r
+       else\r
+       {\r
+               SendBufferedLine("480 User not authenticated");\r
+       }\r
        return true;\r
 }\r
 \r
@@ -179,7 +403,7 @@ const bool NNTPConnection::HandleGroupCommand(const NNTPCommand &command)
 {\r
        if(command.m_arguments.size()==1)\r
        {\r
-               Board board;\r
+               Board board(m_db);\r
                if(board.Load(command.m_arguments[0])==true)\r
                {\r
                        std::ostringstream tempstr;\r
@@ -202,7 +426,7 @@ const bool NNTPConnection::HandleGroupCommand(const NNTPCommand &command)
        else\r
        {\r
                SendBufferedLine("501 Syntax error");\r
-               m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPConnection::HandleGroupCommand syntax error");\r
+               m_log->debug("NNTPConnection::HandleGroupCommand syntax error");\r
        }\r
 \r
        return true;\r
@@ -231,7 +455,7 @@ const bool NNTPConnection::HandleLastCommand(const NNTPCommand &command)
        {\r
                if(m_status.m_messageid!=-1)\r
                {\r
-                       Message mess;\r
+                       Message mess(m_db);\r
 \r
                        if(mess.LoadPrevious(m_status.m_messageid,m_status.m_boardid))\r
                        {\r
@@ -301,7 +525,7 @@ const bool NNTPConnection::HandleListCommand(const NNTPCommand &command)
        {\r
                bool show;\r
                std::ostringstream tempstr;\r
-               BoardList bl;\r
+               BoardList bl(m_db);\r
                bl.Load();\r
 \r
                SendBufferedLine("215 list of newsgroups follows");\r
@@ -317,7 +541,7 @@ const bool NNTPConnection::HandleListCommand(const NNTPCommand &command)
                                show=uwildmat((*i).GetBoardName().c_str(),arg2.c_str());\r
                        }\r
 \r
-                       if(show==true)\r
+                       if(show==true && (*i).GetSaveReceivedMessages()==true)\r
                        {\r
                                tempstr << (*i).GetBoardName() << " " << (*i).GetHighMessageID() << " " << (*i).GetLowMessageID() << " " << (m_status.m_allowpost ? "y" : "n");\r
                                SendBufferedLine(tempstr.str());\r
@@ -332,7 +556,7 @@ const bool NNTPConnection::HandleListCommand(const NNTPCommand &command)
        {\r
                bool show;\r
                std::ostringstream tempstr;\r
-               BoardList bl;\r
+               BoardList bl(m_db);\r
                bl.Load();\r
 \r
                SendBufferedLine("215 list of newsgroups follows");\r
@@ -348,7 +572,7 @@ const bool NNTPConnection::HandleListCommand(const NNTPCommand &command)
                                show=uwildmat((*i).GetBoardName().c_str(),arg2.c_str());\r
                        }\r
 \r
-                       if(show==true)\r
+                       if(show==true && (*i).GetSaveReceivedMessages()==true)\r
                        {\r
                                tempstr << (*i).GetBoardName() << "\t" << (*i).GetBoardDescription();\r
                                SendBufferedLine(tempstr.str());\r
@@ -375,7 +599,7 @@ const bool NNTPConnection::HandleListCommand(const NNTPCommand &command)
        {\r
                // unknown arg\r
                SendBufferedLine("501 Syntax error");\r
-               m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPConnection::HandleListCommand unhandled LIST variant");\r
+               m_log->debug("NNTPConnection::HandleListCommand unhandled LIST variant");\r
        }\r
 \r
        return true;\r
@@ -385,9 +609,8 @@ const bool NNTPConnection::HandleListGroupCommand(const NNTPCommand &command)
 {\r
 \r
        std::ostringstream tempstr;\r
-       Board board;\r
+       Board board(m_db);\r
        bool validgroup=false;\r
-       int tempint;\r
        int lownum=-1;\r
        int highnum=-1;\r
 \r
@@ -433,7 +656,7 @@ const bool NNTPConnection::HandleListGroupCommand(const NNTPCommand &command)
        {\r
                // unknown arg\r
                SendBufferedLine("501 Syntax error");\r
-               m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPConnection::HandleListGroupCommand unknown arguments");\r
+               m_log->debug("NNTPConnection::HandleListGroupCommand unknown arguments");\r
        }\r
 \r
        if(validgroup)\r
@@ -455,7 +678,7 @@ const bool NNTPConnection::HandleListGroupCommand(const NNTPCommand &command)
                tempstr << "211 " << board.GetMessageCount() << " " << board.GetLowMessageID() << " " << board.GetHighMessageID() << " " << board.GetBoardName();\r
                SendBufferedLine(tempstr.str());\r
 \r
-               MessageList ml;\r
+               MessageList ml(m_db);\r
                ml.LoadRange(lownum,highnum,board.GetBoardID());\r
 \r
                for(std::vector<Message>::iterator i=ml.begin(); i!=ml.end(); i++)\r
@@ -492,18 +715,18 @@ const bool NNTPConnection::HandleModeCommand(const NNTPCommand &command)
                                SendBufferedLine("201 Posting prohibited");\r
                        }\r
                        \r
-                       m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPConnection::HandleModeCommand set mode to reader");\r
+                       m_log->debug("NNTPConnection::HandleModeCommand set mode to reader");\r
                }\r
                else\r
                {\r
                        SendBufferedLine("501 Syntax error");\r
-                       m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPConnection::HandleModeCommand unknown MODE argument : "+arg);\r
+                       m_log->debug("NNTPConnection::HandleModeCommand unknown MODE argument : "+arg);\r
                }\r
        }\r
        else\r
        {\r
                SendBufferedLine("501 Syntax error");\r
-               m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPConnection::HandleModeCommand no argument supplied for MODE");     \r
+               m_log->debug("NNTPConnection::HandleModeCommand no argument supplied for MODE");        \r
        }\r
 \r
        return true;\r
@@ -513,16 +736,23 @@ const bool NNTPConnection::HandleNewGroupsCommand(const NNTPCommand &command)
 {\r
        if(command.m_arguments.size()>=2)\r
        {\r
-               DateTime date;\r
-               int tempint;\r
+               Poco::DateTime date;\r
+               int tempyear=0;\r
+               int tempmonth=0;\r
+               int tempday=0;\r
                if(command.m_arguments[0].size()==8)\r
                {\r
-                       StringFunctions::Convert(command.m_arguments[0].substr(0,4),tempint);\r
-                       date.SetYear(tempint);\r
-                       StringFunctions::Convert(command.m_arguments[0].substr(4,2),tempint);\r
-                       date.SetMonth(tempint);\r
-                       StringFunctions::Convert(command.m_arguments[0].substr(6,2),tempint);\r
-                       date.SetDay(tempint);\r
+                       StringFunctions::Convert(command.m_arguments[0].substr(0,4),tempyear);\r
+                       StringFunctions::Convert(command.m_arguments[0].substr(4,2),tempmonth);\r
+                       StringFunctions::Convert(command.m_arguments[0].substr(6,2),tempday);\r
+                       try\r
+                       {\r
+                               date.assign(tempyear,tempmonth,tempday,date.hour(),date.minute(),date.second());\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               m_log->fatal("NNTPConnection::HandleNewGroupsCommand error assigning date");\r
+                       }\r
                }\r
                else\r
                {\r
@@ -534,35 +764,40 @@ const bool NNTPConnection::HandleNewGroupsCommand(const NNTPCommand &command)
                        the current year, and the previous century otherwise.\r
                        */\r
                        int century;\r
-                       DateTime now;\r
-                       now.SetToGMTime();\r
-                       century=now.GetYear()-(now.GetYear()%100);\r
+                       Poco::DateTime now;\r
+                       century=now.year()-(now.year()%100);\r
 \r
-                       StringFunctions::Convert(command.m_arguments[0].substr(0,2),tempint);\r
-                       tempint<=now.GetYear()-century ? tempint+=century : tempint+=(century-100);\r
+                       StringFunctions::Convert(command.m_arguments[0].substr(0,2),tempyear);\r
+                       tempyear<=now.year()-century ? tempyear+=century : tempyear+=(century-100);\r
                        \r
                        //tempint > 50 ? tempint+=1900 : tempint+=2000;\r
                        \r
-                       date.SetYear(tempint);\r
-                       StringFunctions::Convert(command.m_arguments[0].substr(2,2),tempint);\r
-                       date.SetMonth(tempint);\r
-                       StringFunctions::Convert(command.m_arguments[0].substr(4,2),tempint);\r
-                       date.SetDay(tempint);\r
+                       StringFunctions::Convert(command.m_arguments[0].substr(2,2),tempmonth);\r
+                       StringFunctions::Convert(command.m_arguments[0].substr(4,2),tempday);\r
+                       try\r
+                       {\r
+                               date.assign(tempyear,tempmonth,tempday);\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               m_log->fatal("NNTPConnection::HandleNewGroupsCommand error assigning date");\r
+                       }\r
                }\r
 \r
-               date.Normalize();\r
-\r
-               BoardList bl;\r
+               BoardList bl(m_db);\r
 \r
-               bl.LoadNew(date.Format("%Y-%m-%d %H:%M:%S"));\r
+               bl.LoadNew(Poco::DateTimeFormatter::format(date,"%Y-%m-%d %H:%M:%S"));\r
 \r
                SendBufferedLine("231 List of new newsgroups follows");\r
 \r
                for(BoardList::iterator i=bl.begin(); i!=bl.end(); i++)\r
                {\r
-                       std::ostringstream tempstr;\r
-                       tempstr << (*i).GetBoardName() << " " << (*i).GetHighMessageID() << " " << (*i).GetLowMessageID() << " " << m_status.m_allowpost ? "y" : "n";\r
-                       SendBufferedLine(tempstr.str());\r
+                       if((*i).GetSaveReceivedMessages()==true)\r
+                       {\r
+                               std::ostringstream tempstr;\r
+                               tempstr << (*i).GetBoardName() << " " << (*i).GetHighMessageID() << " " << (*i).GetLowMessageID() << " " << m_status.m_allowpost ? "y" : "n";\r
+                               SendBufferedLine(tempstr.str());\r
+                       }\r
                }\r
 \r
                SendBufferedLine(".");\r
@@ -571,7 +806,7 @@ const bool NNTPConnection::HandleNewGroupsCommand(const NNTPCommand &command)
        else\r
        {\r
                SendBufferedLine("501 Syntax error");\r
-               m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPConnection::HandleNewGroupsCommand syntax error");\r
+               m_log->debug("NNTPConnection::HandleNewGroupsCommand syntax error");\r
        }\r
 \r
        return true;\r
@@ -584,7 +819,7 @@ const bool NNTPConnection::HandleNextCommand(const NNTPCommand &command)
        {\r
                if(m_status.m_messageid!=-1)\r
                {\r
-                       Message mess;\r
+                       Message mess(m_db);\r
 \r
                        if(mess.LoadNext(m_status.m_messageid,m_status.m_boardid))\r
                        {\r
@@ -636,11 +871,13 @@ const bool NNTPConnection::HandleOverCommand(const NNTPCommand &command)
                        messageuuid=command.m_arguments[0];\r
                        messageuuid=StringFunctions::Replace(messageuuid,"<","");\r
                        messageuuid=StringFunctions::Replace(messageuuid,">","");\r
+                       /*\r
                        // get rid of @ and everything after\r
                        if(messageuuid.find("@")!=std::string::npos)\r
                        {\r
                                messageuuid.erase(messageuuid.find("@"));\r
                        }\r
+                       */\r
                }\r
                // single article or range\r
                else\r
@@ -672,7 +909,7 @@ const bool NNTPConnection::HandleOverCommand(const NNTPCommand &command)
 \r
        if(messageuuid!="")\r
        {\r
-               Message mess;\r
+               Message mess(m_db);\r
                if(mess.Load(messageuuid))\r
                {\r
                        SendBufferedLine("224 Overview information follows");\r
@@ -686,13 +923,13 @@ const bool NNTPConnection::HandleOverCommand(const NNTPCommand &command)
        }\r
        else\r
        {\r
-               Board bd;\r
+               Board bd(m_db);\r
                if(m_status.m_boardid!=-1 && bd.Load(m_status.m_boardid))\r
                {\r
                        // single message\r
                        if(highmessageid==-2)\r
                        {\r
-                               Message mess;\r
+                               Message mess(m_db);\r
                                if(mess.Load(lowmessageid,m_status.m_boardid))\r
                                {\r
                                        SendBufferedLine("224 Overview information follows");\r
@@ -707,7 +944,7 @@ const bool NNTPConnection::HandleOverCommand(const NNTPCommand &command)
                        // range with no upper bound\r
                        else if(highmessageid==-1)\r
                        {\r
-                               MessageList ml;\r
+                               MessageList ml(m_db);\r
                                ml.LoadRange(lowmessageid,bd.GetHighMessageID(),m_status.m_boardid);\r
                                if(ml.size()>0)\r
                                {\r
@@ -726,7 +963,7 @@ const bool NNTPConnection::HandleOverCommand(const NNTPCommand &command)
                        // range with upper and lower bound\r
                        else if(highmessageid>=lowmessageid)\r
                        {\r
-                               MessageList ml;\r
+                               MessageList ml(m_db);\r
                                ml.LoadRange(lowmessageid,highmessageid,m_status.m_boardid);\r
                                if(ml.size()>0)\r
                                {\r
@@ -775,12 +1012,28 @@ const bool NNTPConnection::HandlePostCommand(const NNTPCommand &command)
 \r
 void NNTPConnection::HandlePostedMessage(const std::string &message)\r
 {\r
-       Message mess;\r
+       Message mess(m_db);\r
 \r
        if(mess.ParseNNTPMessage(message))\r
        {\r
-               mess.StartFreenetInsert();\r
-               SendBufferedLine("240 Article received OK");\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
+               }\r
+               if(mess.StartFreenetInsert())\r
+               {\r
+                       SendBufferedLine("240 Article received OK");\r
+               }\r
+               else\r
+               {\r
+                       SendBufferedLine("441 Posting failed.  Make sure the identity you are sending with exists!");\r
+               }\r
        }\r
        else\r
        {\r
@@ -824,7 +1077,7 @@ void NNTPConnection::HandleReceivedData()
                        {\r
                                SendBufferedLine("500 Unknown command");\r
 \r
-                               m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPConnection::HandleReceivedData received unhandled NNTP command : "+commandline);\r
+                               m_log->debug("NNTPConnection::HandleReceivedData received unhandled NNTP command : "+commandline);\r
                        }\r
 \r
                }\r
@@ -854,6 +1107,147 @@ void NNTPConnection::HandleReceivedData()
        }\r
 }\r
 \r
+const bool NNTPConnection::HandleSetTrustCommand(const NNTPCommand &command)\r
+{\r
+       if(command.m_arguments.size()>=3)\r
+       {\r
+               std::string type=command.m_arguments[0];\r
+               StringFunctions::UpperCase(type,type);\r
+               if(type=="MESSAGE" || type=="TRUSTLIST" || type=="MESSAGECOMMENT" || type=="TRUSTLISTCOMMENT")\r
+               {\r
+                       if(m_status.m_authenticated)\r
+                       {\r
+                               bool found=false;\r
+                               bool valid=false;\r
+                               int trust=-1;\r
+                               std::string comment="";\r
+                               std::string nntpname="";\r
+\r
+                               if(type=="MESSAGE" || type=="TRUSTLIST")\r
+                               {\r
+                                       for(int i=1; i<command.m_arguments.size()-1; i++)\r
+                                       {\r
+                                               if(i!=1)\r
+                                               {\r
+                                                       nntpname+=" ";\r
+                                               }\r
+                                               nntpname+=command.m_arguments[i];\r
+                                       }\r
+\r
+                                       if(command.m_arguments[command.m_arguments.size()-1]!="null")\r
+                                       {\r
+                                               StringFunctions::Convert(command.m_arguments[command.m_arguments.size()-1],trust);\r
+                                       }\r
+\r
+                                       if(trust>=-1 && trust<=100)\r
+                                       {\r
+                                               valid=true;\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       int startpos=-1;\r
+                                       // get nntpname\r
+                                       for(int i=1; i<command.m_arguments.size() && startpos==-1; i++)\r
+                                       {\r
+                                               if(command.m_arguments[i].size()>0 && command.m_arguments[i][0]!='\"')\r
+                                               {\r
+                                                       if(i!=1)\r
+                                                       {\r
+                                                               nntpname+=" ";\r
+                                                       }\r
+                                                       nntpname+=command.m_arguments[i];\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       startpos=i;\r
+                                               }\r
+                                       }\r
+\r
+                                       // get comment\r
+                                       for(int i=startpos; i<command.m_arguments.size(); i++)\r
+                                       {\r
+                                               if(i!=startpos)\r
+                                               {\r
+                                                       comment+=" ";\r
+                                               }\r
+                                               comment+=command.m_arguments[i];\r
+                                       }\r
+                                       // strip " from comment beginning and end\r
+                                       if(comment.size()>0 && comment[0]=='\"')\r
+                                       {\r
+                                               comment.erase(0,1);\r
+                                       }\r
+                                       if(comment.size()>0 && comment[comment.size()-1]=='\"')\r
+                                       {\r
+                                               comment.erase(comment.size()-1);\r
+                                       }\r
+\r
+                                       valid=true;\r
+                               }\r
+\r
+                               TrustExtension tr(m_db,m_status.m_authuser.GetID());\r
+\r
+                               if(type=="MESSAGE")\r
+                               {\r
+                                       if(tr.SetMessageTrust(nntpname,trust))\r
+                                       {\r
+                                               found=true;\r
+                                       }\r
+                               }\r
+                               if(type=="TRUSTLIST")\r
+                               {\r
+                                       if(tr.SetTrustListTrust(nntpname,trust))\r
+                                       {\r
+                                               found=true;\r
+                                       }\r
+                               }\r
+                               if(type=="MESSAGECOMMENT")\r
+                               {\r
+                                       if(tr.SetMessageTrustComment(nntpname,comment))\r
+                                       {\r
+                                               found=true;\r
+                                       }\r
+                               }\r
+                               if(type=="TRUSTLISTCOMMENT")\r
+                               {\r
+                                       if(tr.SetTrustListTrustComment(nntpname,comment))\r
+                                       {\r
+                                               found=true;\r
+                                       }\r
+                               }\r
+\r
+                               if(found && valid)\r
+                               {\r
+                                       SendBufferedLine("280 Trust Set");\r
+                               }\r
+                               else if(found==false)\r
+                               {\r
+                                       SendBufferedLine("480 Identity not found");\r
+                               }\r
+                               else\r
+                               {\r
+                                       SendBufferedLine("501 Syntax error");\r
+                               }\r
+\r
+                       }\r
+                       else\r
+                       {\r
+                               SendBufferedLine("480 User not authenticated");\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       SendBufferedLine("501 Syntax error");\r
+               }\r
+       }\r
+       else\r
+       {\r
+               SendBufferedLine("501 Syntax error");\r
+       }\r
+       return true;\r
+}\r
+\r
 const bool NNTPConnection::HandleStatCommand(const NNTPCommand &command)\r
 {\r
        SendArticleParts(command);\r
@@ -866,15 +1260,26 @@ const bool NNTPConnection::HandleQuitCommand(const NNTPCommand &command)
        SendBufferedLine("205 Connection Closing");\r
        SocketSend();\r
        Disconnect();\r
-       m_log->WriteLog(LogFile::LOGLEVEL_INFO,"NNTPConnection::HandleQuitCommand client closed connection");\r
+       m_log->information("NNTPConnection::HandleQuitCommand client closed connection");\r
        return true;\r
 }\r
 \r
-void NNTPConnection::Run()\r
+void NNTPConnection::run()\r
 {\r
        struct timeval tv;\r
        fd_set writefs,readfs;\r
        int rval;\r
+       std::string tempval("");\r
+\r
+       LoadDatabase();\r
+\r
+       m_status.m_authuser.SetDB(m_db);\r
+       Option option(m_db);\r
+       option.Get("NNTPAllowPost",tempval);\r
+       if(tempval=="true")\r
+       {\r
+               m_status.m_allowpost=true;\r
+       }\r
 \r
        // seed random number generater for this thread\r
        srand(time(NULL));\r
@@ -918,10 +1323,17 @@ void NNTPConnection::Run()
                }\r
                else if(rval==SOCKET_ERROR)\r
                {\r
-                       m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPConnection::run select returned -1 : "+GetSocketErrorMessage());   \r
+                       m_log->error("NNTPConnection::run select returned -1 : "+GetSocketErrorMessage());      \r
+               }\r
+\r
+               //process all remaining commands in buffer\r
+               std::vector<char>::size_type rbs=0;\r
+               while(rbs!=m_receivebuffer.size())\r
+               {\r
+                       rbs=m_receivebuffer.size();\r
+                       HandleReceivedData();\r
                }\r
 \r
-//     }while(!Disconnected() && !ZThread::Thread::interrupted());\r
        }while(!Disconnected() && !IsCancelled());\r
 \r
        Disconnect();\r
@@ -938,7 +1350,7 @@ void NNTPConnection::SendArticleOverInfo(Message &message)
        line=tempval+"\t";\r
        line+=message.GetSubject()+"\t";\r
        line+=message.GetFromName()+"\t";\r
-       line+=message.GetDateTime().Format("%a, %d %b %y %H:%M:%S -0000")+"\t";\r
+       line+=Poco::DateTimeFormatter::format(message.GetDateTime(),"%w, %d %b %y %H:%M:%S -0000")+"\t";\r
        line+=message.GetNNTPArticleID()+"\t";\r
        references=message.GetInReplyTo();\r
        if(references.size()>0)\r
@@ -949,7 +1361,7 @@ void NNTPConnection::SendArticleOverInfo(Message &message)
                        {\r
                                line+=" ";\r
                        }\r
-                       line+="<"+(*i).second+"@freenetproject.org>";\r
+                       line+="<"+(*i).second+">"; //+"@freenetproject.org>";\r
                }\r
                line+="\t";\r
        }\r
@@ -992,7 +1404,7 @@ void NNTPConnection::SendArticleParts(const NNTPConnection::NNTPCommand &command
                successcode="223";\r
        }\r
 \r
-       Message message;\r
+       Message message(m_db);\r
        int messageid=m_status.m_messageid;\r
        std::string articleid="";\r
        int type=0;     // default to current messageid, 1=messageid, 2=articleid\r
@@ -1009,6 +1421,21 @@ void NNTPConnection::SendArticleParts(const NNTPConnection::NNTPCommand &command
                else\r
                {\r
                        articleid=command.m_arguments[0];\r
+                       //strip off < and > and everthing after @\r
+                       if(articleid.size()>0 && articleid[0]=='<')\r
+                       {\r
+                               articleid.erase(0,1);\r
+                       }\r
+                       if(articleid.size()>0 && articleid[articleid.size()-1]=='>')\r
+                       {\r
+                               articleid.erase(articleid.size()-1);\r
+                       }\r
+                       /*\r
+                       if(articleid.size()>0 && articleid.find('@')!=std::string::npos)\r
+                       {\r
+                               articleid.erase(articleid.find('@'));\r
+                       }\r
+                       */\r
                        message.Load(articleid);\r
                        type=2;\r
                }\r
@@ -1168,7 +1595,7 @@ void NNTPConnection::SocketReceive()
        else if(rval==0)\r
        {\r
                Disconnect();\r
-               m_log->WriteLog(LogFile::LOGLEVEL_INFO,"NNTPConnection::SocketReceive remote host closed connection");\r
+               m_log->information("NNTPConnection::SocketReceive remote host closed connection");\r
        }\r
        else if(rval==-1)\r
        {\r
@@ -1176,7 +1603,7 @@ void NNTPConnection::SocketReceive()
                StringFunctions::Convert(GetSocketErrorNumber(),errnostr);\r
                // error on receive - close the connection\r
                Disconnect();\r
-               m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPConnection::SocketReceive recv returned -1 : "+errnostr+" - "+GetSocketErrorMessage());\r
+               m_log->error("NNTPConnection::SocketReceive recv returned -1 : "+errnostr+" - "+GetSocketErrorMessage());\r
        }\r
 }\r
 \r
@@ -1193,7 +1620,7 @@ void NNTPConnection::SocketSend()
                {\r
                        std::string errnostr;\r
                        StringFunctions::Convert(GetSocketErrorNumber(),errnostr);\r
-                       m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPConnection::SocketSend returned -1 : "+errnostr+" - "+GetSocketErrorMessage());\r
+                       m_log->error("NNTPConnection::SocketSend returned -1 : "+errnostr+" - "+GetSocketErrorMessage());\r
                }\r
        }\r
 }\r