From ead36160aff9378c4a918858b36f9f390fd33de8 Mon Sep 17 00:00:00 2001 From: Martin Vidner Date: Tue, 20 Jan 2009 06:54:24 +0100 Subject: [PATCH] Added --wpa-pass. Thanks to Arne Bergene Fossaa, even though I ended up not using his patch: I use a different PBKDF2 library that does not have an advertising clause: http://matt.ucc.asn.au/src/pbkdf2.py --- cnetworkmanager | 10 ++++++ pbkdf2.py | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 pbkdf2.py diff --git a/cnetworkmanager b/cnetworkmanager index 894baf0..be26c4b 100755 --- a/cnetworkmanager +++ b/cnetworkmanager @@ -15,6 +15,8 @@ import time import uuid import math import hashlib +import pbkdf2 +from binascii import hexlify import ConfigParser # knm config from optparse import OptionParser try: @@ -1212,6 +1214,9 @@ op.add_option("--wep-pass", op.add_option("--wpa-psk-hex", metavar="KEY", help="use this WPA key of 64 hex digits") +op.add_option("--wpa-pass", + metavar="KEY", + help="use this WPA passphrase") op.add_option("-m", "--monitor", action="store_true", default=False, help="loop to show dbus signals") @@ -1333,6 +1338,11 @@ if options.connect != None: if options.wpa_psk_hex != None: c = mkconmap_psk(options.connect, options.wpa_psk_hex) us.addCon(c) + if options.wpa_pass != None: + wpa_psk_hex = hexlify(pbkdf2.pbkdf2(options.wpa_pass, options.connect, 4096, 32)) + print "pbkdf2", wpa_psk_hex + c = mkconmap_psk(options.connect, wpa_psk_hex) + us.addCon(c) if Connect(options.connect): LOOP = True diff --git a/pbkdf2.py b/pbkdf2.py new file mode 100644 index 0000000..fd22e73 --- /dev/null +++ b/pbkdf2.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python + +# A simple implementation of pbkdf2 using stock python modules. See RFC2898 +# for details. Basically, it derives a key from a password and salt. + +# (c) 2004 Matt Johnston +# This code may be freely used and modified for any purpose. + +# Revision history +# v0.1 October 2004 - Initial release +# v0.2 8 March 2007 - Make usable with hashlib in Python 2.5 and use +# v0.3 "" the correct digest_size rather than always 20 + +import sys +import hmac +from binascii import hexlify, unhexlify +from struct import pack +try: + # only in python 2.5 + import hashlib + sha = hashlib.sha1 + md5 = hashlib.md5 + sha256 = hashlib.sha256 +except ImportError: + # fallback + import sha + import md5 + +# this is what you want to call. +def pbkdf2( password, salt, itercount, keylen, hashfn = sha ): + try: + # depending whether the hashfn is from hashlib or sha/md5 + digest_size = hashfn().digest_size + except TypeError: + digest_size = hashfn.digest_size + # l - number of output blocks to produce + l = keylen / digest_size + if keylen % digest_size != 0: + l += 1 + + h = hmac.new( password, None, hashfn ) + + T = "" + for i in range(1, l+1): + T += pbkdf2_F( h, salt, itercount, i ) + + return T[0: keylen] + +def xorstr( a, b ): + if len(a) != len(b): + raise "xorstr(): lengths differ" + + ret = '' + for i in range(len(a)): + ret += chr(ord(a[i]) ^ ord(b[i])) + + return ret + +def prf( h, data ): + hm = h.copy() + hm.update( data ) + return hm.digest() + +# Helper as per the spec. h is a hmac which has been created seeded with the +# password, it will be copy()ed and not modified. +def pbkdf2_F( h, salt, itercount, blocknum ): + U = prf( h, salt + pack('>i',blocknum ) ) + T = U + + for i in range(2, itercount+1): + U = prf( h, U ) + T = xorstr( T, U ) + + return T + + +def test(): + # test vector from rfc3211 + password = 'password' + salt = unhexlify( '1234567878563412' ) + password = 'All n-entities must communicate with other n-entities via n-1 entiteeheehees' + itercount = 500 + keylen = 16 + ret = pbkdf2( password, salt, itercount, keylen ) + hexret = ' '.join(map(lambda c: '%02x' % ord(c), ret)).upper() + print "key: %s" % hexret + print "expected: 6A 89 70 BF 68 C9 2C AE A8 4A 8D F2 85 10 85 86" + + # from botan + password = unhexlify('6561696D72627A70636F706275736171746B6D77') + expect = 'C9A0B2622F13916036E29E7462E206E8BA5B50CE9212752EB8EA2A4AA7B40A4CC1BF' + salt = unhexlify('45248F9D0CEBCB86A18243E76C972A1F3B36772A') + keylen = 34 + itercount = 100 + ret = pbkdf2( password, salt, itercount, keylen ) + hexret = hexlify(ret).upper() + print "key: %s" % hexret + print "expected: %s" % expect + + + +if __name__ == '__main__': + test() -- 2.11.4.GIT