pax_global_header 0000666 0000000 0000000 00000000064 12314573364 0014522 g ustar 00root root 0000000 0000000 52 comment=fcf4ec291a77e54964d04200af06ffbc1a6ca634 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/ 0000775 0000000 0000000 00000000000 12314573364 0027206 5 ustar 00root root 0000000 0000000 .gitignore 0000664 0000000 0000000 00000000067 12314573364 0031122 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 *.py[coa] /django_sshkey.egg-info /testproject/test.db LICENSE 0000664 0000000 0000000 00000002726 12314573364 0030143 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 Copyright (c) 2014, Clemson University All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the {organization} nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MANIFEST.in 0000664 0000000 0000000 00000000533 12314573364 0030666 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 include LICENSE include README.rst include README.upgrading.rst include lookup.py include lookup.sh include django-sshkey-lookup include django-sshkey-lookup-all include django-sshkey-lookup-by-username include django-sshkey-lookup-by-fingerprint recursive-include django_sshkey/migrations *.py recursive-include django_sshkey/templates.example * README.rst 0000664 0000000 0000000 00000014265 12314573364 0030626 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 ============= django-sshkey ============= django-sshkey allows you to associate multiple SSH public keys with Django user accounts. It provides views to list, add, edit, and delete keys, each of which is intended for end-user consumption. It also provides a lookup view and corresponding lookup commands that are suitable for use with the ``AuthorizedKeysCommand`` feature in OpenSSH_ 6.2 and above. The Django app ============== To use django-sshkey in your Django project, simply add ``django_sshkey`` to ``INSTALLED_APPS`` in ``settings.py``, map the URLs into your project, and provide templates for the views (example templates are provided in the source). In order to associate an incoming public key with a user you must define ``SSHKEY_AUTHORIZED_KEYS_OPTIONS`` in your project's ``settings.py``. This should be a string containing options accepted by sshd, with ``{username}`` being replaced with the username of the user associated with the incoming public key. For instance:: SSHKEY_AUTHORIZED_KEYS_OPTIONS = 'command="my-command {username}",no-pty' in settings.py will cause keys produced by the below commands to look similar to:: command="my-command fred",no-pty ssh-rsa AAAAB3NzaC1yc2E... assuming the key ``AAAAB3NzaC1yc2E...`` is owned by fred. URL Configuration ----------------- This text assumes that your project's ``urls.py`` maps ``django_sshkey.urls`` into the URL namespace as follows:: import django_sshkey.urls urlpatterns = patterns('', ... url('^sshkey/', include(django_sshkey.urls)), ... ) You will need to adjust your URLs in the examples below if you use a different mapping. .. WARNING:: The ``/sshkey/lookup`` URL can expose all public keys that have been uploaded to your site. Although they are public keys, it is probably a good idea to limit what systems can access this URL via your web server's configuration. Most of the lookup methods below require access to this URL, and only the systems that need to run the lookup commands should have access to it. Tying OpenSSH to django-sshkey ============================== There are multiple methods of connecting OpenSSH to django-sshkey. All of the methods listed here require the use of the ``AuthorizedKeysCommand`` directive in ``sshd_config`` present in OpenSSH 6.2 and above. Please note that the command that is referenced by this directive and its ancestor directories must be owned by root and writable only by owner. Unless otherwise stated, all of the methods below use the ``SSHKEY_LOOKUP_URL`` environment variable to determine the URL of the ``/sshkey/lookup`` URL. If this environment variable is not defined then it will default to ``http://localhost:8000/sshkey/lookup``. If this environment variable is defined in the sshd process then it will be inherited by the ``AuthorizedKeysCommand``. Additionally, all of the methods below use either ``curl`` (preferred) or ``wget``. Some commands also use ``ssh-keygen``. These commands must be present in ``PATH``. If you would prefer not to use these external commands then there are variants of the lookup commands implemented purely in Python. However, they are *much* slower. To use the variants, replace ``lookup`` with ``pylookup``. For example, use ``django-sshkey-pylookup-all`` instead of ``django-sshkey-lookup-all``. Using ``django-sshkey-lookup-all`` ---------------------------------- ``Usage: django-sshkey-lookup-all`` This program prints all SSH public keys that are defined on your site. sshd will have to scan through all of them to find the first match, so with many keys this method will be slow. However, it does not require a patched OpenSSH server. This program: * can be used directly with ``AuthorizedKeysCommand`` (the username parameter is ignored). * does not require a patched OpenSSH server. * does not scale well to a large number of user keys. Using ``django-sshkey-lookup-by-username`` ------------------------------------------ ``Usage: django-sshkey-lookup-by-username USERNAME`` This program prints all SSH public keys that are associated with the specified user. This program: * can be used directly with ``AuthorizedKeysCommand``. * does not require a patched OpenSSH server. * is ideal if each Django user corresponds to a system user account. Using ``django-sshkey-lookup-by-fingerprint`` --------------------------------------------- ``Usage: django-sshkey-lookup-by-fingerprint`` This program prints all SSH public keys that match the given fingerprint. The fingerprint is determined by the first of the following that is found: 1. The ``SSH_KEY_FINGERPRINT`` environment variable, which should contain the MD5 fingerprint of the key (this is the second field generated by ``ssh-keygen -l``). 2. The ``SSH_KEY`` environment variable, which should contain the key in standard openssh format (the same format as ``~/.ssh/id_rsa.pub``), is sent to ``ssh-keygen -l`` to determine the fingerprint. 3. The key in standard openssh format is read from standard input and is sent to ``ssh-keygen -l`` to determine the fingerprint. This program: * can be used directly with ``AuthorizedKeysCommand`` (the username parameter is ignored). * requires a patched OpenSSH server; compatible patches can be found at one of the following locations: - openssh-akcenv_ (this is the preferred patch) - openssh-stdinkey_ * is ideal if you want all Django users to access SSH via a shared system user account and be identified by their SSH public key. Using ``django-sshkey-lookup`` ------------------------------ ``Usage: django-sshkey-lookup URL [USERNAME]`` This program is a wrapper around the previous two commands. The first parameter is placed in the ``SSHKEY_LOOKUP_URL`` environment variable. If the second parameter is present then ``django-sshkey-lookup-by-username`` is executed; otherwise ``django-sshkey-lookup-by-fingerprint`` is executed. This command is compatible with the old script ``lookup.sh`` but was renamed to have a less ambiguous name when installed system-wide. A symlink is left in its place for backwards compatibility. .. _OpenSSH: http://www.openssh.com/ .. _openssh-akcenv: https://github.com/ScottDuckworth/openssh-akcenv .. _openssh-stdinkey: https://github.com/ScottDuckworth/openssh-stdinkey README.upgrading.rst 0000664 0000000 0000000 00000004670 12314573364 0032604 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 Upgrading and Downgrading ========================= django-sshkey is equipped with South_ migrations. This makes changes to the database schema in upgrades or downgrades a simple process. Migrations will only be present on minor version changes. To use South migrations, you must have the south app in your project's ``INSTALLED_APPS``. The following table maps django-sshkey version to migration labels: +---------+---------------+-------+------------------------------------------+ | Version | App Name | Label | Notes | +=========+===============+=======+==========================================+ | 1.0 | sshkey | 0001 | Migrations were not present in 1.0.x | +---------+---------------+-------+------------------------------------------+ | 1.1 | sshkey | 0002 | | +---------+---------------+-------+------------------------------------------+ | 2.0+ | django_sshkey | 0001 | See Upgrading from 1.1.x to 2.x below | +---------+---------------+-------+------------------------------------------+ To upgrade, install the new version of django-sshkey and then migrate your project to its corresponding label from the table above using the following command:: python manage.py migrate APP_NAME LABEL To downgrade, perform the migration down to the label of the desired version before installing the older django-sshkey. Upgrading from 1.1.x to 2.x --------------------------- django-sshkey 2.x renames the sshkey app to django_sshkey. However, the database table names are not changed. To upgrade, all references to the sshkey module must be changed to django_sshkey. This includes all instances of ``import sshkey`` or ``from sshkey import ...`` and all references to sshkey in URL patterns, views, or templates, as well as updating ``INSTALLED_APPS`` in ``settings.py``. Once you have made those changes you will need to fake the initial migration for django_sshkey:: python manage.py migrate --fake django_sshkey 0001_initial This completes the upgrade process. The only thing that remains is the two existing migration records in the ``south_migrationhistory`` table from the now nonexistent sshkey app. These records do not cause any problems, but they can be removed at your discrection using the following SQL statement on your database:: DELETE FROM south_migrationhistory WHERE app_name="sshkey"; .. _South: http://south.aeracode.org/ django-sshkey-lookup 0000775 0000000 0000000 00000003432 12314573364 0033134 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 #!/bin/sh # Copyright (c) 2014, Clemson University # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the {organization} nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. if [ $# -eq 0 ]; then echo "Usage: $0 URL [USERNAME]" >&2 exit 1 fi SSHKEY_LOOKUP_URL="$1" export SSHKEY_LOOKUP_URL if [ $# -eq 1 ]; then exec `dirname $0`/django-sshkey-lookup-by-fingerprint else exec `dirname $0`/django-sshkey-lookup-by-username "$2" fi django-sshkey-lookup-all 0000775 0000000 0000000 00000003256 12314573364 0033706 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 #!/bin/sh # Copyright (c) 2014, Clemson University # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the {organization} nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. url="${SSHKEY_LOOKUP_URL:-http://localhost:8000/sshkey/lookup}" if type curl >/dev/null 2>&1; then exec curl -s "$url" else exec wget -q -O - "$url" fi django-sshkey-lookup-by-fingerprint 0000775 0000000 0000000 00000004141 12314573364 0036067 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 #!/bin/bash # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the {organization} nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. url="${SSHKEY_LOOKUP_URL:-http://localhost:8000/sshkey/lookup}" if [ "x$SSH_KEY_FINGERPRINT" != "x" ]; then fingerprint="$SSH_KEY_FINGERPRINT" else if [ "x$SSH_KEY" == "x" ] && ! read SSH_KEY; then echo "Error: cannot retrieve fingerprint from environment or stdin" >&2 exit 1 fi info="$(ssh-keygen -lf /dev/stdin <<< "$SSH_KEY")" if [ $? -ne 0 ]; then echo "Error: $info" >&2 exit 1 fi info=($info) fingerprint="${info[1]}" fi if type curl >/dev/null 2>&1; then exec curl -s -G "$url" --data-urlencode "fingerprint=${fingerprint}" else exec wget -q -O - "${url}?fingerprint=${fingerprint}" fi django-sshkey-lookup-by-username 0000775 0000000 0000000 00000003336 12314573364 0035364 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 #!/bin/sh # Copyright (c) 2014, Clemson University # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the {organization} nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. url="${SSHKEY_LOOKUP_URL:-http://localhost:8000/sshkey/lookup}" if type curl >/dev/null 2>&1; then exec curl -s -G "$url" --data-urlencode "username=$1" else exec wget -q -O - "${url}?username=$1" fi django_sshkey/ 0000775 0000000 0000000 00000000000 12314573364 0031757 5 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634 __init__.py 0000664 0000000 0000000 00000003036 12314573364 0034072 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey # Copyright (c) 2014, Clemson University # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the {organization} nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. __version__ = '2.1.0' admin.py 0000664 0000000 0000000 00000003635 12314573364 0033430 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey # Copyright (c) 2014, Clemson University # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the {organization} nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from django.contrib import admin from django_sshkey.models import UserKey class UserKeyAdmin(admin.ModelAdmin): list_display = [ '__unicode__', 'user', 'name', 'fingerprint', 'created', 'last_modified', ] search_fields = [ 'user__username', ] readonly_fields = [ 'fingerprint', 'created', 'last_modified', ] admin.site.register(UserKey, UserKeyAdmin) forms.py 0000664 0000000 0000000 00000003256 12314573364 0033465 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey # Copyright (c) 2014, Clemson University # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the {organization} nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from django import forms from django_sshkey.models import UserKey class UserKeyForm(forms.ModelForm): class Meta: model = UserKey fields = ['name', 'key'] migrations/ 0000775 0000000 0000000 00000000000 12314573364 0034133 5 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey 0001_initial.py 0000664 0000000 0000000 00000012640 12314573364 0036601 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey/migrations # encoding: utf-8 import datetime from south.db import db from south.v2 import SchemaMigration from django.db import models class Migration(SchemaMigration): def forwards(self, orm): # Adding model 'UserKey' db.create_table('sshkey_userkey', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), ('name', self.gf('django.db.models.fields.CharField')(max_length=50, blank=True)), ('key', self.gf('django.db.models.fields.TextField')(max_length=2000)), ('fingerprint', self.gf('django.db.models.fields.CharField')(db_index=True, max_length=47, blank=True)), ('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, null=True, blank=True)), ('last_modified', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, null=True, blank=True)), )) db.send_create_signal('django_sshkey', ['UserKey']) # Adding unique constraint on 'UserKey', fields ['user', 'name'] db.create_unique('sshkey_userkey', ['user_id', 'name']) def backwards(self, orm): # Removing unique constraint on 'UserKey', fields ['user', 'name'] db.delete_unique('sshkey_userkey', ['user_id', 'name']) # Deleting model 'UserKey' db.delete_table('sshkey_userkey') models = { 'auth.group': { 'Meta': {'object_name': 'Group'}, 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) }, 'auth.permission': { 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, 'auth.user': { 'Meta': {'object_name': 'User'}, 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) }, 'contenttypes.contenttype': { 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) }, 'django_sshkey.userkey': { 'Meta': {'unique_together': "[('user', 'name')]", 'object_name': 'UserKey', 'db_table': "'sshkey_userkey'"}, 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), 'fingerprint': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '47', 'blank': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'key': ('django.db.models.fields.TextField', [], {'max_length': '2000'}), 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'null': 'True', 'blank': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) } } complete_apps = ['django_sshkey'] __init__.py 0000664 0000000 0000000 00000000000 12314573364 0036232 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey/migrations models.py 0000664 0000000 0000000 00000007142 12314573364 0033620 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey # Copyright (c) 2014, Clemson University # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the {organization} nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from django.db import models from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django_sshkey.util import sshkey_re, sshkey_fingerprint class UserKey(models.Model): user = models.ForeignKey(User, db_index=True) name = models.CharField(max_length=50, blank=True) key = models.TextField(max_length=2000) fingerprint = models.CharField(max_length=47, blank=True, db_index=True) created = models.DateTimeField(auto_now_add=True, null=True) last_modified = models.DateTimeField(auto_now=True, null=True) class Meta: db_table = 'sshkey_userkey' unique_together = [ ('user', 'name'), ] def __unicode__(self): return unicode(self.user) + u': ' + self.name def clean_fields(self, exclude=None): if not exclude or 'key' not in exclude: self.key = self.key.strip() def clean(self): m = sshkey_re.match(self.key) errmsg = 'Key is not a valid SSH protocol 2 base64-encoded key' if not m: raise ValidationError(errmsg) try: self.fingerprint = sshkey_fingerprint(m.group('b64key')) except TypeError: raise ValidationError(errmsg) if not self.name: comment = m.group('comment') if not comment: raise ValidationError('Name or key comment required') self.name = comment def validate_unique(self, exclude=None): if self.pk is None: objects = type(self).objects else: objects = type(self).objects.exclude(pk=self.pk) if exclude is None or 'name' not in exclude: if objects.filter(user=self.user, name=self.name).count(): message = 'You already have a key with that name' raise ValidationError({'name': [message]}) if exclude is None or 'key' not in exclude: try: other = objects.get(fingerprint=self.fingerprint, key=self.key) if self.user == other.user: message = 'You already have that key on file (%s)' % other.name else: message = 'Somebody else already has that key on file' raise ValidationError({'key': [message]}) except type(self).DoesNotExist: pass settings.py 0000664 0000000 0000000 00000004057 12314573364 0034177 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey # Copyright (c) 2014, Clemson University # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # * Neither the name of the {organization} nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from django.conf import settings SSHKEY_AUTHORIZED_KEYS_OPTIONS = getattr(settings, 'SSHKEY_AUTHORIZED_KEYS_OPTIONS', None) SSHKEY_AUTHORIZED_KEYS_COMMAND = getattr(settings, 'SSHKEY_AUTHORIZED_KEYS_COMMAND', None) if SSHKEY_AUTHORIZED_KEYS_COMMAND is not None: import warnings with warnings.catch_warnings(): import warnings warnings.simplefilter('default', DeprecationWarning) warnings.warn( 'SSHKEY_AUTHORIZED_KEYS_COMMAND has been deprecated; ' 'use SSHKEY_AUTHORIZED_KEYS_OPTIONS instead.', DeprecationWarning) templates.example/ 0000775 0000000 0000000 00000000000 12314573364 0035407 5 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey sshkey/ 0000775 0000000 0000000 00000000000 12314573364 0036715 5 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey/templates.example userkey_detail.html 0000664 0000000 0000000 00000000445 12314573364 0042617 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey/templates.example/sshkey {% if action == 'add' %}
{{ error_message }}
{% endif %} userkey_list.html 0000664 0000000 0000000 00000001141 12314573364 0042322 0 ustar 00root root 0000000 0000000 django-sshkey-fcf4ec291a77e54964d04200af06ffbc1a6ca634-fcf4ec291a77e54964d04200af06ffbc1a6ca634/django_sshkey/templates.example/sshkeyKey | Fingerprint | Created | Last Modified | ||
---|---|---|---|---|---|
{{ userkey.name }} | {{ userkey.fingerprint }} | {{ userkey.created }} | {{ userkey.last_modified }} | Edit | Delete |