OpenAccess main logic

OK, the big one to wrap your head around.  I’ll try to pseudocode it for you

  • initialize all the things
  • log the battery, temp, time, date, reboot status
  • start loop
    • check for serial commands, execute if any
    • set the current time
    • check for an exit button press, open if there is one
    • check battery if needed
    • toggle relays if needed
    • reset doorbell if needed
    • reset door hold if needed
    • if tag read
      • if timeout reached, exit tag reading
      • if keypad button pressed
        • if escape, backspace
        • if enter
          • if we’re reading a new tag, go to that procedure
          • else, go to auth procedure
        • if a number add it to the pin (variable, 4-8 numbers)
    • if button pressed
      • if the we are ‘exiting’ (authed)
        • if the user can hold the door and the door hold button is pressed, toggle that state (exiting other states)
        • if the user can use doorbell mode and the doorbell mode button is pressed, toggle that state (exiting other states)
        • if the user can add a key and the add a key button is pressed, go into that mode
        • if the enter button is pressed and the door is in a doorbell or door hold state
          • open the door
    • if the pin entered is too big, overflow it
    • if the exit relay should be closed, do it
    • if a key has been read, go into that mode
  • restart loop

There’s the main loop, checks basically everything and is written to fall through as fast as possible.

The associated functions are here:

void enter_new_tag_entry_mode()
{
exit_timeout();
logging(logDate());
logging(” – “);
loggingln(“new member attempt”);
LCD_clear();
LCD_displn(“New member:”,0);
LCD_displn(“swipe new tag”,1);
new_tag_entry = 1;
}

This one sets up the code for a new tag (after the existing user with those privliges has swiped and pressed the required key).

void reset_tag_reading(int reader_num)
{
//Serial.print(“tag reader “);
//Serial.println(reader_num,HEX);
if(reader_num == 1)
{
reader1 = reader1 >> 1;//fix for extra zero
tag = reader1;
reader1Count = 0;
reader1 = 0;
}
else if(reader_num == 2)
{
reader2 = reader2 >> 1;//fix for extra zero
tag = reader2;
reader2Count = 0;
reader2 = 0;
}
printname = “”;
printname += tag;
logging(logDate());
logging(” – “);
logging(printname);
loggingln(” tag read”);
LCD_clear();
LCD_displn(“Please Enter”,0);
LCD_displn(“Pin:”,1);
tag_read = 1;
clear_pin();//not needed?
RFID_start_time = current_time;
}

So, this clears the display and starts reading a tag again if the pin has not been completely entered before another tag is swiped.

void new_user_entry()
{
//Serial.print(“Tag = “);
//Serial.println(tag,DEC);
//Serial.print(“Pin = “);
//for(int i=0;i<digit;i++)
//{
// Serial.print(pin[i]);
//}
if (digit<4) //too short of a pin
{
clear_pin();
int d = 300;
LCD_clear();
LCD_displn(“pin too short”,0);
beep_repeat(2,200,2);
reader2 = tag;//hack
reset_tag_reading(2);//hack
RFID_start_time = millis();
}
else
{
String toHash = “”;
toHash += tag;
//put in raw tag to eeprom
for(int i=0;i<(sizeof(pin)/sizeof(pin[0]));i++)
{
toHash += pin[i];
}
clear_pin();
char hashed[32];
toHash.toCharArray(hashed,32);
char *md5str = MD5::make_digest(MD5::make_hash(hashed), 16);
for (int i=0;i<num_users;i++)
{
if(!user_present(i))
{
String name = “New Member “;
name += logDate();
priv= 1;
//put in raw tag to eeprom
write_EE(i, name, priv, md5str);
break;
}
}
//Serial.println(md5str);
logging(logDate());
logging(” – “);
logging(“new user “);
logging(md5str);
loggingln(” added”);
LCD_clear();
LCD_displn(“Welcome”,0);
LCD_displn(“New member”,1);

for(int i=0;i<(sizeof(hashed)/sizeof(hashed[0]));i++) //also should not be needed
{
hashed[i] = 0;
}
new_tag_entry = 0;
toHash = “”; //not needed?
RFID_reset();
exit();
}
}

This code creates a new user entry with a 4 digit minimum pin and hashes the pin and tag together to store that.

