version 0.3.28
[fms.git] / src / freenet / identityintroductioninserter.cpp
1 #include "../../include/freenet/identityintroductioninserter.h"\r
2 #include "../../include/freenet/identityintroductionxml.h"\r
3 #include "../../include/stringfunctions.h"\r
4 #include "../../include/hex.h"\r
5 #include "../../include/option.h"\r
6 \r
7 #include <Poco/SHA1Engine.h>\r
8 \r
9 #ifdef XMEM\r
10         #include <xmem.h>\r
11 #endif\r
12 \r
13 IdentityIntroductionInserter::IdentityIntroductionInserter()\r
14 {\r
15         Initialize();\r
16 }\r
17 \r
18 IdentityIntroductionInserter::IdentityIntroductionInserter(FCPv2::Connection *fcp):IFCPConnected(fcp)\r
19 {\r
20         Initialize();\r
21 }\r
22 \r
23 void IdentityIntroductionInserter::CheckForNewInserts()\r
24 {\r
25         SQLite3DB::Recordset rs=m_db->Query("SELECT LocalIdentityID, Day, UUID, Solution FROM tblIdentityIntroductionInserts WHERE Inserted='false';");\r
26         if(!rs.Empty())\r
27         {\r
28                 if(rs.GetField(0) && rs.GetField(1) && rs.GetField(2))\r
29                 {\r
30                         StartInsert(rs.GetInt(0),rs.GetField(1),rs.GetField(2),rs.GetField(3));\r
31                 }\r
32         }\r
33 }\r
34 \r
35 void IdentityIntroductionInserter::FCPConnected()\r
36 {\r
37         m_inserting=false;\r
38 }\r
39 \r
40 void IdentityIntroductionInserter::FCPDisconnected()\r
41 {\r
42 \r
43 }\r
44 \r
45 const bool IdentityIntroductionInserter::HandleMessage(FCPv2::Message &message)\r
46 {\r
47 \r
48         if(message["Identifier"].find("IdentityIntroductionInserter")==0)\r
49         {\r
50                 std::vector<std::string> idparts;\r
51                 StringFunctions::Split(message["Identifier"],"|",idparts);\r
52                 \r
53                 // no action for URIGenerated\r
54                 if(message.GetName()=="URIGenerated")\r
55                 {\r
56                         return true;\r
57                 }\r
58 \r
59                 if(message.GetName()=="PutFailed")\r
60                 {\r
61                         // if fatal error, or data is already there - remove insert from database\r
62                         if(message["Fatal"]=="true" || message["Code"]=="9")\r
63                         {\r
64                                 m_db->Execute("DELETE FROM tblIdentityIntroductionInserts WHERE UUID='"+idparts[3]+"';");\r
65                                 // update the puzzle from the request table (set to not found) because we don't need it anymore and don't want to user tyring to solve it again\r
66                                 m_db->Execute("UPDATE tblIntroductionPuzzleRequests SET Found='false' WHERE UUID='"+idparts[3]+"';");\r
67                                 m_log->warning("IdentityIntroductionInserter::HandleMessage received fatal error trying to insert IdentityIntroduction "+idparts[3]);\r
68                         }\r
69                         m_inserting=false;\r
70                         return true;\r
71                 }\r
72 \r
73                 if(message.GetName()=="PutSuccessful")\r
74                 {\r
75                         m_db->Execute("UPDATE tblIdentityIntroductionInserts SET Inserted='true' WHERE UUID='"+idparts[3]+"';");\r
76                         m_inserting=false;\r
77                         m_log->information("IdentityIntroductionInserter::HandleMessage successfully inserted IdentityIntroduction "+idparts[3]);\r
78                         return true;\r
79                 }\r
80 \r
81                 if(message.GetName()=="IdentifierCollision")\r
82                 {\r
83                         m_inserting=false;\r
84                         return true;\r
85                 }\r
86         }\r
87 \r
88         return false;\r
89 }\r
90 \r
91 void IdentityIntroductionInserter::Initialize()\r
92 {\r
93         m_inserting=false;\r
94         Option::Instance()->Get("MessageBase",m_messagebase);\r
95 }\r
96 \r
97 void IdentityIntroductionInserter::Process()\r
98 {\r
99         Poco::DateTime now;\r
100 \r
101         // only do 1 insert at a time\r
102         if(!m_inserting && m_lastchecked<(now-Poco::Timespan(0,0,1,0,0)))\r
103         {\r
104                 CheckForNewInserts();\r
105                 m_lastchecked=now;\r
106         }\r
107 }\r
108 \r
109 void IdentityIntroductionInserter::RegisterWithThread(FreenetMasterThread *thread)\r
110 {\r
111         thread->RegisterFCPConnected(this);\r
112         thread->RegisterFCPMessageHandler(this);\r
113         thread->RegisterPeriodicProcessor(this);\r
114 }\r
115 \r
116 void IdentityIntroductionInserter::StartInsert(const long localidentityid, const std::string &day, const std::string &UUID, const std::string &solution)\r
117 {\r
118         FCPv2::Message message;\r
119         IdentityIntroductionXML xml;\r
120         std::string publickey;\r
121         std::string data;\r
122         std::string datasizestr;\r
123         std::string encodedhash;\r
124         \r
125         SQLite3DB::Statement st=m_db->Prepare("SELECT PublicKey FROM tblLocalIdentity WHERE PublicKey IS NOT NULL AND PublicKey<>'' AND LocalIdentityID=?;");\r
126         st.Bind(0,localidentityid);\r
127         st.Step();\r
128 \r
129         if(st.RowReturned())\r
130         {\r
131                 st.ResultText(0,publickey);\r
132 \r
133                 xml.SetIdentity(publickey);\r
134                 data=xml.GetXML();\r
135                 StringFunctions::Convert(data.size(),datasizestr);\r
136 \r
137                 Poco::SHA1Engine sha1;\r
138                 sha1.update(solution);\r
139                 encodedhash=Poco::DigestEngine::digestToHex(sha1.digest());\r
140                 StringFunctions::UpperCase(encodedhash,encodedhash);\r
141 \r
142                 message.SetName("ClientPut");\r
143                 message["URI"]="KSK@"+m_messagebase+"|"+day+"|"+UUID+"|"+encodedhash+".xml";\r
144                 message["Identifier"]="IdentityIntroductionInserter|"+message["URI"];\r
145                 message["UploadFrom"]="direct";\r
146                 message["DataLength"]=datasizestr;\r
147 \r
148                 m_fcp->Send(message);\r
149                 m_fcp->Send(std::vector<char>(data.begin(),data.end()));\r
150 \r
151                 m_inserting=true;\r
152         }\r
153         else\r
154         {\r
155                 m_log->debug("IdentityIntroductionInserter::StartInsert could not find a public key for identity.  It is probably a new identity that doesn't have a key yet.");\r
156         }\r
157 \r
158 }\r