#include "action_header.h" #include #include "../../cryptoplugin/ICryptoFactory.h" #include "../server_settings.h" extern ICryptoFactory *crypto_fak; namespace { bool verify_signature(void) { if(crypto_fak==NULL) return false; #ifdef _WIN32 const std::string pubkey_fn="urbackup_dsa.pub"; #else const std::string pubkey_fn="urbackup/urbackup_dsa.pub"; #endif return crypto_fak->verifyFile(pubkey_fn, "urbackup/UrBackupUpdate.exe", "urbackup/UrBackupUpdate.sig"); } std::string constructClientSettings(Helper& helper, int clientid, const std::string& clientname) { ServerSettings settings(helper.getDatabase(), clientid); SSettings *settingsptr=settings.getSettings(); std::string ret="\r\n"; ret+="internet_mode_enabled="+nconvert(settingsptr->internet_mode_enabled)+"\r\n"; ret+="internet_server="+settingsptr->internet_server+"\r\n"; ret+="internet_server_port="+nconvert(settingsptr->internet_server_port)+"\r\n"; ret+="internet_authkey="+settingsptr->internet_authkey+"\r\n"; if(!clientname.empty()) { ret+="computername="+clientname+"\r\n"; } return ret; } bool replaceToken(const std::string end_token, const std::string& repl, std::string& data, size_t& offset) { for(size_t i=offset;irepl.size()) { data.replace(data.begin()+offset, data.begin()+offset+repl.size(), repl.begin(), repl.end()); offset=i+end_token.size(); return true; } else { Server->Log("Cannot replace, because data is too large", LL_ERROR); return false; } } } return false; } bool replaceStrings(Helper& helper, const std::string& settings, std::string& data) { const std::string settings_start_token="#48692563-17e4-4ccb-a078-f14372fdbe20"; const std::string settings_end_token="#6e7f6ba0-8478-4946-b70a-f1c7e83d28cc"; const std::string ident_start_token="#17460620-769b-4add-85aa-a764efe84ab7"; const std::string ident_end_token="#569d42d2-1b40-4745-a426-e86a577c7f1a"; bool replaced_settings=false; bool replaced_ident=false; for(size_t i=0;iid==-1) return; bool all_client_rights; std::vector clientids = helper.clientRights(RIGHT_SETTINGS, all_client_rights); std::string errstr; if( session!=NULL && (all_client_rights || !clientids.empty() ) ) { int clientid=watoi(GET[L"clientid"]); if(all_client_rights || std::find(clientids.begin(), clientids.end(), clientid)!=clientids.end() ) { Server->Log("Verifying UrBackupUpdate.exe signature...", LL_INFO); if(verify_signature()) { IQuery *q=helper.getDatabase()->Prepare("SELECT name FROM clients WHERE id=?"); q->Bind(clientid); db_results res=q->Read(); q->Reset(); std::string clientname; if(!res.empty()) { clientname=Server->ConvertToUTF8(res[0][L"name"]); } std::string data=getFile("urbackup/UrBackupUpdate.exe"); if( replaceStrings(helper, constructClientSettings(helper, clientid, clientname), data) ) { Server->setContentType(tid, "application/octet-stream"); Server->addHeader(tid, "Content-Disposition: attachment; filename=\"UrBackup Client ("+clientname+").exe\""); Server->addHeader(tid, "Content-Length: "+nconvert(data.size()) ); Server->WriteRaw(tid, data.c_str(), data.size(), false); } else { errstr="Replacing data in install file failed"; } } else { errstr="Signature verification failed"; } } else { errstr="No right to download client"; } } else { errstr="No right to download any client"; } if(!errstr.empty()) { Server->Log(errstr, LL_ERROR); helper.Write("ERROR: "+errstr); } }