version 0.2.9
authorSomeDude <SomeDude@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw>
Sat, 12 Apr 2008 09:18:00 +0000 (11:18 +0200)
committerDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Sat, 12 Apr 2008 09:18:00 +0000 (11:18 +0200)
CMakeLists.txt
include/global.h
include/localidentity.h [new file with mode: 0644]
include/message.h
include/nntp/nntpconnection.h
src/charsetconverter.cpp
src/global.cpp
src/localidentity.cpp [new file with mode: 0644]
src/message.cpp
src/nntp/nntpconnection.cpp
src/nntp/nntplistener.cpp

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