X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fnntp%2Fnntpconnection.cpp;h=54d7c9417a463eb5af33d673b47ab5c1e3736f19;hb=7ddb1aeb0b3dc7384597e75f7b3557f2d8f6d14c;hp=ac75d4d310ffb0f931252a23b4f71ba3a950345a;hpb=868c533e84b3c81b6604b45b84efa32073aa20b4;p=fms.git diff --git a/src/nntp/nntpconnection.cpp b/src/nntp/nntpconnection.cpp index ac75d4d..54d7c94 100644 --- a/src/nntp/nntpconnection.cpp +++ b/src/nntp/nntpconnection.cpp @@ -6,8 +6,12 @@ #include "../../include/message.h" #include "../../include/messagelist.h" #include "../../include/option.h" +#include "../../include/nntp/extensiontrust.h" -#include +#include + +//#include +#include "../../include/pthreadwrapper/thread.h" #ifdef XMEM #include @@ -25,8 +29,9 @@ NNTPConnection::NNTPConnection(SOCKET sock) m_status.m_boardid=-1; m_status.m_messageid=-1; m_status.m_mode=MODE_NONE; + m_status.m_authenticated=false; - Option::instance()->Get("NNTPAllowPost",tempval); + Option::Instance()->Get("NNTPAllowPost",tempval); if(tempval=="true") { m_status.m_allowpost=true; @@ -65,6 +70,58 @@ const bool NNTPConnection::HandleArticleCommand(const NNTPCommand &command) return true; } +const bool NNTPConnection::HandleAuthInfoCommand(const NNTPCommand &command) +{ + if(command.m_arguments.size()<2) + { + SendBufferedLine("501 Syntax error"); + } + else if(m_status.m_authenticated==true) + { + SendBufferedLine("502 Command unavailable"); // not available when already authenticated + } + else + { + std::string arg=command.m_arguments[0]; + StringFunctions::UpperCase(arg,arg); + std::string name=""; + // get remaining args as part of the name since a name might have a space and the args are split on spaces + for(std::vector::const_iterator i=command.m_arguments.begin()+1; i!=command.m_arguments.end(); i++) + { + // we split on the space, so add it back + if(i!=command.m_arguments.begin()+1) + { + name+=" "; + } + name+=(*i); + } + if(arg=="USER") + { + LocalIdentity localid; + if(localid.Load(name)) + { + m_status.m_authuser=localid; + m_status.m_authenticated=true; + SendBufferedLine("281 Authentication accepted"); + } + else + { + SendBufferedLine("481 Authentication failed"); + } + } + else if(arg=="PASS") + { + SendBufferedLine("482 Authentication commands issued out of sequence"); // only require username + } + else + { + SendBufferedLine("501 Syntax error"); + } + } + + return true; +} + const bool NNTPConnection::HandleBodyCommand(const NNTPCommand &command) { SendArticleParts(command); @@ -77,7 +134,10 @@ const bool NNTPConnection::HandleCapabilitiesCommand(const NNTPCommand &command) SendBufferedLine("101 Capability list :"); SendBufferedLine("VERSION 2"); - SendBufferedLine("MODE-READER"); + if(m_status.m_authenticated==false) // RFC 4643 2.2 0 - don't advertise MODE-READER after authentication + { + SendBufferedLine("MODE-READER"); + } SendBufferedLine("READER"); SendBufferedLine("LIST OVERVIEW.FMT"); SendBufferedLine("OVER MSGID"); @@ -85,6 +145,11 @@ const bool NNTPConnection::HandleCapabilitiesCommand(const NNTPCommand &command) { SendBufferedLine("POST"); } + if(m_status.m_authenticated==false) + { + SendBufferedLine("AUTHINFO USER"); + } + SendBufferedLine("XFMSTRUST"); SendBufferedLine("."); return true; @@ -160,6 +225,22 @@ const bool NNTPConnection::HandleCommand(const NNTPCommand &command) { return HandleOverCommand(command); } + if(command.m_command=="AUTHINFO") + { + return HandleAuthInfoCommand(command); + } + if(command.m_command=="XGETTRUST") + { + return HandleGetTrustCommand(command); + } + if(command.m_command=="XSETTRUST") + { + return HandleSetTrustCommand(command); + } + if(command.m_command=="XGETTRUSTLIST") + { + return HandleGetTrustListCommand(command); + } return false; } @@ -172,6 +253,120 @@ const bool NNTPConnection::HandleDateCommand(const NNTPCommand &command) return true; } +const bool NNTPConnection::HandleGetTrustCommand(const NNTPCommand &command) +{ + if(command.m_arguments.size()>=2) + { + std::string type=command.m_arguments[0]; + StringFunctions::UpperCase(type,type); + if(type=="MESSAGE" || type=="TRUSTLIST") + { + if(m_status.m_authenticated) + { + bool found=false; + int trust=-1; + std::string nntpname=""; + for(int i=1; i=0 && found) + { + std::string truststr=""; + StringFunctions::Convert(trust,truststr); + SendBufferedLine("280 "+truststr); + } + else if(found) + { + SendBufferedLine("281 null"); + } + else + { + SendBufferedLine("480 Identity not found"); + } + + } + else + { + SendBufferedLine("480 User not authenticated"); + } + } + else + { + SendBufferedLine("501 Syntax error"); + } + } + else + { + SendBufferedLine("501 Syntax error"); + } + return true; +} + +const bool NNTPConnection::HandleGetTrustListCommand(const NNTPCommand &command) +{ + if(m_status.m_authenticated) + { + TrustExtension tr(m_status.m_authuser.GetID()); + std::map > trustlist; + if(tr.GetTrustList(trustlist)) + { + SendBufferedLine("280 Trust list follows"); + for(std::map >::iterator i=trustlist.begin(); i!=trustlist.end(); i++) + { + std::ostringstream tempstr; + tempstr << (*i).first << "\t"; + if((*i).second.first>-1) + { + tempstr << (*i).second.first; + } + else + { + tempstr << "null"; + } + tempstr << "\t"; + if((*i).second.second>-1) + { + tempstr << (*i).second.second; + } + else + { + tempstr << "null"; + } + SendBufferedLine(tempstr.str()); + } + SendBufferedLine("."); + } + else + { + SendBufferedLine("501 Syntax error"); + } + } + else + { + SendBufferedLine("480 User not authenticated"); + } + return true; +} + const bool NNTPConnection::HandleGroupCommand(const NNTPCommand &command) { if(command.m_arguments.size()==1) @@ -230,7 +425,7 @@ const bool NNTPConnection::HandleLastCommand(const NNTPCommand &command) { Message mess; - if(mess.Load(m_status.m_messageid,m_status.m_boardid)) + if(mess.LoadPrevious(m_status.m_messageid,m_status.m_boardid)) { std::ostringstream tempstr; @@ -314,9 +509,9 @@ const bool NNTPConnection::HandleListCommand(const NNTPCommand &command) show=uwildmat((*i).GetBoardName().c_str(),arg2.c_str()); } - if(show==true) + if(show==true && (*i).GetSaveReceivedMessages()==true) { - tempstr << (*i).GetBoardName() << "\t" << (*i).GetHighMessageID() << "\t" << (*i).GetLowMessageID() << "\t" << (m_status.m_allowpost ? "y" : "n"); + tempstr << (*i).GetBoardName() << " " << (*i).GetHighMessageID() << " " << (*i).GetLowMessageID() << " " << (m_status.m_allowpost ? "y" : "n"); SendBufferedLine(tempstr.str()); } } @@ -345,7 +540,7 @@ const bool NNTPConnection::HandleListCommand(const NNTPCommand &command) show=uwildmat((*i).GetBoardName().c_str(),arg2.c_str()); } - if(show==true) + if(show==true && (*i).GetSaveReceivedMessages()==true) { tempstr << (*i).GetBoardName() << "\t" << (*i).GetBoardDescription(); SendBufferedLine(tempstr.str()); @@ -384,7 +579,6 @@ const bool NNTPConnection::HandleListGroupCommand(const NNTPCommand &command) std::ostringstream tempstr; Board board; bool validgroup=false; - int tempint; int lownum=-1; int highnum=-1; @@ -557,9 +751,12 @@ const bool NNTPConnection::HandleNewGroupsCommand(const NNTPCommand &command) for(BoardList::iterator i=bl.begin(); i!=bl.end(); i++) { - std::ostringstream tempstr; - tempstr << (*i).GetBoardName() << " " << (*i).GetHighMessageID() << " " << (*i).GetLowMessageID() << " " << m_status.m_allowpost ? "y" : "n"; - SendBufferedLine(tempstr.str()); + if((*i).GetSaveReceivedMessages()==true) + { + std::ostringstream tempstr; + tempstr << (*i).GetBoardName() << " " << (*i).GetHighMessageID() << " " << (*i).GetLowMessageID() << " " << m_status.m_allowpost ? "y" : "n"; + SendBufferedLine(tempstr.str()); + } } SendBufferedLine("."); @@ -583,7 +780,7 @@ const bool NNTPConnection::HandleNextCommand(const NNTPCommand &command) { Message mess; - if(mess.Load(m_status.m_messageid,m_status.m_boardid)) + if(mess.LoadNext(m_status.m_messageid,m_status.m_boardid)) { std::ostringstream tempstr; @@ -633,6 +830,13 @@ const bool NNTPConnection::HandleOverCommand(const NNTPCommand &command) messageuuid=command.m_arguments[0]; messageuuid=StringFunctions::Replace(messageuuid,"<",""); messageuuid=StringFunctions::Replace(messageuuid,">",""); + /* + // get rid of @ and everything after + if(messageuuid.find("@")!=std::string::npos) + { + messageuuid.erase(messageuuid.find("@")); + } + */ } // single article or range else @@ -771,8 +975,24 @@ void NNTPConnection::HandlePostedMessage(const std::string &message) if(mess.ParseNNTPMessage(message)) { - mess.StartFreenetInsert(); - SendBufferedLine("240 Article received OK"); + // if we authenticated, set the username to the authenticated user + if(m_status.m_authenticated) + { + mess.SetFromName(m_status.m_authuser.GetName()); + } + // handle a messages posted to an adminboard + if(mess.PostedToAdministrationBoard()==true) + { + mess.HandleAdministrationMessage(); + } + if(mess.StartFreenetInsert()) + { + SendBufferedLine("240 Article received OK"); + } + else + { + SendBufferedLine("441 Posting failed. Make sure the identity you are sending with exists!"); + } } else { @@ -846,6 +1066,83 @@ void NNTPConnection::HandleReceivedData() } } +const bool NNTPConnection::HandleSetTrustCommand(const NNTPCommand &command) +{ + if(command.m_arguments.size()>=3) + { + std::string type=command.m_arguments[0]; + StringFunctions::UpperCase(type,type); + if(type=="MESSAGE" || type=="TRUSTLIST") + { + if(m_status.m_authenticated) + { + bool found=false; + bool valid=false; + int trust=-1; + std::string nntpname=""; + for(int i=1; i=-1 && trust<=100) + { + valid=true; + } + + TrustExtension tr(m_status.m_authuser.GetID()); + + if(type=="MESSAGE") + { + if(tr.SetMessageTrust(nntpname,trust)) + { + found=true; + } + } + if(type=="TRUSTLIST") + { + if(tr.SetTrustListTrust(nntpname,trust)) + { + found=true; + } + } + + if(found && valid) + { + SendBufferedLine("280 Trust Set"); + } + else if(found==false) + { + SendBufferedLine("480 Identity not found"); + } + else + { + SendBufferedLine("501 Syntax error"); + } + + } + else + { + SendBufferedLine("480 User not authenticated"); + } + } + else + { + SendBufferedLine("501 Syntax error"); + } + } + else + { + SendBufferedLine("501 Syntax error"); + } + return true; +} + const bool NNTPConnection::HandleStatCommand(const NNTPCommand &command) { SendArticleParts(command); @@ -862,7 +1159,7 @@ const bool NNTPConnection::HandleQuitCommand(const NNTPCommand &command) return true; } -void NNTPConnection::run() +void NNTPConnection::Run() { struct timeval tv; fd_set writefs,readfs; @@ -908,15 +1205,16 @@ void NNTPConnection::run() SocketSend(); } } - else if(rval==-1) + else if(rval==SOCKET_ERROR) { m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPConnection::run select returned -1 : "+GetSocketErrorMessage()); } - }while(!Disconnected() && !ZThread::Thread::interrupted()); - +// }while(!Disconnected() && !ZThread::Thread::interrupted()); + }while(!Disconnected() && !IsCancelled()); + Disconnect(); - + } void NNTPConnection::SendArticleOverInfo(Message &message) @@ -940,7 +1238,7 @@ void NNTPConnection::SendArticleOverInfo(Message &message) { line+=" "; } - line+="<"+(*i).second+">"; + line+="<"+(*i).second+">"; //+"@freenetproject.org>"; } line+="\t"; } @@ -1000,6 +1298,21 @@ void NNTPConnection::SendArticleParts(const NNTPConnection::NNTPCommand &command else { articleid=command.m_arguments[0]; + //strip off < and > and everthing after @ + if(articleid.size()>0 && articleid[0]=='<') + { + articleid.erase(0,1); + } + if(articleid.size()>0 && articleid[articleid.size()-1]=='>') + { + articleid.erase(articleid.size()-1); + } + /* + if(articleid.size()>0 && articleid.find('@')!=std::string::npos) + { + articleid.erase(articleid.find('@')); + } + */ message.Load(articleid); type=2; } @@ -1163,9 +1476,11 @@ void NNTPConnection::SocketReceive() } else if(rval==-1) { + std::string errnostr; + StringFunctions::Convert(GetSocketErrorNumber(),errnostr); // error on receive - close the connection Disconnect(); - m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPConnection::SocketReceive recv returned -1 : "+GetSocketErrorMessage()); + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPConnection::SocketReceive recv returned -1 : "+errnostr+" - "+GetSocketErrorMessage()); } } @@ -1180,7 +1495,9 @@ void NNTPConnection::SocketSend() } else if(rval==-1) { - m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPConnection::SocketSend returned -1 : "+GetSocketErrorMessage()); + std::string errnostr; + StringFunctions::Convert(GetSocketErrorNumber(),errnostr); + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPConnection::SocketSend returned -1 : "+errnostr+" - "+GetSocketErrorMessage()); } } }