On 23.1.2013 23:45, Rob Crittenden wrote:
Jan Cholasta wrote:
On 10.1.2013 05:56, Jan Cholasta wrote:
Hi,

Patch 91 removes module ipapython.compat. The code that uses it doesn't
work with ancient Python versions anyway, so there's no need to keep it
around.

Patch 92 adds support for automatic generation of RFC 6594 SSHFP DNS
records to ipa-client-install and host plugin, as described in
<http://freeipa.org/page/V3/RFC_6594_SSHFP_DNS_records>. Note that
<https://fedorahosted.org/freeipa/ticket/2642#comment:7> still applies.

https://fedorahosted.org/freeipa/ticket/2642

Honza


Self-NACK, forgot to actually remove ipapython/compat.py in the first
patch. Also removed an unnecessary try block from the second patch.

Honza

These look good. I'm a little concerned about the magic numbers in the
SSHFP code. I know these come from the RFCs. Can you add a comment there
so future developers know where the values for key type and fingerprint
type come from?

rob

Comment added.

--
Jan Cholasta
>From 57b1976a037aae13fb637aa586c8ee7fa10a9aeb Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Tue, 8 Jan 2013 16:11:05 +0100
Subject: [PATCH 1/2] Drop ipapython.compat.

---
 ipapython/certdb.py                    |  2 +-
 ipapython/compat.py                    | 81 ----------------------------------
 ipapython/ssh.py                       |  3 +-
 ipaserver/install/certs.py             |  3 +-
 ipaserver/rpcserver.py                 |  5 +--
 tests/test_ipaserver/test_rpcserver.py |  3 +-
 6 files changed, 7 insertions(+), 90 deletions(-)
 delete mode 100644 ipapython/compat.py

diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index 2c0529b..7a06da5 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -21,7 +21,7 @@ from ipapython import ipautil
 from ipapython import nsslib
 from ipalib import pkcs10
 import tempfile
-from ipapython.compat import sha1
+from hashlib import sha1
 import shutil
 import os
 
diff --git a/ipapython/compat.py b/ipapython/compat.py
deleted file mode 100644
index 36d0384..0000000
--- a/ipapython/compat.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Authors:
-#   Jason Gerard DeRose <jder...@redhat.com>
-#
-# Copyright (C) 2009  Red Hat
-# see file 'COPYING' for use and warranty information
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Abstracts some compatibility issues for Python 2.4 - Python 2.6.
-
-Python 2.6
-==========
-
-The ``json`` module was added in Python 2.6, which previously was in an external
-package and called ``simplejson``.  The `compat` module abstracts the difference
-so you can use the ``json`` module generically like this:
-
->>> from compat import json
->>> json.dumps({'hello': 'world'})
-'{"hello": "world"}'
-
-In Python 2.6 the ``parse_qs()`` function was moved from the ``cgi`` module to
-the ``urlparse`` module.  Although ``cgi.parse_qs()`` is still available and
-only raises a ``PendingDeprecationWarning``, we still provide some
-future-proofing here so you can import ``parse_qs()`` generically like this:
-
->>> from compat import parse_qs
->>> parse_qs('hello=world&how=are+you%3F')
-{'how': ['are you?'], 'hello': ['world']}
-
-For more information, see *What's New in Python 2.6*:
-
-    http://docs.python.org/whatsnew/2.6.html
-
-
-Python 2.5
-==========
-
-The ``hashlib`` module was added in Python2.5, after which use of the ``sha``
-and ``md5`` modules is deprecated.  You can generically import a ``sha1`` class
-from the `compat` module like this:
-
->>> from compat import sha1
->>> sha1('hello world').hexdigest()
-'2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'
-
-And generically import an ``md5`` class like this:
-
->>> from compat import md5
->>> md5('hello world').hexdigest()
-'5eb63bbbe01eeed093cb22bb8f5acdc3'
-
-For more information, see *What's New in Python 2.5*:
-
-    http://python.org/doc/2.5/whatsnew/whatsnew25.html
-"""
-
-import sys
-if sys.version_info[:2] >= (2, 6):
-    import json
-    from urlparse import parse_qs
-else:
-    import simplejson as json
-    from cgi import parse_qs
-try:
-    from hashlib import sha1, md5   #pylint: disable=E0611
-except ImportError:
-    from sha import new as sha1
-    from md5 import new as md5
diff --git a/ipapython/ssh.py b/ipapython/ssh.py
index 6686e91..3294aa4 100644
--- a/ipapython/ssh.py
+++ b/ipapython/ssh.py
@@ -25,8 +25,7 @@ SSH utilities.
 import base64
 import re
 import struct
-
-from ipapython.compat import md5, sha1
+from hashlib import md5, sha1
 
 __all__ = ['SSHPublicKey']
 
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index 7b40858..360639d 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -28,6 +28,7 @@ import xml.dom.minidom
 import pwd
 import fcntl
 import base64
+from hashlib import sha1
 
 from ipapython import nsslib
 from ipapython import dogtag
@@ -48,8 +49,6 @@ import nss.nss as nss
 
 from ipalib import api
 
-from ipapython.compat import sha1
-
 # Apache needs access to this database so we need to create it
 # where apache can reach
 NSS_DIR = "/etc/httpd/alias"
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
index 8bce48b..581c30b 100644
--- a/ipaserver/rpcserver.py
+++ b/ipaserver/rpcserver.py
@@ -23,7 +23,6 @@ RPC server.
 Also see the `ipalib.rpc` module.
 """
 
