From 189cda437fec933f036d41fa011e6dd8c7f3f956 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 22 Mar 2016 18:02:40 -0400 Subject: [PATCH] Add model test. Finish file signing method. Add key signing exceptions. --- mayan/apps/django_gpg/admin.py | 22 +-- mayan/apps/django_gpg/exceptions.py | 12 ++ mayan/apps/django_gpg/literals.py | 8 + .../migrations/0002_auto_20160322_1756.py | 24 +++ .../migrations/0003_auto_20160322_1810.py | 59 ++++++++ .../migrations/0004_auto_20160322_2202.py | 24 +++ mayan/apps/django_gpg/models.py | 141 ++++++++++++------ mayan/apps/django_gpg/settings.py | 12 +- mayan/apps/django_gpg/tests/literals.py | 63 ++++++++ mayan/apps/django_gpg/tests/test_models.py | 16 ++ 10 files changed, 316 insertions(+), 65 deletions(-) create mode 100644 mayan/apps/django_gpg/migrations/0002_auto_20160322_1756.py create mode 100644 mayan/apps/django_gpg/migrations/0003_auto_20160322_1810.py create mode 100644 mayan/apps/django_gpg/migrations/0004_auto_20160322_2202.py create mode 100644 mayan/apps/django_gpg/tests/test_models.py diff --git a/mayan/apps/django_gpg/admin.py b/mayan/apps/django_gpg/admin.py index 4de5c004be..8aa6c2872d 100644 --- a/mayan/apps/django_gpg/admin.py +++ b/mayan/apps/django_gpg/admin.py @@ -7,21 +7,9 @@ from .models import Key @admin.register(Key) class KeyAdmin(admin.ModelAdmin): - #date_hierarchy = 'datetime' - list_display = ('key_id', 'user_id', 'key_type') - #readonly_fields = list_display - - """ - key_id = models.CharField( - max_length=16, unique=True, verbose_name=_('Key ID') + list_display = ( + 'key_id', 'user_id', 'creation_date', 'expiration_date', 'key_type' ) - creation_date = models.DateField(verbose_name=_('Creation date')) - expiration_date = models.DateField(verbose_name=_('Expiration date')) - fingerprint = models.CharField( - max_length=40, verbose_name=_('Fingerprint') - ) - length = models.PositiveIntegerField(verbose_name=_('Length')) - algorithm = models.PositiveIntegerField(verbose_name=_('Algorithm')) - user_id = models.TextField(verbose_name=_('User ID')) - key_type = models.CharField(max_length=3, verbose_name=_('Type')) - """ + list_filter = ('key_type',) + readonly_fields = list_display + ('fingerprint', 'length', 'algorithm') + search_fields = ('key_id', 'user_id',) diff --git a/mayan/apps/django_gpg/exceptions.py b/mayan/apps/django_gpg/exceptions.py index e9473a61bf..31691d4a42 100644 --- a/mayan/apps/django_gpg/exceptions.py +++ b/mayan/apps/django_gpg/exceptions.py @@ -39,3 +39,15 @@ class KeyDoesNotExist(GPGException): class KeyImportError(GPGException): pass + + +class NeedPassphrase(GPGException): + """ + Passphrase is needed but none was provided + """ + + +class PassphraseError(GPGException): + """ + Passphrase provided is incorrect + """ diff --git a/mayan/apps/django_gpg/literals.py b/mayan/apps/django_gpg/literals.py index 85b75e061f..2a8b14997a 100644 --- a/mayan/apps/django_gpg/literals.py +++ b/mayan/apps/django_gpg/literals.py @@ -7,6 +7,14 @@ KEY_TYPES = { 'sec': _('Secret'), } +KEY_TYPE_PUBLIC = 'pub' +KEY_TYPE_SECRET = 'sec' + +KEY_TYPE_CHOICES = ( + (KEY_TYPE_PUBLIC, _('Public')), + (KEY_TYPE_SECRET, _('Secret')), +) + KEY_CLASS_RSA = 'RSA' KEY_CLASS_DSA = 'DSA' KEY_CLASS_ELG = 'ELG-E' diff --git a/mayan/apps/django_gpg/migrations/0002_auto_20160322_1756.py b/mayan/apps/django_gpg/migrations/0002_auto_20160322_1756.py new file mode 100644 index 0000000000..fd085a20d6 --- /dev/null +++ b/mayan/apps/django_gpg/migrations/0002_auto_20160322_1756.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_gpg', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='key', + name='data', + ), + migrations.AddField( + model_name='key', + name='key_data', + field=models.TextField(default='', verbose_name='Key data'), + preserve_default=False, + ), + ] diff --git a/mayan/apps/django_gpg/migrations/0003_auto_20160322_1810.py b/mayan/apps/django_gpg/migrations/0003_auto_20160322_1810.py new file mode 100644 index 0000000000..40689f948e --- /dev/null +++ b/mayan/apps/django_gpg/migrations/0003_auto_20160322_1810.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_gpg', '0002_auto_20160322_1756'), + ] + + operations = [ + migrations.AlterField( + model_name='key', + name='algorithm', + field=models.PositiveIntegerField(verbose_name='Algorithm', editable=False), + ), + migrations.AlterField( + model_name='key', + name='creation_date', + field=models.DateField(verbose_name='Creation date', editable=False), + ), + migrations.AlterField( + model_name='key', + name='expiration_date', + field=models.DateField(verbose_name='Expiration date', null=True, editable=False, blank=True), + ), + migrations.AlterField( + model_name='key', + name='fingerprint', + field=models.CharField(verbose_name='Fingerprint', unique=True, max_length=40, editable=False), + ), + migrations.AlterField( + model_name='key', + name='key_data', + field=models.TextField(verbose_name='Key data', editable=False), + ), + migrations.AlterField( + model_name='key', + name='key_id', + field=models.CharField(verbose_name='Key ID', unique=True, max_length=16, editable=False), + ), + migrations.AlterField( + model_name='key', + name='key_type', + field=models.CharField(verbose_name='Type', max_length=3, editable=False), + ), + migrations.AlterField( + model_name='key', + name='length', + field=models.PositiveIntegerField(verbose_name='Length', editable=False), + ), + migrations.AlterField( + model_name='key', + name='user_id', + field=models.TextField(verbose_name='User ID', editable=False), + ), + ] diff --git a/mayan/apps/django_gpg/migrations/0004_auto_20160322_2202.py b/mayan/apps/django_gpg/migrations/0004_auto_20160322_2202.py new file mode 100644 index 0000000000..a2bea9e955 --- /dev/null +++ b/mayan/apps/django_gpg/migrations/0004_auto_20160322_2202.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_gpg', '0003_auto_20160322_1810'), + ] + + operations = [ + migrations.AlterField( + model_name='key', + name='key_data', + field=models.TextField(verbose_name='Key data'), + ), + migrations.AlterField( + model_name='key', + name='key_type', + field=models.CharField(verbose_name='Type', max_length=3, editable=False, choices=[('pub', 'Public'), ('sec', 'Secret')]), + ), + ] diff --git a/mayan/apps/django_gpg/models.py b/mayan/apps/django_gpg/models.py index 49f7763b51..14bf97b1e9 100644 --- a/mayan/apps/django_gpg/models.py +++ b/mayan/apps/django_gpg/models.py @@ -1,10 +1,5 @@ from __future__ import absolute_import, unicode_literals -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO - from datetime import date import logging import os @@ -13,20 +8,37 @@ import tempfile import gnupg -from django.conf import settings -from django.core.exceptions import PermissionDenied -from django.core.files import File -from django.core.urlresolvers import reverse -from django.db import models, transaction +from django.core.exceptions import ValidationError +from django.db import models from django.utils.encoding import python_2_unicode_compatible -from django.utils.timezone import now -from django.utils.translation import ugettext, ugettext_lazy as _ +from django.utils.translation import ugettext_lazy as _ -from .settings import setting_gpg_path, setting_keyservers +from .literals import KEY_TYPE_CHOICES, KEY_TYPE_SECRET +from .exceptions import NeedPassphrase, PassphraseError +from .settings import setting_gpg_path, setting_keyserver +ERROR_MSG_NEED_PASSPHRASE = 'NEED_PASSPHRASE' +ERROR_MSG_BAD_PASSPHRASE = 'BAD_PASSPHRASE' +ERROR_MSG_GOOD_PASSPHRASE = 'GOOD_PASSPHRASE' +OUTPUT_MESSAGE_CONTAINS_PRIVATE_KEY = 'Contains private key' logger = logging.getLogger(__name__) +def gpg_command(function): + temporary_directory = tempfile.mkdtemp() + os.chmod(temporary_directory, 0x1C0) + + gpg = gnupg.GPG( + gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value + ) + + result = function(gpg=gpg) + + shutil.rmtree(temporary_directory) + + return result + + class KeyManager(models.Manager): def receive_key(self, key_id): temporary_directory = tempfile.mkdtemp() @@ -37,7 +49,7 @@ class KeyManager(models.Manager): gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value ) - import_results = gpg.recv_keys(setting_keyservers.value[0], key_id) + import_results = gpg.recv_keys(setting_keyserver.value, key_id) key_data = gpg.export_keys(import_results.fingerprints[0]) @@ -52,29 +64,48 @@ class KeyManager(models.Manager): gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value ) - result = gpg.search_keys(query=query, keyserver=setting_keyservers.value[0]) + result = gpg.search_keys( + query=query, keyserver=setting_keyserver.value + ) shutil.rmtree(temporary_directory) return result + def public_keys(self): + return self.filter(key_type='pub') + + def private_keys(self): + return self.filter(key_type='') + @python_2_unicode_compatible class Key(models.Model): - data = models.TextField(verbose_name=_('Data')) + key_data = models.TextField(verbose_name=_('Key data')) key_id = models.CharField( - max_length=16, unique=True, verbose_name=_('Key ID') + editable=False, max_length=16, unique=True, verbose_name=_('Key ID') + ) + creation_date = models.DateField( + editable=False, verbose_name=_('Creation date') ) - creation_date = models.DateField(verbose_name=_('Creation date')) expiration_date = models.DateField( - blank=True, null=True, verbose_name=_('Expiration date') + blank=True, editable=False, null=True, + verbose_name=_('Expiration date') ) fingerprint = models.CharField( - max_length=40, unique=True, verbose_name=_('Fingerprint') + editable=False, max_length=40, unique=True, + verbose_name=_('Fingerprint') + ) + length = models.PositiveIntegerField( + editable=False, verbose_name=_('Length') + ) + algorithm = models.PositiveIntegerField( + editable=False, verbose_name=_('Algorithm') + ) + user_id = models.TextField(editable=False, verbose_name=_('User ID')) + key_type = models.CharField( + choices=KEY_TYPE_CHOICES, editable=False, max_length=3, + verbose_name=_('Type') ) - length = models.PositiveIntegerField(verbose_name=_('Length')) - algorithm = models.PositiveIntegerField(verbose_name=_('Algorithm')) - user_id = models.TextField(verbose_name=_('User ID')) - key_type = models.CharField(max_length=3, verbose_name=_('Type')) objects = KeyManager() @@ -82,44 +113,49 @@ class Key(models.Model): verbose_name = _('Key') verbose_name_plural = _('Keys') + def clean(self): + def import_key(gpg): + return gpg.import_keys(key_data=self.key_data) + + import_results = gpg_command(function=import_key) + + if not import_results.count: + raise ValidationError('Invalid key data') + def save(self, *args, **kwargs): temporary_directory = tempfile.mkdtemp() - logger.debug('temporary_directory: %s', temporary_directory) - gpg = gnupg.GPG( gnupghome=temporary_directory, gpgbinary=setting_gpg_path.value ) - import_results = gpg.import_keys(key_data=self.data) + import_results = gpg.import_keys(key_data=self.key_data) - logger.debug('import_results.results: %s', import_results.results) - logger.debug('import_results.fingerprints: %s', import_results.fingerprints) + key_info = gpg.list_keys(keys=import_results.fingerprints[0])[0] - key_data = gpg.list_keys(keys=import_results.fingerprints[0])[0] - - logger.debug('key_data: %s', key_data) + logger.debug('key_info: %s', key_info) shutil.rmtree(temporary_directory) - self.key_id = key_data['keyid'] - self.algorithm = key_data['algo'] - self.creation_date = date.fromtimestamp(int(key_data['date'])) - if key_data['expires']: - self.expiration_date = date.fromtimestamp(int(key_data['expires'])) - self.fingerprint = key_data['fingerprint'] - self.length = int(key_data['length']) - self.user_id = key_data['uids'][0] - self.key_type = key_data['type'] + self.key_id = key_info['keyid'] + self.algorithm = key_info['algo'] + self.creation_date = date.fromtimestamp(int(key_info['date'])) + if key_info['expires']: + self.expiration_date = date.fromtimestamp(int(key_info['expires'])) + self.fingerprint = key_info['fingerprint'] + self.length = int(key_info['length']) + self.user_id = key_info['uids'][0] + if OUTPUT_MESSAGE_CONTAINS_PRIVATE_KEY in import_results.results[0]['text']: + self.key_type = KEY_TYPE_SECRET + else: + self.key_type = key_info['type'] super(Key, self).save(*args, **kwargs) def __str__(self): return self.key_id - def sign_file(self, file_object, passphrase=None, clearsign=True, detach=False, binary=False): - output = StringIO() - + def sign_file(self, file_object, passphrase=None, clearsign=True, detached=False, binary=False, output=None): temporary_directory = tempfile.mkdtemp() gpg = gnupg.GPG( @@ -128,3 +164,20 @@ class Key(models.Model): import_results = gpg.import_keys(key_data=self.data) + file_sign_results = gpg.sign_file( + file=file_object, keyid=import_results.fingerprints[0], + passphrase=passphrase, clearsign=clearsign, detach=detached, + binary=binary, output=output + ) + + shutil.rmtree(temporary_directory) + + logger.debug('file_sign_results.stderr: %s', file_sign_results.stderr) + + if ERROR_MSG_NEED_PASSPHRASE in file_sign_results.stderr: + if ERROR_MSG_BAD_PASSPHRASE in file_sign_results.stderr: + raise PassphraseError + elif ERROR_MSG_GOOD_PASSPHRASE not in file_sign_results.stderr: + raise NeedPassphrase + + return file_sign_results diff --git a/mayan/apps/django_gpg/settings.py b/mayan/apps/django_gpg/settings.py index 10d7464fb1..c7d3da34f1 100644 --- a/mayan/apps/django_gpg/settings.py +++ b/mayan/apps/django_gpg/settings.py @@ -8,10 +8,6 @@ from django.utils.translation import ugettext_lazy as _ from smart_settings import Namespace namespace = Namespace(name='django_gpg', label=_('Signatures')) -setting_keyservers = namespace.add_setting( - global_name='SIGNATURES_KEYSERVERS', default=['pool.sks-keyservers.net'], - help_text=_('List of keyservers to be queried for unknown keys.') -) setting_gpg_home = namespace.add_setting( global_name='SIGNATURES_GPG_HOME', default=os.path.join(settings.MEDIA_ROOT, 'gpg_home'), @@ -24,3 +20,11 @@ setting_gpg_path = namespace.add_setting( global_name='SIGNATURES_GPG_PATH', default='/usr/bin/gpg', help_text=_('Path to the GPG binary.'), is_path=True ) +setting_keyserver = namespace.add_setting( + global_name='SIGNATURES_KEYSERVER', default='pool.sks-keyservers.net', + help_text=_('Keyserver used to query for keys.') +) +setting_keyservers = namespace.add_setting( + global_name='SIGNATURES_KEYSERVERS', default=['pool.sks-keyservers.net'], + help_text=_('List of keyservers to be queried for unknown keys.') +) diff --git a/mayan/apps/django_gpg/tests/literals.py b/mayan/apps/django_gpg/tests/literals.py index 6d18beb52d..822bdcd593 100644 --- a/mayan/apps/django_gpg/tests/literals.py +++ b/mayan/apps/django_gpg/tests/literals.py @@ -4,3 +4,66 @@ TEST_GPG_HOME = '/tmp/test_gpg_home' TEST_KEY_ID = '607138F1AECC5A5CA31CB7715F3F7F75D210724D' TEST_KEYSERVERS = ['pool.sks-keyservers.net'] TEST_UIDS = 'Roberto Rosario' + +TEST_KEY_DATA = '''-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG v1 + +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 +8aeg3z/W+YctdRt81bi5isgM+oML9LAQ +=JZ5G +-----END PGP PRIVATE KEY BLOCK-----''' + +TEST_KEY_ID = '4125E9C571F378AC' +TEST_KEY_FINGERPRINT = '6A24574E0A35004CDDFD22704125E9C571F378AC' diff --git a/mayan/apps/django_gpg/tests/test_models.py b/mayan/apps/django_gpg/tests/test_models.py new file mode 100644 index 0000000000..69d74f3b04 --- /dev/null +++ b/mayan/apps/django_gpg/tests/test_models.py @@ -0,0 +1,16 @@ +from __future__ import unicode_literals + +from django.test import TestCase + +from ..models import Key + +from .literals import TEST_KEY_DATA, TEST_KEY_FINGERPRINT, TEST_KEY_ID + + +class KeyTestCase(TestCase): + def test_key_instance_creation(self): + # Creating a Key instance is analogous to importing a key + key = Key.objects.create(key_data=TEST_KEY_DATA) + + self.assertEqual(key.key_id, TEST_KEY_ID) + self.assertEqual(key.fingerprint, TEST_KEY_FINGERPRINT)