def pksadd(): keytext = request.form["keytext"] result = pgp.add_pgp_key(keytext) if result[0]: return "", 200, {"X-HKP-Results-Count": "1"} else: return "Key add failed", 400, {"X-HKP-Results-Count": "1"}
def handle_key_broadcast(): # Recieve a new key broadcast. if 'key' in request.form: key = request.form["key"] else: # Prevent crashes from recieving an empty post. return res = pgp.add_pgp_key(key) if res[0]: return "", 200 else: return "", 600 + res[1]
def addkey(): # Read in the key data from the form. try: keydata = request.args.get("keydata") except KeyError: return json.dumps({"error": 1, "msg": "no-key"}), 401, {"Content-Type": "application/json"} # Attempt to add the key. key = pgp.add_pgp_key(keydata) if key[0]: pgpactions.broadcast_add(key[2]) return json.dumps({"error": 0, "msg": key[1]}), 200, {"Content-Type": "application/json"} else: return json.dumps({"error": key[1], "msg": "invalid-key-data"}), 401, {"Content-Type": "application/json"}
def add(): # Get the key from the form key = request.form.get("enterkey") if not key: return render_template("submit.html") else: # Import the key imported = pgp.add_pgp_key(key) if not imported[0]: if imported[1] == -1: return render_template("submit.html", success=False, errormsg="Seems like an error happened importing your key. Double-check you copy/pasted it correctly.") elif imported[1] == -2: return render_template("submit.html", success=False, errormsg="Your key is already added on the server and is unchanged.") elif imported[1] == -3: return render_template("submit.html", success=False, errormsg="Your key was invalid and could not be imported.") else: keyinfo = pgp.get_pgp_keyinfo(imported[1]) broadcast_add(imported[2]) return redirect(url_for("frontend.getkeyinfo", key=keyinfo.shortid, added=True)), 302
def synch_keys(): print("Synching keys...") # We only synch once per bootup, because when a new key is added to any server, it's automatically distributed. # This ensures servers don't lag behind the rest of the pool. # Get the latest sync time. synch = db.Synch.query.order_by(db.Synch.synch_time.desc()).limit(1).first() if not synch: # No synchs has been made - this is the first one. dt = datetime.datetime(1970, 1, 1, 1, 0, 0) else: dt = synch.synch_time print("Synching since {}".format(dt)) # Open up our servers list. synch_servers = cfg.cfg.config.keyservers_synch # Contact them, one-by-one. synch_dict = {} for server in synch_servers: assert isinstance(server, str) if not server.startswith("http"): # Force HTTPS by default, for security. server_url = "https://" + server else: server_url = server server = server.split("://")[1] try: r = requests.get(server_url + "/api/v{}/sync/since".format(cfg.API_VERSION), params={"ts": dt.timestamp()}) except requests.exceptions.ConnectionError: # Whoops. continue if r.status_code != 200: # Server is either down or does not have pooling enabled. continue synch_dict[server] = r.json() chosen = (None, 0, []) # Choose server to synch from. for key, value in synch_dict.items(): if value["number"] > chosen[1]: chosen = (key, value["number"], value["keys"]) # Only the strongest and the fittest survive. # Begin downloading keys. for key in chosen[2]: base_url = "http://" + chosen[0] + "/api/v{}/getkey/{}".format(cfg.API_VERSION, key) try: r = requests.get(base_url) except requests.exceptions.ConnectionError: # what continue if r.status_code != 200: # This makes even less sense continue if not r.headers["content-type"] == "application/json": # This MAKES EVEN LESS SENSE continue keydata = r.json()["key"] pgp.add_pgp_key(keydata) # Update the synched table. new_synch = db.Synch() new_synch.synch_time = datetime.datetime.utcnow() new_synch.synch_count = chosen[1] db.db.session.add(new_synch) db.db.session.commit()
def import_key(keyserver: str, keyid: str): """ Attempts to import a key from the keyserver. :param keyserver: The keyserver to import from. :param keyid: The Key ID to import. :return: One of many codes: - 0: Success - -1: key not found - -2: Could not connect to keyserver - -3: Invalid key - -4: Already exists on server unchanged """ # Check to see if the server is a skier server. is_skier = False try: if 'http://' not in keyserver and "https://" not in keyserver: keyserver = "http://" + keyserver r = requests.post(keyserver + "/skier", data=[API_VERSION,SKIER_VERSION]) if r.status_code == 200: js = r.json() # Check the API version to make sure we're compatible. if js['api_version'] == API_VERSION: is_skier = True except: pass # Lookup the key. data = None if not is_skier: name = keyserver + "/pks/lookup" params = {"op": "get", "search": keyid, "options": "mr"} try: r = requests.get(name, params=params) except requests.exceptions.ConnectionError: return -2 else: if r.status_code == 200: data = r.text elif r.status_code == 404: return -1 elif r.status_code == 500: return -2 else: name = keyserver + "/api/{}/getkey/{}".format(API_VERSION, keyid) try: r = requests.get(name) except requests.exceptions.ConnectionError: return -2 else: if r.status_code == 200: data = r.json()['key'] else: return -1 if data: added = pgp.add_pgp_key(data) if added[0]: return 0 else: if added[1] == -1: # invalid return -3 elif added[1] == -2: # exists return -4