Hello community, here is the log from the commit of package yubikey-piv-manager for openSUSE:Factory checked in at 2016-10-18 10:42:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yubikey-piv-manager (Old) and /work/SRC/openSUSE:Factory/.yubikey-piv-manager.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yubikey-piv-manager" Changes: -------- --- /work/SRC/openSUSE:Factory/yubikey-piv-manager/yubikey-piv-manager.changes 2016-09-05 21:23:45.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.yubikey-piv-manager.new/yubikey-piv-manager.changes 2016-10-18 10:42:38.000000000 +0200 @@ -1,0 +2,22 @@ +Thu Oct 13 19:55:42 UTC 2016 - t.gru...@katodev.de + +- Remove build requirement python-pyside-tools + +------------------------------------------------------------------- +Wed Oct 12 14:30:45 UTC 2016 - t.gru...@katodev.de + +- Version 1.4.1 (released 2016-09-30) + - Now displays a confirmation dialog box when overwriting certificate data in a slot (including in the macOS Sierra wizard). + - On initialization, now shows a warning when the PIN or PUK has been changed in another tool. + - It is now possible to close the initialization and the expired PIN dialog boxes without closing the application. + - Bugfix: Connecting to a Certificate Authority should now work as expected (even over a network). + - Bugfix: Layout in the initialization dialog box was not acting as expected when the radio buttons were clicked. + +- Version 1.4.0 (released 2016-09-20) + - New wizard for setting up a YubiKey for pairing with macOS Sierra, providing an easy way to generate certificates in the authentication and key management slots. After the YubiKey is paired, macOS Sierra will recognize the YubiKey and allow you to pair it with an account on macOS. + - Improved appearance on Retina displays. + - More specific error messages when trying to import a certificate that is too large. + - Bugfix: Connecting to a Certificate Authority should now work again. + - Removed touch policy that was erroneously added in the previous version. + +------------------------------------------------------------------- Old: ---- yubikey-piv-manager-1.3.0.tar.gz yubikey-piv-manager-1.3.0.tar.gz.sig New: ---- yubikey-piv-manager-1.4.1.tar.gz yubikey-piv-manager-1.4.1.tar.gz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yubikey-piv-manager.spec ++++++ --- /var/tmp/diff_new_pack.q7tgMo/_old 2016-10-18 10:42:39.000000000 +0200 +++ /var/tmp/diff_new_pack.q7tgMo/_new 2016-10-18 10:42:39.000000000 +0200 @@ -18,7 +18,7 @@ %define bname pivman Name: yubikey-piv-manager -Version: 1.3.0 +Version: 1.4.1 Release: 0 Summary: YubiKey PIV Manager GUI License: GPL-3.0+ ++++++ yubikey-piv-manager-1.3.0.tar.gz -> yubikey-piv-manager-1.4.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/ChangeLog new/yubikey-piv-manager-1.4.1/ChangeLog --- old/yubikey-piv-manager-1.3.0/ChangeLog 2016-08-18 11:17:01.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/ChangeLog 2016-09-30 15:38:51.000000000 +0200 @@ -1,3 +1,225 @@ +2016-09-30 Dag Heyman <d...@yubico.com> + + * NEWS: Update NEWS + +2016-09-30 Dag Heyman <d...@yubico.com> + + * NEWS, pivman/__init__.py: Update NEWS and version for 1.4.1 + +2016-09-29 Dag Heyman <d...@yubico.com> + + * NEWS: Update NEWS for 1.4.1 + +2016-09-29 Dag Heyman <d...@yubico.com> + + * pivman/utils.py: Use certutil dump for CA check + +2016-09-27 Dag Heyman <d...@yubico.com> + + * NEWS, pivman/__init__.py: Update NEWS and version for upcoming + release + +2016-09-27 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/view/init_dialog.py: Warn user when PIN + or PUK is changed with other tool + +2016-09-27 Dag Heyman <d...@yubico.com> + + * pivman/view/main.py: Closing modal dialogs should not close app The init dialog and the pin expiration dialog are now closable + without closing the whole application. + +2016-09-27 Dag Heyman <d...@yubico.com> + + * pivman/view/init_dialog.py: Fix spelling error + +2016-09-26 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/view/cert.py, + pivman/view/generate_dialog.py, pivman/view/init_dialog.py: Add + overwrite warning for macOS wizard Add a overwrite warning when running the setup for macOS wizard on a + YubiKey that already have certificates in those slots. The existing overwrite warnings now only appear when a slot has a + certificate. Closes #15 + +2016-09-26 Dag Heyman <d...@yubico.com> + + * pivman/messages.py: Remove extra space + +2016-09-23 Dag Heyman <d...@yubico.com> + + * pivman/view/init_dialog.py: UI fix in init dialog + +2016-09-19 Dag Heyman <d...@yubico.com> + + * NEWS: Update NEWS + +2016-09-19 Dag Heyman <d...@yubico.com> + + * pivman/__init__.py: Update version + +2016-09-15 Dag Heyman <d...@yubico.com> + + * pivman/__init__.py: Update version + +2016-09-15 Dag Heyman <d...@yubico.com> + + * pivman/controller.py: Add more specific error messages on too + large certs + +2016-09-14 Dag Heyman <d...@yubico.com> + + * NEWS: Update release number in NEWS + +2016-09-14 Dag Heyman <d...@yubico.com> + + * pivman/messages.py: Adjust wording in macOS dialog + +2016-09-14 Dag Heyman <d...@yubico.com> + + * pivman/view/generate_dialog.py, pivman/view/init_dialog.py, + pivman/view/manage.py, pivman/view/set_pin_dialog.py: Never accept + dialog right before modal message + +2016-09-14 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/view/init_dialog.py: Fixup PIN + compability warning + +2016-09-14 Dag Heyman <d...@yubico.com> + + * pivman/__init__.py: Update version + +2016-09-13 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/view/init_dialog.py, + pivman/view/set_pin_dialog.py, pivman/view/utils.py: Remove + allow-numeric checkbox + +2016-09-13 Dag Heyman <d...@yubico.com> + + * pivman/__init__.py: Update version + +2016-09-12 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/utils.py, pivman/view/init_dialog.py: + Ensure PIN is numeric in macOS dialog If PIN is not numeric when setting up for macOS, ask user to change + PIN. + +2016-09-12 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/view/init_dialog.py, + pivman/view/set_pin_dialog.py, pivman/view/utils.py: Make + non-numeric PIN opt-in The PIV standard and macOS only supports numeric PINs. Make + non-numeric PINs opt-in and inform the user that all environments + doesn't support it. + +2016-09-12 Dag Heyman <d...@yubico.com> + + * pivman/messages.py: Remove the word please + +2016-09-12 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/utils.py: Change the wording in the + macOS dialog + +2016-09-09 Dag Heyman <d...@yubico.com> + + * pivman/__init__.py: Update version + +2016-09-09 Dain Nilsson <d...@yubico.com> + + * pivman/controller.py, pivman/view/main.py: Use ECCP256 for macOS. + +2016-09-09 Dain Nilsson <d...@yubico.com> + + * pivman/view/init_dialog.py, pivman/view/main.py, + pivman/watcher.py: Fix deadlock in device initialization. + +2016-09-09 Dain Nilsson <d...@yubico.com> + + * pivman/utils.py: Remove subprocess.mswindows. + +2016-09-09 Dag Heyman <d...@yubico.com> + + * pivman/view/init_dialog.py, pivman/view/main.py: Refactor macOS + dialog + +2016-09-09 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/view/init_dialog.py: Add heading to + macOS dialog + +2016-09-09 Dag Heyman <d...@yubico.com> + + * pivman/view/init_dialog.py, pivman/view/main.py: Small fixes macOS + dialog + +2016-09-09 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/utils.py: Add confirmation message to + macOS setup + +2016-09-09 Dag Heyman <d...@yubico.com> + + * pivman/controller.py, pivman/messages.py, pivman/utils.py, + pivman/view/init_dialog.py, pivman/view/main.py: Show button for + macOS setup from main window When on macOS Sierra or later, show always show a button for the + macOS setup. + +2016-09-08 Dain Nilsson <d...@yubico.com> + + * pivman/piv_cmd.py: Use sys.platform instead of + subprocess.mswindows. In Python 3.5 subprocess.mswindows has been removed. + +2016-09-07 Dag Heyman <d...@yubico.com> + + * pivman/controller.py, pivman/view/main.py: Don't show macOS dialog + if slots not empty + +2016-09-07 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/view/init_dialog.py: Wordwrap in macOS + dialog + +2016-09-07 Dag Heyman <d...@yubico.com> + + * pivman/messages.py, pivman/view/init_dialog.py: Small fixes for + macOS dialog + +2016-09-07 Dag Heyman <d...@yubico.com> + + * pivman/controller.py, pivman/messages.py, + pivman/view/init_dialog.py, pivman/view/main.py: Add macOS Sierra + specific dialog When initializing a key on macOS Sierra or later, ask if the user + wants to generate certificates for pairing. + +2016-09-02 Dag Heyman <d...@yubico.com> + + * NEWS: Fix NEWS + +2016-08-31 Dag Heyman <d...@yubico.com> + + * pivman/view/generate_dialog.py: Fix flake8 warning + +2016-08-31 Dag Heyman <d...@yubico.com> + + * NEWS, pivman/__init__.py: Update NEWS + +2016-08-31 Dag Heyman <d...@yubico.com> + + * pivman/view/generate_dialog.py: Don't close gen key dialog on PIN + cancel When asked for PIN when generating key, don't close the whole dialog + if user hits cancel. + +2016-08-31 Dag Heyman <d...@yubico.com> + + * pivman/storage.py: Revert "Show touch policy for generate key by + default." This reverts commit e15c40092109f17f292285ff632d9f0476142137. + +2016-08-29 Dag Heyman <d...@yubico.com> + + * pivman/utils.py: Fix call to certutil on windows + 2016-08-18 Dag Heyman <d...@yubico.com> * NEWS, pivman/__init__.py: Update version and NEWS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/NEWS new/yubikey-piv-manager-1.4.1/NEWS --- old/yubikey-piv-manager-1.3.0/NEWS 2016-08-18 11:08:18.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/NEWS 2016-09-30 15:38:23.000000000 +0200 @@ -1,3 +1,17 @@ +* Version 1.4.1 (released 2016-09-30) + ** Now displays a confirmation dialog box when overwriting certificate data in a slot (including in the macOS Sierra wizard). + ** On initialization, now shows a warning when the PIN or PUK has been changed in another tool. + ** It is now possible to close the initialization and the expired PIN dialog boxes without closing the application. + ** Bugfix: Connecting to a Certificate Authority should now work as expected (even over a network). + ** Bugfix: Layout in the initialization dialog box was not acting as expected when the radio buttons were clicked. + +* Version 1.4.0 (released 2016-09-20) + ** New wizard for setting up a YubiKey for pairing with macOS Sierra, providing an easy way to generate certificates in the authentication and key management slots. After the YubiKey is paired, macOS Sierra will recognize the YubiKey and allow you to pair it with an account on macOS. + ** Improved appearance on Retina displays. + ** More specific error messages when trying to import a certificate that is too large. + ** Bugfix: Connecting to a Certificate Authority should now work again. + ** Removed touch policy that was erroneously added in the previous version. + * Version 1.3.0 (released 2016-08-18) ** Updated to be inline with yubico-piv-tool 1.4.2. ** Allow generation of a authentication certificate when initialising a new YubiKey. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/PKG-INFO new/yubikey-piv-manager-1.4.1/PKG-INFO --- old/yubikey-piv-manager-1.3.0/PKG-INFO 2016-08-18 11:17:01.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/PKG-INFO 2016-09-30 15:38:51.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: yubikey-piv-manager -Version: 1.3.0 +Version: 1.4.1 Summary: Tool for configuring your PIV-enabled YubiKey. Home-page: https://github.com/Yubico/yubikey-piv-manager Author: Yubico Open Source Maintainers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/__init__.py new/yubikey-piv-manager-1.4.1/pivman/__init__.py --- old/yubikey-piv-manager-1.3.0/pivman/__init__.py 2016-08-18 11:07:28.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/__init__.py 2016-09-30 15:34:41.000000000 +0200 @@ -24,4 +24,4 @@ # non-source form of such a combination shall include the source code # for the parts of OpenSSL used as well as that of the covered work. -__version__ = "1.3.0" +__version__ = "1.4.1" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/controller.py new/yubikey-piv-manager-1.4.1/pivman/controller.py --- old/yubikey-piv-manager-1.3.0/pivman/controller.py 2016-08-18 09:18:19.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/controller.py 2016-09-27 13:06:03.000000000 +0200 @@ -24,7 +24,7 @@ # non-source form of such a combination shall include the source code # for the parts of OpenSSL used as well as that of the covered work. -from pivman.utils import test, der_read +from pivman.utils import test, der_read, is_macos_sierra_or_later from pivman.piv import PivError, WrongPinError from pivman.storage import settings, SETTINGS from pivman.view.utils import get_active_window, get_text @@ -39,7 +39,6 @@ import time import struct - YKPIV_OBJ_PIVMAN_DATA = 0x5fff00 TAG_PIVMAN_DATA = 0x80 # Wrapper for pivman data @@ -50,8 +49,13 @@ FLAG1_PUK_BLOCKED = 0x01 # PUK is blocked AUTH_SLOT = '9a' -DEFAULT_SUBJECT = "/CN=Yubico PIV Authentication" -AUTH_CERT_VALID_DAYS = 10950 # 30 years +ENCRYPTION_SLOT = '9d' +DEFAULT_AUTH_SUBJECT = "/CN=Yubico PIV Authentication" +DEFAULT_ENCRYPTION_SUBJECT = "/CN=Yubico PIV Encryption" +DEFAULT_VALID_DAYS = 10950 # 30 years + +NEO_MAX_CERT_LEN = 1024 * 2 - 23 +YK4_MAX_CERT_LEN = 1024 * 3 - 23 def parse_pivtool_data(raw_data): @@ -240,7 +244,7 @@ for i in range(8): # Invalidate the PUK test(self._key.set_puk, '', '000000', catches=ValueError) - def initialize(self, auth_cert, pin, puk=None, key=None, old_pin='123456', + def initialize(self, pin, puk=None, key=None, old_pin='123456', old_puk='12345678'): if not self.authenticated: @@ -257,15 +261,22 @@ self.change_pin(old_pin, pin) - if auth_cert: - self.create_auth_cert(pin) + def setup_for_macos(self, pin): - def create_auth_cert(self, pin): - generated_key = self.generate_key(AUTH_SLOT) - cert = self.selfsign_certificate( - AUTH_SLOT, pin, generated_key, - DEFAULT_SUBJECT, AUTH_CERT_VALID_DAYS) - self.import_certificate(cert, AUTH_SLOT) + """Generate self-signed certificates in slot 9a and 9d + to allow pairing a YubiKey with a user account on macOS""" + + auth_key = self.generate_key(AUTH_SLOT, 'ECCP256') + auth_cert = self.selfsign_certificate( + AUTH_SLOT, pin, auth_key, + DEFAULT_AUTH_SUBJECT, DEFAULT_VALID_DAYS) + self.import_certificate(auth_cert, AUTH_SLOT) + + encryption_key = self.generate_key(ENCRYPTION_SLOT, 'ECCP256') + encryption_cert = self.selfsign_certificate( + ENCRYPTION_SLOT, pin, encryption_key, + DEFAULT_ENCRYPTION_SUBJECT, DEFAULT_VALID_DAYS) + self.import_certificate(encryption_cert, ENCRYPTION_SLOT) def set_authentication(self, new_key, is_pin=False): if not self.authenticated: @@ -415,8 +426,19 @@ try: self._key.import_cert(cert, slot, frmt, password) except ValueError: - if len(cert) > 2048 and self.version_tuple < (4, 2, 7): - raise ValueError('Certificate is to large to fit in buffer.') + cert_len = len(cert) + if cert_len > NEO_MAX_CERT_LEN and self.version_tuple < (4, 2, 7): + raise ValueError( + 'Certificate too large, maximum is ' + + str(NEO_MAX_CERT_LEN) + + ' bytes (was ' + + str(cert_len) + ' bytes).') + elif cert_len > YK4_MAX_CERT_LEN: + raise ValueError( + 'Certificate too large, maximum is ' + + str(YK4_MAX_CERT_LEN) + + ' bytes (was ' + + str(cert_len) + ' bytes).') else: raise self.update_chuid() @@ -425,3 +447,8 @@ if not self.authenticated: raise ValueError('Not authenticated') self._key.delete_cert(slot) + + def should_show_macos_dialog(self): + return is_macos_sierra_or_later() \ + and AUTH_SLOT not in self.certs \ + and ENCRYPTION_SLOT not in self.certs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/messages.py new/yubikey-piv-manager-1.4.1/pivman/messages.py --- old/yubikey-piv-manager-1.3.0/pivman/messages.py 2016-08-15 15:06:00.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/messages.py 2016-09-27 13:20:44.000000000 +0200 @@ -163,8 +163,7 @@ save_csr = "Save Certificate Signing Request as..." generate_key = "Generate new key..." generate_key_warning_1 = "A new private key will be generated and stored in " \ - "slot '%s'. Anything currently in the slot will be deleted. This action " \ - "cannot be undone." + "slot '%s'." generating_key = "Generating new key..." generated_key = "New key generated" generated_key_desc_1 = "A new private key has been generated in slot '%s'." @@ -178,7 +177,7 @@ importing_file = "Importing from file..." unsupported_file = "Unsupported file type" delete_cert = "Delete certificate" -delete_cert_warning_1 = "This will delete the certificate and key stored in " \ +delete_cert_warning_1 = "This will delete the certificate and key stored in " \ "slot '%s' of your YubiKey, and cannot be undone." deleting_cert = "Deleting certificate..." cert_exported = "Certificate exported" @@ -256,6 +255,31 @@ "will start slowly blinking. At that point please touch the button on " \ "your YubiKey." touch_prompt = "Touch the button now..." -auth_cert = "Authentication certificate" -auth_cert_desc = "Generate a certificate for authentication" expiration_date = "Expiration date" +setting_up_macos = "Setting up for macOS..." +macos_pairing_title = "Set Up YubiKey for macOS" +macos_pairing_desc = "<p>This version of macOS allows you to pair your " \ + "YubiKey with your user account. When you have completed the pairing, " \ + "you can use your YubiKey to log in to your Mac.</p><p>" \ + "Do you want to generate certificates for this purpose (recommended)?</p>" +setup_for_macos = "Setup for macOS" +setup_macos_compl = "Setup for macOS completed" +setup_macos_compl_desc = "Your YubiKey is now ready to be paired with your " \ + "user account. To start the pairing process, remove and re-insert " \ + "your YubiKey." +non_numeric_pin_warning = "For cross-platform compatibility, " \ + "we recommend " \ + "you enter a PIN of 6-8 numeric digits." +non_numeric_pin = "Pairing your YubiKey with macOS requires your PIN to only "\ + "contain numeric characters. Do you want to change your PIN?" +overwrite_slot_warning = "Overwrite slot?" +overwrite_slot_warning_desc = "This will overwrite all data currently " \ + "stored in slot '%s'. This action cannot be undone. " \ + "Do you want to continue?" +overwrite_slot_warning_macos = "This will overwrite all data currently " \ + "stored in slot '9a' and '9d'. This action cannot be undone. "\ + "Do you want to continue?" +not_default_pin = "Your credentials for the YubiKey are not the default " \ + "values. This may occur when the PIN or PUK has been changed with a " \ + "different tool. Use the 'Manage device PINs' option to change the " \ + "credentials." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/piv_cmd.py new/yubikey-piv-manager-1.4.1/pivman/piv_cmd.py --- old/yubikey-piv-manager-1.3.0/pivman/piv_cmd.py 2016-08-15 15:06:00.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/piv_cmd.py 2016-09-14 12:54:55.000000000 +0200 @@ -44,7 +44,7 @@ def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - cmd = CMD + '.exe' if subprocess.mswindows else CMD + cmd = CMD + '.exe' if sys.platform == 'win32' else CMD paths = [basedir] + os.environ.get('PATH', '').split(os.pathsep) for path in paths: path = path.strip('"') @@ -90,7 +90,7 @@ self._base_args = set_arg(self._base_args, opt, value) def run(self, *args, **kwargs): - if subprocess.mswindows: # Avoid showing console window on Windows + if sys.platform == 'win32': # Avoid showing console window on Windows startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/qt_resources.py new/yubikey-piv-manager-1.4.1/pivman/qt_resources.py --- old/yubikey-piv-manager-1.3.0/pivman/qt_resources.py 2016-08-18 11:17:01.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/qt_resources.py 2016-09-30 15:38:51.000000000 +0200 @@ -2,7 +2,7 @@ # Resource object code # -# Created: Thu Aug 18 11:17:01 2016 +# Created: Fri Sep 30 15:38:51 2016 # by: The Resource Compiler for PySide (Qt v4.8.7) # # WARNING! All changes made in this file will be lost! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/storage.py new/yubikey-piv-manager-1.4.1/pivman/storage.py --- old/yubikey-piv-manager-1.3.0/pivman/storage.py 2016-08-10 13:32:06.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/storage.py 2016-08-31 09:34:53.000000000 +0200 @@ -69,8 +69,7 @@ SHOWN_SLOTS = Setting('shown_slots', sorted(CERT_SLOTS.keys()), list) SUBJECT = Setting('subject', '/CN=%s' % getuser(), str) TOUCH_POLICY = Setting('touch_policy', False, bool) - TOUCH_POLICY_SLOTS = Setting('touch_policy_slots', - sorted(CERT_SLOTS.keys()), list) + TOUCH_POLICY_SLOTS = Setting('touch_policy_slots', [], list) class SettingsOverlay(object): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/utils.py new/yubikey-piv-manager-1.4.1/pivman/utils.py --- old/yubikey-piv-manager-1.3.0/pivman/utils.py 2016-08-15 15:05:50.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/utils.py 2016-09-29 10:15:06.000000000 +0200 @@ -31,17 +31,21 @@ import subprocess import os import tempfile +import sys def has_ca(): try: - if subprocess.mswindows: + if sys.platform == 'win32': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW p = subprocess.Popen( - ['certutil', '-ping'], stdout=subprocess.PIPE, + ['certutil', '-dump'], stdout=subprocess.PIPE, startupinfo=startupinfo) - return p.returncode == 0 + output, _ = p.communicate() + # 'certutil -dump' returns one line when no CA is available. + return len(str.splitlines(output)) > 1 + except OSError: pass return False @@ -139,3 +143,11 @@ l *= 256 l += byte2int(b) return l + + +def is_macos_sierra_or_later(): + if sys.platform == 'darwin': + from platform import mac_ver + mac_version = tuple(int(x) for x in mac_ver()[0].split('.')) + return mac_version >= (10, 12) + return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/view/cert.py new/yubikey-piv-manager-1.4.1/pivman/view/cert.py --- old/yubikey-piv-manager-1.3.0/pivman/view/cert.py 2016-08-15 15:05:50.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/view/cert.py 2016-09-26 09:50:46.000000000 +0200 @@ -248,13 +248,6 @@ self.layout().insertWidget(0, self._status) def _import_file(self, controller, release): - res = QtGui.QMessageBox.warning(self, m.import_from_file, - m.import_from_file_warning_1 % - self._slot, - QtGui.QMessageBox.Ok, - QtGui.QMessageBox.Cancel) - if res != QtGui.QMessageBox.Ok: - return fn, fn_filter = QtGui.QFileDialog.getOpenFileName( self, m.import_from_file, filter=FILE_FILTER) @@ -283,8 +276,22 @@ try: if not controller.poll(): controller.reconnect() - controller.ensure_authenticated() + except Exception as e: + QtGui.QMessageBox.warning(self, m.error, str(e)) + + # User confirmation for overwriting slot data + if self._slot in controller.certs: + res = QtGui.QMessageBox.warning( + self, + m.overwrite_slot_warning, + m.overwrite_slot_warning_desc % self._slot, + QtGui.QMessageBox.Ok, + QtGui.QMessageBox.Cancel) + if res == QtGui.QMessageBox.Cancel: + return + + try: worker = QtCore.QCoreApplication.instance().worker worker.post(m.importing_file, func, partial( self._import_file_callback, controller, release), True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/view/generate_dialog.py new/yubikey-piv-manager-1.4.1/pivman/view/generate_dialog.py --- old/yubikey-piv-manager-1.3.0/pivman/view/generate_dialog.py 2016-08-15 15:13:19.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/view/generate_dialog.py 2016-09-26 09:52:23.000000000 +0200 @@ -28,7 +28,6 @@ from pivman import messages as m from pivman.utils import has_ca, request_cert_from_ca from pivman.storage import settings, SETTINGS -from pivman.piv import DeviceGoneError from pivman.view.usage_policy_dialog import UsagePolicyDialog from pivman.view.utils import SUBJECT_VALIDATOR @@ -180,6 +179,7 @@ return self._out_type.checkedButton().property('value') def _generate(self): + if self.out_format != 'pk' and not \ self._subject.hasAcceptableInput(): QtGui.QMessageBox.warning(self, m.invalid_subject, @@ -211,12 +211,21 @@ self._controller.ensure_authenticated(pin) except Exception as e: QtGui.QMessageBox.warning(self, m.error, str(e)) - if not isinstance(e, DeviceGoneError): - self.accept() return valid_days = QtCore.QDate.currentDate().daysTo(self._expire_date.date()) + # User confirmation for overwriting slot data + if self._slot in self._controller.certs: + res = QtGui.QMessageBox.warning( + self, + m.overwrite_slot_warning, + m.overwrite_slot_warning_desc % self._slot, + QtGui.QMessageBox.Ok, + QtGui.QMessageBox.Cancel) + if res == QtGui.QMessageBox.Cancel: + return + worker = QtCore.QCoreApplication.instance().worker worker.post( m.generating_key, (self._do_generate, pin, out_fn, valid_days), @@ -258,7 +267,6 @@ self._controller.import_certificate(cert, self._slot) def _generate_callback2(self, result): - self.accept() if isinstance(result, Exception): QtGui.QMessageBox.warning(self, m.error, str(result)) else: @@ -286,3 +294,4 @@ message += '\n' + m.gen_out_ca QtGui.QMessageBox.information(self, m.generated_key, message) + self.accept() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/view/init_dialog.py new/yubikey-piv-manager-1.4.1/pivman/view/init_dialog.py --- old/yubikey-piv-manager-1.3.0/pivman/view/init_dialog.py 2016-08-15 15:22:28.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/view/init_dialog.py 2016-09-27 13:22:17.000000000 +0200 @@ -26,14 +26,18 @@ from PySide import QtGui, QtCore from pivman import messages as m -from pivman.piv import DeviceGoneError, PivError, KEY_LEN +from pivman.piv import DeviceGoneError, PivError, WrongPinError, KEY_LEN +from pivman.view.set_pin_dialog import SetPinDialog from pivman.view.utils import KEY_VALIDATOR, pin_field from pivman.utils import complexity_check from pivman.storage import settings, SETTINGS from pivman.yubicommon import qt -from pivman.controller import AUTH_SLOT from binascii import b2a_hex +from pivman.controller import AUTH_SLOT, ENCRYPTION_SLOT import os +import re + +NUMERIC_PATTERN = re.compile("^[0-9]+$") class PinPanel(QtGui.QWidget): @@ -42,15 +46,18 @@ super(PinPanel, self).__init__() self._complex = settings[SETTINGS.COMPLEX_PINS] - - layout = QtGui.QFormLayout(self) + layout = QtGui.QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) - - layout.addRow(headers.section(m.pin)) + rowLayout = QtGui.QFormLayout() + rowLayout.addRow(headers.section(m.pin)) self._new_pin = pin_field() - layout.addRow(m.new_pin_label, self._new_pin) + rowLayout.addRow(m.new_pin_label, self._new_pin) self._confirm_pin = pin_field() - layout.addRow(m.verify_pin_label, self._confirm_pin) + rowLayout.addRow(m.verify_pin_label, self._confirm_pin) + layout.addLayout(rowLayout) + self._non_numeric_pin_warning = QtGui.QLabel(m.non_numeric_pin_warning) + self._non_numeric_pin_warning.setWordWrap(True) + layout.addWidget(self._non_numeric_pin_warning) @property def pin(self): @@ -104,12 +111,12 @@ if btn == self._kt_pin: self.layout().removeWidget(self._adv_panel) self._adv_panel.hide() - self.adjustSize() - self.parentWidget().adjustSize() else: self._adv_panel.reset() self.layout().addWidget(self._adv_panel) self._adv_panel.show() + self.adjustSize() + self.parentWidget().adjustSize() @property def use_pin(self): @@ -202,18 +209,6 @@ return puk -class DefaultCertPanel(QtGui.QWidget): - - def __init__(self, headers): - super(DefaultCertPanel, self).__init__() - layout = QtGui.QVBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - layout.addWidget(headers.section(m.auth_cert)) - self._auth_cert_cb = QtGui.QCheckBox(m.auth_cert_desc) - self._auth_cert_cb.setChecked(True) - layout.addWidget(self._auth_cert_cb) - - class InitDialog(qt.Dialog): def __init__(self, controller, parent=None): @@ -233,10 +228,6 @@ not settings[SETTINGS.PIN_AS_KEY]: layout.addWidget(self._key_panel) - if AUTH_SLOT not in self._controller.certs: - self._auth_cert_panel = DefaultCertPanel(self.headers) - layout.addWidget(self._auth_cert_panel) - layout.addStretch() buttons = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok) @@ -249,10 +240,6 @@ pin = self._pin_panel.pin key = self._key_panel.key puk = self._key_panel.puk - try: - auth_cert = self._auth_cert_panel._auth_cert_cb.isChecked() - except AttributeError: - auth_cert = None if key is not None and puk is None: res = QtGui.QMessageBox.warning(self, m.no_puk, @@ -269,20 +256,106 @@ worker = QtCore.QCoreApplication.instance().worker worker.post( m.initializing, - (self._controller.initialize, auth_cert, pin, puk, key), + (self._controller.initialize, pin, puk, key), self._init_callback, True ) - except (DeviceGoneError, PivError, ValueError) as e: + except DeviceGoneError: + QtGui.QMessageBox.warning(self, m.error, m.device_unplugged) + self.close() + except (PivError, ValueError) as e: QtGui.QMessageBox.warning(self, m.error, str(e)) def _init_callback(self, result): if isinstance(result, DeviceGoneError): QtGui.QMessageBox.warning(self, m.error, m.device_unplugged) - self.accept() + self.close() + if isinstance(result, WrongPinError): + QtGui.QMessageBox.warning(self, m.error, m.not_default_pin) + self.close() elif isinstance(result, Exception): QtGui.QMessageBox.warning(self, m.error, str(result)) else: if not settings.is_locked(SETTINGS.PIN_AS_KEY): settings[SETTINGS.PIN_AS_KEY] = self._key_panel.use_pin self.accept() + + +class MacOSPairingDialog(qt.Dialog): + + def __init__(self, controller, parent=None): + super(MacOSPairingDialog, self).__init__(parent) + self.setWindowTitle(m.macos_pairing_title) + self._controller = controller + self._build_ui() + + def _build_ui(self): + layout = QtGui.QVBoxLayout(self) + lbl = QtGui.QLabel(m.macos_pairing_desc) + lbl.setWordWrap(True) + layout.addWidget(lbl) + buttons = QtGui.QDialogButtonBox() + yes_btn = buttons.addButton(QtGui.QDialogButtonBox.Yes) + yes_btn.setDefault(True) + no_btn = buttons.addButton(QtGui.QDialogButtonBox.No) + no_btn.setAutoDefault(False) + no_btn.setDefault(False) + buttons.accepted.connect(self._setup) + buttons.rejected.connect(self.close) + layout.addWidget(buttons) + + def _setup(self): + try: + if not self._controller.poll(): + self._controller.reconnect() + + pin = self._controller.ensure_pin() + if NUMERIC_PATTERN.match(pin): + self._controller.ensure_authenticated(pin) + + # User confirmation for overwriting slot data + if (AUTH_SLOT in self._controller.certs + or ENCRYPTION_SLOT in self._controller.certs): + res = QtGui.QMessageBox.warning( + self, + m.overwrite_slot_warning, + m.overwrite_slot_warning_macos, + QtGui.QMessageBox.Cancel, + QtGui.QMessageBox.Ok) + if res == QtGui.QMessageBox.Cancel: + return + + worker = QtCore.QCoreApplication.instance().worker + worker.post( + m.setting_up_macos, + (self._controller.setup_for_macos, pin), + self.setup_callback, + True + ) + else: + res = QtGui.QMessageBox.warning( + self, + m.error, + m.non_numeric_pin, + QtGui.QMessageBox.Yes, + QtGui.QMessageBox.No) + + if res == QtGui.QMessageBox.Yes: + SetPinDialog(self._controller, self).exec_() + + except DeviceGoneError: + QtGui.QMessageBox.warning(self, m.error, m.device_unplugged) + self.close() + except Exception as e: + QtGui.QMessageBox.warning(self, m.error, str(e)) + + def setup_callback(self, result): + if isinstance(result, DeviceGoneError): + QtGui.QMessageBox.warning(self, m.error, m.device_unplugged) + self.close() + elif isinstance(result, Exception): + QtGui.QMessageBox.warning(self, m.error, str(result)) + else: + QtGui.QMessageBox.information( + self, m.setup_macos_compl, m.setup_macos_compl_desc) + self.accept() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/view/main.py new/yubikey-piv-manager-1.4.1/pivman/view/main.py --- old/yubikey-piv-manager-1.3.0/pivman/view/main.py 2016-08-15 15:05:50.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/view/main.py 2016-09-27 13:06:08.000000000 +0200 @@ -27,9 +27,10 @@ from PySide import QtGui from PySide import QtCore from pivman import messages as m +from pivman.utils import is_macos_sierra_or_later from pivman.watcher import ControllerWatcher from pivman.view.utils import IMPORTANT -from pivman.view.init_dialog import InitDialog +from pivman.view.init_dialog import InitDialog, MacOSPairingDialog from pivman.view.set_pin_dialog import SetPinDialog from pivman.view.manage import ManageDialog from pivman.view.cert import CertDialog @@ -43,7 +44,7 @@ self._lock = QtCore.QMutex() self._controller = ControllerWatcher() self._build_ui() - self._controller.on_found(self._refresh_controller, True) + self._controller.on_found(self._refresh_controller) self._controller.on_lost(self._no_controller) self._no_controller() @@ -61,6 +62,11 @@ self._pin_btn = QtGui.QPushButton(m.manage_pin) self._pin_btn.clicked.connect(self._manage_pin) btns.addWidget(self._pin_btn) + self._setup_macos_btn = QtGui.QPushButton(m.setup_for_macos) + if is_macos_sierra_or_later(): + self._setup_macos_btn.clicked.connect( + self._controller.wrap(self._setup_for_macos)) + btns.addWidget(self._setup_macos_btn) layout.addLayout(btns) self._messages = QtGui.QTextEdit() @@ -76,21 +82,27 @@ CertDialog(self._controller, self).exec_() self.refresh() + def _setup_for_macos(self, controller): + MacOSPairingDialog(controller, self).exec_() + self.refresh() + def refresh(self): - self._controller.use(self._refresh_controller, True) + self._controller.use(self._refresh_controller) def _no_controller(self): self._pin_btn.setEnabled(False) self._cert_btn.setEnabled(False) + self._setup_macos_btn.setEnabled(False) self._messages.setHtml(m.no_key) - def _refresh_controller(self, controller, release): + def _refresh_controller(self, controller): if not controller.poll(): self._no_controller() return self._pin_btn.setEnabled(True) self._cert_btn.setDisabled(controller.pin_blocked) + self._setup_macos_btn.setDisabled(controller.pin_blocked) messages = [] if controller.pin_blocked: @@ -105,12 +117,11 @@ if controller.is_uninitialized(): dialog = InitDialog(controller, self) if dialog.exec_(): - self.refresh() - else: - QtCore.QCoreApplication.instance().quit() + if controller.should_show_macos_dialog(): + self._setup_for_macos(controller) + else: + self.refresh() elif controller.is_pin_expired() and not controller.pin_blocked: dialog = SetPinDialog(controller, self, True) if dialog.exec_(): self.refresh() - else: - QtCore.QCoreApplication.instance().quit() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/view/manage.py new/yubikey-piv-manager-1.4.1/pivman/view/manage.py --- old/yubikey-piv-manager-1.3.0/pivman/view/manage.py 2016-08-08 14:55:33.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/view/manage.py 2016-09-14 12:58:08.000000000 +0200 @@ -135,6 +135,6 @@ self.refresh(controller) def _reset_callback(self, release, result): - self.accept() QtGui.QMessageBox.information(self, m.device_resetted, m.device_resetted_desc) + self.accept() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/view/set_pin_dialog.py new/yubikey-piv-manager-1.4.1/pivman/view/set_pin_dialog.py --- old/yubikey-piv-manager-1.3.0/pivman/view/set_pin_dialog.py 2016-08-08 14:55:33.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/view/set_pin_dialog.py 2016-09-14 13:00:29.000000000 +0200 @@ -63,12 +63,12 @@ self._old_pin = pin_field() layout.addWidget(self._old_pin) layout.addWidget(QtGui.QLabel(self.label_new)) + self._new_pin = pin_field() layout.addWidget(self._new_pin) layout.addWidget(QtGui.QLabel(self.label_verify)) self._confirm_pin = pin_field() layout.addWidget(self._confirm_pin) - self._new_pin.textChanged.connect(self._check_confirm) self._confirm_pin.textChanged.connect(self._check_confirm) @@ -131,9 +131,9 @@ else: self.reject() else: - self.accept() QtGui.QMessageBox.information(self, self.info_changed, self.desc_changed) + self.accept() class SetPukDialog(SetPinDialog): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/view/utils.py new/yubikey-piv-manager-1.4.1/pivman/view/utils.py --- old/yubikey-piv-manager-1.3.0/pivman/view/utils.py 2016-08-15 15:05:50.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/view/utils.py 2016-09-13 15:01:16.000000000 +0200 @@ -31,6 +31,7 @@ IMPORTANT = '<strong>%s</strong>' PIN_VALIDATOR = QtGui.QRegExpValidator(QtCore.QRegExp(r'.{6,8}')) +NUMERIC_PIN_VALIDATOR = QtGui.QRegExpValidator(QtCore.QRegExp(r'[0-9]{6,8}')) KEY_VALIDATOR = QtGui.QRegExpValidator(QtCore.QRegExp(r'[0-9a-fA-F]{48}')) SUBJECT_VALIDATOR = QtGui.QRegExpValidator(QtCore.QRegExp( r'^(/[a-zA-Z]+=[^/]+)+/?$')) @@ -79,7 +80,6 @@ field = QtGui.QLineEdit() field.setEchoMode(QtGui.QLineEdit.Password) field.setMaxLength(8) - field.setValidator(PIN_VALIDATOR) return field diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/pivman/watcher.py new/yubikey-piv-manager-1.4.1/pivman/watcher.py --- old/yubikey-piv-manager-1.3.0/pivman/watcher.py 2016-08-15 15:05:50.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/pivman/watcher.py 2016-09-14 12:54:55.000000000 +0200 @@ -45,7 +45,6 @@ self._fn() def __call__(self): - raise Exception('EXPLICIT CALL') self._fn() self._fn = lambda: None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yubikey-piv-manager-1.3.0/yubikey_piv_manager.egg-info/PKG-INFO new/yubikey-piv-manager-1.4.1/yubikey_piv_manager.egg-info/PKG-INFO --- old/yubikey-piv-manager-1.3.0/yubikey_piv_manager.egg-info/PKG-INFO 2016-08-18 11:17:01.000000000 +0200 +++ new/yubikey-piv-manager-1.4.1/yubikey_piv_manager.egg-info/PKG-INFO 2016-09-30 15:38:51.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: yubikey-piv-manager -Version: 1.3.0 +Version: 1.4.1 Summary: Tool for configuring your PIV-enabled YubiKey. Home-page: https://github.com/Yubico/yubikey-piv-manager Author: Yubico Open Source Maintainers