gimrrdataprot: initial version
authorFrantisek Hrbata <frantisek@hrbata.com>
Mon, 4 Jan 2021 16:52:54 +0000 (17:52 +0100)
committerFrantisek Hrbata <frantisek@hrbata.com>
Mon, 4 Jan 2021 16:52:54 +0000 (17:52 +0100)
Simple protocol to be used for adding user public keys via krb
authentication.

Signed-off-by: Frantisek Hrbata <frantisek@hrbata.com>
gimrrdataprot.py [new file with mode: 0755]

diff --git a/gimrrdataprot.py b/gimrrdataprot.py
new file mode 100755 (executable)
index 0000000..0e0c7e1
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+
+# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
+
+"""
+Copyright © 2020 Frantisek Hrbata <frantisek@hrbata.com>
+This program is free software. It comes without any warranty, to
+the extent permitted by applicable law. You can redistribute it
+and/or modify it under the terms of the Do What The Fuck You Want
+To Public License, Version 2, as published by Sam Hocevar. See
+http://www.wtfpl.net/ for more details.
+"""
+
+"""
+dump protocol
+-------------------------------
+|data size | data type | data |
+-------------------------------
+
+data size - 2bytes, size includes data type
+data type - 2bytes identifying data type(command)
+data - payload
+"""
+
+import socket
+import gssapi
+
+DATA_TYPE_ERR = 0
+DATA_TYPE_MSG = 1
+DATA_TYPE_AUTH_TOKEN = 2
+DATA_TYPE_PUB_KEY = 3
+
+def recv_data(sock, max_size=4096, timeout=3):
+    sock.settimeout(timeout)
+    buf = sock.recv(2)
+    size = int.from_bytes(buf, 'big')
+    if size > max_size:
+        raise Exception("recv data too long")
+
+    buf = b''
+    while size != len(buf):
+        buf += sock.recv(size - len(buf))
+
+    if len(buf) < 2:
+        raise Exception("no command found")
+
+    data_type = int.from_bytes(buf[0:2], 'big')
+    data = buf[2:]
+    return (data_type, data)
+
+def recv_data_dec(secctx, sock, max_size=4096, timeout=3):
+    data_type, data = recv_data(sock, max_size, timeout)
+
+    data_dec = secctx.decrypt(data)
+    return (data_type, data_dec)
+
+def send_data(sock, data_type, data, max_size=4096, timeout=3):
+    if type(data) == str:
+        data = data.encode()
+
+    data_size = len(data) + 2
+    if data_size > min(max_size, 2**16):
+        raise Exception("send data too long")
+
+    if data_type > 2**16 or data_type < 0:
+        raise Exception("command out of range")
+
+    buf = data_size.to_bytes(2, 'big')
+    buf += data_type.to_bytes(2, 'big')
+    buf += data
+
+    sock.sendall(buf)
+
+def send_data_enc(secctx, sock, data_type, data, max_size=4096, timeout=3):
+    if type(data) == str:
+        data = data.encode()
+
+    data_enc = secctx.encrypt(data)
+
+    return send_data(sock, data_type, data_enc, max_size, timeout)