diff --git a/bazaar/Protect/ProtectClient.cpp b/bazaar/Protect/ProtectClient.cpp index ecf0af592..647a4e15a 100644 --- a/bazaar/Protect/ProtectClient.cpp +++ b/bazaar/Protect/ProtectClient.cpp @@ -38,7 +38,7 @@ VectorMap ProtectClient::SendMap(VectorMap const & // copy vectormap adding client id and a magic number VectorMapdataMap(v, 1); dataMap.Add("APPID", "ProtectClient"); - dataMap.Add("CLIENTID=", clientID); + dataMap.Add("CLIENTID", clientID); // sets cypher key (and create a random IV) cypher->SetKey(key); @@ -49,44 +49,48 @@ VectorMap ProtectClient::SendMap(VectorMap const & postData += HexString((*cypher)(StoreAsXML(dataMap, "ProtectClient"))); client.Post(postData); - lastContents = client.ExecuteRedirect(); + String contents = client.ExecuteRedirect(); // if contents start with "ERROR", just fetch the error desc // and put it in result map VectorMap resMap; - if(lastContents.StartsWith("ERROR=")) + if(contents.StartsWith("ERROR=")) { - int i = lastContents.Find("\r"); + int i = contents.Find("\r"); String s; if(i >= 0) - s = lastContents.Mid(6, i - 6); + s = contents.Mid(6, i - 6); else - s = lastContents.Mid(6); - resMap.Add("ERROR", s); + s = contents.Mid(6); + int errCode = atoi(~s); + resMap.Add("ERROR", errCode); + resMap.Add("ERRORMSG", ProtectMessage(errCode)); return resMap; } // otherwise, if lastContents don't start with IV field - // fetch the error from http client - if(!lastContents.StartsWith("IV=")) + // signals it + if(!contents.StartsWith("IV=")) { - resMap.Add("ERROR", client.GetStatusLine()); + resMap.Add("ERROR", PROTECT_MISSING_IV); + resMap.Add("ERRORMSG", ProtectMessage(PROTECT_MISSING_IV)); return resMap; } // well, we've at least the IV, so we can fetch it and DATA field and decrypt - StringStream s(lastContents); + StringStream s(contents); String line = s.GetLine(); String IV = ScanHexString(line.Mid(3)); line = s.GetLine(); if(!line.StartsWith("DATA=")) { - resMap.Add("ERROR", "Missing DATA field"); + resMap.Add("ERROR", PROTECT_BAD_DATA); + resMap.Add("ERRORMSG", ProtectMessage(PROTECT_BAD_DATA)); return resMap; } // decodes DATA field and read VectorMap from it cypher->SetKey(key, IV); - String decoded = (*cypher)(line.Mid(5)); + String decoded = (*cypher)(ScanHexString(line.Mid(5))); try { LoadFromXML(resMap, decoded); @@ -94,25 +98,32 @@ VectorMap ProtectClient::SendMap(VectorMap const & catch(...) { resMap.Clear(); - resMap.Add("ERROR", "Bad DATA received"); + resMap.Add("ERROR", PROTECT_BAD_DATA); + resMap.Add("ERRORMSG", ProtectMessage(PROTECT_BAD_DATA)); } return resMap; } // create a persistent link to server -bool ProtectClient::Connect(int persistTime) +bool ProtectClient::Connect(void) { + lastError = 0; + // if already connected, disconnect first - Disconnect(); + if(!Disconnect()) + return false; // send a connect packet to server VectorMapv; - v.Add("CONNECT", persistTime); + v.Add("REASON", ProtectReasonStr(PROTECT_CONNECT)); VectorMap res = SendMap(v); // check for errors - if(res.Find("CONNECTED") < 0) + if(res.Find("ERROR") >= 0) + { + lastError = res.Get("ERROR"); return false; + } connected = true; return true; @@ -121,39 +132,124 @@ bool ProtectClient::Connect(int persistTime) // disconnect from server bool ProtectClient::Disconnect(void) { + lastError = 0; + if(!connected) return true; // sends a disconnect packet to server VectorMapv; - v.Add("DISCONNECT", ""); + v.Add("REASON", ProtectReasonStr(PROTECT_DISCONNECT)); VectorMap res = SendMap(v); // check for errors - if(res.Find("DISCONNECTED") < 0) + if(res.Find("ERROR") >= 0) + { + lastError = res.Get("ERROR"); return false; + } connected = false; return true; } -// sends data and get response data -VectorMap ProtectClient::Send(VectorMap const &v) +// refresh server connection +bool ProtectClient::Refresh(void) { - VectorMap res; - - // checks if connection is established - if(!connected) + lastError = 0; + + // sends a refresh packet to server + VectorMapv; + v.Add("REASON", ProtectReasonStr(PROTECT_REFRESH)); + VectorMap res = SendMap(v); + + // check for errors + if(res.Find("ERROR") >= 0) { - res.Add("ERROR", "NOT CONNECTED TO SERVER"); - return res; + lastError = res.Get("ERROR"); + return false; } - // send the map and get results - res = SendMap(v); + return true; +} + +// get license key +String ProtectClient::GetKey(void) +{ + lastError = 0; + + // sends a getkey packet to server + VectorMapv; + v.Add("REASON", ProtectReasonStr(PROTECT_GETKEY)); + VectorMap res = SendMap(v); + + // check for errors + if(res.Find("ERROR") >= 0) + { + lastError = res.Get("ERROR"); + return ""; + } + if(res.Find("KEY") < 0) + { + lastError = 999; + return ""; + } + return res.Get("KEY"); +} + +// gets license info +bool ProtectClient::GetLicenseInfo(void) +{ + lastError = 0; + + // sends a getinfo packet to server + VectorMapv; + v.Add("REASON", ProtectReasonStr(PROTECT_GETLICENSEINFO)); + VectorMap res = SendMap(v); + + // check for errors + if(res.Find("ERROR") >= 0) + { + lastError = res.Get("ERROR"); + return false; + } - // return result map - return res; + if(res.Find("EMAIL") >= 0) userEMail = res.Get("USEREMAIL"); + if(res.Find("USERNAME") >= 0) userName = res.Get("USERNAME"); + if(res.Find("USERADDRESS") >= 0) userAddress = res.Get("USERADDRESS"); + if(res.Find("USERCOUNTRY") >= 0) userCountry = res.Get("USERCOUNTRY"); + if(res.Find("USERPHONE") >= 0) userPhone = res.Get("USERPHONE"); + if(res.Find("USERFAX") >= 0) userFax = res.Get("USERFAX"); + if(res.Find("USERCELL") >= 0) userCell = res.Get("USERCELL"); + if(res.Find("EXPIRETIME") >= 0) expireTime = res.Get("EXPIRETIME"); + if(res.Find("NUMLICENSES") >= 0) numLicenses = res.Get("NUMLICENSES"); + + return true; +} + +// register app +bool ProtectClient::Register(void) +{ + lastError = 0; + + // sends a register packet to server + VectorMapv; + v.Add("REASON", ProtectReasonStr(PROTECT_REGISTER)); + v.Add("EMAIL", userEMail); + v.Add("USERNAME", userName); + v.Add("USERADDRESS", userAddress); + v.Add("USERCOUNTRY", userCountry); + v.Add("USERPHONE", userPhone); + v.Add("USERFAX", userFax); + v.Add("USERCELL", userCell); + VectorMap res = SendMap(v); + + // check for errors + if(res.Find("ERROR") >= 0) + { + lastError = res.Get("ERROR"); + return false; + } } END_UPP_NAMESPACE diff --git a/bazaar/Protect/ProtectClient.h b/bazaar/Protect/ProtectClient.h index 89d93882f..53a377aa3 100644 --- a/bazaar/Protect/ProtectClient.h +++ b/bazaar/Protect/ProtectClient.h @@ -15,8 +15,8 @@ class ProtectClient // the HTTP client HttpClient client; - // last HTTP answer - String lastContents; + // last error code for failed operations + int lastError; // the cypher -- can be changed between available // in Cypher package @@ -28,6 +28,23 @@ class ProtectClient // client id -- generated as random dword on creation String clientID; + // license ID -- got from server upon registration + String licenseID; + + // user data + String userEMail; + String userName; + String userAddress; + String userCountry; + String userZIP; + String userPhone; + String userFax; + String userCell; + + // license expire time and number of them + Time expireTime; + int numLicenses; + // key and IV for encrypted communication String key; qword IV; @@ -57,22 +74,41 @@ class ProtectClient // sets communication key ProtectClient &SetKey(String const &_key) { key = _key; return *this; } - // read last HTTP answer got from server - // useful mostly for debugging purposes - String const &GetLastContents(void) { return lastContents; } - String GetLastHeaders(void) { return client.GetHeaders(); } - String GetLastStatus(void) { return client.GetStatusLine(); } - String GetLastError(void) { return client.GetError(); } - int GetLastStatusCode(void) { return client.GetStatusCode(); } + // read last error code and message + int GetLastError(void) { return lastError; } + String GetLastErrorMsg(void) { return ProtectMessage(lastError); } + + // checks whether we're connected to server + bool IsConnected(void) { return connected; } // create a persistent link to server - bool Connect(int persistTime); + bool Connect(void); // disconnect from server bool Disconnect(void); + + // refresh server connection + bool Refresh(void); + + // get license key + String GetKey(void); + + // gets license info + bool GetLicenseInfo(void); + + // register app + bool Register(void); - // sends data and get response data - VectorMap Send(VectorMap const &v); + // set user data -- for registration + // filled automatically by GETLICENSEINFO request + ProtectClient &SetUserEMail(String const &mail) { userEMail = mail; return *this; } + ProtectClient &SetUserName(String const &name) { userName = name; return *this; } + ProtectClient &SetUserAddress(String const &address) { userAddress = address; return *this; } + ProtectClient &SetUserCountry(String const &country) { userCountry = country; return *this; } + ProtectClient &SetUserZip(String const &zip) { userZIP = zip; return *this; } + ProtectClient &SetUserPhone(String const &phone) { userPhone = phone; return *this; } + ProtectClient &SetUserFax(String const &fax) { userFax = fax; return *this; } + ProtectClient &SetUserCell(String const &cell) { userCell = cell; return *this; } }; END_UPP_NAMESPACE diff --git a/bazaar/Protect/ProtectServer.cpp b/bazaar/Protect/ProtectServer.cpp index 5ef4d50e5..9ce29e7bc 100644 --- a/bazaar/Protect/ProtectServer.cpp +++ b/bazaar/Protect/ProtectServer.cpp @@ -103,7 +103,28 @@ void ProtectServer::OnRequest() // GETKEY gets application key // REGISTER registers app for timed demo // GETLICENSEINFO gets info about license (name, expiration date, app version....) - VectorMap results = ProcessRequest(data); + if(data.Find("REASON") < 0 || data.Find("CLIENTID") < 0) + { + SendError(PROTECT_BAD_DATA); + return; + } + String ClientID = data.Get("CLIENTID"); + int reason = ProtectReason(data.Get("REASON")); + if(reason < PROTECT_CONNECT || reason > PROTECT_GETLICENSEINFO) + { + SendError(PROTECT_BAD_DATA); + return; + } + if(reason != PROTECT_CONNECT && reason != PROTECT_REGISTER && !IsClientConnected(ClientID)) + { + SendError(PROTECT_NOT_CONNECTED); + return; + } + VectorMap results = ProcessRequest(reason, data); + if(reason == PROTECT_CONNECT && results.Find("ERROR") < 0) + ConnectClient(ClientID); + else if(reason == PROTECT_DISCONNECT) + DisconnectClient(ClientID); // encodes results and send back to client cypher->SetKey(key); @@ -120,10 +141,22 @@ void ProtectServer::OnClosed() // process client request // takes a VectorMap on input from client // produces a response VectorMap to be returned -VectorMap ProtectServer::ProcessRequest(VectorMap const &v) +VectorMap ProtectServer::ProcessRequest(int reason, VectorMap const &v) { - // @@@@ TO DO - BY NOW JUST RETURN INPUT DATA - return VectorMap(v, 1); + VectorMap res; + switch(reason) + { + case PROTECT_REGISTER: + break; + + case PROTECT_GETKEY: + res.Add("KEY", "THIS IS A DUMMY KEY"); + break; + + default: + break; + } + return res; } END_UPP_NAMESPACE diff --git a/bazaar/Protect/ProtectServer.h b/bazaar/Protect/ProtectServer.h index ad1550227..0d00c8282 100644 --- a/bazaar/Protect/ProtectServer.h +++ b/bazaar/Protect/ProtectServer.h @@ -48,7 +48,7 @@ class ProtectServer : public ScgiServer // process client request // takes a VectorMap on input from client // produces a response VectorMap to be returned - virtual VectorMap ProcessRequest(VectorMap const &v); + virtual VectorMap ProcessRequest(int reason, VectorMap const &v); public: