Commit 6acd9954 by Scott Duckworth

Merge branch 'release/2.2.0'

parents ae7e943b 6087de92
This diff is collapsed. Click to expand it.
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
This program is distributed under the GNU LGPL. Copyright (c) 2014, Clemson University
See COPYING and COPYING.LESSER for details. 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.
include LICENSE include LICENSE
include COPYING include README.rst
include COPYING.LESSER include README.upgrading.rst
include README.md
include lookup.py include lookup.py
include lookup.sh include lookup.sh
include openssh-6.2p2-authorized-keys-command-stdin.diff include django-sshkey-lookup
recursive-include django_sshkey/management *.py 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/migrations *.py
recursive-include django_sshkey/templates.example * recursive-include django_sshkey/templates.example *
README.rst
\ No newline at end of file
django-sshkey lets you use a patched OpenSSH server to authenticate incoming
SSH connections via public key authentication and identify the Django User that
owns that key.
# The OpenSSH Patch
At the top level of this repository is a patch for OpenSSH 6.2p2 which modifies
the AuthorizedKeysCommand config option so that the incoming SSH public key is
passed to the command via standard input. The incoming username will still be
passed as the first argument to the specified command.
# The Django app
The Django app is located in the django\_sshkey directory at the top level of
this repository. You should point Django to it in your project's settings.py
or copy it into your project's directory.
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 BLAHBLAHBLAH
assuming the key "BLAHBLAHBLAH" is owned by fred.
## URL Configuration
This text assumes that your Django project's urls.py maps django\_sshkey.urls into the
url namespace as follows:
urlpatterns = patterns('',
...
url('^sshkey/', include(django_sshkey.urls)),
...
)
You will need to adjust your URLs if you use a different mapping.
# Tying OpenSSH's AuthorizedKeysCommand to the django-sshkey
There are three provided ways of connecting AuthorizedKeysCommand to Django.
In all cases it is recommended and/or required that the command specified with
AuthorizedKeysCommand be a shell script that is owned by and only writable by
root which invokes one of the commands below:
## Using lookup.sh
*Usage: lookup.sh URL [USERNAME]*
URL should be the full URL to /sshkey/lookup on your Django web server running
the sshkey app.
If USERNAME is specified, lookup keys owned by that user and print them to
standard output. Any standard input is ignored.
If USERNAME is not specified, the incoming public key should be provided on
standard input; if the key is found it is printed to standard output.
This command assumes that some fairly standard commands, like ssh-keygen and
curl, are found in $PATH.
This is generally the fastest method.
## Using lookup.py
*Usage: lookup.py URL [USERNAME]*
Same as above, but it's all written in Python and doesn't rely on external
commands.
The parent directory of the django\_sshkey app must be in PYTHONPATH.
This is generally the second fastest method.
## Using manage.py sshkey\_authorized\_keys\_command
*Usage: PATH\_TO\_DJANGO\_PROJECT/manage.py sshkey\_authorized\_keys\_command [USERNAME]*
Same semantics for USERNAME as above.
This method does not rely on the /sshkey/lookup URL, and instead creates its
own database connection each time it is invoked.
This is generally the slowest method.
=============
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
Upgrading and Downgrading
=========================
django-sshkey is equipped with [South][1] 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-anyvcs version to migration labels:
Version App Name Label Notes
1.0.x sshkey 0001 Migrations were not present in 1.0.x
1.1.x sshkey 0002
2.0.x 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";
[1]: http://south.aeracode.org/
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/
#!/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
#!/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
#!/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
#!/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
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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.0.1' __version__ = '2.2.0'
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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.contrib import admin
from django_sshkey.models import UserKey from django_sshkey.models import UserKey
......
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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 import forms
from django_sshkey.models import UserKey from django_sshkey.models import UserKey
......
# Copyright 2013 Scott Duckworth
#
# This file is part of django-sshkey.
#
# django-sshkey is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# django-sshkey is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>.
# Copyright 2013 Scott Duckworth
#
# This file is part of django-sshkey.
#
# django-sshkey is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# django-sshkey is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>.
# Copyright 2013 Scott Duckworth
#
# This file is part of django-sshkey.
#
# django-sshkey is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# django-sshkey is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>.
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from django_sshkey.models import sshkey_fingerprint, UserKey
import base64
import hashlib
import sys
class Command(BaseCommand):
args = '[<username>]'
def handle(self, *args, **options):
if len(args) == 0:
line = sys.stdin.readline()
if not line:
raise CommandError('no input given')
fingerprint = sshkey_fingerprint(line)
keys = UserKey.objects.filter(fingerprint=fingerprint)
elif len(args) == 1:
keys = UserKey.objects.filter(user__username=args[0])
else:
raise CommandError('invalid number of arguments')
status = 1
for key in keys:
status = 0
try:
options = 'command="%s" ' % (
settings.SSHKEY_AUTHORIZED_KEYS_COMMAND.format(username=key.user.username).replace('"', r'\"')
)
except AttributeError:
options = ''
print(options + key.key)
return status
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
import base64 from django_sshkey.util import sshkey_re, sshkey_fingerprint
import hashlib
import re
sshkey_re = re.compile(r'(?P<type>[\w-]+)\s+(?P<b64key>\S+)(?:\s+(?P<comment>\S+))?$')
def sshkey_fingerprint(b64key):
key = base64.b64decode(b64key)
fp_plain = hashlib.md5(key).hexdigest()
return ':'.join(a+b for a,b in zip(fp_plain[::2], fp_plain[1::2]))
class UserKey(models.Model): class UserKey(models.Model):
user = models.ForeignKey(User, db_index=True) user = models.ForeignKey(User, db_index=True)
......
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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 from django.conf import settings
......
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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.test import TestCase from django.test import TestCase
from django.test.client import Client from django.test.client import Client
......
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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.urls.defaults import patterns, url try:
from django.conf.urls.defaults import patterns, url
except ImportError:
from django.conf.urls import patterns, url
urlpatterns = patterns('django_sshkey.views', urlpatterns = patterns('django_sshkey.views',
url(r'^lookup$', 'lookup'), url(r'^lookup$', 'lookup'),
......
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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.
def lookup_command(args): import re
import sys
SSHKEY_LOOKUP_URL_DEFAULT = 'http://localhost:8000/sshkey/lookup'
sshkey_re = re.compile(r'(?P<type>[\w-]+)\s+(?P<b64key>\S+)(?:\s+(?P<comment>\S.+))?$')
def sshkey_fingerprint(b64key):
import base64
import hashlib
key = base64.b64decode(b64key)
fp_plain = hashlib.md5(key).hexdigest()
return ':'.join(a+b for a,b in zip(fp_plain[::2], fp_plain[1::2]))
def lookup_all(url):
import urllib import urllib
if len(args) == 1:
url = args[0]
line = sys.stdin.readline()
if not line:
sys.stderr.write('no input given\n')
sys.exit(2)
fingerprint = sshkey_fingerprint(line)
url += '?fingerprint=' + urllib.quote_plus(fingerprint)
elif len(args) == 2:
url, username = args
url += '?username=' + urllib.quote_plus(username)
else:
sys.stderr.write('Invalid number of arguments\n')
sys.exit(2)
response = urllib.urlopen(url) response = urllib.urlopen(url)
status = 1 return response.readlines()
for line in response.readlines():
status = 0 def lookup_by_username(url, username):
sys.stdout.write(line) import urllib
sys.exit(status) url += '?' + urllib.urlencode({'username': username})
response = urllib.urlopen(url)
return response.readlines()
def lookup_by_fingerprint(url, fingerprint):
import urllib
url += '?' + urllib.urlencode({'fingerprint': fingerprint})
response = urllib.urlopen(url)
return response.readlines()
def lookup_all_main():
import sys
from os import getenv
url = getenv('SSHKEY_LOOKUP_URL', SSHKEY_LOOKUP_URL_DEFAULT)
for key in lookup_all(url):
sys.stdout.write(key)
def lookup_by_username_main():
import sys
from os import getenv
if len(sys.argv) < 2:
sys.stderr.write('Usage: %s USERNAME\n' % sys.argv[0])
sys.exit(1)
username = sys.argv[1]
url = getenv('SSHKEY_LOOKUP_URL', SSHKEY_LOOKUP_URL_DEFAULT)
for key in lookup_by_username(url, username):
sys.stdout.write(key)
def lookup_by_fingerprint_main():
import sys
from os import getenv
fingerprint = getenv('SSH_KEY_FINGERPRINT')
if fingerprint is None:
key = getenv('SSH_KEY')
if key is None:
key = sys.stdin.readline()
if not key:
sys.stderr.write(
"Error: cannot retrieve fingerprint from environment or stdin\n"
)
sys.exit(1)
m = sshkey_re.match(key)
if not m:
sys.stderr.write(
"Error: cannot parse SSH protocol 2 base64-encoded key"
)
sys.exit(1)
fingerprint = sshkey_fingerprint(m.group('b64key'))
url = getenv('SSHKEY_LOOKUP_URL', SSHKEY_LOOKUP_URL_DEFAULT)
for key in lookup_by_fingerprint(url, fingerprint):
sys.stdout.write(key)
def lookup_main():
import sys
from os import environ
if len(sys.argv) < 2:
sys.stderr.write('Usage: %s URL [USERNAME]\n' % sys.argv[0])
sys.exit(1)
url = sys.argv[1]
if len(sys.argv) == 2:
environ['SSHKEY_LOOKUP_URL'] = url
lookup_by_fingerprint_main()
else:
username = sys.argv[2]
for key in lookup_by_username(url, username):
sys.stdout.write(key)
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.views.decorators.http import require_http_methods, require_GET from django.views.decorators.http import require_http_methods, require_GET
......
#!/usr/bin/env python #!/usr/bin/env python
# Copyright 2013 Scott Duckworth # Copyright (c) 2014, Clemson University
# All rights reserved.
# #
# This file is part of django-sshkey. # Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# #
# django-sshkey is free software: you can redistribute it and/or modify # * Redistributions of source code must retain the above copyright notice, this
# it under the terms of the GNU Lesser General Public License as published # list of conditions and the following disclaimer.
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# #
# django-sshkey is distributed in the hope that it will be useful, # * Redistributions in binary form must reproduce the above copyright notice,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # this list of conditions and the following disclaimer in the documentation
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # and/or other materials provided with the distribution.
# GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public License # * Neither the name of the {organization} nor the names of its
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>. # 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.
import warnings
import django_sshkey.util import django_sshkey.util
import sys
django_sshkey.util.lookup_command(sys.argv[1:]) warnings.warn("lookup.py is deprecated; use django-sshkey-pylookup",
DeprecationWarning)
django_sshkey.util.lookup_main()
#!/bin/bash
# Copyright 2013 Scott Duckworth
#
# This file is part of django-sshkey.
#
# django-sshkey is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# django-sshkey is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with django-sshkey. If not, see <http://www.gnu.org/licenses/>.
url="$1"
if [ $# -eq 1 ]; then
read line
fingerprint=$(ssh-keygen -lf /dev/stdin <<< $line | cut -f2 -d' ')
exec curl -s -G "$url" --data-urlencode "fingerprint=${fingerprint}"
elif [ $# -eq 2 ]; then
username="$2"
exec curl -s -G "$url" --data-urlencode "username=${username}"
else
echo "Invalid number of arguments" >&2
exit 2
fi
django-sshkey-lookup
\ No newline at end of file
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 3ff6faa..61cad6f 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -458,11 +458,11 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
static int
user_key_command_allowed2(struct passwd *user_pw, Key *key)
{
- FILE *f;
+ FILE *f_out, *f_in;
int ok, found_key = 0;
struct passwd *pw;
struct stat st;
- int status, devnull, p[2], i;
+ int status, devnull, pipe_in[2], pipe_out[2], i;
pid_t pid;
char *username, errmsg[512];
@@ -499,8 +499,15 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
goto out;
}
- if (pipe(p) != 0) {
+ if (pipe(pipe_in) != 0) {
+ error("%s: pipe: %s", __func__, strerror(errno));
+ goto out;
+ }
+
+ if (pipe(pipe_out) != 0) {
error("%s: pipe: %s", __func__, strerror(errno));
+ close(pipe_in[0]);
+ close(pipe_in[1]);
goto out;
}
@@ -516,21 +523,18 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
switch ((pid = fork())) {
case -1: /* error */
error("%s: fork: %s", __func__, strerror(errno));
- close(p[0]);
- close(p[1]);
+ close(pipe_in[0]);
+ close(pipe_in[1]);
+ close(pipe_out[0]);
+ close(pipe_out[1]);
return 0;
case 0: /* child */
for (i = 0; i < NSIG; i++)
signal(i, SIG_DFL);
- if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
- error("%s: open %s: %s", __func__, _PATH_DEVNULL,
- strerror(errno));
- _exit(1);
- }
/* Keep stderr around a while longer to catch errors */
- if (dup2(devnull, STDIN_FILENO) == -1 ||
- dup2(p[1], STDOUT_FILENO) == -1) {
+ if (dup2(pipe_in[0], STDIN_FILENO) == -1 ||
+ dup2(pipe_out[1], STDOUT_FILENO) == -1) {
error("%s: dup2: %s", __func__, strerror(errno));
_exit(1);
}
@@ -547,11 +551,16 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
strerror(errno));
_exit(1);
}
- /* stdin is pointed to /dev/null at this point */
- if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
+ if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
+ error("%s: open %s: %s", __func__, _PATH_DEVNULL,
+ strerror(errno));
+ _exit(1);
+ }
+ if (dup2(devnull, STDERR_FILENO) == -1) {
error("%s: dup2: %s", __func__, strerror(errno));
_exit(1);
}
+ close(devnull);
execl(options.authorized_keys_command,
options.authorized_keys_command, user_pw->pw_name, NULL);
@@ -565,18 +574,32 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
temporarily_use_uid(pw);
- close(p[1]);
- if ((f = fdopen(p[0], "r")) == NULL) {
+ close(pipe_in[0]);
+ close(pipe_out[1]);
+ if ((f_in = fdopen(pipe_in[1], "w")) == NULL) {
error("%s: fdopen: %s", __func__, strerror(errno));
- close(p[0]);
+ close(pipe_in[1]);
+ close(pipe_out[0]);
/* Don't leave zombie child */
kill(pid, SIGTERM);
while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
;
goto out;
}
- ok = check_authkeys_file(f, options.authorized_keys_command, key, pw);
- fclose(f);
+ if ((f_out = fdopen(pipe_out[0], "r")) == NULL) {
+ error("%s: fdopen: %s", __func__, strerror(errno));
+ fclose(f_in);
+ close(pipe_out[0]);
+ /* Don't leave zombie child */
+ kill(pid, SIGTERM);
+ while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
+ ;
+ goto out;
+ }
+ key_write(key, f_in);
+ fclose(f_in);
+ ok = check_authkeys_file(f_out, options.authorized_keys_command, key, pw);
+ fclose(f_out);
while (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR) {
# 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.
import os import os
from setuptools import setup from setuptools import setup
README = open(os.path.join(os.path.dirname(__file__), 'README.md')).read() README = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
# allow setup.py to be run from any path # allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
execfile('django_sshkey/__init__.py') exec(open('django_sshkey/__init__.py').read())
setup( setup(
name='django-sshkey', name='django-sshkey',
version=__version__, version=__version__,
packages=['django_sshkey'], packages=['django_sshkey'],
include_package_data=True, include_package_data=True,
license='GNU Lesser General Public License v3 (LGPLv3)', license='BSD',
description='A Django app to identify users by their SSH public keys.', description='Associates multiple SSH public keys with Django user accounts.',
long_description=README, long_description=README,
url='https://bitbucket.org/ClemsonSoCUnix/django-sshkey', url='https://bitbucket.org/ClemsonSoCUnix/django-sshkey',
author='Scott Duckworth', author='Scott Duckworth',
...@@ -23,7 +51,7 @@ setup( ...@@ -23,7 +51,7 @@ setup(
'Environment :: Web Environment', 'Environment :: Web Environment',
'Framework :: Django', 'Framework :: Django',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)', 'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.6',
...@@ -31,4 +59,18 @@ setup( ...@@ -31,4 +59,18 @@ setup(
'Topic :: Internet :: WWW/HTTP', 'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
], ],
scripts=[
'django-sshkey-lookup',
'django-sshkey-lookup-all',
'django-sshkey-lookup-by-username',
'django-sshkey-lookup-by-fingerprint',
],
entry_points={
'console_scripts': [
'django-sshkey-pylookup = django_sshkey.util:lookup_main',
'django-sshkey-pylookup-all = django_sshkey.util:lookup_all_main',
'django-sshkey-pylookup-by-username = django_sshkey.util:lookup_by_username_main',
'django-sshkey-pylookup-by-fingerprint = django_sshkey.util:lookup_by_fingerprint_main',
],
},
) )
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment