Source code for privacyidea.lib.applications.ssh
# privacyIDEA
# Jul 18, 2014 Cornelius Kölbel
# License: AGPLv3
# contact: http://www.privacyidea.org
#
# This code is free software; you can redistribute it and/or
# modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
# License as published by the Free Software Foundation; either
# version 3 of the License, or any later version.
#
# This code 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 AFFERO GENERAL PUBLIC LICENSE for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
This file is tested in tests/test_lib_machinetokens.py
"""
from privacyidea.lib.applications import MachineApplicationBase
import logging
from privacyidea.lib.token import get_tokens
from privacyidea.lib.policy import TYPE
from privacyidea.lib.serviceid import get_serviceids
from privacyidea.lib import _
log = logging.getLogger(__name__)
[docs]
class MachineApplication(MachineApplicationBase):
"""
This is the application for SSH.
Possible options:
user
"""
application_name = "ssh"
'''as the authentication item is no sensitive information,
we can set bulk_call to True. Thus the admin can call
all public keys to distribute them via salt.
FIXME: This is only true for SSH pub keys.
If we would support OTP with SSH, this might be sensitive information!
'''
allow_bulk_call = True
[docs]
@staticmethod
def get_authentication_item(token_type,
serial,
challenge=None,
options=None,
filter_param=None,
user_agent=None):
"""
:param token_type: the type of the token. At the moment
we support the tokenype "sshkey"
:param serial: the serial number of the token.
:return auth_item: Return the SSH pub keys.
"""
options = options or {}
ret = {}
filter_param = filter_param or {}
user_filter = filter_param.get("user")
if token_type.lower() == "sshkey":
toks = get_tokens(serial=serial, active=True)
if len(toks) == 1:
# We return this entry, either if no user_filter is requested
# or if the user_filter matches the user
if (user_filter and user_filter == options.get("user")) or \
not user_filter:
# tokenclass is a SSHkeyTokenClass
tokclass = toks[0]
# We just return the ssh public key, so that
# it can be included into authorized keys.
log.info("Using SSH key {!s} for SSH user {!s}".format(tokclass.token.serial,
options.get("user")))
ret["sshkey"] = tokclass.get_sshkey()
# We return the username if the token is assigned to a
# user, so that this username could be used to save
# the ssh key accordingly
user_object = toks[0].user
if user_object:
uInfo = user_object.get_specific_info(["username"])
if "username" in uInfo:
ret["username"] = uInfo.get("username")
else:
log.debug("The requested user {!s} does not match the user "
"option ({!s}) of the SSH application.".format(
user_filter, options.get("user")))
else:
log.info(f"Token {serial!r}, type {token_type!r} is not supported by "
"SSH application module")
return ret
[docs]
@staticmethod
def get_options():
"""
returns a dictionary with a list of options
"""
sids = [s.name for s in get_serviceids()]
options = {"sshkey":
{'user': {'type': TYPE.STRING,
'description': _('The username on the SSH server.')},
'service_id': {'type': TYPE.STRING,
'description': _('The service ID of the SSH server. '
'Several servers can have the same service ID.'),
'value': sids}}
}
return options