diff options
Diffstat (limited to 'ipalib')
-rw-r--r-- | ipalib/parameters.py | 2 | ||||
-rw-r--r-- | ipalib/plugins/host.py | 33 | ||||
-rw-r--r-- | ipalib/plugins/user.py | 26 | ||||
-rw-r--r-- | ipalib/util.py | 56 |
4 files changed, 70 insertions, 47 deletions
diff --git a/ipalib/parameters.py b/ipalib/parameters.py index 13f04b45..53756a80 100644 --- a/ipalib/parameters.py +++ b/ipalib/parameters.py @@ -772,8 +772,6 @@ class Param(ReadOnly): This method is called once for each value in a multivalue. """ - if type(value) is not unicode: - return value if self.normalizer is None: return value try: diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py index 91b3ce67..e1c07b53 100644 --- a/ipalib/plugins/host.py +++ b/ipalib/plugins/host.py @@ -39,8 +39,10 @@ from ipalib.plugins.dns import get_reverse_zone from ipalib import _, ngettext from ipalib import x509 from ipalib.request import context -from ipalib.util import validate_sshpubkey, output_sshpubkey -from ipapython.ipautil import ipa_generate_password, CheckedIPAddress, make_sshfp +from ipalib.util import (normalize_sshpubkey, validate_sshpubkey_no_options, + convert_sshpubkey_post) +from ipapython.ipautil import ipa_generate_password, CheckedIPAddress +from ipapython.ssh import SSHPublicKey from ipapython.dn import DN __doc__ = _(""" @@ -131,7 +133,10 @@ def update_sshfp_record(zone, record, entry_attrs): pubkeys = entry_attrs['ipasshpubkey'] or () sshfps=[] for pubkey in pubkeys: - sshfp = unicode(make_sshfp(pubkey)) + try: + sshfp = SSHPublicKey(pubkey).fingerprint_dns_sha1() + except ValueError, UnicodeDecodeError: + continue if sshfp is not None: sshfps.append(sshfp) @@ -180,6 +185,9 @@ host_output_params = ( Str('managedby', label=_('Failed managedby'), ), + Str('sshpubkeyfp*', + label=_('SSH public key fingerprint'), + ), ) def validate_ipaddr(ugettext, ipaddr): @@ -216,7 +224,6 @@ class host(LDAPObject): 'fqdn', 'description', 'l', 'nshostlocation', 'krbprincipalname', 'nshardwareplatform', 'nsosversion', 'usercertificate', 'memberof', 'managedby', 'memberindirect', 'memberofindirect', 'macaddress', - 'sshpubkeyfp', ] uuid_attribute = 'ipauniqueid' attribute_members = { @@ -303,15 +310,13 @@ class host(LDAPObject): label=_('MAC address'), doc=_('Hardware MAC address(es) on this host'), ), - Bytes('ipasshpubkey*', validate_sshpubkey, + Str('ipasshpubkey*', validate_sshpubkey_no_options, cli_name='sshpubkey', - label=_('Base-64 encoded SSH public key'), + label=_('SSH public key'), + normalizer=normalize_sshpubkey, + csv=True, flags=['no_search'], ), - Str('sshpubkeyfp*', - label=_('SSH public key fingerprint'), - flags=['virtual_attribute', 'no_create', 'no_update', 'no_search'], - ), ) def get_dn(self, *keys, **options): @@ -472,7 +477,7 @@ class host_add(LDAPCreate): # fetched anywhere. entry_attrs['has_keytab'] = False - output_sshpubkey(ldap, dn, entry_attrs) + convert_sshpubkey_post(ldap, dn, entry_attrs) return dn @@ -717,7 +722,7 @@ class host_mod(LDAPUpdate): self.obj.suppress_netgroup_memberof(entry_attrs) - output_sshpubkey(ldap, dn, entry_attrs) + convert_sshpubkey_post(ldap, dn, entry_attrs) return dn @@ -802,7 +807,7 @@ class host_find(LDAPSearch): if options.get('all', False): entry_attrs['managing'] = self.obj.get_managed_hosts(entry[0]) - output_sshpubkey(ldap, dn, entry_attrs) + convert_sshpubkey_post(ldap, dn, entry_attrs) return truncated @@ -836,7 +841,7 @@ class host_show(LDAPRetrieve): self.obj.suppress_netgroup_memberof(entry_attrs) - output_sshpubkey(ldap, dn, entry_attrs) + convert_sshpubkey_post(ldap, dn, entry_attrs) return dn diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py index 3f005091..84a63dfa 100644 --- a/ipalib/plugins/user.py +++ b/ipalib/plugins/user.py @@ -30,7 +30,8 @@ from ipalib import output from ipapython.ipautil import ipa_generate_password from ipapython.ipavalidate import Email import posixpath -from ipalib.util import validate_sshpubkey, output_sshpubkey +from ipalib.util import (normalize_sshpubkey, validate_sshpubkey, + convert_sshpubkey_post) if api.env.in_server and api.env.context in ['lite', 'server']: from ipaserver.plugins.ldap2 import ldap2 import os @@ -86,6 +87,9 @@ user_output_params = ( Flag('has_keytab', label=_('Kerberos keys available'), ), + Str('sshpubkeyfp*', + label=_('SSH public key fingerprint'), + ), ) status_output_params = ( @@ -200,7 +204,7 @@ class user(LDAPObject): 'uid', 'givenname', 'sn', 'homedirectory', 'loginshell', 'uidnumber', 'gidnumber', 'mail', 'ou', 'telephonenumber', 'title', 'memberof', 'nsaccountlock', - 'memberofindirect', 'sshpubkeyfp', + 'memberofindirect', ] search_display_attributes = [ 'uid', 'givenname', 'sn', 'homedirectory', 'loginshell', @@ -357,15 +361,13 @@ class user(LDAPObject): label=_('Account disabled'), flags=['no_option'], ), - Bytes('ipasshpubkey*', validate_sshpubkey, + Str('ipasshpubkey*', validate_sshpubkey, cli_name='sshpubkey', - label=_('Base-64 encoded SSH public key'), + label=_('SSH public key'), + normalizer=normalize_sshpubkey, + csv=True, flags=['no_search'], ), - Str('sshpubkeyfp*', - label=_('SSH public key fingerprint'), - flags=['virtual_attribute', 'no_create', 'no_update', 'no_search'], - ), ) def _normalize_and_validate_email(self, email, config=None): @@ -567,7 +569,7 @@ class user_add(LDAPCreate): self.obj.get_password_attributes(ldap, dn, entry_attrs) - output_sshpubkey(ldap, dn, entry_attrs) + convert_sshpubkey_post(ldap, dn, entry_attrs) return dn @@ -636,7 +638,7 @@ class user_mod(LDAPUpdate): convert_nsaccountlock(entry_attrs) self.obj._convert_manager(entry_attrs, **options) self.obj.get_password_attributes(ldap, dn, entry_attrs) - output_sshpubkey(ldap, dn, entry_attrs) + convert_sshpubkey_post(ldap, dn, entry_attrs) return dn api.register(user_mod) @@ -678,7 +680,7 @@ class user_find(LDAPSearch): self.obj._convert_manager(attrs, **options) self.obj.get_password_attributes(ldap, dn, attrs) convert_nsaccountlock(attrs) - output_sshpubkey(ldap, dn, attrs) + convert_sshpubkey_post(ldap, dn, attrs) return truncated msg_summary = ngettext( @@ -698,7 +700,7 @@ class user_show(LDAPRetrieve): convert_nsaccountlock(entry_attrs) self.obj._convert_manager(entry_attrs, **options) self.obj.get_password_attributes(ldap, dn, entry_attrs) - output_sshpubkey(ldap, dn, entry_attrs) + convert_sshpubkey_post(ldap, dn, entry_attrs) return dn api.register(user_show) diff --git a/ipalib/util.py b/ipalib/util.py index 155d9329..ca71e78d 100644 --- a/ipalib/util.py +++ b/ipalib/util.py @@ -34,7 +34,7 @@ from dns.exception import DNSException from ipalib import errors from ipalib.text import _ -from ipapython.ipautil import decode_ssh_pubkey +from ipapython.ssh import SSHPublicKey from ipapython.dn import DN, RDN @@ -266,37 +266,55 @@ def validate_hostname(hostname, check_fqdn=True, allow_underscore=False): else: validate_domain_name(hostname,allow_underscore) -def validate_sshpubkey(ugettext, pubkey): +def normalize_sshpubkey(value): + return SSHPublicKey(value).openssh() + +def validate_sshpubkey(ugettext, value): try: - algo, data, fp = decode_ssh_pubkey(pubkey) - except ValueError: + SSHPublicKey(value) + except ValueError, UnicodeDecodeError: return _('invalid SSH public key') -def output_sshpubkey(ldap, dn, entry_attrs): +def validate_sshpubkey_no_options(ugettext, value): + try: + pubkey = SSHPublicKey(value) + except ValueError, UnicodeDecodeError: + return _('invalid SSH public key') + + if pubkey.has_options(): + return _('options are not allowed') + +def convert_sshpubkey_post(ldap, dn, entry_attrs): if 'ipasshpubkey' in entry_attrs: - pubkeys = entry_attrs.get('ipasshpubkey') + pubkeys = entry_attrs.pop('ipasshpubkey') else: - entry = ldap.get_entry(dn, ['ipasshpubkey']) - pubkeys = entry[1].get('ipasshpubkey') - if pubkeys is None: + old_entry_attrs = ldap.get_entry(dn, ['ipasshpubkey']) + pubkeys = old_entry_attrs[1].get('ipasshpubkey') + if not pubkeys: return + newpubkeys = [] fingerprints = [] for pubkey in pubkeys: try: - algo, data, fp = decode_ssh_pubkey(pubkey) - fp = u':'.join([fp[j:j+2] for j in range(0, len(fp), 2)]) - fingerprints.append(u'%s (%s)' % (fp, algo)) - except ValueError: - pass + pubkey = SSHPublicKey(pubkey) + except ValueError, UnicodeDecodeError: + continue + + fp = pubkey.fingerprint_hex_md5() + comment = pubkey.comment() + if comment: + fp = u'%s %s' % (fp, comment) + fp = u'%s (%s)' % (fp, pubkey.keytype()) + + newpubkeys.append(pubkey.openssh()) + fingerprints.append(fp) + + if newpubkeys: + entry_attrs['ipasshpubkey'] = newpubkeys if fingerprints: entry_attrs['sshpubkeyfp'] = fingerprints -def normalize_sshpubkeyfp(value): - value = value.split()[0] - value = unicode(c for c in value if c in '0123456789ABCDEFabcdef') - return value - class cachedproperty(object): """ A property-like attribute that caches the return value of a method call. |