#include "ProtectClient.h" NAMESPACE_UPP ProtectClient::ProtectClient() { // generates client id clientID = -1; // defaults to Snow2 Cypher cypher = new Snow2; } ProtectClient::~ProtectClient() { // if connected, disconnect from server Disconnect(); } // sets the encrypting engine // default Cypher at startup is Snow2 // WARNING -- takes Cypher ownership void ProtectClient::SetCypher(Cypher *c) { // sets the new cypher freeing previous one cypher = c; } // sends a VectorMap to server in encrypted form // and gets its response VectorMap ProtectClient::SendMap(VectorMap const &v) { // copy vectormap adding client id and a magic number VectorMapdataMap(v, 1); dataMap.Add("APPID", "ProtectClient"); // sets cypher key (and create a random IV) cypher->SetKey(key); String postData; postData += "IV=" + HexString(cypher->GetNonce()) + "&"; postData += "DATA="; postData += HexString((*cypher)(StoreAsXML(dataMap, "ProtectClient"))); client.Post(postData); String contents = client.ExecuteRedirect(); // if contents start with "ERROR", just fetch the error desc // and put it in result map VectorMap resMap; // if contents don't start with IV field signals it if(!contents.StartsWith("IV=")) { 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(contents); String line = s.GetLine(); String IV = ScanHexString(line.Mid(3)); line = s.GetLine(); if(!line.StartsWith("DATA=")) { 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)(ScanHexString(line.Mid(5))); try { LoadFromXML(resMap, decoded); } catch(...) { resMap.Clear(); resMap.Add("ERROR", PROTECT_BAD_DATA); resMap.Add("ERRORMSG", ProtectMessage(PROTECT_BAD_DATA)); } return resMap; } // create a persistent link to server bool ProtectClient::Connect(void) { lastError = 0; // disconnect first, im case we're already connected Disconnect(); // send a connect packet to server VectorMapv; v.Add("REASON", PROTECT_CONNECT); v.Add("EMAIL", userEMail); v.Add("CLIENTID", (int)clientID); VectorMap res = SendMap(v); // check for errors if(res.Find("ERROR") >= 0) { lastError = res.Get("ERROR"); clientID = -1; return false; } int i = res.Find("CLIENTID"); if(i < 0) clientID = -1; else clientID = (int)res[i]; return true; } // disconnect from server bool ProtectClient::Disconnect(void) { lastError = 0; // sends a disconnect packet to server VectorMapv; v.Add("REASON", PROTECT_DISCONNECT); v.Add("CLIENTID", (int)clientID); VectorMap res = SendMap(v); // we're probably disconnected anyways.... clientID = -1; // check for errors if(res.Find("ERROR") >= 0) { lastError = res.Get("ERROR"); return false; } return true; } // refresh server connection bool ProtectClient::Refresh(void) { lastError = 0; // sends a refresh packet to server VectorMapv; v.Add("REASON", PROTECT_REFRESH); v.Add("CLIENTID", (int)clientID); VectorMap res = SendMap(v); // check for errors if(res.Find("ERROR") >= 0) { lastError = res.Get("ERROR"); clientID = -1; return false; } return true; } // get license key String ProtectClient::GetKey(void) { lastError = 0; // sends a getkey packet to server VectorMapv; v.Add("REASON", PROTECT_GETKEY); v.Add("CLIENTID", (int)clientID); 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", PROTECT_GETLICENSEINFO); v.Add("CLIENTID", (int)clientID); VectorMap res = SendMap(v); // check for errors if(res.Find("ERROR") >= 0) { lastError = res.Get("ERROR"); return false; } if(res.Find("EMAIL") >= 0) userEMail = res.Get("EMAIL"); if(res.Find("NAME") >= 0) userName = res.Get("NAME"); if(res.Find("ADDRESS") >= 0) userAddress = res.Get("ADDRESS"); if(res.Find("COUNTRY") >= 0) userCountry = res.Get("COUNTRY"); if(res.Find("ZIP") >= 0) userZIP = res.Get("ZIP"); if(res.Find("PHONE") >= 0) userPhone = res.Get("PHONE"); if(res.Find("FAX") >= 0) userFax = res.Get("FAX"); if(res.Find("CELL") >= 0) userCell = res.Get("CELL"); if(res.Find("EXPIRETIME") >= 0) expireTime = res.Get("EXPIRETIME"); if(res.Find("NUMLICENSES") >= 0) numLicenses = res.Get("NUMLICENSES"); return true; } // updates user data on server bool ProtectClient::UpdateUserData(void) { lastError = 0; // sends a register packet to server VectorMapv; v.Add("REASON", PROTECT_UPDATEUSERDATA); v.Add("CLIENTID", (int)clientID); v.Add("EMAIL", userEMail); v.Add("NAME", userName); v.Add("ADDRESS", userAddress); v.Add("COUNTRY", userCountry); v.Add("ZIP", userZIP); v.Add("PHONE", userPhone); v.Add("FAX", userFax); v.Add("CELL", userCell); VectorMap res = SendMap(v); // check for errors if(res.Find("ERROR") >= 0) { lastError = res.Get("ERROR"); return false; } return true; } // register app bool ProtectClient::Register(void) { lastError = 0; // sends a register packet to server VectorMapv; v.Add("REASON", PROTECT_REGISTER); v.Add("EMAIL", userEMail); v.Add("NAME", userName); v.Add("ADDRESS", userAddress); v.Add("COUNTRY", userCountry); v.Add("ZIP", userZIP); v.Add("PHONE", userPhone); v.Add("FAX", userFax); v.Add("CELL", userCell); VectorMap res = SendMap(v); // check for errors if(res.Find("ERROR") >= 0) { lastError = res.Get("ERROR"); return false; } } END_UPP_NAMESPACE