1
0
mirror of https://github.com/PurpleI2P/pyseeder synced 2025-01-30 16:44:16 +00:00

Merge pull request #4 from l-n-s/devel

Added --no-encryption option and github transport
This commit is contained in:
Darknet Villain 2017-06-26 09:14:22 +00:00 committed by GitHub
commit e54a17fbbe
8 changed files with 108 additions and 12 deletions

View File

@ -2,13 +2,20 @@
import os import os
import sys import sys
import argparse import argparse
import logging
import pyseeder.transport import pyseeder.transport
import pyseeder.actions import pyseeder.actions
from pyseeder.utils import PyseederException from pyseeder.utils import PyseederException
log = logging.getLogger(__name__)
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--loglevel', default=logging.INFO, help="Log level",
choices=[logging.CRITICAL, logging.ERROR, logging.WARNING,
logging.INFO, logging.DEBUG])
subparsers = parser.add_subparsers(title="actions", subparsers = parser.add_subparsers(title="actions",
help="Command to execute") help="Command to execute")
@ -25,6 +32,8 @@ def main():
help="RSA private key (default: data/priv_key.pem)") help="RSA private key (default: data/priv_key.pem)")
kg_parser.add_argument("--cert", default=None, kg_parser.add_argument("--cert", default=None,
help="Certificate (example: data/user_at_mail.i2p.crt)") help="Certificate (example: data/user_at_mail.i2p.crt)")
kg_parser.add_argument("--no-encryption", action="store_true",
help="Disable private key encryption")
kg_parser.set_defaults(func=pyseeder.actions.keygen) kg_parser.set_defaults(func=pyseeder.actions.keygen)
@ -44,6 +53,8 @@ echo $YOUR_PASSWORD | %(prog)s --netdb /path/to/netDb \\
help="Output file (default: output/i2pseeds.su3)") help="Output file (default: output/i2pseeds.su3)")
rs_parser.add_argument("--netdb", required=True, rs_parser.add_argument("--netdb", required=True,
help="Path to netDb folder (example: ~/.i2pd/netDb)") help="Path to netDb folder (example: ~/.i2pd/netDb)")
rs_parser.add_argument("--no-encryption", action="store_true",
help="Disable private key encryption")
rs_parser.set_defaults(func=pyseeder.actions.reseed) rs_parser.set_defaults(func=pyseeder.actions.reseed)
@ -97,12 +108,17 @@ echo $YOUR_PASSWORD | %(prog)s --netdb /path/to/netDb \\
help=".su3 file (default: output/i2pseeds.su3)") help=".su3 file (default: output/i2pseeds.su3)")
serve_parser.set_defaults(func=pyseeder.actions.serve) serve_parser.set_defaults(func=pyseeder.actions.serve)
args = parser.parse_args() args = parser.parse_args()
logging.basicConfig(level=args.loglevel,
format='%(levelname)-8s %(message)s')
if hasattr(args, "func"): if hasattr(args, "func"):
try: try:
args.func(args) args.func(args)
except PyseederException as pe: except PyseederException as pe:
print("Pyseeder error: {}".format(pe)) log.critical("Pyseeder error: {}".format(pe))
sys.exit(1) sys.exit(1)
else: else:
parser.print_help() parser.print_help()

View File

@ -11,9 +11,14 @@ def keygen(args):
for f in [args.cert, args.private_key]: check_writable(f) for f in [args.cert, args.private_key]: check_writable(f)
from pyseeder.crypto import keygen from pyseeder.crypto import keygen
from getpass import getpass
priv_key_password = getpass("Set private key password: ").encode("utf-8") if args.no_encryption:
keygen(args.cert, args.private_key, priv_key_password, args.signer_id) priv_key_password = None
else:
from getpass import getpass
priv_key_password = getpass("Set private key password: ").encode("utf-8")
keygen(args.cert, args.private_key, args.signer_id, priv_key_password)
def reseed(args): def reseed(args):
"""Sub-command to generate reseed file""" """Sub-command to generate reseed file"""
@ -21,7 +26,12 @@ def reseed(args):
for f in [args.netdb, args.private_key]: check_readable(f) for f in [args.netdb, args.private_key]: check_readable(f)
from pyseeder.su3file import SU3File from pyseeder.su3file import SU3File
priv_key_password = input().encode("utf-8")
if args.no_encryption:
priv_key_password = None
else:
priv_key_password = input().encode("utf-8")
su3file = SU3File(args.signer_id) su3file = SU3File(args.signer_id)
su3file.reseed(args.netdb) su3file.reseed(args.netdb)
su3file.write(args.outfile, args.private_key, priv_key_password) su3file.write(args.outfile, args.private_key, priv_key_password)

View File

