From: SomeDude Date: Sat, 12 Apr 2008 09:18:00 +0000 (+0200) Subject: version 0.2.9 X-Git-Url: https://git.pterodactylus.net/?p=fms.git;a=commitdiff_plain;h=0574a75431d98ed64c5cc6291600bb3759b399a6 version 0.2.9 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 742bfc2..3758251 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ src/commandthread.cpp src/datetime.cpp src/global.cpp src/hex.cpp +src/localidentity.cpp src/logfile.cpp src/main.cpp src/message.cpp diff --git a/include/global.h b/include/global.h index c5f7325..a220145 100644 --- a/include/global.h +++ b/include/global.h @@ -5,7 +5,7 @@ #include #include "pthreadwrapper/thread.h" -#define FMS_VERSION "0.2.8" +#define FMS_VERSION "0.2.9" // opens database and creates tables and initial inserts if necessary void SetupDB(); diff --git a/include/localidentity.h b/include/localidentity.h new file mode 100644 index 0000000..4a0598e --- /dev/null +++ b/include/localidentity.h @@ -0,0 +1,28 @@ +#ifndef _localidentity_ +#define _localidentity_ + +#include "idatabase.h" + +class LocalIdentity:public IDatabase +{ +public: + LocalIdentity(); + + const bool Load(const int id); + const bool Load(const std::string &name); + + const int GetID() const { return m_id; } + const std::string GetName() const { return m_name; } + const std::string GetPublicKey() const { return m_publickey; } + const std::string GetPrivateKey() const { return m_privatekey; } + +private: + void Initialize(); + + int m_id; + std::string m_name; + std::string m_publickey; + std::string m_privatekey; +}; + +#endif // _localidentity_ diff --git a/include/message.h b/include/message.h index eda6752..5aed3ed 100644 --- a/include/message.h +++ b/include/message.h @@ -22,6 +22,8 @@ public: std::vector GetBoards() const { return m_boards; } std::map GetInReplyTo() const { return m_inreplyto; } + void SetFromName(const std::string &fromname) { m_fromname=fromname; } + const std::string GetNNTPHeaders() const; const std::string GetNNTPArticleID() const; const std::string GetNNTPBody() const; diff --git a/include/nntp/nntpconnection.h b/include/nntp/nntpconnection.h index 64a1645..e31fd1b 100644 --- a/include/nntp/nntpconnection.h +++ b/include/nntp/nntpconnection.h @@ -4,6 +4,7 @@ #include "../socketdefines.h" #include "../ilogger.h" #include "../message.h" +#include "../localidentity.h" #include #include @@ -51,6 +52,8 @@ private: bool m_isposting; long m_boardid; long m_messageid; + LocalIdentity m_authuser; // -1 if user not authenticated, otherwise id of user from tblLocalIdentity + bool m_authenticated; }; void SendBuffered(const std::string &data); @@ -83,6 +86,7 @@ private: const bool HandleNewGroupsCommand(const NNTPCommand &command); const bool HandlePostCommand(const NNTPCommand &command); const bool HandleOverCommand(const NNTPCommand &command); + const bool HandleAuthInfoCommand(const NNTPCommand &command); SOCKET m_socket; ClientStatus m_status; diff --git a/src/charsetconverter.cpp b/src/charsetconverter.cpp index f6f73d4..97ba594 100644 --- a/src/charsetconverter.cpp +++ b/src/charsetconverter.cpp @@ -48,7 +48,7 @@ const bool CharsetConverter::Convert(const std::string &input, std::string &outp { std::vector invec(input.begin(),input.end()); std::vector outvec(invec.size()*4,0); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__APPLE__) || defined(__DARWIN__) const char *inptr=&invec[0]; #else char *inptr=&invec[0]; diff --git a/src/global.cpp b/src/global.cpp index d145a54..587f141 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -472,6 +472,9 @@ void SetupDB() // TODO remove sometime after 0.1.17 FixCapitalBoardNames(); + // run analyze - may speed up some queries + db->Execute("ANALYZE;"); + } void ConvertDB0100To0101() diff --git a/src/localidentity.cpp b/src/localidentity.cpp new file mode 100644 index 0000000..35843a3 --- /dev/null +++ b/src/localidentity.cpp @@ -0,0 +1,60 @@ +#include "../include/localidentity.h" + +#ifdef XMEM + #include +#endif + +LocalIdentity::LocalIdentity() +{ + Initialize(); +} + +void LocalIdentity::Initialize() +{ + m_id=-1; + m_name=""; + m_publickey=""; + m_privatekey=""; +} + +const bool LocalIdentity::Load(const int id) +{ + + Initialize(); + + SQLite3DB::Statement st=m_db->Prepare("SELECT LocalIdentityID,Name,PublicKey,PrivateKey FROM tblLocalIdentity WHERE LocalIdentityID=?;"); + st.Bind(0,id); + st.Step(); + if(st.RowReturned()) + { + st.ResultInt(0,m_id); + st.ResultText(1,m_name); + st.ResultText(2,m_publickey); + st.ResultText(3,m_privatekey); + return true; + } + else + { + return false; + } + +} + +const bool LocalIdentity::Load(const std::string &name) +{ + Initialize(); + + SQLite3DB::Statement st=m_db->Prepare("SELECT LocalIdentityID FROM tblLocalIdentity WHERE Name=?;"); + st.Bind(0,name); + st.Step(); + if(st.RowReturned()) + { + int id=-1; + st.ResultInt(0,id); + return Load(id); + } + else + { + return false; + } +} \ No newline at end of file diff --git a/src/message.cpp b/src/message.cpp index 8582146..4bc8cb6 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -747,6 +747,10 @@ void Message::StripAdministrationBoards() st.Step(); if(st.RowReturned()) { + if(m_replyboardname==(*i)) + { + m_replyboardname=""; + } i=m_boards.erase(i); } else @@ -755,4 +759,8 @@ void Message::StripAdministrationBoards() } st.Reset(); } + if(m_replyboardname=="" && m_boards.begin()!=m_boards.end()) + { + m_replyboardname=(*m_boards.begin()); + } } diff --git a/src/nntp/nntpconnection.cpp b/src/nntp/nntpconnection.cpp index cc5cffe..b3eeecc 100644 --- a/src/nntp/nntpconnection.cpp +++ b/src/nntp/nntpconnection.cpp @@ -28,6 +28,7 @@ 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); if(tempval=="true") @@ -68,6 +69,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); @@ -80,7 +133,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"); @@ -88,6 +144,10 @@ const bool NNTPConnection::HandleCapabilitiesCommand(const NNTPCommand &command) { SendBufferedLine("POST"); } + if(m_status.m_authenticated==false) + { + SendBufferedLine("AUTHINFO USER"); + } SendBufferedLine("."); return true; @@ -163,6 +223,10 @@ const bool NNTPConnection::HandleCommand(const NNTPCommand &command) { return HandleOverCommand(command); } + if(command.m_command=="AUTHINFO") + { + return HandleAuthInfoCommand(command); + } return false; } @@ -783,6 +847,12 @@ void NNTPConnection::HandlePostedMessage(const std::string &message) if(mess.ParseNNTPMessage(message)) { + // 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(); diff --git a/src/nntp/nntplistener.cpp b/src/nntp/nntplistener.cpp index 7f6e469..01fa442 100644 --- a/src/nntp/nntplistener.cpp +++ b/src/nntp/nntplistener.cpp @@ -184,6 +184,10 @@ void NNTPListener::StartListen() sock=socket(current->ai_family,current->ai_socktype,current->ai_protocol); if(sock!=INVALID_SOCKET) { + #ifndef _WIN32 + const char optval='1'; + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&optval,1); + #endif if(bind(sock,current->ai_addr,current->ai_addrlen)==0) { if(listen(sock,10)==0)