Browse Source

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

Added --no-encryption option and github transport
pull/5/head
Darknet Villain 7 years ago committed by GitHub
parent
commit
e54a17fbbe
  1. 18
      pyseeder.py
  2. 18
      pyseeder/actions.py
  3. 12
      pyseeder/crypto.py
  4. 2
      pyseeder/su3file.py
  5. 6
      pyseeder/transport.py
  6. 49
      pyseeder/transports/github.py
  7. 1
      requirements.txt
  8. 14
      transports.ini.example

18
pyseeder.py

@ -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()

18
pyseeder/actions.py

@ -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)

12
pyseeder/crypto.py

@ -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()

2
pyseeder/su3file.py

@ -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:

6
pyseeder/transport.py

@ -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))

49
pyseeder/transports/github.py

@ -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")

1
requirements.txt

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

14
transports.ini.example

@ -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

Loading…
Cancel
Save