commit 89f552b73b83dd44b3a4cb489d0b79fbd3198d25 Author: ilv ilv@users.noreply.github.com Date: Tue Jul 15 16:06:47 2014 -0400
Finally added fingerprint support. I got stuck on a 'concept error' for a long while. --- spec/design/core.txt | 38 ++++++++++++++++++++++---------------- src/dropbox.py | 32 +++++++++++++++++++++++--------- src/gettor.py | 31 ++++++++++++++++++++++++++----- 3 files changed, 71 insertions(+), 30 deletions(-)
diff --git a/spec/design/core.txt b/spec/design/core.txt index 4c180d6..ce07238 100644 --- a/spec/design/core.txt +++ b/spec/design/core.txt @@ -1,8 +1,11 @@ Google Summer of Code 2014 GetTor Revamp - Core module Author: Israel Leiva - <israel.leiva@usach.cl, ilv@riseup.net> - Last update: 2014-06-20 - Version: 0.04 - Changes: [0.04] + Last update: 2014-07-15 + Version: 0.05 + Changes: + [0.05] + Added fingerprint support + [0.04] Changed log format in 'Design' Added section 'Features' Deleted stuff from 'Discussion' and added some others @@ -81,7 +84,9 @@ files inside the providers directory. Each one of these files should follow the ConfigParser's format. There should be a section [provider] with the option 'name' for the provider's - name (e.g. Dropbox) + name (e.g. Dropbox), and a section [key] with the option + 'fingerprint' for the key's fingerprint that signed the + uploaded packages.
Following sections should specify the operating system and its options should be the locale. When more than one link is @@ -89,32 +94,33 @@ should be specified as a multiline value. Each link has the format:
- link link_signature key_fingerprint + link link_signature
Example:
[provider] name: Dropbox
+ [key] + fingerprint: 123A 456B 789C 012D 345E 678F 901G 234H 567I 890J + [linux] - en: https://foo.bar https://foo.bar.asc 111-222-333-444, - https://foo.bar https://foo.bar.asc 555-666-777-888 + en: https://foo.bar https://foo.bar.asc, + https://foo.bar https://foo.bar.asc
- es: https://bar.baz https://bar.baz.asc 555-666-777-888 + es: https://bar.baz https://bar.baz.asc
PROVIDER NAME - operating_system locale link package_signature key_fingerprint - - The key fingerprint is joined by '-' characters for convenience, - but it's sent back to the service module separated by spaces. + operating_system locale link package_signature
- The official mirrors are considered as just another provider. + NOTE: For now, the official mirrors are considered just as + another provider.
_log_request(operating_system, locale) - Log information about the request for future stats (e.g. which - OS from which service is the most required). All logging - should be done with the logging module. + Log information about the request for future stats (e.g. which + OS from which service is the most required). All logging + should be done with the logging module.
* Providers: There should be one module/script per provider in charge of generating the .links file with the proper format, including diff --git a/src/dropbox.py b/src/dropbox.py index e6612a9..08084ef 100644 --- a/src/dropbox.py +++ b/src/dropbox.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import re import os +import gnupg import dropbox import gettor
@@ -58,9 +59,7 @@ def upload_files(basedir, client):
for name in os.listdir(basedir): path = os.path.abspath(os.path.join(basedir, name)) - if os.path.isfile(path) - and p.match(path) - and valid_bundle_format(name): + if os.path.isfile(path) and p.match(path) and valid_bundle_format(name): files.append(name)
for file in files: @@ -89,27 +88,42 @@ def upload_files(basedir, client): return files
# Test app for now +# TO DO: use config file app_key = '' app_secret = '' access_token = '' -# Should we use a dropbox.cfg? upload_dir = 'upload/' +tbb_key = 'tbb-key.asc'
client = dropbox.client.DropboxClient(access_token)
+# Import key that signed the packages and get fingerprint +gpg = gnupg.GPG() +key_data = open(tbb_key).read() +import_result = gpg.import_keys(key_data) +fingerprint = import_result.results[0]['fingerprint'] +# Make groups of four characters to make fingerprint more readable +# e.g. 123A 456B 789C 012D 345E 678F 901G 234H 567I 890J +readable = ' '.join(fingerprint[i:i+4] for i in xrange(0, len(fingerprint), 4)) + try: uploaded_files = upload_files(upload_dir, client) - # Fingerprint generation pending... - fingerprint = '111-222-333-444' core = gettor.Core('gettor.cfg') - # Erase the old links file - core.create_links_file('Dropbox') + # This erases the old links file + core.create_links_file('Dropbox', readable)
for file in uploaded_files: + # build file names asc = file + '.asc' + abs_file = os.path.abspath(os.path.join(upload_dir, file)) + abs_asc = os.path.abspath(os.path.join(upload_dir, asc)) + + # build links link_file = client.share(file) link_asc = client.share(asc) - link = link_file[u'url'] + ' ' + link_asc[u'url'] + ' ' + fingerprint + link = link_file[u'url'] + ' ' + link_asc[u'url'] + + # add links operating_system, locale = get_bundle_info(file) core.add_link('Dropbox', operating_system, locale, link) except (ValueError, RuntimeError) as e: diff --git a/src/gettor.py b/src/gettor.py index d5492cd..253c01e 100644 --- a/src/gettor.py +++ b/src/gettor.py @@ -262,7 +262,21 @@ class Core(object): providers[pname] = self._get_config_option(operating_system, locale, config) except RuntimeError as e: - self.logger.warning("Links misconfiguration %s" % str(e)) + self.logger.warning("-- Links misconfiguration %s" % str(e)) + + # Each provider must have a fingerprint of the key used to + # sign the uploaded packages + try: + self.logger.debug("-- Trying to get fingerprint from %s", + pname) + fingerprint = self._get_config_option('key', 'fingerprint', + config) + providers[pname] = providers[pname] + "\nFingerprint: " + providers[pname] = providers[pname] + fingerprint + self.logger.debug("-- Fingerprint added %s", fingerprint) + except ValueError as e: + self.logger.warning("-- No fingerprint found for provider %s" % + pname)
# Create the final links list with all providers all_links = [] @@ -273,7 +287,7 @@ class Core(object): all_links.append( "\n%s\n%s\n" % (key, ''.join(providers[key])) ) - + if all_links: return "".join(all_links) else: @@ -312,19 +326,24 @@ class Core(object): except ConfigParser.Error as e: raise RuntimeError("Unexpected error: %s" % str(e))
- def create_links_file(self, provider): + def create_links_file(self, provider, fingerprint): """ Public method to create a links file for a provider.
This should be used by all providers since it writes the links file with the proper format. It backs up the old links file (if exists) and creates a new one. The name for the links file - is the provider's name in lowercase. It raises a general - exception if something goes wrong while creating the new file. + is the provider's name in lowercase. It receives the fingerprint + of the key that signed the packages. + + It raises a general exception if something goes wrong while + creating the new file.
Arguments: provider: Provider's name. The links file will use this name in lower case. + fingerprint: Fingerprint of the key that signed the packages + to be uploaded to the provider. """ linksfile = os.path.join(self.linksdir, provider.lower() + '.links') linksfile_backup = "" @@ -342,6 +361,8 @@ class Core(object): content = ConfigParser.RawConfigParser() content.add_section('provider') content.set('provider', 'name', provider) + content.add_section('key') + content.set('key', 'fingerprint', fingerprint) content.add_section('linux') content.add_section('windows') content.add_section('osx')