Thejesh GN avatar Thejesh GN committed 1a434d4

setup.py for installation

Comments (0)

Files changed (4)

-# g2fa - Google two factor Authentication
+# pyg2fa - Google two factor Authentication
 
 ### Welcome
 Welcome to g2fa. Google two factor auth for Python based apps.
 
 Repo:
-$hg clone http://code.thejeshgn.com/py-g2fa
+$hg clone http://code.thejeshgn.com/pyg2fa
 
 
 ### usage:
 * Clone or download g2fa.py
-* Change YOUR_SECRET_INITIAL_KEY, it should be at least 16, base 32 characters, keep this secret, this could be different for different app users
-* python g2fa.py
-* It will print the info for testing. Most important things are otp and QR code for Google Auth android app
-* User scans this QR code on his mobile which generates OTP on his mobile which you will compare using g2fa.py on your server side
+* cd to folder
+* sudo python setup.py install
+* for test run  
+	import pyg2fa  
+	pyg2fa.test()
+* The test uses YOUR_SECRET_INITIAL_KEY, it should be at least 16, base 32 characters, this is secret, this could be different for different web app users
+* It will print the URL of QR code, Scan it using your Google Authenticator application
+* For testing enter the OTP generated by the Google Authenticator, the python program should print True if everything goes right.
+* make sure time on your comp and on your phone is in sync
 
 
 ### Ponder:
 * Clock on server and on android need to be in sync
 
-### Future:
-* Will add verify method which will allow clients clock to drift server time by +/- <defined> minutes.
+### Recent change:
+* Added validate method which will allow clients clock to drift server time by +/- defined seconds.
+
+###future
+* Developer documents and an demo web application
 
 #### Copyright (C) 2012 Thejesh GN <i at thejeshgn dot com >, MIT License
-

g2fa.py

-#!/usr/bin/python
-###############################################################################
-# Repo: http://code.thejeshgn.com/g2fa
-# Copyright (C) 2012 Thejesh GB <i@thejeshgn.com>
-#
-# 
-#
-# MIT License:
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy of
-# this software and associated documentation files (the "Software"), to deal in
-# the Software without restriction, including without limitation the rights to
-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-# of the Software, and to permit persons to whom the Software is furnished to do
-# so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-###############################################################################
-import base64
-import time
-import math
-import struct
-import hashlib, hmac
-import binascii
-
-period = 30 #interval between two generated keys
-length = 6  #length of OTP
-b32 = {  "A" : 0, "B" : 1,"C" : 2, "D" : 3, "E" : 4, "F" : 5,  "G" : 6, "H" : 7,  "I" : 8, "J" : 9,  "K" : 10,     "L" : 11,  "M" : 12,     "N" : 13,  "O" : 14,     "P" : 15,  "Q" : 16,     "R" : 17,  "S" : 18,     "T" : 19,  "U" : 20,     "V" : 21,  "W" : 22,     "X" : 23,  "Y" : 24,     "Z" : 25,  "2" : 26,     "3" : 27,  "4" : 28,     "5" : 29,  "6" : 30,     "7" : 31 }
-
-
-def decode(data):
-	data 	= data.upper()
-	n	= 0
-	j	= 0
-	binary = ""
-
-
-	for char in data:
-		n = n << 5
-		n = n + b32[char]
-		j = j + 5
-		if j >= 8 :
-			j = j - 8
-			binary = binary+chr((n & (0xFF << j)) >> j);
-	return binary
-
-def timestamp():
-	return int(round(time.time()/period))
-
-
-def otp(key, time):
-	bin_counter = struct.pack('!L', 0)+struct.pack('!L', time)
-	# values = (time)
-	# s = struct.Struct('!L')
-	# packed_data = s.pack(values)
-	# print 'Original values:', values
-	# print 'Format string  :', s.format
-	# print 'Uses           :', s.size, 'bytes'
-	# print 'Packed Value   :', binascii.hexlify(packed_data)
-	digest = hmac.new(key, bin_counter, hashlib.sha1)
-	# print digest.hexdigest()
-	result = str(truncate(digest.digest())).ljust(length, '0')
-	return result
-
-def truncate(hash):
-	offset = ord(hash[19]) & 0xf;
-	return (
-	    ((ord(hash[offset+0]) & 0x7f) << 24 ) |
-	    ((ord(hash[offset+1]) & 0xff) << 16 ) |
-	    ((ord(hash[offset+2]) & 0xff) << 8 ) |
-	    (ord(hash[offset+3]) & 0xff)
-	) % pow(10, length)
-	
- #Verifys a user inputted key against the current timestamp. Checks window
-def validate(b32secretKey, userOTP, window = 4):
-	timeStamp = timestamp()
-	timeStampInInt = int(timeStamp)
-	binarySeed = decode(b32secretKey)
-	timestampRange = range(timeStampInInt-window, timeStampInInt+window)
-	for ts in timestampRange:
-		o = otp(binarySeed, ts)
-		#print o
-		if int(o) == int(userOTP):
-			return True
-	return False
-
-def qrCodeURL(site, secretKey):
-	return "http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=otpauth://totp/"+site+"?secret="+secretKey+"&chld=H|0"
-
-
-#This is for testing only
-if __name__ == "__main__":
-	YOUR_SECRET_INITIAL_KEY = "KKK67SDNLXIOG65U"   # must be at least 16 base 32 characters, keep this secret
-	print qrCodeURL("http://g2fa-example.com", YOUR_SECRET_INITIAL_KEY)
-	userOTP = raw_input("Enter OTP: ")
-	TIME_STAMP = timestamp()
-	print validate(YOUR_SECRET_INITIAL_KEY, int(userOTP), 4)	
+#!/usr/bin/python
+###############################################################################
+# Repo: http://code.thejeshgn.com/g2fa
+# Copyright (C) 2012 Thejesh GB <i@thejeshgn.com>
+#
+# 
+#
+# MIT License:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+###############################################################################
+import base64
+import time
+import math
+import struct
+import hashlib, hmac
+import binascii
+
+period = 30 #interval between two generated keys
+length = 6  #length of OTP
+b32 = {  "A" : 0, "B" : 1,"C" : 2, "D" : 3, "E" : 4, "F" : 5,  "G" : 6, "H" : 7,  "I" : 8, "J" : 9,  "K" : 10,     "L" : 11,  "M" : 12,     "N" : 13,  "O" : 14,     "P" : 15,  "Q" : 16,     "R" : 17,  "S" : 18,     "T" : 19,  "U" : 20,     "V" : 21,  "W" : 22,     "X" : 23,  "Y" : 24,     "Z" : 25,  "2" : 26,     "3" : 27,  "4" : 28,     "5" : 29,  "6" : 30,     "7" : 31 }
+
+
+def decode(data):
+	data 	= data.upper()
+	n	= 0
+	j	= 0
+	binary = ""
+
+
+	for char in data:
+		n = n << 5
+		n = n + b32[char]
+		j = j + 5
+		if j >= 8 :
+			j = j - 8
+			binary = binary+chr((n & (0xFF << j)) >> j);
+	return binary
+
+def timestamp():
+	return int(round(time.time()/period))
+
+
+def otp(key, time):
+	bin_counter = struct.pack('!L', 0)+struct.pack('!L', time)
+	# values = (time)
+	# s = struct.Struct('!L')
+	# packed_data = s.pack(values)
+	# print 'Original values:', values
+	# print 'Format string  :', s.format
+	# print 'Uses           :', s.size, 'bytes'
+	# print 'Packed Value   :', binascii.hexlify(packed_data)
+	digest = hmac.new(key, bin_counter, hashlib.sha1)
+	# print digest.hexdigest()
+	result = str(truncate(digest.digest())).ljust(length, '0')
+	return result
+
+def truncate(hash):
+	offset = ord(hash[19]) & 0xf;
+	return (
+	    ((ord(hash[offset+0]) & 0x7f) << 24 ) |
+	    ((ord(hash[offset+1]) & 0xff) << 16 ) |
+	    ((ord(hash[offset+2]) & 0xff) << 8 ) |
+	    (ord(hash[offset+3]) & 0xff)
+	) % pow(10, length)
+	
+ #Verifys a user inputted key against the current timestamp. Checks window
+def validate(b32secretKey, userOTP, window = 4):
+	timeStamp = timestamp()
+	timeStampInInt = int(timeStamp)
+	binarySeed = decode(b32secretKey)
+	timestampRange = range(timeStampInInt-window, timeStampInInt+window)
+	for ts in timestampRange:
+		o = otp(binarySeed, ts)
+		#print o
+		if int(o) == int(userOTP):
+			return True
+	return False
+
+def qrCodeURL(site, secretKey):
+	return "http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=otpauth://totp/"+site+"?secret="+secretKey+"&chld=H|0"
+
+
+#This is for testing only
+def test():
+	YOUR_SECRET_INITIAL_KEY = "KKK67SDNLXIOG65U"   # must be at least 16 base 32 characters, keep this secret
+	print qrCodeURL("http://g2fa-example.com", YOUR_SECRET_INITIAL_KEY)
+	userOTP = raw_input("Enter OTP: ")
+	TIME_STAMP = timestamp()
+	print validate(YOUR_SECRET_INITIAL_KEY, int(userOTP), 4)
+
+from distutils.core import setup
+from os import path
+
+long_desc = open(path.join(path.dirname(__file__), "README.markdown"), "U").read()
+
+setup(name="pyg2fa", version="1.1",
+      url="http://code.thejeshgn.com/pyg2fa",
+      author="Thejesh GN",
+      author_email="i@thejeshgn.com",
+      description="Google two factor Authentication for Python",
+      long_description=long_desc,
+      py_modules=["pyg2fa"])
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.