Skip to content

Commit

Permalink
fix BOTH bugs that lead to password errors around char 20 (in default…
Browse files Browse the repository at this point in the history
… charset)
  • Loading branch information
csarn committed Oct 29, 2014
1 parent 4058652 commit 3c58d09
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 34 deletions.
64 changes: 31 additions & 33 deletions pwmlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Written by Miquel Burns and Eric H. Jung
PHP version written by Pedro Gimeno Fortea
<http://www.formauri.es/personal/pgimeno/>
and updated by Miquel Matthew 'Fire' Burns
<[email protected]>
Ported to Python by Aurelien Bompard
<http://aurelien.bompard.org>
<http://aurelien.bompard.org>
Updated by Richard Beales
<[email protected]>
Expand All @@ -38,9 +38,9 @@
import sys, hmac, math


class PWM_Error(Exception):
class PWM_Error(Exception):
"""
Password Maker Error class, inherits from Exception, currently
Password Maker Error class, inherits from Exception, currently
does nothing else
"""
pass
Expand Down Expand Up @@ -91,10 +91,10 @@ def generatepassword(self,hashAlgorithm, key, data, whereToUseL33t, l33tLevel, p
else:
trim = True
hashAlgorithm = alg[0]
# Check for validity of algorithm
# Check for validity of algorithm
if hashAlgorithm not in self.valid_algs:
raise PWM_Error("Unknown or misspelled algorithm: %s. Valid algorithms: %s" % (hashAlgorithm, ", ".join(self.valid_algs)))

# apply the algorithm
hashclass = PWM_HashUtils()
password = ''
Expand All @@ -107,31 +107,31 @@ def generatepassword(self,hashAlgorithm, key, data, whereToUseL33t, l33tLevel, p
key = "%s\n%s" % (tkey, count)
# for non-hmac algorithms, the key is master pw and url concatenated
if hashAlgorithm.count("hmac") == 0:
data = key+data
dat = key+data
if hashAlgorithm == "sha256":
password += hashclass.any_sha256(data, charset, trim)
password += hashclass.any_sha256(dat, charset, trim)
elif hashAlgorithm == "hmac-sha256":
password += hashclass.any_hmac_sha256(key, data, charset, trim)
password += hashclass.any_hmac_sha256(key, dat, charset, trim)
elif hashAlgorithm == "sha1":
password += hashclass.any_sha1(data, charset, trim)
password += hashclass.any_sha1(dat, charset, trim)
elif hashAlgorithm == "hmac-sha1":
password += hashclass.any_hmac_sha1(key, data, charset, trim)
password += hashclass.any_hmac_sha1(key, dat, charset, trim)
elif hashAlgorithm == "md4":
password += hashclass.any_md4(data, charset, trim)
password += hashclass.any_md4(dat, charset, trim)
elif hashAlgorithm == "hmac-md4":
password += hashclass.any_hmac_md4(key, data, charset, trim)
password += hashclass.any_hmac_md4(key, dat, charset, trim)
elif hashAlgorithm == "md5":
password += hashclass.any_md5(data, charset, trim)
password += hashclass.any_md5(dat, charset, trim)
elif hashAlgorithm == "hmac-md5":
password += hashclass.any_hmac_md5(key, data, charset, trim)
password += hashclass.any_hmac_md5(key, dat, charset, trim)
elif hashAlgorithm == "rmd160":
password += hashclass.any_rmd160(data, charset, trim)
password += hashclass.any_rmd160(dat, charset, trim)
elif hashAlgorithm == "hmac-rmd160":
password += hashclass.any_hmac_rmd160(key, data, charset, trim)
password += hashclass.any_hmac_rmd160(key, dat, charset, trim)
else:
raise PWM_Error("Unknown or misspelled algorithm: %s. Valid algorithms: %s" % (hashAlgorithm, ", ".join(self.valid_algs)))
count += 1

if prefix:
password = prefix + password
if suffix:
Expand All @@ -140,14 +140,14 @@ def generatepassword(self,hashAlgorithm, key, data, whereToUseL33t, l33tLevel, p




class PWM_HashUtils:
def rstr2any(self, input, encoding, trim=True):
"""Convert a raw string to an arbitrary string encoding. Set trim
"""Convert a raw string to an arbitrary string encoding. Set trim
to false for keeping leading zeros"""
divisor = len(encoding)
remainders = []

# Convert to an array of 16-bit big-endian values, forming the dividend
dividend = []
# pad this
Expand All @@ -156,7 +156,7 @@ def rstr2any(self, input, encoding, trim=True):
inp = input # Because Miquel is a lazy twit and didn't want to do a search and replace
for i in range(len(dividend)):
dividend[i] = (ord(inp[i * 2]) << 8) | ord(inp[i * 2 + 1])

# Repeatedly perform a long division. The binary array forms the dividend,
# the length of the encoding is the divisor. Once computed, the quotient
# forms the dividend for the next step. We stop when the dividend is zero.
Expand All @@ -166,8 +166,8 @@ def rstr2any(self, input, encoding, trim=True):
quotient = []
x = 0
for i in range(len(dividend)):
x = (int(x) << 16) + dividend[i]
q = math.floor(x / divisor)
x = (x << 16) + dividend[i]
q = x // divisor
x -= q * divisor
if len(quotient) > 0 or q > 0:
quotient.append(q)
Expand All @@ -180,18 +180,18 @@ def rstr2any(self, input, encoding, trim=True):
x = 0
for i in range(len(dividend)):
x = (x << 16) + dividend[i]
q = math.floor(x / divisor)
q = x // divisor
x -= q * divisor
if len(quotient) > 0 or q > 0:
quotient[len(quotient)] = q
remainders[j] = x
dividend = quotient
# Convert the remainders to the output string

# Convert the remainders to the output string
output = ""
for i in range(len(remainders)-1, 0, -1):
output += encoding[int(remainders[i])]
for i in reversed(remainders):
output += encoding[i]

return output

def any_md5(self, s, e, t):
Expand Down Expand Up @@ -292,7 +292,7 @@ def __str__(self):
self.UseLeet,
self.LeetLvl,
)


def load(self):
import os
Expand All @@ -309,5 +309,3 @@ def save(self):
f = open('pwm.settings','wb')
pickle.dump(self,f)
f.close()


4 changes: 3 additions & 1 deletion testpwmlib.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def test_generatepassword_19chars(self):
def test_generatepassword_20chars(self):
res = self.pw.generatepassword('md5','asdf','passwordmaker.org'+''+'',False,1,20,self.pw.FULL_CHARSET,'','')
self.assertEqual(res,'FRRHm)k+UyQiY~%Dj;h*')

def test_64chars(self):
res = self.pw.generatepassword('md5','asdf','passwordmaker.org'+''+'',False,1,64,self.pw.FULL_CHARSET,'','')
self.assertEqual(res,'FRRHm)k+UyQiY~%Dj;h*FV[{:[email protected]=-]pF}UyDtCZ9#')
if __name__ == '__main__':
unittest.main()

0 comments on commit 3c58d09

Please sign in to comment.