From 68491420d2a350e948e3a17ed3b8529665bba790 Mon Sep 17 00:00:00 2001 From: Fang Date: Thu, 4 Jun 2020 17:12:35 +0200 Subject: [PATCH 1/4] eyre: refactor %delete to reuse timeout logic Turns +on-channel-timeout into +discard-channel, which cleans up the entirety of the channel, based on its current state. This allows us to simplify the %delete channel request into a simple function call. --- pkg/arvo/sys/vane/eyre.hoon | 78 +++++++++++-------------------------- 1 file changed, 22 insertions(+), 56 deletions(-) diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index 43c3d7596..62e402cc1 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -1486,50 +1486,10 @@ $(requests t.requests) :: %delete - =/ unitsession - (~(get by session.channel-state.state) channel-id) - :: - ?~ unitsession - $(requests t.requests) - :: - =/ session u.unitsession - =. session.channel-state.state - (~(del by session.channel-state.state) channel-id) - :: + =^ moves state + (discard-channel channel-id |) =. gall-moves - %+ weld gall-moves - :: - :: produce a list of moves which cancels every gall subscription - :: - %+ turn ~(tap by subscriptions.session) - |= [channel-wire=wire ship=@p app=term =path duc=^duct] - ^- move - :: - [duc %pass channel-wire [%g %deal [our ship] app %leave ~]] - :: - ?: ?=([%& *] state.session) - =. gall-moves - :_ gall-moves - :: - ^- move - ?> ?=([%& *] state.session) - :^ duct.p.state.session %pass /channel/timeout/[channel-id] - [%b %rest date.p.state.session] - :: - $(requests t.requests) - :: - ?> ?=([%| *] state.session) - =. duct-to-key.channel-state.state - (~(del by duct-to-key.channel-state.state) p.state.session) - :: - ?~ heartbeat.session $(requests t.requests) - =. gall-moves - %+ snoc gall-moves - %^ cancel-heartbeat-move - channel-id - date.u.heartbeat.session - duct.u.heartbeat.session - :: + (weld gall-moves moves) $(requests t.requests) :: == @@ -1671,10 +1631,12 @@ channel(heartbeat (some [heartbeat-time duct])) == (snoc http-moves (set-heartbeat-move channel-id heartbeat-time)) - :: +on-channel-timeout: we received a wake to clear an old session + :: +discard-channel: remove a channel from state :: - ++ on-channel-timeout - |= channel-id=@t + :: cleans up state, timers, and gall subscriptions of the channel + :: + ++ discard-channel + |= [channel-id=@t expired=?] ^- [(list move) server-state] :: =/ usession=(unit channel) @@ -1686,6 +1648,10 @@ :_ %_ state session.channel-state (~(del by session.channel-state.state) channel-id) + :: + duct-to-key.channel-state + ?. ?=(%| -.state.session) duct-to-key.channel-state.state + (~(del by duct-to-key.channel-state.state) p.state.session) == =/ heartbeat-cancel=(list move) ?~ heartbeat.session ~ @@ -1694,7 +1660,13 @@ date.u.heartbeat.session duct.u.heartbeat.session == + =/ expire-cancel=(list move) + ?: expired ~ + ?. ?=(%& -.state.session) ~ + =, p.state.session + [(cancel-timeout-move channel-id date duct)]~ %+ weld heartbeat-cancel + %+ weld expire-cancel :: produce a list of moves which cancels every gall subscription :: %+ turn ~(tap by subscriptions.session) @@ -2108,13 +2080,7 @@ [(zing (flop moves)) http-server-gate] :: discard channel state, and cancel any active gall subscriptions :: - =^ mov server-state.ax (on-channel-timeout:by-channel channel-id) - :: cancel channel timer - :: - =/ channel (~(got by session.channel-state) channel-id) - =? mov ?=([%& *] state.channel) - :_ mov - (cancel-timeout-move:by-channel channel-id p.state.channel) + =^ mov server-state.ax (discard-channel:by-channel channel-id |) $(moves [mov moves], inactive t.inactive) :: :: %vega: notifies us of a completed kernel upgrade @@ -2362,10 +2328,10 @@ ?> ?=([%b %wake *] sign) ?^ error.sign [[duct %slip %d %flog %crud %wake u.error.sign]~ http-server-gate] - =/ on-channel-timeout - on-channel-timeout:by-channel:(per-server-event event-args) + =/ discard-channel + discard-channel:by-channel:(per-server-event event-args) =^ moves server-state.ax - (on-channel-timeout i.t.t.wire) + (discard-channel i.t.t.wire &) [moves http-server-gate] :: %heartbeat From b54dc7cd345bf430d44dbdc9dd316698de67f8e1 Mon Sep 17 00:00:00 2001 From: Fang Date: Thu, 4 Jun 2020 22:06:13 +0200 Subject: [PATCH 2/4] eyre, zuse: expire channels with their sessions Associates channels with the authentication sessions that opened them, and deletes the channel when its associated session expires. Also updates the debug dashboard to display channel counts per session. --- bin/solid.pill | 4 +- pkg/arvo/app/dbug.hoon | 5 +- pkg/arvo/sys/vane/eyre.hoon | 71 +++++++++++++++++++------ pkg/arvo/sys/zuse.hoon | 3 ++ pkg/interface/dbug/src/js/views/eyre.js | 2 +- 5 files changed, 64 insertions(+), 21 deletions(-) diff --git a/bin/solid.pill b/bin/solid.pill index f10d60221..e6a2605f7 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dfaee098f2dca396c17aa1ddf1d2755f5f7d8639864b0e970fce0290d67008cc -size 20306202 +oid sha256:9f7988e3ffc99ecd8cb66daf469bff3b9cb41ca82895a91cae7d4f7d59bb48a7 +size 20308420 diff --git a/pkg/arvo/app/dbug.hoon b/pkg/arvo/app/dbug.hoon index 90124315b..a45e8d6a2 100644 --- a/pkg/arvo/app/dbug.hoon +++ b/pkg/arvo/app/dbug.hoon @@ -360,12 +360,13 @@ :- %a %+ turn %+ sort ~(tap by sessions:auth-state:v-eyre) - |= [[@uv a=@da] [@uv b=@da]] - (gth a b) + |= [[@uv a=session:eyre] [@uv b=session:eyre]] + (gth expiry-time.a expiry-time.b) |= [cookie=@uv session:eyre] %- pairs :~ 'cookie'^s+(end 3 4 (rsh 3 2 (scot %x (shax cookie)))) 'expiry'^(time expiry-time) + 'channels'^(numb ~(wyt in channels)) == :: :: /eyre/channels.json diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index 62e402cc1..64281742c 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -969,7 +969,7 @@ =/ first-session=? =(~ sessions.authentication-state.state) =/ expires-at=@da (add now session-timeout) =. sessions.authentication-state.state - (~(put by sessions.authentication-state.state) session expires-at) + (~(put by sessions.authentication-state.state) session [expires-at ~]) :: =/ cookie-line=@t (session-cookie-string session &) @@ -1026,15 +1026,33 @@ (handle-response response) :: delete the requesting session, or all sessions if so specified :: - =. sessions.authentication-state.state - =; all=? - ?: all ~ - (~(del by sessions.authentication-state.state) u.session-id) - ?~ body.request | - =- ?=(^ -) - %+ get-header:http 'all' - (fall (rush q.u.body.request yquy:de-purl:html) ~) - (handle-response response) + =^ channels=(list @t) sessions.authentication-state.state + =* sessions sessions.authentication-state.state + =/ all=? + ?~ body.request | + =- ?=(^ -) + %+ get-header:http 'all' + (fall (rush q.u.body.request yquy:de-purl:html) ~) + ?. all + :_ (~(del by sessions) u.session-id) + %~ tap in + channels:(~(gut by sessions) u.session-id *session) + :_ ~ + %~ tap in + %+ roll ~(val by sessions) + |= [session all=(set @t)] + (~(uni in all) channels) + :: close all affected channels, then send the response + :: + =| moves=(list move) + |- ^- (quip move server-state) + ?~ channels + =^ moz state + (handle-response response) + [(weld moves moz) state] + =^ moz state + (discard-channel:by-channel i.channels |) + $(moves (weld moves moz), channels t.channels) :: +session-id-from-request: attempt to find a session cookie :: ++ session-id-from-request @@ -1325,6 +1343,16 @@ :: =. duct-to-key.channel-state.state (~(put by duct-to-key.channel-state.state) duct channel-id) + :: associate this channel with the session cookie + :: + =. sessions.authentication-state.state + =/ session-id=(unit @uv) + (session-id-from-request:authentication request) + ?~ session-id sessions.authentication-state.state + %+ ~(jab by sessions.authentication-state.state) + u.session-id + |= =session + session(channels (~(put in channels.session) channel-id)) :: initialize sse heartbeat :: =/ heartbeat-time=@da (add now ~s20) @@ -1796,7 +1824,9 @@ :: tough luck, we don't create/revive sessions here :: no-op - :_ (~(put by sessions) u.session-id (add now session-timeout)) + :_ %+ ~(jab by sessions) u.session-id + |= =session + session(expiry-time (add now session-timeout)) =- response-header.http-event(headers -) %^ set-header:http 'set-cookie' (session-cookie-string u.session-id &) @@ -2363,11 +2393,9 @@ =* sessions sessions.authentication-state.server-state.ax =. sessions.authentication-state.server-state.ax %- ~(gas by *(map @uv session)) - %+ murn ~(tap in sessions) + %+ skip ~(tap in sessions) |= [cookie=@uv session] - ^- (unit [@uv session]) - ?: (lth expiry-time now) ~ - `[cookie expiry-time] + (lth expiry-time now) :: if there's any cookies left, set a timer for the next expected expiry :: ^- [(list move) _http-server-gate] @@ -2399,7 +2427,18 @@ ++ load => |% +$ axle-2019-10-6 - [date=%~2019.10.6 =server-state] + [date=%~2019.10.6 server-state=server-state-2019-10-6] + :: + +$ server-state-2019-10-6 + $: bindings=(list [=binding =duct =action]) + connections=(map duct outstanding-connection) + authentication-state=sessions=(map @uv @da) + =channel-state + domains=(set turf) + =http-config + ports=[insecure=@ud secure=(unit @ud)] + outgoing-duct=duct + == -- |= old=$%(axle axle-2019-10-6) ^+ ..^$ diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index 6c4a2c11b..99750fa3c 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -1213,6 +1213,9 @@ :: to properly handle cookie expiration as a security mechanism. :: expiry-time=@da + :: channels: channels opened by this session + :: + channels=(set @t) :: :: TODO: We should add a system for individual capabilities; we should :: mint some sort of long lived cookie for mobile apps which only has diff --git a/pkg/interface/dbug/src/js/views/eyre.js b/pkg/interface/dbug/src/js/views/eyre.js index 88e4bde91..738a685cf 100644 --- a/pkg/interface/dbug/src/js/views/eyre.js +++ b/pkg/interface/dbug/src/js/views/eyre.js @@ -146,7 +146,7 @@ export class Eyre extends Component { const sessionItems = props.authentication.map(s => { return (
- {`${s.cookie} expires ${msToDa(s.expiry)}`} + {`${s.cookie} expires ${msToDa(s.expiry)}, uses ${s.channels} channel(s)`}
); }); From a4785458d156eed0a0d32c0a2b6d294acae1527c Mon Sep 17 00:00:00 2001 From: Fang Date: Wed, 10 Jun 2020 20:37:12 +0200 Subject: [PATCH 3/4] eyre: don't lose redirect upon failing login If we failed the password check, the login page served to us would never include any redirect details, even if they were there in the original request. Now we simply (attempt to) parse out the redirect field a little earlier. --- pkg/arvo/sys/vane/eyre.hoon | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/arvo/sys/vane/eyre.hoon b/pkg/arvo/sys/vane/eyre.hoon index f5304226e..5cb26cdf3 100644 --- a/pkg/arvo/sys/vane/eyre.hoon +++ b/pkg/arvo/sys/vane/eyre.hoon @@ -950,12 +950,13 @@ ?~ parsed (return-static-data-on-duct 400 'text/html' (login-page ~ our)) :: + =/ redirect=(unit @t) (get-header:http 'redirect' u.parsed) ?~ password=(get-header:http 'password' u.parsed) - (return-static-data-on-duct 400 'text/html' (login-page ~ our)) + (return-static-data-on-duct 400 'text/html' (login-page redirect our)) :: check that the password is correct :: ?. =(u.password code) - (return-static-data-on-duct 400 'text/html' (login-page ~ our)) + (return-static-data-on-duct 400 'text/html' (login-page redirect our)) :: mint a unique session cookie :: =/ session=@uv @@ -981,7 +982,7 @@ =- out(moves [- moves.out]) [duct %pass /sessions/expire %b %wait expires-at] :: - ?~ redirect=(get-header:http 'redirect' u.parsed) + ?~ redirect %- handle-response :* %start :- status-code=200 From e35bb4b72a945716f61351f805029386d45819af Mon Sep 17 00:00:00 2001 From: Fang Date: Thu, 18 Jun 2020 21:48:35 +0200 Subject: [PATCH 4/4] pill: update --- bin/solid.pill | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/solid.pill b/bin/solid.pill index e6a2605f7..073e2fbbe 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f7988e3ffc99ecd8cb66daf469bff3b9cb41ca82895a91cae7d4f7d59bb48a7 -size 20308420 +oid sha256:2c0c3e34876875722a8505d8e98843738460d6d8b3ab8872274a876f7859ae71 +size 17336122