From: Frantisek Hrbata Date: Mon, 4 Jan 2021 16:52:54 +0000 (+0100) Subject: gimrrdataprot: initial version X-Git-Tag: v0.4~10 X-Git-Url: http://www.hrbata.com/gitweb/?a=commitdiff_plain;h=2ca4fb9ad5c6a4e0a0098db97eadf47110d57f9b;p=gimrr.git gimrrdataprot: initial version Simple protocol to be used for adding user public keys via krb authentication. Signed-off-by: Frantisek Hrbata --- diff --git a/gimrrdataprot.py b/gimrrdataprot.py new file mode 100755 index 0000000..0e0c7e1 --- /dev/null +++ b/gimrrdataprot.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 + +""" +Copyright © 2020 Frantisek Hrbata +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)