Add Python 3 subpackage (#1244237)
This commit is contained in:
parent
a5fbf513aa
commit
90e1c46dfa
2115
python-yubico-python3.patch
Normal file
2115
python-yubico-python3.patch
Normal file
File diff suppressed because it is too large
Load Diff
547
python-yubico-python3_util_examples.patch
Normal file
547
python-yubico-python3_util_examples.patch
Normal file
@ -0,0 +1,547 @@
|
||||
From 9039356ba6a08c21ac6b25200dc58e3d14ab1367 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Viktorin <pviktori@redhat.com>
|
||||
Date: Fri, 3 Jul 2015 14:10:55 +0200
|
||||
Subject: [PATCH] Add Python3 compatibility to util and examples
|
||||
|
||||
- Use print as a function
|
||||
- Use 'as' syntax when catching exceptions
|
||||
- Use six.moves.input instead of raw_input
|
||||
- Split text & bytes
|
||||
- Use binascii.hexlify instead of encode('hex')
|
||||
|
||||
Also, add iv argument to AES.new. It is required in newer
|
||||
versions of PyCrypto.
|
||||
---
|
||||
examples/configure_neo_ndef | 16 +++---
|
||||
examples/configure_nist_test_key | 13 ++---
|
||||
examples/nist_challenge_response | 25 +++++----
|
||||
examples/rolling_challenge_response | 105 +++++++++++++++++++-----------------
|
||||
examples/update_cfg_remove_cr | 22 ++++----
|
||||
examples/yubikey-inventory | 4 +-
|
||||
util/yubikey-totp | 18 +++----
|
||||
yubico/yubikey_frame.py | 18 +++----
|
||||
yubico/yubikey_neo_usb_hid.py | 2 +-
|
||||
9 files changed, 119 insertions(+), 104 deletions(-)
|
||||
|
||||
diff --git a/examples/configure_neo_ndef b/examples/configure_neo_ndef
|
||||
index 81bd927..44fc87d 100755
|
||||
--- a/examples/configure_neo_ndef
|
||||
+++ b/examples/configure_neo_ndef
|
||||
@@ -5,7 +5,8 @@ Set up a YubiKey NEO NDEF
|
||||
|
||||
import sys
|
||||
import struct
|
||||
-import urllib
|
||||
+
|
||||
+import six
|
||||
|
||||
import yubico
|
||||
import yubico.yubikey_neo_usb_hid
|
||||
@@ -16,18 +17,21 @@ if len(sys.argv) != 2:
|
||||
|
||||
url = sys.argv[1]
|
||||
|
||||
+if sys.version_info >= (3, 0):
|
||||
+ url = url.encode('utf-8')
|
||||
+
|
||||
try:
|
||||
YK = yubico.yubikey_neo_usb_hid.YubiKeyNEO_USBHID(debug=True)
|
||||
- print "Version : %s " % YK.version()
|
||||
+ print("Version : %s " % YK.version())
|
||||
|
||||
ndef = yubico.yubikey_neo_usb_hid.YubiKeyNEO_NDEF(data = url)
|
||||
|
||||
- user_input = raw_input('Write configuration to YubiKey? [y/N] : ')
|
||||
+ user_input = six.moves.input('Write configuration to YubiKey? [y/N] : ')
|
||||
if user_input in ('y', 'ye', 'yes'):
|
||||
YK.write_ndef(ndef)
|
||||
- print "\nSuccess!"
|
||||
+ print("\nSuccess!")
|
||||
else:
|
||||
- print "\nAborted"
|
||||
+ print("\nAborted")
|
||||
except yubico.yubico_exception.YubicoError as inst:
|
||||
- print "ERROR: %s" % inst.reason
|
||||
+ print("ERROR: %s" % inst.reason)
|
||||
sys.exit(1)
|
||||
diff --git a/examples/configure_nist_test_key b/examples/configure_nist_test_key
|
||||
index 8bb80b6..ae0dd22 100755
|
||||
--- a/examples/configure_nist_test_key
|
||||
+++ b/examples/configure_nist_test_key
|
||||
@@ -7,24 +7,25 @@ Set up a YubiKey with a NIST PUB 198 A.2
|
||||
import sys
|
||||
import struct
|
||||
import yubico
|
||||
+import six
|
||||
|
||||
slot=2
|
||||
|
||||
try:
|
||||
YK = yubico.find_yubikey(debug=True)
|
||||
- print "Version : %s " % YK.version()
|
||||
+ print("Version : %s " % YK.version())
|
||||
|
||||
Cfg = YK.init_config()
|
||||
- key='h:303132333435363738393a3b3c3d3e3f40414243'
|
||||
+ key = b'h:303132333435363738393a3b3c3d3e3f40414243'
|
||||
Cfg.mode_challenge_response(key, type='HMAC', variable=True)
|
||||
Cfg.extended_flag('SERIAL_API_VISIBLE', True)
|
||||
|
||||
- user_input = raw_input('Write configuration to slot %i of YubiKey? [y/N] : ' % slot )
|
||||
+ user_input = six.moves.input('Write configuration to slot %i of YubiKey? [y/N] : ' % slot )
|
||||
if user_input in ('y', 'ye', 'yes'):
|
||||
YK.write_config(Cfg, slot=slot)
|
||||
- print "\nSuccess!"
|
||||
+ print("\nSuccess!")
|
||||
else:
|
||||
- print "\nAborted"
|
||||
+ print("\nAborted")
|
||||
except yubico.yubico_exception.YubicoError as inst:
|
||||
- print "ERROR: %s" % inst.reason
|
||||
+ print("ERROR: %s" % inst.reason)
|
||||
sys.exit(1)
|
||||
diff --git a/examples/nist_challenge_response b/examples/nist_challenge_response
|
||||
index 0c42ea2..f5ea188 100755
|
||||
--- a/examples/nist_challenge_response
|
||||
+++ b/examples/nist_challenge_response
|
||||
@@ -8,8 +8,8 @@ import sys
|
||||
import yubico
|
||||
|
||||
expected = \
|
||||
- '\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82' + \
|
||||
- '\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24'
|
||||
+ b'\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82' + \
|
||||
+ b'\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24'
|
||||
|
||||
# turn on YubiKey debug if -v is given as an argument
|
||||
debug = False
|
||||
@@ -19,25 +19,28 @@ if len(sys.argv) > 1:
|
||||
# Look for and initialize the YubiKey
|
||||
try:
|
||||
YK = yubico.find_yubikey(debug=debug)
|
||||
- print "Version : %s " % YK.version()
|
||||
- print "Serial : %i" % YK.serial()
|
||||
- print ""
|
||||
+ print("Version : %s " % YK.version())
|
||||
+ print("Serial : %i" % YK.serial())
|
||||
+ print("")
|
||||
|
||||
# Do challenge-response
|
||||
- secret = 'Sample #2'.ljust(64, chr(0x0))
|
||||
- print "Sending challenge : %s\n" % repr(secret)
|
||||
+ secret = b'Sample #2'.ljust(64, b'\0')
|
||||
+ print("Sending challenge : %s\n" % repr(secret))
|
||||
|
||||
response = YK.challenge_response(secret, slot=2)
|
||||
except yubico.yubico_exception.YubicoError as inst:
|
||||
- print "ERROR: %s" % inst.reason
|
||||
+ print("ERROR: %s" % inst.reason)
|
||||
sys.exit(1)
|
||||
|
||||
-print "Response :\n%s\n" % yubico.yubico_util.hexdump(response)
|
||||
+print("Response :\n%s\n" % yubico.yubico_util.hexdump(response))
|
||||
+
|
||||
+# Workaround for http://bugs.python.org/issue24596
|
||||
+del YK
|
||||
|
||||
# Check if the response matched the expected one
|
||||
if response == expected:
|
||||
- print "OK! Response matches the NIST PUB 198 A.2 expected response."
|
||||
+ print("OK! Response matches the NIST PUB 198 A.2 expected response.")
|
||||
sys.exit(0)
|
||||
else:
|
||||
- print "ERROR! Response does NOT match the NIST PUB 198 A.2 expected response."
|
||||
+ print("ERROR! Response does NOT match the NIST PUB 198 A.2 expected response.")
|
||||
sys.exit(1)
|
||||
diff --git a/examples/rolling_challenge_response b/examples/rolling_challenge_response
|
||||
index c383f00..c371392 100755
|
||||
--- a/examples/rolling_challenge_response
|
||||
+++ b/examples/rolling_challenge_response
|
||||
@@ -22,8 +22,10 @@ import json
|
||||
import hmac
|
||||
import argparse
|
||||
import hashlib
|
||||
+import binascii
|
||||
|
||||
import yubico
|
||||
+import six
|
||||
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
@@ -70,10 +72,10 @@ def parse_args():
|
||||
|
||||
def init_demo(args):
|
||||
""" Initializes the demo by asking a few questions and creating a new stat file. """
|
||||
- hmac_key = raw_input("Enter HMAC-SHA1 key as 40 chars of hex (or press enter for random key) : ")
|
||||
+ hmac_key = six.moves.input("Enter HMAC-SHA1 key as 40 chars of hex (or press enter for random key) : ")
|
||||
if hmac_key:
|
||||
try:
|
||||
- hmac_key = hmac_key.decode('hex')
|
||||
+ hmac_key = binascii.unhexlify(hmac_key)
|
||||
except:
|
||||
sys.stderr.write("Could not decode HMAC-SHA1 key. Please enter 40 hex-chars.\n")
|
||||
sys.exit(1)
|
||||
@@ -83,12 +85,12 @@ def init_demo(args):
|
||||
sys.stderr.write("Decoded HMAC-SHA1 key is %i bytes, expected 20.\n" %( len(hmac_key)))
|
||||
sys.exit(1)
|
||||
|
||||
- print "To program a YubiKey >= 2.2 for challenge-response with this key, use :"
|
||||
- print ""
|
||||
- print " $ ykpersonalize -%i -ochal-resp -ochal-hmac -ohmac-lt64 -a %s" % (args.slot, hmac_key.encode('hex'))
|
||||
- print ""
|
||||
+ print("To program a YubiKey >= 2.2 for challenge-response with this key, use :")
|
||||
+ print("")
|
||||
+ print(" $ ykpersonalize -%i -ochal-resp -ochal-hmac -ohmac-lt64 -a %s" % (args.slot, binascii.hexlify(hmac_key).decode('ascii')))
|
||||
+ print("")
|
||||
|
||||
- passphrase = raw_input("Enter the secret passphrase to protect with the rolling challenges : ")
|
||||
+ passphrase = six.moves.input("Enter the secret passphrase to protect with the rolling challenges : ")
|
||||
|
||||
secret_dict = {"count": 0,
|
||||
"passphrase": passphrase,
|
||||
@@ -99,81 +101,84 @@ def do_challenge(args):
|
||||
""" Send a challenge to the YubiKey and use the result to decrypt the state file. """
|
||||
outer_j = load_state_file(args)
|
||||
challenge = outer_j["challenge"]
|
||||
- print "Challenge : %s" % (challenge)
|
||||
- response = get_yubikey_response(args, outer_j["challenge"].decode('hex'))
|
||||
+ print("Challenge : %s" % (challenge))
|
||||
+ response = get_yubikey_response(args, binascii.unhexlify(outer_j["challenge"]))
|
||||
if args.debug or args.verbose:
|
||||
- print "\nGot %i bytes response %s\n" % (len(response), response.encode('hex'))
|
||||
+ print("\nGot %i bytes response %s\n" % (len(response), binascii.hexlify(response)))
|
||||
else:
|
||||
- print "Response : %s" % (response.encode('hex'))
|
||||
+ print("Response : %s" % binascii.hexlify(response))
|
||||
inner_j = decrypt_with_response(args, outer_j["inner"], response)
|
||||
if args.verbose or args.debug:
|
||||
- print "\nDecrypted 'inner' :\n%s\n" % (inner_j)
|
||||
+ print("\nDecrypted 'inner' :\n%s\n" % (inner_j))
|
||||
|
||||
secret_dict = {}
|
||||
try:
|
||||
- secret_dict = json.loads(inner_j)
|
||||
+ secret_dict = json.loads(inner_j.decode('ascii'))
|
||||
except ValueError:
|
||||
sys.stderr.write("\nCould not parse decoded data as JSON, you probably did not produce the right response.\n")
|
||||
sys.exit(1)
|
||||
|
||||
secret_dict["count"] += 1
|
||||
|
||||
- print "\nThe passphrase protected using rolling challenges is :\n"
|
||||
- print "\t%s\n\nAccessed %i times.\n" % (secret_dict["passphrase"], secret_dict["count"])
|
||||
- roll_next_challenge(args, secret_dict["hmac_key"].decode('hex'), secret_dict)
|
||||
+ print("\nThe passphrase protected using rolling challenges is :\n")
|
||||
+ print("\t%s\n\nAccessed %i times.\n" % (secret_dict["passphrase"], secret_dict["count"]))
|
||||
+ roll_next_challenge(args, binascii.unhexlify(secret_dict["hmac_key"]), secret_dict)
|
||||
|
||||
def get_yubikey_response(args, challenge):
|
||||
"""
|
||||
Do challenge-response with the YubiKey if one is found. Otherwise prompt user to fake a response. """
|
||||
try:
|
||||
YK = yubico.find_yubikey(debug = args.debug)
|
||||
- response = YK.challenge_response(challenge.ljust(64, chr(0x0)), slot = args.slot)
|
||||
+ response = YK.challenge_response(challenge.ljust(64, b'\0'), slot = args.slot)
|
||||
return response
|
||||
except yubico.yubico_exception.YubicoError as e:
|
||||
- print "YubiKey challenge-response failed (%s)" % e.reason
|
||||
- print ""
|
||||
- response = raw_input("Assuming you do not have a YubiKey. Enter repsonse manually (hex encoded) : ")
|
||||
- return response
|
||||
+ print("YubiKey challenge-response failed (%s)" % e.reason)
|
||||
+ print("")
|
||||
+ response = six.moves.input("Assuming you do not have a YubiKey. Enter repsonse manually (hex encoded) : ")
|
||||
+ return binascii.unhexlify(response)
|
||||
|
||||
def roll_next_challenge(args, hmac_key, inner_dict):
|
||||
"""
|
||||
When we have the HMAC-SHA1 key in clear, generate a random challenge and compute the
|
||||
expected response for that challenge.
|
||||
+
|
||||
+ hmac_key is a 20-byte bytestring
|
||||
"""
|
||||
- if len(hmac_key) != 20:
|
||||
- hmac_key = hmac_key.decode('hex')
|
||||
+ if len(hmac_key) != 20 or not isinstance(hmac_key, bytes):
|
||||
+ hmac_key = binascii.unhexlify(hmac_key)
|
||||
|
||||
challenge = os.urandom(args.challenge_length)
|
||||
response = get_response(hmac_key, challenge)
|
||||
|
||||
- print "Generated challenge : %s" % (challenge.encode('hex'))
|
||||
- print "Expected response : %s (sssh, don't tell anyone)" % (response)
|
||||
- print ""
|
||||
+ print("Generated challenge : %s" % binascii.hexlify(challenge).decode('ascii'))
|
||||
+ print("Expected response : %s (sssh, don't tell anyone)" % binascii.hexlify(response).decode('ascii'))
|
||||
+ print("")
|
||||
if args.debug or args.verbose or args.init:
|
||||
- print "To manually verify that your YubiKey produces this response, use :"
|
||||
- print ""
|
||||
- print " $ ykchalresp -%i -x %s" % (args.slot, challenge.encode('hex'))
|
||||
- print ""
|
||||
+ print("To manually verify that your YubiKey produces this response, use :")
|
||||
+ print("")
|
||||
+ print(" $ ykchalresp -%i -x %s" % (args.slot, binascii.hexlify(challenge).decode('ascii')))
|
||||
+ print("")
|
||||
|
||||
- inner_dict["hmac_key"] = hmac_key.encode('hex')
|
||||
+ inner_dict["hmac_key"] = binascii.hexlify(hmac_key).decode('ascii')
|
||||
inner_j = json.dumps(inner_dict, indent = 4)
|
||||
if args.verbose or args.debug:
|
||||
- print "Inner JSON :\n%s\n" % (inner_j)
|
||||
+ print("Inner JSON :\n%s\n" % (inner_j))
|
||||
inner_ciphertext = encrypt_with_response(args, inner_j, response)
|
||||
- outer_dict = {"challenge": challenge.encode('hex'),
|
||||
- "inner": inner_ciphertext,
|
||||
+ outer_dict = {"challenge": binascii.hexlify(challenge).decode('ascii'),
|
||||
+ "inner": inner_ciphertext.decode('ascii'),
|
||||
}
|
||||
outer_j = json.dumps(outer_dict, indent = 4)
|
||||
if args.verbose or args.debug:
|
||||
- print "\nOuter JSON :\n%s\n" % (outer_j)
|
||||
+ print("\nOuter JSON :\n%s\n" % (outer_j))
|
||||
|
||||
- print "Saving 'outer' JSON to file '%s'" % (args.filename)
|
||||
+ print("Saving 'outer' JSON to file '%s'" % (args.filename))
|
||||
write_state_file(args, outer_j)
|
||||
|
||||
def get_response(hmac_key, challenge):
|
||||
- """ Compute the expected response for `challenge'. """
|
||||
+ """ Compute the expected response for `challenge', as hexadecimal string """
|
||||
+ print(binascii.hexlify(hmac_key), binascii.hexlify(challenge), hashlib.sha1)
|
||||
h = hmac.new(hmac_key, challenge, hashlib.sha1)
|
||||
- return h.hexdigest()
|
||||
+ return h.digest()
|
||||
|
||||
def encrypt_with_response(args, data, key):
|
||||
"""
|
||||
@@ -191,14 +196,14 @@ def encrypt_with_response(args, data, key):
|
||||
data += ' ' * (16 - pad)
|
||||
|
||||
# need to pad key as well
|
||||
- aes_key = key.decode('hex')
|
||||
- aes_key += chr(0x0) * (32 - len(aes_key))
|
||||
+ aes_key = key
|
||||
+ aes_key += b'\0' * (32 - len(aes_key))
|
||||
if args.debug:
|
||||
- print ("AES-CBC encrypting 'inner' with key (%i bytes) : %s" % (len(aes_key), aes_key.encode('hex')))
|
||||
+ print(("AES-CBC encrypting 'inner' with key (%i bytes) : %s" % (len(aes_key), binascii.hexlify(aes_key))))
|
||||
|
||||
- obj = AES.new(aes_key, AES.MODE_CBC)
|
||||
+ obj = AES.new(aes_key, AES.MODE_CBC, b'\0' * 16)
|
||||
ciphertext = obj.encrypt(data)
|
||||
- return ciphertext.encode('hex')
|
||||
+ return binascii.hexlify(ciphertext)
|
||||
|
||||
def decrypt_with_response(args, data, key):
|
||||
"""
|
||||
@@ -206,17 +211,17 @@ def decrypt_with_response(args, data, key):
|
||||
"""
|
||||
aes_key = key
|
||||
try:
|
||||
- aes_key = key.decode('hex')
|
||||
- except TypeError:
|
||||
+ aes_key = binascii.unhexlify(key)
|
||||
+ except (TypeError, binascii.Error):
|
||||
# was not hex encoded
|
||||
pass
|
||||
# need to pad key
|
||||
- aes_key += chr(0x0) * (32 - len(aes_key))
|
||||
+ aes_key += b'\0' * (32 - len(aes_key))
|
||||
if args.debug:
|
||||
- print ("AES-CBC decrypting 'inner' using key (%i bytes) : %s" % (len(aes_key), aes_key.encode('hex')))
|
||||
+ print(("AES-CBC decrypting 'inner' using key (%i bytes) : %s" % (len(aes_key), binascii.hexlify(aes_key))))
|
||||
|
||||
- obj = AES.new(aes_key, AES.MODE_CBC)
|
||||
- plaintext = obj.decrypt(data.decode('hex'))
|
||||
+ obj = AES.new(aes_key, AES.MODE_CBC, b'\0' * 16)
|
||||
+ plaintext = obj.decrypt(binascii.unhexlify(data))
|
||||
return plaintext
|
||||
|
||||
def write_state_file(args, data):
|
||||
@@ -236,7 +241,7 @@ def main():
|
||||
else:
|
||||
do_challenge(args)
|
||||
|
||||
- print "\nDone\n"
|
||||
+ print("\nDone\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
diff --git a/examples/update_cfg_remove_cr b/examples/update_cfg_remove_cr
|
||||
index bc27849..78012b3 100755
|
||||
--- a/examples/update_cfg_remove_cr
|
||||
+++ b/examples/update_cfg_remove_cr
|
||||
@@ -6,39 +6,41 @@ Set up a YubiKey for standard OTP with CR, then remove it.
|
||||
import sys
|
||||
import struct
|
||||
import yubico
|
||||
+import six
|
||||
+import binascii
|
||||
|
||||
slot=2
|
||||
|
||||
try:
|
||||
YK = yubico.find_yubikey(debug=True)
|
||||
- print "Version : %s " % YK.version()
|
||||
- print "Status : %s " % YK.status()
|
||||
+ print("Version : %s " % YK.version())
|
||||
+ print("Status : %s " % YK.status())
|
||||
|
||||
Cfg = YK.init_config()
|
||||
Cfg.extended_flag('ALLOW_UPDATE', True)
|
||||
Cfg.ticket_flag('APPEND_CR', True)
|
||||
Cfg.extended_flag('SERIAL_API_VISIBLE', True)
|
||||
- Cfg.uid = '010203040506'.decode('hex')
|
||||
+ Cfg.uid = binascii.unhexlify('010203040506')
|
||||
Cfg.fixed_string("m:ftccftbbftdd")
|
||||
Cfg.aes_key('h:' + 32 * 'a')
|
||||
|
||||
- user_input = raw_input('Write configuration to slot %i of YubiKey? [y/N] : ' % slot )
|
||||
+ user_input = six.moves.input('Write configuration to slot %i of YubiKey? [y/N] : ' % slot )
|
||||
if user_input in ('y', 'ye', 'yes'):
|
||||
YK.write_config(Cfg, slot=slot)
|
||||
- print "\nSuccess!"
|
||||
- print "Status : %s " % YK.status()
|
||||
+ print("\nSuccess!")
|
||||
+ print("Status : %s " % YK.status())
|
||||
else:
|
||||
- print "\nAborted"
|
||||
+ print("\nAborted")
|
||||
sys.exit(0)
|
||||
|
||||
- raw_input("Press enter to update...")
|
||||
+ six.moves.input("Press enter to update...")
|
||||
|
||||
Cfg = YK.init_config(update=True)
|
||||
Cfg.ticket_flag('APPEND_CR', False)
|
||||
|
||||
print ("Updating...");
|
||||
YK.write_config(Cfg, slot=slot)
|
||||
- print "\nSuccess!"
|
||||
+ print("\nSuccess!")
|
||||
except yubico.yubico_exception.YubicoError as inst:
|
||||
- print "ERROR: %s" % inst.reason
|
||||
+ print("ERROR: %s" % inst.reason)
|
||||
sys.exit(1)
|
||||
diff --git a/examples/yubikey-inventory b/examples/yubikey-inventory
|
||||
index 0b34a22..e36414d 100755
|
||||
--- a/examples/yubikey-inventory
|
||||
+++ b/examples/yubikey-inventory
|
||||
@@ -29,9 +29,9 @@ if len(sys.argv) > 1:
|
||||
keys = get_all_yubikeys(debug)
|
||||
|
||||
if not keys:
|
||||
- print "No YubiKey found."
|
||||
+ print("No YubiKey found.")
|
||||
else:
|
||||
n = 1
|
||||
for this in keys:
|
||||
- print "YubiKey #%02i : %s %s" % (n, this.description, this.status())
|
||||
+ print("YubiKey #%02i : %s %s" % (n, this.description, this.status()))
|
||||
n += 1
|
||||
diff --git a/util/yubikey-totp b/util/yubikey-totp
|
||||
index f02ad07..9ace901 100755
|
||||
--- a/util/yubikey-totp
|
||||
+++ b/util/yubikey-totp
|
||||
@@ -38,6 +38,7 @@ import time
|
||||
import struct
|
||||
import yubico
|
||||
import argparse
|
||||
+import binascii
|
||||
|
||||
default_slot=2
|
||||
default_time=int(time.time())
|
||||
@@ -97,18 +98,17 @@ def make_totp(args):
|
||||
"""
|
||||
YK = yubico.find_yubikey(debug=args.debug)
|
||||
if args.debug or args.verbose:
|
||||
- print "Version : %s " % YK.version()
|
||||
+ print("Version : %s " % YK.version())
|
||||
if args.debug:
|
||||
- print "Serial : %i" % YK.serial()
|
||||
- print ""
|
||||
+ print("Serial : %i" % YK.serial())
|
||||
+ print("")
|
||||
# Do challenge-response
|
||||
secret = struct.pack("> Q", args.time / args.step).ljust(64, chr(0x0))
|
||||
if args.debug:
|
||||
- print "Sending challenge : %s\n" % (secret.encode('hex'))
|
||||
+ print("Sending challenge : %s\n" % (binascii.hexlify(secret)))
|
||||
response = YK.challenge_response(secret, slot=args.slot)
|
||||
# format with appropriate number of leading zeros
|
||||
- fmt = "%." + str(args.digits) + "i"
|
||||
- totp_str = fmt % (yubico.yubico_util.hotp_truncate(response, length=args.digits))
|
||||
+ totp_str = '%.*i' % (args.digits, yubico.yubico_util.hotp_truncate(response, length=args.digits))
|
||||
return totp_str
|
||||
|
||||
def main():
|
||||
@@ -118,14 +118,14 @@ def main():
|
||||
otp = None
|
||||
try:
|
||||
otp = make_totp(args)
|
||||
- except yubico.yubico_exception.YubicoError, e:
|
||||
- print "ERROR: %s" % (e.reason)
|
||||
+ except yubico.yubico_exception.YubicoError as e:
|
||||
+ print("ERROR: %s" % (e.reason))
|
||||
return 1
|
||||
|
||||
if not otp:
|
||||
return 1
|
||||
|
||||
- print otp
|
||||
+ print(otp)
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
diff --git a/yubico/yubikey_frame.py b/yubico/yubikey_frame.py
|
||||
index c43c6a1..f095d20 100644
|
||||
--- a/yubico/yubikey_frame.py
|
||||
+++ b/yubico/yubikey_frame.py
|
||||
@@ -101,24 +101,24 @@ def _debug_string(self, debug, data):
|
||||
yubikey_defs.SLOT_SWAP,
|
||||
]:
|
||||
# annotate according to config_st (see yubikey_defs.to_string())
|
||||
- if ord(data[-1]) == 0x80:
|
||||
+ if yubico_util.ord_byte(data[-1]) == 0x80:
|
||||
return (data, "FFFFFFF")
|
||||
- if ord(data[-1]) == 0x81:
|
||||
+ if yubico_util.ord_byte(data[-1]) == 0x81:
|
||||
return (data, "FFFFFFF")
|
||||
- if ord(data[-1]) == 0x82:
|
||||
+ if yubico_util.ord_byte(data[-1]) == 0x82:
|
||||
return (data, "FFUUUUU")
|
||||
- if ord(data[-1]) == 0x83:
|
||||
+ if yubico_util.ord_byte(data[-1]) == 0x83:
|
||||
return (data, "UKKKKKK")
|
||||
- if ord(data[-1]) == 0x84:
|
||||
+ if yubico_util.ord_byte(data[-1]) == 0x84:
|
||||
return (data, "KKKKKKK")
|
||||
- if ord(data[-1]) == 0x85:
|
||||
+ if yubico_util.ord_byte(data[-1]) == 0x85:
|
||||
return (data, "KKKAAAA")
|
||||
- if ord(data[-1]) == 0x86:
|
||||
+ if yubico_util.ord_byte(data[-1]) == 0x86:
|
||||
return (data, "AAlETCr")
|
||||
- if ord(data[-1]) == 0x87:
|
||||
+ if yubico_util.ord_byte(data[-1]) == 0x87:
|
||||
return (data, "rCR")
|
||||
# after payload
|
||||
- if ord(data[-1]) == 0x89:
|
||||
+ if yubico_util.ord_byte(data[-1]) == 0x89:
|
||||
return (data, " Scr")
|
||||
else:
|
||||
return (data, '')
|
||||
diff --git a/yubico/yubikey_neo_usb_hid.py b/yubico/yubikey_neo_usb_hid.py
|
||||
index 88fceba..7030c59 100644
|
||||
--- a/yubico/yubikey_neo_usb_hid.py
|
||||
+++ b/yubico/yubikey_neo_usb_hid.py
|
||||
@@ -188,7 +188,7 @@ def to_string(self):
|
||||
first = struct.pack(fmt,
|
||||
len(data),
|
||||
self.ndef_type,
|
||||
- data.ljust(_NDEF_DATA_SIZE, chr(0x0)),
|
||||
+ data.ljust(_NDEF_DATA_SIZE, b'\0'),
|
||||
self.access_code,
|
||||
)
|
||||
#crc = 0xffff - yubico_util.crc16(first)
|
||||
@ -3,15 +3,25 @@
|
||||
%{!?python2_sitelib: %global python2_sitelib %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")}
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel} != 0 && 0%{?rhel} <= 7
|
||||
# Do not build python3 subpackage for RHEL <= 7
|
||||
%bcond_with python3
|
||||
%else
|
||||
%bcond_without python3
|
||||
%endif
|
||||
|
||||
Name: python-yubico
|
||||
Version: 1.2.3
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Summary: Pure-python library for interacting with Yubikeys
|
||||
|
||||
License: BSD
|
||||
URL: https://github.com/Yubico/python-yubico
|
||||
Source0: https://github.com/Yubico/python-yubico/archive/%{name}-%{version}.tar.gz
|
||||
|
||||
Patch0: %{name}-python3.patch
|
||||
Patch1: %{name}-python3_util_examples.patch
|
||||
|
||||
BuildArch: noarch
|
||||
BuildRequires: python2-devel
|
||||
BuildRequires: python-setuptools
|
||||
@ -21,33 +31,98 @@ BuildRequires: pyusb
|
||||
%endif
|
||||
Requires: pyusb
|
||||
|
||||
%if %{with python3}
|
||||
BuildRequires: python3-devel
|
||||
BuildRequires: python3-setuptools
|
||||
BuildRequires: python3-nose
|
||||
BuildRequires: python3-pyusb
|
||||
%endif
|
||||
|
||||
%description
|
||||
Pure-python library for interacting with Yubikeys
|
||||
|
||||
%if %{with python3}
|
||||
%package -n python3-yubico
|
||||
Summary: Pure-python library for interacting with Yubikeys
|
||||
|
||||
%description -n python3-yubico
|
||||
Pure-python library for interacting with Yubikeys. For Python 3.
|
||||
%endif
|
||||
|
||||
%prep
|
||||
%setup -q -n %{name}-%{name}-%{version}
|
||||
%setup -qc
|
||||
|
||||
mv %{name}-%{name}-%{version} python2
|
||||
|
||||
pushd python2
|
||||
sed -i 's|setup_requires=|tests_require=|' setup.py
|
||||
popd
|
||||
|
||||
%if %{with python3}
|
||||
cp -a python{2,3}
|
||||
|
||||
pushd python3
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
popd
|
||||
%endif
|
||||
|
||||
|
||||
%build
|
||||
sed -i 's|setup_requires=|tests_require=|' setup.py
|
||||
pushd python2
|
||||
%{__python2} setup.py build
|
||||
popd
|
||||
|
||||
%if %{with python3}
|
||||
pushd python3
|
||||
%{__python3} setup.py build
|
||||
popd
|
||||
%endif
|
||||
|
||||
|
||||
%install
|
||||
pushd python2
|
||||
%{__python2} setup.py install -O1 --skip-build --root $RPM_BUILD_ROOT
|
||||
popd
|
||||
|
||||
%if %{with python3}
|
||||
pushd python3
|
||||
%{__python3} setup.py install -O1 --skip-build --root $RPM_BUILD_ROOT
|
||||
popd
|
||||
%endif
|
||||
|
||||
|
||||
%files
|
||||
%doc COPYING NEWS README
|
||||
%doc python2/COPYING python2/NEWS python2/README
|
||||
%{python2_sitelib}/*
|
||||
|
||||
%if %{with python3}
|
||||
%files -n python3-yubico
|
||||
%doc python3/COPYING python3/NEWS python3/README
|
||||
%{python3_sitelib}/*
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel} == 0 || 0%{?rhel} >= 7
|
||||
%check
|
||||
|
||||
pushd python2
|
||||
# Exclude tests that require a physical yubikey attached.
|
||||
nosetests -e test_challenge_response -e test_serial -e test_status
|
||||
%endif
|
||||
popd
|
||||
|
||||
%if %{with python3}
|
||||
pushd python3
|
||||
# Exclude tests that require a physical yubikey attached.
|
||||
nosetests-%{python3_version} -e test_challenge_response -e test_serial -e test_status
|
||||
popd
|
||||
%endif # with python3
|
||||
|
||||
%endif # rhel
|
||||
|
||||
%changelog
|
||||
* Mon Jul 20 2015 Miro Hrončok <mhroncok@redhat.com> - 1.2.3-3
|
||||
- Add Python 3 subpackage (#1244237)
|
||||
|
||||
* Thu Jun 18 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.3-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user