src/http/pages/peermaintenancepage.cpp\r
src/http/pages/peertrustpage.cpp\r
src/http/pages/showcaptchapage.cpp\r
+src/nntp/extensiontrust.cpp\r
src/nntp/nntpconnection.cpp\r
src/nntp/nntplistener.cpp\r
src/nntp/uwildmat.cpp\r
#include <vector>\r
#include "pthreadwrapper/thread.h"\r
\r
-#define FMS_VERSION "0.2.15"\r
+#define FMS_VERSION "0.2.16"\r
\r
// opens database and creates tables and initial inserts if necessary\r
void SetupDB();\r
--- /dev/null
+#ifndef _extension_trust_\r
+#define _extension_trust_\r
+\r
+#include "../idatabase.h"\r
+\r
+class TrustExtension:public IDatabase\r
+{\r
+public:\r
+ TrustExtension();\r
+ TrustExtension(const int &localidentityid);\r
+\r
+ void SetLocalIdentityID(const int id) { m_localidentityid=id; }\r
+\r
+ const bool GetMessageTrust(const std::string &nntpname, int &trust);\r
+ const bool GetTrustListTrust(const std::string &nntpname, int &trust);\r
+\r
+ const bool SetMessageTrust(const std::string &nntpname, const int trust);\r
+ const bool SetTrustListTrust(const std::string &nntpname, const int trust);\r
+\r
+ const bool GetTrustList(std::map<std::string,std::pair<int,int> > &trustlist);\r
+\r
+private:\r
+\r
+ const int GetIdentityID(const std::string &nntpname); // return -1 if not found\r
+\r
+ int m_localidentityid;\r
+\r
+};\r
+\r
+#endif // _extension_trust\r
const bool HandlePostCommand(const NNTPCommand &command);\r
const bool HandleOverCommand(const NNTPCommand &command);\r
const bool HandleAuthInfoCommand(const NNTPCommand &command);\r
+ const bool HandleGetTrustCommand(const NNTPCommand &command);\r
+ const bool HandleSetTrustCommand(const NNTPCommand &command);\r
+ const bool HandleGetTrustListCommand(const NNTPCommand &command);\r
\r
SOCKET m_socket;\r
ClientStatus m_status;\r
with NULL local message trust (the peer message trust must be NULL or >= your\r
configured minimum as well), but you will not download trust lists from\r
identities with NULL local trust list trust.\r
+\r
+NNTP EXTENSIONS\r
+---------------\r
+The following commands are available through the NNTP connection. The client\r
+must have authenticated for the commands to work.\r
+\r
+XSETTRUST MESSAGE userid@keypart val\r
+XSETTRUST TRUSTLIST userid@keypart val\r
+\r
+Responses:\r
+2xx Trust Set\r
+4xx Unknown ID or other error\r
+5xx Syntax error\r
+\r
+XGETTRUST MESSAGE userid@keypart\r
+XGETTRUST TRUSTLIST userid@keypart\r
+\r
+Responses:\r
+2xx val\r
+4xx Unknown ID or other error\r
+5xx Syntax error\r
+\r
+XGETTRUSTLIST\r
+messagetrust and trustlisttrust will be 0 to 100 or can be the string "null"\r
+without quotes.\r
+\r
+Responses:\r
+2xx Trust List Follows\r
+userid@keypart TAB messagetrust TAB trustlisttrust\r
+.\r
+4xx other error\r
<body>\r
\r
<div class="banner">\r
- FMS : Freenet Message System\r
+ FMS Site of [IDENTITYNAME]\r
</div>\r
\r
<div class="content_main">\r
sql="SELECT tblLocalIdentity.LocalIdentityID ";\r
sql+="FROM tblLocalIdentity INNER JOIN tblMessageInserts ON tblLocalIdentity.LocalIdentityID=tblMessageInserts.LocalIdentityID ";\r
sql+="WHERE tblMessageInserts.Day>=? AND ((tblLocalIdentity.LastInsertedMessageList<=? OR tblLocalIdentity.LastInsertedMessageList IS NULL OR tblLocalIdentity.LastInsertedMessageList='') OR tblLocalIdentity.LocalIdentityID IN (SELECT LocalIdentityID FROM tmpMessageListInsert)) ";\r
- sql+=";";\r
+ sql+="GROUP BY tblLocalIdentity.LocalIdentityID;";\r
\r
SQLite3DB::Statement st=m_db->Prepare(sql);\r
st.Bind(0,previous.Format("%Y-%m-%d"));\r
st.Finalize();\r
\r
\r
- st=m_db->Prepare("SELECT MessageDate, MessageIndex, PublicKey, MessageID FROM tblMessage INNER JOIN tblIdentity ON tblMessage.IdentityID=tblIdentity.IdentityID WHERE MessageIndex IS NOT NULL ORDER BY MessageDate DESC, MessageTime DESC LIMIT 100;");\r
+ st=m_db->Prepare("SELECT MessageDate, MessageIndex, PublicKey, MessageID FROM tblMessage INNER JOIN tblIdentity ON tblMessage.IdentityID=tblIdentity.IdentityID WHERE MessageIndex IS NOT NULL ORDER BY MessageDate DESC, MessageTime DESC LIMIT 200;");\r
SQLite3DB::Statement st2=m_db->Prepare("SELECT BoardName FROM tblBoard INNER JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID WHERE tblMessageBoard.MessageID=?;");\r
st.Step();\r
while(st.RowReturned())\r
}\r
StringFunctions::Convert(index,indexstr);\r
\r
- // actually insert message\r
xmlstr=mlxml.GetXML();\r
\r
// only insert if the last message this identity inserted is different than this message\r
if(m_lastinsertedxml[localidentityid]!=xmlstr)\r
{\r
+ std::string targeturi="";\r
StringFunctions::Convert(xmlstr.size(),xmlsizestr);\r
\r
message.SetName("ClientPut");\r
m_fcp->SendMessage(message);\r
m_fcp->SendRaw(xmlstr.c_str(),xmlstr.size());\r
\r
- m_inserting.push_back(localidentityid);\r
+ /*\r
+ // insert a USK redirect to the file we just inserted\r
+ targeturi=message["URI"];\r
+ message.Reset();\r
+ message.SetName("ClientPut");\r
+ message["URI"]="USK"+privatekey.substr(3)+m_messagebase+"|"+now.Format("%Y.%m.%d")+"|MessageList/0/MessageList.xml";\r
+ message["Identifier"]=message["URI"];\r
+ message["UploadFrom"]="redirect";\r
+ message["TargetURI"]=targeturi;\r
+ m_fcp->SendMessage(message);\r
+ */\r
+ message.Reset();\r
+ message.SetName("ClientPut");\r
+ message["URI"]="USK"+privatekey.substr(3)+m_messagebase+"|"+now.Format("%Y.%m.%d")+"|MessageList/0/MessageList.xml";\r
+ message["Identifier"]=message["URI"];\r
+ message["UploadFrom"]="direct";\r
+ message["DataLength"]=xmlsizestr;\r
+ m_fcp->SendMessage(message);\r
+ m_fcp->SendRaw(xmlstr.c_str(),xmlstr.size());\r
\r
+ m_inserting.push_back(localidentityid);\r
m_lastinsertedxml[localidentityid]=xmlstr;\r
+\r
return true;\r
}\r
else\r
{\r
std::string content="";\r
\r
- content="<h2>FMS site of "+SanitizeOutput(name)+"</h2>";\r
-\r
content+="<h3>My last few posts</h3>";\r
\r
SQLite3DB::Statement boardst=m_db->Prepare("SELECT tblBoard.BoardName FROM tblBoard INNER JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID WHERE tblMessageBoard.MessageID=? ORDER BY tblBoard.BoardName COLLATE NOCASE;");\r
st.Step();\r
}\r
\r
- return StringFunctions::Replace(htmltemplate,"[CONTENT]",content);\r
+ std::string output=StringFunctions::Replace(htmltemplate,"[CONTENT]",content);\r
+ return StringFunctions::Replace(output,"[IDENTITYNAME]",SanitizeOutput(name));\r
\r
}\r
\r
--- /dev/null
+#include "../../include/nntp/extensiontrust.h"\r
+#include "../../include/stringfunctions.h"\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+TrustExtension::TrustExtension()\r
+{\r
+ m_localidentityid=-1;\r
+}\r
+\r
+TrustExtension::TrustExtension(const int &localidentityid)\r
+{\r
+ m_localidentityid=localidentityid;\r
+}\r
+\r
+const int TrustExtension::GetIdentityID(const std::string &nntpname)\r
+{\r
+ std::vector<std::string> nameparts;\r
+ StringFunctions::Split(nntpname,"@",nameparts);\r
+\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT IdentityID, PublicKey FROM tblIdentity WHERE Name=? AND PublicKey IS NOT NULL AND PublicKey <> '' ;");\r
+ st.Bind(0,nameparts[0]);\r
+ st.Step();\r
+\r
+ while(st.RowReturned())\r
+ {\r
+ int id=-1;\r
+ std::vector<std::string> keyparts;\r
+ std::string publickey="";\r
+\r
+ st.ResultText(1,publickey);\r
+ StringFunctions::SplitMultiple(publickey,"@,",keyparts);\r
+\r
+ if(keyparts.size()>1)\r
+ {\r
+ publickey=StringFunctions::Replace(StringFunctions::Replace(keyparts[1],"~",""),"-","");\r
+ if(nameparts[0]+"@"+publickey==nntpname)\r
+ {\r
+ st.ResultInt(0,id);\r
+ return id;\r
+ }\r
+ }\r
+\r
+ st.Step();\r
+ }\r
+\r
+ return -1;\r
+\r
+}\r
+\r
+const bool TrustExtension::GetMessageTrust(const std::string &nntpname, int &trust)\r
+{\r
+ if(m_localidentityid>=0)\r
+ {\r
+ int id=GetIdentityID(nntpname);\r
+ if(id>=0)\r
+ {\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT LocalMessageTrust FROM tblIdentityTrust WHERE LocalIdentityID=? AND IdentityID=?;");\r
+ st.Bind(0,m_localidentityid);\r
+ st.Bind(1,id);\r
+ st.Step();\r
+\r
+ if(st.RowReturned())\r
+ {\r
+ int tr=-1;\r
+ if(st.ResultNull(0)==false)\r
+ {\r
+ st.ResultInt(0,tr);\r
+ }\r
+ trust=tr;\r
+ }\r
+ else\r
+ {\r
+ trust=-1;\r
+ }\r
+ return true;\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
+\r
+const bool TrustExtension::GetTrustList(std::map<std::string,std::pair<int,int> > &trustlist)\r
+{\r
+ if(m_localidentityid>=0)\r
+ {\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT tblIdentityTrust.LocalMessageTrust,tblIdentityTrust.LocalTrustListTrust,tblIdentity.Name,tblIdentity.PublicKey FROM tblIdentityTrust INNER JOIN tblIdentity ON tblIdentityTrust.IdentityID=tblIdentity.IdentityID WHERE tblIdentityTrust.LocalIdentityID=? AND tblIdentity.Name IS NOT NULL AND tblIdentity.PublicKey IS NOT NULL AND tblIdentity.PublicKey <> '' ;");\r
+ st.Bind(0,m_localidentityid);\r
+ st.Step();\r
+ while(st.RowReturned())\r
+ {\r
+ int messagetrust=-1;\r
+ int trustlisttrust=-1;\r
+ std::string name="";\r
+ std::string publickey="";\r
+ std::vector<std::string> keyparts;\r
+ std::string nntpname="";\r
+\r
+ if(st.ResultNull(0)==false)\r
+ {\r
+ st.ResultInt(0,messagetrust);\r
+ }\r
+ if(st.ResultNull(1)==false)\r
+ {\r
+ st.ResultInt(1,trustlisttrust);\r
+ }\r
+ st.ResultText(2,name);\r
+ st.ResultText(3,publickey);\r
+\r
+ StringFunctions::SplitMultiple(publickey,"@,",keyparts);\r
+ if(keyparts.size()>1)\r
+ {\r
+ publickey=StringFunctions::Replace(StringFunctions::Replace(keyparts[1],"~",""),"-","");\r
+ nntpname=name+"@"+publickey;\r
+ }\r
+\r
+ trustlist[nntpname]=std::pair<int,int>(messagetrust,trustlisttrust);\r
+\r
+ st.Step();\r
+ }\r
+ return true;\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
+\r
+const bool TrustExtension::GetTrustListTrust(const std::string &nntpname, int &trust)\r
+{\r
+ if(m_localidentityid>=0)\r
+ {\r
+ int id=GetIdentityID(nntpname);\r
+ if(id>=0)\r
+ {\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT LocalTrustListTrust FROM tblIdentityTrust WHERE LocalIdentityID=? AND IdentityID=?;");\r
+ st.Bind(0,m_localidentityid);\r
+ st.Bind(1,id);\r
+ st.Step();\r
+\r
+ if(st.RowReturned())\r
+ {\r
+ int tr=-1;\r
+ if(st.ResultNull(0)==false)\r
+ {\r
+ st.ResultInt(0,tr);\r
+ }\r
+ trust=tr;\r
+ }\r
+ else\r
+ {\r
+ trust=-1;\r
+ }\r
+ return true;\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
+\r
+const bool TrustExtension::SetMessageTrust(const std::string &nntpname, const int trust)\r
+{\r
+ if(m_localidentityid>=0 && trust>=-1 && trust<=100)\r
+ {\r
+ int id=GetIdentityID(nntpname);\r
+ if(id>=0)\r
+ {\r
+ SQLite3DB::Statement st=m_db->Prepare("UPDATE tblIdentityTrust SET LocalMessageTrust=? WHERE LocalIdentityID=? AND IdentityID=?;");\r
+ if(trust==-1)\r
+ {\r
+ st.Bind(0);\r
+ }\r
+ else\r
+ {\r
+ st.Bind(0,trust);\r
+ }\r
+ st.Bind(1,m_localidentityid);\r
+ st.Bind(2,id);\r
+ st.Step();\r
+\r
+ return true;\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
+\r
+const bool TrustExtension::SetTrustListTrust(const std::string &nntpname, const int trust)\r
+{\r
+ if(m_localidentityid>=0 && trust>=-1 && trust<=100)\r
+ {\r
+ int id=GetIdentityID(nntpname);\r
+ if(id>=0)\r
+ {\r
+ SQLite3DB::Statement st=m_db->Prepare("UPDATE tblIdentityTrust SET LocalTrustListTrust=? WHERE LocalIdentityID=? AND IdentityID=?;");\r
+ if(trust==-1)\r
+ {\r
+ st.Bind(0);\r
+ }\r
+ else\r
+ {\r
+ st.Bind(0,trust);\r
+ }\r
+ st.Bind(1,m_localidentityid);\r
+ st.Bind(2,id);\r
+ st.Step();\r
+\r
+ return true;\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
#include "../../include/message.h"\r
#include "../../include/messagelist.h"\r
#include "../../include/option.h"\r
+#include "../../include/nntp/extensiontrust.h"\r
\r
#include <algorithm>\r
\r
{\r
SendBufferedLine("AUTHINFO USER");\r
}\r
+ SendBufferedLine("XFMSTRUST");\r
SendBufferedLine(".");\r
\r
return true;\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
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")\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
+ nntpname+=command.m_arguments[i];\r
+ }\r
+\r
+ TrustExtension tr(m_status.m_authuser.GetID());\r
+\r
+ if(type=="MESSAGE")\r
+ {\r
+ if(tr.GetMessageTrust(nntpname,trust))\r
+ {\r
+ found=true;\r
+ }\r
+ }\r
+ if(type=="TRUSTLIST")\r
+ {\r
+ if(tr.GetTrustListTrust(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_status.m_authuser.GetID());\r
+ std::map<std::string,std::pair<int,int> > trustlist;\r
+ if(tr.GetTrustList(trustlist))\r
+ {\r
+ SendBufferedLine("280 Trust list follows");\r
+ for(std::map<std::string,std::pair<int,int> >::iterator i=trustlist.begin(); i!=trustlist.end(); i++)\r
+ {\r
+ std::ostringstream tempstr;\r
+ tempstr << (*i).first << "\t";\r
+ if((*i).second.first>-1)\r
+ {\r
+ tempstr << (*i).second.first;\r
+ } \r
+ else\r
+ {\r
+ tempstr << "null";\r
+ }\r
+ tempstr << "\t";\r
+ if((*i).second.second>-1)\r
+ {\r
+ tempstr << (*i).second.second;\r
+ }\r
+ else\r
+ {\r
+ tempstr << "null";\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
const bool NNTPConnection::HandleGroupCommand(const NNTPCommand &command)\r
{\r
if(command.m_arguments.size()==1)\r
}\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")\r
+ {\r
+ if(m_status.m_authenticated)\r
+ {\r
+ bool found=false;\r
+ bool valid=false;\r
+ int trust=-1;\r
+ std::string nntpname="";\r
+ for(int i=1; i<command.m_arguments.size()-1; i++)\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
+ TrustExtension tr(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
+\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