Access Protocol: Difference between revisions

426 bytes added ,  19:20, 26 July 2017
no edit summary
(Created page with " = Overview = == Catalyst App == * [https://github.com/Hive13/HiveWeb GitHub link] * Actually do something with the temperatures presented to it. * Add in OpenID Support ** F...")
 
No edit summary
Line 40: Line 40:
* Each request is sent from the RFID to the server as a POST with a JSON body.
* Each request is sent from the RFID to the server as a POST with a JSON body.
* Each device has a key pre-shared with the server to mutually authenticate w/o SSL, which some of our MCUs have no hope of doing.
* Each device has a key pre-shared with the server to mutually authenticate w/o SSL, which some of our MCUs have no hope of doing.
* The body object contains a "device" key with the name of the device requesting access - if the server doesn't know about this device, it'll fail.
* The body object contains a <code>device</code> key with the name of the device requesting access - if the server doesn't know about this device, it'll fail.
* The data object also contains an operation - if not', 'access' is assumed.  Other options are 'vend' and 'log'.  Currently, 'log' does nothing but return a success.
* The data object also contains an operation - if not, <code>access</code> is assumed.  Other options are <code>vend</code> and <code>log</code>.  Currently, <code>log</code> does nothing but return a success.
* Finally, for "vend" or "access", the data object contains a "badge" key, containing the presented badge number.
* Finally, for <code>vend</code> or <code>access</code>, the data object contains a <code>badge</code> key, containing the presented badge number as an integer.
* The checksum is computed like this: ([https://github.com/Hive13/HiveWeb/blob/master/lib/HiveWeb/View/ChecksummedJSON.pm Here's where it's done on the server.])
* The checksum is computed like this: ([https://github.com/Hive13/HiveWeb/blob/master/lib/HiveWeb/View/ChecksummedJSON.pm Here's where it's done on the server.])
*# Sort all of the keys recursively on the data object.
*# Sort all of the keys recursively on the data object.
*# Remove all unnecessary whitespace.
*# Remove all unnecessary whitespace.
*# Prepend the device's shared key.
*# Prepend the device's shared key.
*# Take the SHA-512 checksum of that string - encode as a hex string using uppercase letters (It shouldn't matter, but I can't remember if the RFID MCUs do a strcasecmp() or not)
*# Take the SHA-512 checksum of that string - encode as a hex string - it's case-insensitive everywhere, but I use uppercase.
*# Create an object with keys of data, device, and checksum - that object is the body of the request or response.
*# Create an object with keys of <code>data</code>, <code>device</code>, and <code>checksum</code> - that object is the body of the request or response.
* Each data object has a "random" field - this is random per-packet data to stop replay attacks
* Each data object has a <code>random</code> field - this is random per-packet data to stop replay attacks
* Each request should contain a "random_response" field - this must be copied from the request to the response if present; this solves a different subset of replay attacks.
* Each request should contain a <code>random_response</code> field - this must be copied from the request to the response if present; this solves a different subset of replay attacks.


== General-purpose logging ==
== General-purpose logging ==
* JSON body with data, device, and checksum as described above - TBD what to do about an unknown device.
* JSON body with data, device, and checksum as described above - TBD what to do about an unknown device.
* Data field has key "option" set to "log"
* Data field has key <code>option</code> set to <code>log</code>
* An optional keys is "current_timestamp" in milliseconds, to batch several logs and let the server figure out the timesamps - millis() in Arduino-land works here.
* An optional keys is <code>current_timestamp</code> in milliseconds, to batch several logs and let the server figure out the timesamps - <code>millis()</code> in Arduino-land works here.
* Key "messages" is an array of message objects, containing keys as below:
* Key <code>messages</code> is an array of message objects, containing keys as below:
** "absolute_timestamp" has the server compare it to "current_timestamp" to figure out when the message was generated. Optional.
** <code>absolute_timestamp</code> has the server compare it to <code>current_timestamp</code> to figure out when the message was generated. Optional.
** "relative_timestamp" is how long ago (this number is only positive) the message was generated. Optional.
** <code>relative_timestamp</code> is how long ago (this number is only positive) the message was generated. Optional.
** If neither are specified, the server will timestamp the message with when it hit the DB.
** If neither are specified, the server will timestamp the message with when it hit the DB.
** "data" is the message text.  No reasonable length limit.  Required; the array member will be silently discarded without it.
** <code>data</code> is the message text.  No reasonable length limit.  Required; the array member will be silently discarded without it.
** "severity" is the 0-7 standard syslog values (panic, alert, crit, error, warn, notice, info, debug).  Optional; defaults to info.
** <code>severity</code> is the 0-7 standard syslog values (panic, alert, crit, error, warn, notice, info, debug).  Optional; defaults to info.
* Key "temperatures" is an array of temperature reading objects to log, containing keys as below:
* Key <code>temperatures</code> is an array of temperature reading objects to log, containing keys as below:
** "absolute_timestamp" and "relative_timestamp" function as in "messages".
** <code>absolute_timestamp</code> and <code>relative_timestamp</code> function as in <code>messages</code>.
** "temperature" is the reading, in ***tenths*** of a degree Fahrenheit.  This is done to remove the need for floating-point libraries on microcontrollers, as they are large.  Required.
** <code>temperature</code> is the reading, in '''''tenths''''' of a degree Fahrenheit.  This is done to remove the need for floating-point libraries on microcontrollers, as they are large.  Required.
** "item" is which item the temperature is measuring.  Note that a device must have permission to that item to log temperatures for it.  Required; the array member will be silently discarded if missing or unauthorized.
** <code>item</code> is which item the temperature is measuring.  Note that a device must have permission to that item to log temperatures for it.  Required; the array member will be silently discarded if missing or unauthorized.


== Current protocol weaknesses and notes ==
== Current protocol weaknesses and notes ==
Line 79: Line 79:
== Database Layout ==
== Database Layout ==
* Conventions
* Conventions
** All tables have a ${table_name}_id column that's a UUID as the primary key
** All tables have a <code>${table_name}_id</code> column that's a UUID as the primary key
** Many-to-many tables have the two tables they connect in alpha order
** Many-to-many tables have the two tables they connect in alpha order
*** They do not have their own, separate ID field
*** They do not have their own, separate ID field
Line 87: Line 87:
** Catalyst convention is to use Pascal case for table names.
** Catalyst convention is to use Pascal case for table names.
** Postgres convention is to use Snake case for table names.
** Postgres convention is to use Snake case for table names.
* "members" stores member information.
* <code>members</code> stores member information.
** It needs renamed to "member" for consistency, though the app calls it "Member" with a name override.
** It needs renamed to <code>member</code> for consistency, though the app calls it <code>Member</code> with a name override.
** It also needs old fields blown away.
** It also needs old fields blown away.
* "badge" stores a badge number and which member it belongs to - you can have multiple badges per account
* <code>badge</code> stores a badge number and which member it belongs to - you can have multiple badges per account
* "mgroup" stores the names and IDs of various groups, such as members, leadership, laser certified, &c.  It's called mgroup because "group" is an SQL reserved word.
* <code>mgroup</code> stores the names and IDs of various groups, such as members, leadership, laser certified, &c.  It's called mgroup because <code>group</code> is an SQL reserved word.
* "member_mgroup" is a many-to-many association table to join members to groups.
* <code>member_mgroup</code> is a many-to-many association table to join members to groups.
* "device" stores information about a device - its shared key and name right now.
* <code>device</code> stores information about a device - its shared key and name right now.
* "item" stores information about items that can be accessed - doors, tools, and so on.
* <code>item</code> stores information about items that can be accessed - doors, tools, and so on.
* "device_item" is a many-to-many showing which devices can service which items.
* <code>device_item</code> is a many-to-many showing which devices can service which items.
* "item_mgroup" is a many-to-many granting access to an item to a group.
* <code>item_mgroup"</code> is a many-to-many granting access to an item to a group.


[[Category:RFID]]
[[Category:RFID]]
973

edits