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