mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
171 lines
4.5 KiB
C++
171 lines
4.5 KiB
C++
#include "action_header.h"
|
|
#include <algorithm>
|
|
#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;i<data.size();++i)
|
|
{
|
|
if(next(data, i, end_token) )
|
|
{
|
|
if(i-offset>repl.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;i<data.size();++i)
|
|
{
|
|
if(next(data, i, settings_start_token))
|
|
{
|
|
i+=settings_start_token.size();
|
|
|
|
if(!replaceToken(settings_end_token, settings, data, i))
|
|
{
|
|
return false;
|
|
}
|
|
replaced_settings=true;
|
|
}
|
|
|
|
if(next(data, i, ident_start_token))
|
|
{
|
|
i+=ident_start_token.size();
|
|
|
|
if(!replaceToken(ident_end_token, "\r\n"+helper.getStrippedServerIdentity()+"\r\n", data, i))
|
|
{
|
|
return false;
|
|
}
|
|
replaced_ident=true;
|
|
}
|
|
|
|
if( replaced_ident && replaced_settings)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
ACTION_IMPL(download_client)
|
|
{
|
|
Helper helper(tid, &GET, &PARAMS);
|
|
|
|
SUser *session=helper.getSession();
|
|
if(session!=NULL && session->id==-1) return;
|
|
|
|
bool all_client_rights;
|
|
std::vector<int> 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);
|
|
}
|
|
} |