From 2979ce4410ef4664219ad99c9faf9b79ea666bd5 Mon Sep 17 00:00:00 2001
From: mt <mt@m18.uni-weimar.de>
Date: Wed, 23 Oct 2024 22:21:15 +0000
Subject: [PATCH] keygen in python, logging

---
 gitsync/deploy.py        |  6 +++++-
 gitsync/inner/worker.sh  |  8 ++++----
 gitsync/main.py          | 41 ++++++++++++++++++++++++++++++++--------
 gitsync/requirements.txt |  4 +++-
 4 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/gitsync/deploy.py b/gitsync/deploy.py
index 011c0c29b4..53f5e91a2f 100644
--- a/gitsync/deploy.py
+++ b/gitsync/deploy.py
@@ -1,8 +1,12 @@
 from waitress import serve
 from hafenmeister import ensure_image_ready
+import logging
+logger = logging.getLogger('waitress')
+logger.setLevel(logging.INFO)
+
 import main
 
 ensure_image_ready()
 print("Image ready, starting server...")
 print("Starting server...")
-serve(main.app, host='0.0.0.0', port=3000)
\ No newline at end of file
+serve(main.app, host='0.0.0.0', port=3000)
diff --git a/gitsync/inner/worker.sh b/gitsync/inner/worker.sh
index 8d61fbee65..331450be98 100755
--- a/gitsync/inner/worker.sh
+++ b/gitsync/inner/worker.sh
@@ -3,7 +3,7 @@ cd /ops
 unzip overleaf.zip git.config
 if [ ! -f git.config ]; then
     2>&1 echo "No git.config found"
-    exit 1
+    exit 2
 fi
 GIVEN_URL=$(cat git.config | cut -d ';' -f 1 | tr -d '[:space:]')
 
@@ -11,7 +11,7 @@ IMPORTED_REGEX=$(echo $GIT_REGEX)
 
 if [[ ! $GIVEN_URL =~ $IMPORTED_REGEX ]]; then
     2>&1 echo "URL does not match regex"
-    exit 1
+    exit 3
 fi
 SSH_KEY_DATA=$(cat git.config | cut -d ';' -f 2 | tr -d '[:space:]')
 
@@ -32,7 +32,7 @@ echo "Pushed"
 rm -rf /ops/*
 if [[ $worked_push =~ "fatal" ]]; then
     2>&1 echo "PUSH_GIT_FAILED"
-    exit 1
+    exit 4
 fi
 echo "PUSH_GIT_OK"
-exit 0
\ No newline at end of file
+exit 0
diff --git a/gitsync/main.py b/gitsync/main.py
index 48e0dbb042..0d87cd6d69 100644
--- a/gitsync/main.py
+++ b/gitsync/main.py
@@ -1,20 +1,44 @@
 import flask, secrets
-from flask import send_from_directory
-import os, json, base64, secrets
+from flask import send_from_directory, request
+import io, os, json, base64
+from cryptography.hazmat.primitives import serialization
+from cryptography.hazmat.primitives import asymmetric
+import paramiko
 
 from hafenmeister import run_container
 
+import logging 
+from sys import stdout
+
+# Define logger
+logger = logging.getLogger('gitsync')
+
+# switch to DEBUG to enable logging here
+logger.setLevel(logging.INFO) 
+consoleHandler = logging.StreamHandler(stdout) 
+logger.addHandler(consoleHandler)
 
 app = flask.Flask(__name__)
 app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 * 1000
 
+@app.before_request
+def log_the_request():
+    logger.debug(request)
+
 @app.route('/git/sshkey', methods=['POST'])
 def gen_ssh_key():
-    fnx = secrets.token_hex(12)
-    keymaterial = os.popen(f"mkfifo {fnx} {fnx}.pub && cat {fnx} {fnx}.pub & echo \"y\" | ssh-keygen -N \"\" -t ed25519 -f {fnx} ; rm {fnx} {fnx}.pub").read()
-    privkey = "-----BEGIN OPENSSH PRIVATE" + keymaterial.split("-----BEGIN OPENSSH PRIVATE")[1].split("-----END OPENSSH PRIVATE KEY-----")[0] + "-----END OPENSSH PRIVATE KEY-----"
-    pubkey = "ssh-ed25519 " + keymaterial.split("ssh-ed25519 ")[1].split(" ")[0] + " overleaf@ruhr"
-    return json.dumps({"pubkey": pubkey, "privkey": base64.b64encode(privkey.encode()).decode()})
+    c_ed25519key = asymmetric.ed25519.Ed25519PrivateKey.generate()
+    privpem = c_ed25519key.private_bytes(encoding=serialization.Encoding.PEM,
+                                     format=serialization.PrivateFormat.OpenSSH,
+                                     encryption_algorithm=serialization.NoEncryption())
+    priv_obj = io.StringIO(privpem.decode())
+    p_ed25519key = paramiko.ed25519key.Ed25519Key.from_private_key(priv_obj)
+    pub = c_ed25519key.public_key()
+    openssh_pub = pub.public_bytes(encoding=serialization.Encoding.OpenSSH,
+                               format=serialization.PublicFormat.OpenSSH)
+    pubkey = str(openssh_pub.decode("utf-8")) + " overleaf@ruhr"
+    return json.dumps({"pubkey": pubkey, "privkey": base64.b64encode(privpem).decode("utf-8")})
+
 @app.route('/git/css/bootstrap.min.css', methods=['GET'])
 def cssRoute():
     return send_from_directory('web/css', 'bootstrap.min.css')
@@ -25,14 +49,15 @@ def mainRoute():
     return send_from_directory('web', 'index.html')
 @app.route("/git/gitsync", methods=['POST'])
 def gitsyncRoute():
+    logger.debug("post received")
     auth_header = flask.request.headers.get('internal-auth')
     if not auth_header or auth_header != os.getenv("INTERNAL_AUTH"):
         return flask.jsonify({"success": False, "message": "Unauthorized"})
-    
     operating_dir = "/tmp/overleaf_mounts/overleaf_"+secrets.token_hex(16)
     os.mkdir(operating_dir)
     with open(operating_dir + "/overleaf.zip", "wb") as f:
         f.write(flask.request.data)
     f.close()
     result = run_container(operating_dir)
+    logger.debug(result) 
     return flask.jsonify({"success": result[0], "message": "ok"})
diff --git a/gitsync/requirements.txt b/gitsync/requirements.txt
index fd8aba6834..93754195aa 100644
--- a/gitsync/requirements.txt
+++ b/gitsync/requirements.txt
@@ -1,3 +1,5 @@
 docker
 flask
-waitress
\ No newline at end of file
+waitress
+cryptography
+paramiko
-- 
GitLab