from flask import Flask, request, abort, jsonify from flask_sqlalchemy import SQLAlchemy import subprocess import random import os SUPPORT_KEY = "x2Dmw3hLRDPQa1sg59fAx2Dmw3hLRDPQa1sg59fA" PUBKEYS = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDh5X1s237dOa7lKXMy7cgVDsSL8fR3yuhIAM+Az0p8qQ/lSAGdzH1EXEupmX69g6NAwblsFoVByoO9X7boVZZXlaimPitosOcQNHABxILk4qel38+TxbAZ7i13448cwD3dSH5J13llQUvmfjHx7AfTH8y+/3q8Pf4+w/o1wXhqIm26XfNvUefeymUukdXmDA/+MhvE5zdU3sda8K4iCjLQexVv4n3CI+Y6FPLi2yKBht5RnWYAvjAY4frup1lPEeVk6uq4EZdbjUvaPfDVZx50r9tSDHLXr6epYKh8JDEATcVRuhQv56Ya0AOCptdxgctf+2bls9XX3dZgwEhWT+rOJuQywDx8POpErCfzoAkn4nt/skgd+49R/DA087EDwb9DHgCp0OyRdB9EGndp/3/MNetKBwUcJccr2NgBQABQUzfxQvkgYu7dmHJHq0hwDtI4/Yw/1a4IIDVXdBYbfWkoJpiOy2jS9Nfb38EoWo2n0g1qx3qofA9UuJFdPg8JS9U+AcWNzoqkZGGrEqwhpwBq5SVypZFrZTtnJGJSc581tsyDQKnKdzacpzdhnyUil3CqTmekqwuKgV0tWGNfLpolm+EayGeoPGJ3apRlyxHTSgjVSnjeIFJ1cfrHxbhdbrPQpIAqu8L+IkcPtdkG25QsDXizKt8zERFVcyrvKn1yxw== jean@toulza.fr" ] app = Flask(__name__) app.config['SECRET_KEY'] = '9OLWxND4o83j4K4iuopO' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) @app.route('/request', methods=["POST"]) def request_post(): j = request.json if not j or j["key"] != SUPPORT_KEY: abort(403) if "pubKey" in j and "nom" in j and "prenom" in j and len(j["nom"]) > 3 and len(j["prenom"]) > 3: nom = j["nom"] prenom = j["prenom"] pubkey = j["pubKey"] ip = request.remote_addr localuser, randomport = create_user(nom, prenom, pubkey) print("IP: %s, localuser=%s randomport=%s" % (ip, localuser, randomport)) return jsonify({"status": "ok", "pubkeys": "\n".join(PUBKEYS), "remoteport": randomport, "remoteuser": localuser}) else: abort(403) @app.route('/end', methods=["DELETE"]) def end_delete(): j = request.json if not j or j["key"] != SUPPORT_KEY: print("no json or support key") print(request.data) print(request.form) abort(403) if "pubKey" in j: localuser = find_localuser_by_pubkey(j["pubKey"]) if localuser: delete_localuser(localuser) print("deleted %s" % localuser) return jsonify({"status": "ok"}) else: print("no pubkey") abort(403) def find_localuser_by_pubkey(pubkey): for user in get_localusers(): if os.path.exists("/home/%s/.ssh/authorized_keys" % user): with open("/home/%s/.ssh/authorized_keys" % user) as fp: content = fp.read() if pubkey in content: return user return None def exec_cmd(cmd): p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) retcode = p.wait() stdout, stderr = p.communicate() stdout = stdout.decode("utf8").strip() return retcode, stdout def get_localusers(): retcode, out = exec_cmd("awk -F: '{ print $1 }' /etc/passwd") users = out.split("\n") return users def localuser_exists(username): return username in get_localusers() def create_user(nom, prenom, pubkey): username = (nom[0:3] + prenom[0:3]).lower() while localuser_exists(username): username = username + str(random.randint(1, 99)) print("Creating user %s..." % username) retcode, out = exec_cmd("adduser \ --system \ --shell /bin/false \ --gecos 'LIS67 user account for %s %s' \ --group \ --disabled-password \ --home /home/%s \ %s" % (nom, prenom, username, username)) if retcode != 0: abort(500) try: os.mkdir("/home/%s/.ssh" % username) except: pass with open("/home/%s/.ssh/authorized_keys" % username, "w") as fp: fp.write(pubkey) random_port = find_localport() return username, random_port def find_localport(): retcode, out = exec_cmd("python -c 'import socket; s=socket.socket(); s.bind((\"\", 0)); print(s.getsockname()[1]); s.close()'") return int(out) def delete_localuser(username): exec_cmd("userdel -r -f %s" % username) if __name__ == "__main__": db.create_all() app.run(host="0.0.0.0")