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.