pax_global_header 0000666 0000000 0000000 00000000064 12354337365 0014525 g ustar 00root root 0000000 0000000 52 comment=80071eb959fc4cffaf6549974d7701307a190b0d django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/ 0000775 0000000 0000000 00000000000 12354337365 0026457 5 ustar 00root root 0000000 0000000 .gitignore 0000664 0000000 0000000 00000000067 12354337365 0030373 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d *.py[coa] /django_sshkey.egg-info /testproject/test.db LICENSE 0000664 0000000 0000000 00000002726 12354337365 0027414 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d 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 12354337365 0030137 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d 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 0000777 0000000 0000000 00000000000 12354337365 0030742 2README.rst ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d README.rst 0000664 0000000 0000000 00000014265 12354337365 0030077 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d ============= 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 12354337365 0032055 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d 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 12354337365 0032405 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d #!/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 12354337365 0033157 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d #!/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 12354337365 0035340 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d #!/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 12354337365 0034635 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d #!/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 12354337365 0031230 5 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d __init__.py 0000664 0000000 0000000 00000003036 12354337365 0033343 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/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.2.0' admin.py 0000664 0000000 0000000 00000003635 12354337365 0032701 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/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 12354337365 0032736 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/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 12354337365 0033404 5 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/django_sshkey 0001_initial.py 0000664 0000000 0000000 00000012640 12354337365 0036052 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/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 12354337365 0035503 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/django_sshkey/migrations models.py 0000664 0000000 0000000 00000010663 12354337365 0033073 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/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 SSHKeyFormatError, key_parse def wrap(text, width, end=None): n = 0 t = '' if end is None: while n < len(text): m = n + width t += text[n:m] if len(text) <= m: return t t += '\n' n = m else: while n < len(text): m = n + width if len(text) <= m: return t + text[n:m] m -= len(end) t += text[n:m] + end + '\n' n = m return t 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): try: info = key_parse(self.key) self.fingerprint = info.fingerprint if info.comment: self.key = "%s %s %s" % (info.type.decode(), info.b64key.decode(), info.comment) else: self.key = "%s %s" % (info.type.decode(), info.b64key.decode()) except SSHKeyFormatError as e: raise ValidationError(str(e)) if not self.name: if not info.comment: raise ValidationError('Name or key comment required') self.name = info.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 def export_openssh(self): return self.key.encode('utf-8') def export_rfc4716(self): info = key_parse(self.key) out = b'---- BEGIN SSH2 PUBLIC KEY ----\n' if info.comment: comment = 'Comment: "%s"' % info.comment out += wrap(comment, 72, '\\').encode('ascii') + b'\n' out += wrap(info.b64key, 72).encode('ascii') + b'\n' out += b'---- END SSH2 PUBLIC KEY ----' return out settings.py 0000664 0000000 0000000 00000004057 12354337365 0033450 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/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 12354337365 0034660 5 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/django_sshkey sshkey/ 0000775 0000000 0000000 00000000000 12354337365 0036166 5 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/django_sshkey/templates.example userkey_detail.html 0000664 0000000 0000000 00000000445 12354337365 0042070 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/django_sshkey/templates.example/sshkey {% if action == 'add' %}
{{ error_message }}
{% endif %} userkey_list.html 0000664 0000000 0000000 00000001141 12354337365 0041573 0 ustar 00root root 0000000 0000000 django-sshkey-80071eb959fc4cffaf6549974d7701307a190b0d-80071eb959fc4cffaf6549974d7701307a190b0d/django_sshkey/templates.example/sshkeyKey | Fingerprint | Created | Last Modified | ||
---|---|---|---|---|---|
{{ userkey.name }} | {{ userkey.fingerprint }} | {{ userkey.created }} | {{ userkey.last_modified }} | Edit | Delete |