small adjustments to auth schema

Nothing uses the user and user_session tables yet; I'm trying to
anticipate what auth will need before freezing schema version 3.
This commit is contained in:
Scott Lamb 2018-04-27 06:24:02 -07:00
parent b0071515e0
commit 9982c0b080
2 changed files with 31 additions and 15 deletions

View File

@ -322,7 +322,7 @@ create table user (
-- Updated lazily on database flush; reset when password_id is incremented. -- Updated lazily on database flush; reset when password_id is incremented.
-- This could be used to automatically disable the password on hitting a threshold. -- This could be used to automatically disable the password on hitting a threshold.
password_failure_count integer not null, password_failure_count integer not null default 0,
-- If set, a Unix UID that is accepted for authentication when using HTTP over -- If set, a Unix UID that is accepted for authentication when using HTTP over
-- a Unix domain socket. (Additionally, the UID running Moonfire NVR can authenticate -- a Unix domain socket. (Additionally, the UID running Moonfire NVR can authenticate
@ -332,20 +332,35 @@ create table user (
); );
-- A single session, whether for browser or robot use. -- A single session, whether for browser or robot use.
-- These map at the HTTP layer to two cookies (exact format described
-- elsewhere):
--
-- * "s" holds the session id and an encrypted sequence number for replay
-- protection. To decrease chance of leaks, it's normally marked as
-- HttpOnly, preventing client-side Javascript from accessing it.
--
-- * "sc" holds state needed by client Javascript, such as a CSRF token (which
-- should be copied into POST request bodies) and username (which should be
-- presented in the UI). It should never be marked HttpOnly.
create table user_session ( create table user_session (
-- The session id is a 48-byte blob (which is base64 encoded to 64 bytes in the HTTP cookie). -- The session id is a 20-byte blob. This is the unencoded, unsalted Blake2b-160
-- This is the unencoded SHA3-256 of the unencoded session id. Much like `password_hash`, -- (also 20 bytes) of the unencoded session id. Much like `password_hash`, a
-- a hash is used here so that a leaked database backup can't be trivially used to steal -- hash is used here so that a leaked database backup can't be trivially used
-- credentials. The hash is unsalted; unlike passwords designed for humans to -- to steal credentials.
-- remember, the session id is assumed to itself have sufficient entropy.
session_id_hash blob primary key not null, session_id_hash blob primary key not null,
user_id integer references user (id) not null, user_id integer references user (id) not null,
-- A bitwise mask of flags, currently all properties of the HTTP cookie used to hold the session: -- A TBD-byte random number. Used to derive keys for the replay protection
-- 1: HttpOnly -- and CSRF tokens.
-- 2: Secure seed blob not null,
-- 4: SameSite (lax)
-- A bitwise mask of flags, currently all properties of the HTTP cookies
-- used to hold the session:
-- 1: HttpOnly ("s" cookie only)
-- 2: Secure (both cookies)
-- 4: SameSite=Lax (both cookies)
-- 8: SameSite=Strict ("s" cookie only) - 4 must also be set.
flags integer not null, flags integer not null,
-- The domain of the HTTP cookie used to store this session. The outbound -- The domain of the HTTP cookie used to store this session. The outbound
@ -359,8 +374,8 @@ create table user_session (
creation_password_id integer, -- the id it was created from, if created via password creation_password_id integer, -- the id it was created from, if created via password
creation_time_sec integer not null, -- sec since epoch creation_time_sec integer not null, -- sec since epoch
creation_peer_addr blob, -- IPv4 or IPv6 address, or null for Unix socket.
creation_user_agent text, -- User-Agent header from inbound HTTP request. creation_user_agent text, -- User-Agent header from inbound HTTP request.
creation_peer_addr blob, -- IPv4 or IPv6 address, or null for Unix socket.
revocation_time_sec integer, -- sec since epoch revocation_time_sec integer, -- sec since epoch
revocation_user_agent text, -- User-Agent header from inbound HTTP request. revocation_user_agent text, -- User-Agent header from inbound HTTP request.
@ -383,7 +398,7 @@ create table user_session (
last_use_time_sec integer, -- sec since epoch last_use_time_sec integer, -- sec since epoch
last_use_user_agent text, -- User-Agent header from inbound HTTP request. last_use_user_agent text, -- User-Agent header from inbound HTTP request.
last_use_peer_addr blob, -- IPv4 or IPv6 address, or null for Unix socket. last_use_peer_addr blob, -- IPv4 or IPv6 address, or null for Unix socket.
use_count not null use_count not null default 0
) without rowid; ) without rowid;
create index user_session_uid on user_session (user_id); create index user_session_uid on user_session (user_id);

View File

@ -73,19 +73,20 @@ pub fn run(args: &super::Args, tx: &rusqlite::Transaction) -> Result<(), Error>
flags integer not null, flags integer not null,
password_hash text, password_hash text,
password_id integer not null default 0, password_id integer not null default 0,
password_failure_count integer not null, password_failure_count integer not null default 0,
unix_uid integer unix_uid integer
); );
create table user_session ( create table user_session (
session_id_hash blob primary key not null, session_id_hash blob primary key not null,
user_id integer references user (id) not null, user_id integer references user (id) not null,
seed blob not null,
flags integer not null, flags integer not null,
domain text, domain text,
description text, description text,
creation_password_id integer, creation_password_id integer,
creation_peer_addr blob,
creation_time_sec integer not null, creation_time_sec integer not null,
creation_user_agent text, creation_user_agent text,
creation_peer_addr blob,
revocation_time_sec integer, revocation_time_sec integer,
revocation_user_agent text, revocation_user_agent text,
revocation_peer_addr blob, revocation_peer_addr blob,
@ -94,7 +95,7 @@ pub fn run(args: &super::Args, tx: &rusqlite::Transaction) -> Result<(), Error>
last_use_time_sec integer, last_use_time_sec integer,
last_use_user_agent text, last_use_user_agent text,
last_use_peer_addr blob, last_use_peer_addr blob,
use_count not null use_count not null default 0
) without rowid; ) without rowid;
"#)?; "#)?;
let db_uuid = ::uuid::Uuid::new_v4(); let db_uuid = ::uuid::Uuid::new_v4();