Skip to content
Snippets Groups Projects
Commit 6fa22810 authored by Michael Ensslin's avatar Michael Ensslin
Browse files

Merge branch 'master' of gitlab.stusta.de:stustanet/spacelock

parents 9ea448ee f86a507b
No related branches found
No related tags found
No related merge requests found
# Board design
Printed circuit board with all the electrical components.
# Access Database
* Grants door access.
* The only trusted software component.
Needs PostgreSQL.
-- spacelock database
--
-- creates access tokens, returned by function `gen_token(accesskey)`
--
-- (c) 2019 Wolfgang Walter <wolfgang.walter@stusta.net>
-- (c) 2019 Michael Enßlin <mic@sft.mx>
-- (c) 2019 Jonas Jelten <jj@sft.mx>
-- we use plpython
-- the user loading this file needs superuser access,
-- because the loaded python is untrusted code.
do $$ begin
create language plpython3u;
exception
when duplicate_object then null;
end $$;
-- secret signing key, shared with the door chip
create table if not exists signer (
id bigserial not null,
secret text not null
);
-- permission definitions for door users
create table if not exists permissions (
id bigserial primary key not null,
description text not null,
key text unique not null,
valid_from timestamp with time zone not null,
valid_to timestamp with time zone not null,
active boolean not null
);
-- token creation log
create table if not exists log (
who bigint references permissions(id),
token text not null,
stamp timestamp with time zone default now()
);
-- message signing in python, because we can
create or replace function sign_message (
signing_key text,
now_timestamp double precision,
validity_window_size int,
message_type int,
description text
) returns text as $$
import base64
import hmac
import struct
message_blob = struct.pack(
'<qqB',
int(now_timestamp) - validity_window_size,
int(now_timestamp) + validity_window_size,
message_type
) + description.encode()
signing_key_blob = base64.b64decode(signing_key.encode())
signature = hmac.new(signing_key_blob, msg=message_blob, digestmod='sha256').digest()
combined_blob = signature[:16] + message_blob
return base64.b64encode(combined_blob).decode()
$$ language plpython3u;
-- token generation, this is the entry point for untrusted users
-- this function will be executed in setuid-mode!
-- to grant access, use:
-- create role spacelock;
-- grant execute on function gen_token to some_insecure_user;
create or replace function gen_token (permission_key text)
returns text as $$
declare entry permissions%ROWTYPE;
declare now_time timestamp with time zone;
declare signing_key text;
declare token text;
begin
select now() into now_time;
select * into entry
from permissions
where
key = permission_key and
active is true and
valid_from <= now_time and
valid_to >= now_time;
if entry is NULL then
return NULL;
end if;
select secret into signing_key from signer order by id desc limit 1;
if signing_key is NULL then
return NULL;
end if;
select sign_message(
signing_key,
extract(epoch from now_time),
300, -- 5 minutes token validity
0, -- message type 0: open door
entry.description
) into token;
insert into log (who, token, stamp) values (
entry.id,
token,
now_time
);
return token;
end;
$$ language plpgsql
security definer;
-- aand we're done!
# Door mounting parts
use `openscad`.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment