Advertisement
b25s19_lieberwirth

Access_Control.py

Sep 24th, 2018
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.56 KB | None | 0 0
  1. from __future__ import print_function
  2. import hashlib
  3. import MFRC522
  4. import mysql.connector as mariadb
  5. import RPi.GPIO as gpio
  6. import signal
  7. import sys
  8. import time
  9.  
  10. # Database variables
  11. connection = None
  12. cursor = None
  13. DB_USER = "****" # Omitted
  14. DB_PASS = "*****" # Omitted
  15. DB_NAME = "****************" # Omitted
  16.  
  17. # RFID-Reader Variable
  18. MIFAREReader = None
  19.  
  20. # Defining keypad constants
  21. matrix = [["1", "2", "3", "A"],
  22.           ["4", "5", "6", "B"],
  23.           ["7", "8", "9", "C"],
  24.           ["*", "0", "#", "D"]]
  25. # No GPIO numbering because MFRC522 uses BCM
  26. columns = [32, 36, 38, 40]
  27. rows = [12, 16, 18, 11]
  28.  
  29. # Lockout variables
  30. FailedCount = 0
  31. PenaltyTime = 0
  32. TerminalLocked = False
  33.  
  34.  
  35. class bc:
  36.   #  Console color constants
  37.   PINK = '\033[95m'
  38.   BLUE = '\033[94m'
  39.   GREEN = '\033[92m'
  40.   YELLOW = '\033[93m'
  41.   RED = '\033[91m'
  42.   WHITE = '\033[0m'
  43.   BOLD = '\033[1m'
  44.   UNDERLINE = '\033[4m'
  45.  
  46.  
  47. def getKey():
  48.   # Returns pressed key or nothing
  49.   for j in range(len(columns)):
  50.     gpio.output(columns[j], 0)
  51.     for i in range(len(rows)):
  52.       if gpio.input(rows[i]) == 0:
  53.         while gpio.input(rows[i]) == 0:
  54.           pass
  55.         time.sleep(0.2)
  56.         return matrix[i][j]
  57.     gpio.output(columns[j], 1)
  58.   return False
  59.  
  60.  
  61. # Cleaning up and exiting
  62. def over():
  63.   cursor.close()
  64.   connection.close()
  65.   gpio.cleanup()
  66.   sys.exit()
  67.  
  68.  
  69. # CTRL-C handler
  70. def signal_handler(sig, frame):
  71.   print("\nCtrl-C has been pressed. Quitting...")
  72.   over()
  73.  
  74.  
  75. # Calls log procedure and exits
  76. def log_access(args):
  77.   # Call procedure and commit
  78.   cursor.callproc("log_access", args)
  79.   connection.commit()
  80.  
  81.   # Quit if last argument is true
  82.   if args[3]:
  83.     over()
  84.  
  85.  
  86. # Access status output
  87. def access_msg(msg, success):
  88.   if success:
  89.     print("{}\nAccess granted{}".format(bc.GREEN, bc.WHITE))
  90.   else:
  91.     print("{}\nAccess denied{}".format(bc.RED, bc.WHITE))
  92.  
  93.   print(msg)
  94.  
  95.  
  96. def failhandler():
  97.   global FailedCount
  98.   global PenaltyTime
  99.   global TerminalLocked
  100.  
  101.   # Increment failed count and penaltytime
  102.   FailedCount = FailedCount + 1
  103.   PenaltyTime = PenaltyTime + 5
  104.  
  105.   # Check how many attempts failed so far
  106.   if FailedCount > 2:
  107.     print("Too many failed attempts, terminal is locked")
  108.     print("Please ask an administrator to unlock")
  109.     TerminalLocked = True
  110.   else:
  111.     print("Please try again in {} seconds".format(PenaltyTime))
  112.     time.sleep(PenaltyTime)
  113.     print("Now you can try again")
  114.  
  115.  
  116. def init():
  117.   global cursor
  118.   global connection
  119.   global MIFAREReader
  120.  
  121.   # Initiate RFID-Reader Library
  122.   MIFAREReader = MFRC522.MFRC522()
  123.  
  124.   # Activating GPIO outputs for keypad
  125.   for i in range(4):
  126.     gpio.setup(columns[i], gpio.OUT)
  127.     gpio.output(columns[i], 1)
  128.     gpio.setup(rows[i], gpio.IN, pull_up_down=gpio.PUD_UP)
  129.  
  130.   # Connecting to database and creating cursor object
  131.   connection = mariadb.connect(
  132.     user=DB_USER, password=DB_PASS, database=DB_NAME)
  133.   cursor = connection.cursor()
  134.  
  135.   # Registering CTRL-C handler
  136.   signal.signal(signal.SIGINT, signal_handler)
  137.  
  138.  
  139. def md5encode(in_string):
  140.   m = hashlib.md5()
  141.   m.update(in_string)
  142.   return m.hexdigest()
  143.  
  144.  
  145. # Initialize script
  146. init()
  147.  
  148. # Retrieves rooms into list and prints them to console
  149. cursor.execute("SELECT idRaum, bezeichnung FROM raum ORDER BY idRaum")
  150. rooms = cursor.fetchall()
  151. while True:
  152.   while True:
  153.     # Ask user for a room
  154.     print("Which room do you want to enter? ")
  155.     for room in rooms:
  156.       print("{} - {}".format(room[0], room[1]))
  157.  
  158.     in_raum = ""
  159.     while True:
  160.       # Retrieve keypress
  161.       lastKey = getKey()
  162.  
  163.       # If a key has been pressed
  164.       if lastKey:
  165.         if lastKey == "*":
  166.           # An asterisk exits the script
  167.           over()
  168.         if lastKey == "#":
  169.           # A pound finishes the entry
  170.           break
  171.         else:
  172.           # All other keys append to the entry
  173.           in_raum = in_raum + lastKey
  174.           sys.stdout.write(lastKey)
  175.           sys.stdout.flush()
  176.  
  177.     # Evaluate if users chosen room exists
  178.     cursor.execute("SELECT NULL FROM raum WHERE idRaum=%s", (in_raum,))
  179.     cursor.fetchone()
  180.     if cursor.rowcount == -1:
  181.       print("There is no such room!")
  182.     else:
  183.       break
  184.  
  185.   # Retrieve room using list comprehension
  186.   room = [r[1] for r in rooms if r[0] == int(in_raum)][0]
  187.   print("Entering room: {}".format(room))
  188.   sys.stdout.write("Enter keycode or scan your card: ")
  189.   sys.stdout.flush()
  190.  
  191.   in_keycode = ""
  192.   while True:
  193.     # Retrieve latest keypad-key
  194.     lastKey = getKey()
  195.  
  196.     # If any key has been pressed
  197.     if lastKey:
  198.       if lastKey == "*":
  199.         # Delay probably no longer needed
  200.         # Needs testing
  201.         # time.sleep(0.2)
  202.         break
  203.       elif lastKey == "#":
  204.         # If '#' has been pressed (input finished)
  205.         if TerminalLocked:
  206.           print("Terminal is locked")
  207.         else:
  208.           in_keycode = md5encode(in_keycode)
  209.  
  210.           # Check if keypad-entry is enabled for chosen room
  211.           cursor.execute("""SELECT NULL FROM raum
  212.            WHERE sicherheitslevel = 1
  213.            AND idraum=%s;""", (in_raum,))
  214.           cursor.fetchone()
  215.           if cursor.rowcount == -1:
  216.             access_msg("Only Administrators may enter this room", False)
  217.  
  218.             # Log failed attempt
  219.             log_access([in_raum, in_keycode, None, False])
  220.           else:
  221.             # Check if code exists in database
  222.             cursor.execute("SELECT NULL FROM keycode WHERE `code`=%s",
  223.               (in_keycode,))
  224.             cursor.fetchone()
  225.  
  226.             if cursor.rowcount == -1:
  227.               access_msg("Wrong keycode!", False)
  228.  
  229.               # Log failed attempt
  230.               log_access([in_raum, in_keycode, None, False])
  231.  
  232.               failhandler()
  233.             else:
  234.               # Retrieve employee info
  235.               cursor.execute("""SELECT CONCAT(m.vorname, ' ', m.nachname)
  236.                FROM mitarbeiter m INNER JOIN keycode k
  237.                ON m.idkeycode = k.idkeycode
  238.                AND k.`code`=%s;""", (in_keycode,))
  239.               access_msg("Welcome, {}".format(cursor.fetchone()[0]),
  240.                 True)
  241.  
  242.               # Log successful attempt
  243.               log_access([in_raum, in_keycode, None, True])
  244.         in_keycode = ""
  245.       else:
  246.         # A number has been pressed
  247.  
  248.         # Output asterisk to console
  249.         sys.stdout.write('*')
  250.         sys.stdout.flush()
  251.  
  252.         # Append the new number to the keycode string
  253.         in_keycode = in_keycode + lastKey
  254.  
  255.         # Delay probably no longer needed
  256.         # Needs testing
  257.         # time.sleep(0.2)
  258.  
  259.     # Prepare RFID-Scanner for reading
  260.     status = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
  261.     (status, uid) = MIFAREReader.MFRC522_Anticoll()
  262.     if status == MIFAREReader.MI_OK:
  263.       # This is the default key
  264.       key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
  265.       # Select the tag
  266.       MIFAREReader.MFRC522_SelectTag(uid)
  267.       # Authenticate using block 8, the default key and the UID
  268.       status = MIFAREReader.MFRC522_Auth(
  269.         MIFAREReader.PICC_AUTHENT1A, 8, key, uid)
  270.  
  271.       if status == MIFAREReader.MI_OK:
  272.         # Read Block 8 of RFID into variable
  273.         card_content = MIFAREReader.MFRC522_Read(8)
  274.         # Remove zero padded bytes from string
  275.         # card_content = card_content.split(b'\0', 1)[0]
  276.         card_content = card_content.partition(b'\0')[0]
  277.  
  278.         # Hash the RFID
  279.         card_content = md5encode(card_content)
  280.  
  281.         MIFAREReader.MFRC522_StopCrypto1()
  282.  
  283.         # Search for card in database
  284.         cursor.execute("SELECT NULL FROM transponder WHERE rfid=%s",
  285.           (card_content,))
  286.         cursor.fetchone()
  287.  
  288.         if cursor.rowcount == -1:
  289.           if TerminalLocked:
  290.             print("Terminal is locked")
  291.           else:
  292.             access_msg("This card is not registered in the system!",
  293.                 False)
  294.  
  295.             # Log failed attempt
  296.             log_access([in_raum, None, card_content, False])
  297.  
  298.             failhandler()
  299.         else:
  300.           # Retrieve employee info
  301.           cursor.execute("""SELECT CONCAT(m.vorname, ' ', m.nachname)
  302.            FROM mitarbeiter m INNER JOIN transponder t
  303.            ON m.idTransponder = t.idTransponder
  304.            WHERE t.rfid=%s;""", (card_content,))
  305.  
  306.           access_msg("Welcome, {}".format(cursor.fetchone()[0]), True)
  307.           if TerminalLocked:
  308.             print("You have unlocked the terminal for the technicians")
  309.             TerminalLocked = False
  310.  
  311.           # Log successful attempt
  312.           log_access([in_raum, None, card_content, True])
  313.           over()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement