Download custom client installer via Python
A Python 3 script to create a new client on the server and to download and execute a custom client installer. The current version works with UrBackup 2.x:
import http.client as http
import json
from urllib.parse import urlparse
from urllib.parse import urlencode
from base64 import b64encode
import hashlib
import socket
import shutil
import os
import binascii
#############################
# Settings. Please edit.
#############################
#Your server URL. Do not forget the 'x' at the end
server_url = 'http://example.com:55414/x'
#If you have basic authentication via .htpasswd
server_basic_username = ''
server_basic_password = ''
# Login user needs following rights
# "status": "some"
# "add_client": "all"
# Optionally, to be able to
# install existing clients:
# "settings": "all"
server_username='adduser'
server_password='foo'
#############################
# Global script variables.
# Please do not modify.
# Only modify something after this line
# if you know what you are doing
#############################
session=""
def get_response(action, params, method):
global server_url;
global server_basic_username;
global server_basic_password;
global session;
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=UTF-8'
}
if('server_basic_username' in globals() and len(server_basic_username)>0):
userAndPass = b64encode(str.encode(server_basic_username+":"+server_basic_password)).decode("ascii")
headers['Authorization'] = 'Basic %s' % userAndPass
curr_server_url=server_url+"?"+urlencode({"a": action});
if(len(session)>0):
params["ses"]=session
if method=='GET':
curr_server_url+="&"+urlencode(params);
target = urlparse(curr_server_url)
if not method:
method = 'GET'
if method=='POST':
body = urlencode(params)
else:
body = ''
if(target.scheme=='http'):
h = http.HTTPConnection(target.hostname, target.port)
elif(target.scheme=='https'):
h = http.HTTPSConnection(target.hostname, target.port)
else:
print('Unkown scheme: '+target.scheme)
raise Exception("Unkown scheme: "+target.scheme)
h.request(
method,
target.path+"?"+target.query,
body,
headers)
return h.getresponse();
def get_json(action, params = {}):
response = get_response(action, params, "POST")
if(response.status != 200):
return ""
data = response.read();
response.close()
return json.loads(data.decode("utf-8"))
def download_file(action, outputfn, params):
response = get_response(action, params, "GET");
if(response.status!=200):
return False
with open(outputfn, 'wb') as outputf:
shutil.copyfileobj(response, outputf)
if os.path.getsize(outputfn)<10*1024:
return False
return True
def md5(s):
return hashlib.md5(s.encode()).hexdigest()
print("Logging in...")
salt = get_json("salt", {"username": server_username})
if( not ('ses' in salt) ):
print('Username does not exist')
exit(1)
session = salt["ses"];
if( 'salt' in salt ):
password_md5_bin = hashlib.md5((salt["salt"]+server_password).encode()).digest()
password_md5 = binascii.hexlify(password_md5_bin).decode()
if "pbkdf2_rounds" in salt:
pbkdf2_rounds = int(salt["pbkdf2_rounds"])
if pbkdf2_rounds>0:
password_md5 = binascii.hexlify(hashlib.pbkdf2_hmac('sha256', password_md5_bin,
salt["salt"].encode(), pbkdf2_rounds)).decode()
password_md5 = md5(salt["rnd"]+password_md5)
login = get_json("login", { "username": server_username,
"password": password_md5 })
if('success' not in login or not login['success']):
print('Error during login. Password wrong?')
exit(1)
clientname = socket.gethostname()
print("Creating client "+clientname+"...")
new_client = get_json("add_client", { "clientname": clientname})
if "already_exists" in new_client:
print("Client already exists")
status = get_json("status")
if "client_downloads" in status:
for client in status["client_downloads"]:
if (client["name"] == clientname):
print("Downloading Installer...")
if not download_file("download_client", "Client Installer.exe",
{"clientid": client["id"] }):
print("Downloading client failed")
exit(1)
else:
print("Client already exists and login user has probably no right to access existing clients")
exit(2)
else:
if not "new_authkey" in new_client:
print("Error creating new client")
exit(3)
print("Downloading Installer...")
if not download_file("download_client", "Client Installer.exe",
{"clientid": new_client["new_clientid"],
"authkey": new_client["new_authkey"]
}):
print("Downloading client failed")
exit(1)
print("Sucessfully downloaded client")
os.startfile("Client Installer.exe")
exit(0)
Use e.g. http://cx-freeze.sourceforge.net/ to create an executable, if you need to.
, multiple selections available,