@ -13,19 +13,23 @@ from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.asymmetric import padding
def keygen(pub_key, priv_key, priv_key_password, user_id): def keygen(pub_key, priv_key, user_id, priv_key_password=None):
"""Generate new private key and certificate RSA_SHA512_4096""" """Generate new private key and certificate RSA_SHA512_4096"""
# Generate our key # Generate our key
key = rsa.generate_private_key(public_exponent=65537, key_size=4096, key = rsa.generate_private_key(public_exponent=65537, key_size=4096,
backend=default_backend()) backend=default_backend())
if priv_key_password:
ea = serialization.BestAvailableEncryption(priv_key_password)
else:
ea = serialization.NoEncryption()
# Write our key to disk for safe keeping # Write our key to disk for safe keeping
with open(priv_key, "wb") as f: with open(priv_key, "wb") as f:
f.write(key.private_bytes( f.write(key.private_bytes(
encoding=serialization.Encoding.PEM, encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL, format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.BestAvailableEncryption( encryption_algorithm=ea,
priv_key_password),
)) ))
# Various details about who we are. For a self-signed certificate the # Various details about who we are. For a self-signed certificate the
@ -57,7 +61,7 @@ def keygen(pub_key, priv_key, priv_key_password, user_id):
f.write(cert.public_bytes(serialization.Encoding.PEM)) f.write(cert.public_bytes(serialization.Encoding.PEM))
def append_signature(target_file, priv_key, priv_key_password): def append_signature(target_file, priv_key, priv_key_password=None):
"""Append signature to the end of file""" """Append signature to the end of file"""
with open(target_file, "rb") as f: with open(target_file, "rb") as f:
contents = f.read() contents = f.read()

View File

@ -25,7 +25,7 @@ class SU3File:
self.VERSION = str(int(time.time())).encode("utf-8") self.VERSION = str(int(time.time())).encode("utf-8")
#self.keytype = "RSA_SHA512_4096" #self.keytype = "RSA_SHA512_4096"
def write(self, filename, priv_key, priv_key_password): def write(self, filename, priv_key, priv_key_password=None):
"""Write file to disc""" """Write file to disc"""
nullbyte = bytes([0]) nullbyte = bytes([0])
with open(filename, "wb") as f: with open(filename, "wb") as f:

View File

@ -3,9 +3,11 @@ import urllib.request
from urllib.error import URLError from urllib.error import URLError
import os import os
import importlib import importlib
import logging
from pyseeder.utils import PyseederException from pyseeder.utils import PyseederException, TransportException
log = logging.getLogger(__name__)
RESEED_URLS = [ RESEED_URLS = [
"https://reseed.i2p-projekt.de/", "https://reseed.i2p-projekt.de/",
@ -55,4 +57,6 @@ def upload(filename, config):
except ImportError: except ImportError:
raise PyseederException( raise PyseederException(
"{} transport can't be loaded".format(t)) "{} transport can't be loaded".format(t))
except TransportException as e:
log.error("Transport error: {}".format(e))

View File

@ -0,0 +1,49 @@
#!/usr/bin/env python3
# (re)uploads reseed file to github repository releases as an asset
import requests
from urllib.parse import urljoin
from mimetypes import guess_type
import sys
import os
from pyseeder.utils import TransportException
TRANSPORT_NAME = "github"
def run(filename, config):
API_URL = "https://api.github.com/"
asset_name = os.path.split(filename)[-1]
content_type = guess_type(asset_name)[0] or "application/zip"
creds = (config["username"], config["token"])
release_info_url = urljoin(API_URL, "/repos/{}/releases/tags/{}".format(
config["repo"], config["release_tag"]))
# get release info
try:
resp = requests.get(release_info_url, auth=creds)
except:
raise TransportException("Failed to connect to GitHub API")
if resp.status_code is not 200:
raise TransportException("Check your GitHub API auth settings")
# delete old asset
for x in resp.json()["assets"]:
if x["name"] == asset_name:
r = requests.delete(x["url"], auth=creds)
if r.status_code is not 204:
raise TransportException("Failed to delete asset from GitHub")
# upload new asset
upload_url = resp.json()["upload_url"].split("{")[0] # wat
headers = {'Content-Type': content_type}
params = {'name': asset_name}
data = open(filename, 'rb').read()
r = requests.post(upload_url, headers=headers, params=params, auth=creds,
data=data)
if r.status_code is not 201:
raise TransportException("Failed to upload asset to GitHub API")

View File

@ -1 +1,2 @@
cryptography>=1.4 cryptography>=1.4
requests

View File

@ -1,6 +1,6 @@
[transports] [transports]
; enabled transports separated by space ; enabled transports separated by space
enabled=git enabled=github
[git] [git]
; Folder with git repository to use ; Folder with git repository to use
@ -8,3 +8,15 @@ folder=/home/user/reseed-data-repo
[dropbox] [dropbox]
; todo ; todo
[github]
; GitHub username
username=username
; GitHub API token
; Generate token for this script here --> https://github.com/settings/tokens
; Check scope: public_repo (shall be enough)
token=token
; Repository
repo=username/repo-name
; Repository tag to which asset is being uploaded
release_tag=v1.0