-from cgi import parse_qs
 from xml.sax.saxutils import escape
 from xmlrpclib import Fault
 from wsgiref.util import shift_path_info
@@ -34,6 +33,7 @@ import datetime
 from decimal import Decimal
 import urlparse
 import time
+import json
 
 from ipalib import plugable
 from ipalib.backend import Executioner
@@ -43,7 +43,6 @@ from ipalib.rpc import xml_dumps, xml_loads
 from ipalib.util import parse_time_duration, normalize_name
 from ipapython.dn import DN
 from ipaserver.plugins.ldap2 import ldap2
-from ipapython.compat import json
 from ipalib.session import session_mgr, AuthManager, get_ipa_ccache_name, load_ccache_data, bind_ipa_ccache, release_ipa_ccache, fmt_time, default_max_session_duration
 from ipalib.backend import Backend
 from ipalib.krb_utils import krb5_parse_ccache, KRB5_CCache, krb_ticket_expiration_threshold, krb5_format_principal_name
@@ -211,7 +210,7 @@ def extract_query(environ):
         qstr = environ['QUERY_STRING']
     if qstr:
         query = dict(nicify_query(
-            parse_qs(qstr)#, keep_blank_values=True)
+            urlparse.parse_qs(qstr)#, keep_blank_values=True)
         ))
     else:
         query = {}
diff --git a/tests/test_ipaserver/test_rpcserver.py b/tests/test_ipaserver/test_rpcserver.py
index f423f97..a75a85e 100644
--- a/tests/test_ipaserver/test_rpcserver.py
+++ b/tests/test_ipaserver/test_rpcserver.py
@@ -21,11 +21,12 @@
 Test the `ipaserver.rpc` module.
 """
 
+import json
+
 from tests.util import create_test_api, assert_equal, raises, PluginTester
 from tests.data import unicode_str
 from ipalib import errors, Command
 from ipaserver import rpcserver
-from ipapython.compat import json
 
 
 class StartResponse(object):
-- 
1.8.1

>From 9b99804840294d673d77cdac8a3260f5122f6201 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Tue, 8 Jan 2013 16:13:07 +0100
Subject: [PATCH 2/2] Add support for RFC 6594 SSHFP DNS records.

https://fedorahosted.org/freeipa/ticket/2642
---
 ipa-client/ipa-install/ipa-client-install |  3 +++
 ipalib/plugins/host.py                    |  6 ++++++
 ipapython/ssh.py                          | 16 +++++++++++++---
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index f068c9d..f4884e8 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -1325,6 +1325,9 @@ def update_ssh_keys(server, hostname, ssh_dir, create_sshfp):
             sshfp = pubkey.fingerprint_dns_sha1()
             if sshfp is not None:
                 update_txt += 'update add %s. %s IN SSHFP %s\n' % (hostname, ttl, sshfp)
+            sshfp = pubkey.fingerprint_dns_sha256()
+            if sshfp is not None:
+                update_txt += 'update add %s. %s IN SSHFP %s\n' % (hostname, ttl, sshfp)
         update_txt += 'send\n'
 
         if not do_nsupdate(update_txt):
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index e1c07b5..f464127 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -139,6 +139,12 @@ def update_sshfp_record(zone, record, entry_attrs):
             continue
         if sshfp is not None:
             sshfps.append(sshfp)
+        try:
+            sshfp = SSHPublicKey(pubkey).fingerprint_dns_sha256()
+        except ValueError, UnicodeDecodeError:
+            continue
+        if sshfp is not None:
+            sshfps.append(sshfp)
 
     try:
         api.Command['dnsrecord_mod'](zone, record, sshfprecord=sshfps)
diff --git a/ipapython/ssh.py b/ipapython/ssh.py
index 3294aa4..58505df 100644
--- a/ipapython/ssh.py
+++ b/ipapython/ssh.py
@@ -26,6 +26,7 @@ import base64
 import re
 import struct
 from hashlib import md5, sha1
+from hashlib import sha256  #pylint: disable=E0611
 
 __all__ = ['SSHPublicKey']
 
@@ -187,12 +188,21 @@ class SSHPublicKey(object):
         fp = u':'.join([fp[j:j+2] for j in range(0, len(fp), 2)])
         return fp
 
-    def fingerprint_dns_sha1(self):
+    # SSHFP magic numbers come from RFC 4255 and 6594
+    def _fingerprint_dns(self, fpfunc, fptype):
         if self._keytype == 'ssh-rsa':
             keytype = 1
         elif self._keytype == 'ssh-dss':
             keytype = 2
+        elif self._keytype.startswith('ecdsa-sha2-') and '@' not in self._keytype:
+            keytype = 3
         else:
             return
-        fp = sha1(self._key).hexdigest().upper()
-        return u'%d 1 %s' % (keytype, fp)
+        fp = fpfunc(self._key).hexdigest().upper()
+        return u'%d %d %s' % (keytype, fptype, fp)
+
+    def fingerprint_dns_sha1(self):
+        return self._fingerprint_dns(sha1, 1)
+
+    def fingerprint_dns_sha256(self):
+        return self._fingerprint_dns(sha256, 2)
-- 
1.8.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to