--- /dev/null
+#!/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.
+"""
+
+import argparse
+import socket
+import gssapi
+import os
+import sys
+import gimrrdataprot
+
+parser = argparse.ArgumentParser(description="Register public key on server using krb authentication.");
+parser.add_argument("--server", metavar="ADDR", required=True,
+ help="Connect to server at ADDR for registration.")
+parser.add_argument("--port", metavar="PORT", default=9876, type=int,
+ help="Server port (default: 9876")
+parser.add_argument("--timeout", metavar="SECONDS", default=3, type=int,
+ help="Socket timeout for server's reply (default: 3)")
+parser.add_argument("--principal", metavar="PRINCIPAL",
+ help="Kerberos principal name.")
+parser.add_argument("-k", "--key", metavar="FILE", required=True,
+ help="Path to the public key to use for registration.")
+
+args = parser.parse_args()
+
+server_name = gssapi.Name(args.principal)
+ctx = gssapi.SecurityContext(name=server_name, usage='initiate')
+sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+sock.connect((args.server, args.port))
+
+token_in = None
+while not ctx.complete:
+ token_out = ctx.step(token_in)
+ if not token_out:
+ break
+ gimrrdataprot.send_data(sock, gimrrdataprot.DATA_TYPE_AUTH_TOKEN, token_out)
+ data_type, token_in = gimrrdataprot.recv_data(sock)
+ if data_type == gimrrdataprot.DATA_TYPE_ERR:
+ sys.exit("server returned error: " + token_in.decode())
+ if data_type != gimrrdataprot.DATA_TYPE_AUTH_TOKEN:
+ sys.exit("expecting gssapi auth token")
+
+if os.stat(args.key).st_size > 4096:
+ sys.exit("key file too big")
+
+with open(args.key, "r") as fd:
+ key = fd.read()
+
+gimrrdataprot.send_data_enc(ctx, sock, gimrrdataprot.DATA_TYPE_PUB_KEY, key)
+
+data_type, data = gimrrdataprot.recv_data_dec(ctx, sock)
+if data_type == gimrrdataprot.DATA_TYPE_ERR:
+ sys.exit("server returned error: " + token_in.decode())
+if data_type != gimrrdataprot.DATA_TYPE_MSG:
+ sys.exit("expecting MSG from server")
+
+print(data.decode())