void current_user_entry()
{
//possibly add a time based lack of pin requirement, for example
//store a list of user IDs that have no pin entry allowed, reset
//it at midnight (or noon) and check the card id against all of those before hashing, etc…

//Serial.print(“Tag = “);
//Serial.println(tag,DEC);
//Serial.print(“Pin = “);
//for(int i=0;i<digit;i++)
//{
// Serial.print(pin[i]);
//}
String toHash;
toHash += tag;
for(int i=0;i<(sizeof(pin)/sizeof(pin[0]));i++)
{
toHash += pin[i];
}
clear_pin();
char hashed[32];
toHash.toCharArray(hashed,32);
char *md5str = MD5::make_digest(MD5::make_hash(hashed), 16);
if(authenticate(md5str) == 1)
{
logging(logDate());
logging(” – “);
printname = “”;
for (int j = 0; j < (sizeof(name)/sizeof(name[0])); j++)
{
if(name[j] != 0)
{
printname += name[j];
//Serial.println(name[j],HEX);
}
}
logging(printname);
loggingln(” carded in”);
LCD_clear();
LCD_displn(“Welcome Member:”,0);
LCD_displn(printname,1);
exit();
}
else
{
logging(logDate());
logging(” – “);
//logging(md5str);//
//logging(” – “);//
loggingln(“card entry failed”);
LCD_clear();
LCD_displn(“Invalid entry”,0);
RFID_error_out();
}
//Serial.println(md5str);
//Serial.println();
//Serial.println(test);
for(int i=0;i<(sizeof(hashed)/sizeof(hashed[0]));i++)//should not be needed
{
hashed[i] = 0;
}
toHash = “”; //also not needed?
RFID_reset();
}

This function hashes the pin and card id and checks them against the internal list of users, it then allows or disallows entry.

boolean authenticate(char *md5str)
{

byte hard_hash[5][33] = {
{/*”e0bdc8c7b2e2d33e7889858a30aad569″*/
}
,{
}
,{
}
,{
}
,{
}
};/////////5 hashes
boolean succeed = 1;
for (int k=0;k<5;k++)
{
for (int j=0;j<32;j++)
{
if(hard_hash[k][j] != md5str[j])
{
//Serial.print(“fail: “);
//Serial.println(k,DEC);
//Serial.println(j,DEC);
//Serial.println(hash[j],HEX);
//Serial.println((md5str[j]),HEX);
succeed = 0;
j+=32;
}
}
if(succeed)
{
printname = “Failsafe”;
for (int j = 0; j < printname.length(); j++)///////////////////////////////////////////////////////////////////////untested
{
if(printname[j] != 0)
{
name[j] = printname[j];
//Serial.println(name[j],HEX);
}
}

logging(logDate());
logging(” – “);
loggingln(“Failsafe used”);
return 1;
}
}

for (int i=0;i<num_users;i++)
{
if(can_enter(i))
{
read_EE_hash(i);
succeed = 1;
for (int j=0;j<32;j++)
{
if(hash[j] != (md5str[j]))
{
//Serial.print(“fail: “);
//Serial.println(i,DEC);
//Serial.println(j,DEC);
//Serial.println(hash[j],HEX);
//Serial.println((md5str[j]),HEX);
succeed = 0;
break;
}
}
if(succeed == 1)
{
read_EE_name(i);
read_EE_priv(i);
read_EE_hash(i);
//Serial.print(“win: “);
//serial_user_print(i);
if((priv & bit(PRIV_ADDUSER)) == bit(PRIV_ADDUSER))
{
can_add = 1;
//Serial.println(“can add”);
}
if((priv & bit(PRIV_DOORBELL)) == bit(PRIV_DOORBELL))
{
can_doorbell = 1;
//Serial.println(“can doorbell”);
}
if((priv & bit(PRIV_DOORHOLD)) == bit(PRIV_DOORHOLD))
{
can_doorhold = 1;
//Serial.println(“can door hold”);
}
return 1;
}
}
}
return 0;
}

The hash authentication function has an override built in to allow for hardcoded hashes in the program (not the eeprom) which amounts to a firmware level backdoor.  And everyone knows I’m all about that.  This function goes on to check all the spots in memory and report if the user has certain abilities.  When this function is done the ram is populated with the user info of the person authenticated.

That’s the salient parts of the main code.  I hope that’s enough to get some of you started in the OpenAccess project.

 

Advertisements

3 Responses to “OpenAccess main logic”

  1. OpenAccess privlige functions | Evan's Techie-Blog Says:

    […] Hacks, repairs, arcade games, sci-fi, and some very bad ideas with possibly humorous consequences « OpenAccess main logic […]

  2. OpenAccess Keypad functions | Evan's Techie-Blog Says:

    […] to unprintable.  These steps are done in the key taking process which is longer and in the main logic code.  This is part of the greater OpenAccess […]

  3. OpenAccess 3.0 replacement software | Evan's Techie-Blog Says:

    […] main logic […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: