Merge pull request #2976 from urbit/m/eyre-kill-channels

eyre: expire channels with their sessions
This commit is contained in:
Fang 2020-06-19 00:39:42 +02:00 committed by GitHub
commit 97f7893619
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 172 additions and 145 deletions

View File

@ -2,44 +2,52 @@ jobs:
include:
- os: linux
language: nix
nix: 2.1.3
env: STACK_YAML=pkg/hs/stack.yaml
nix: 2.3.6
before_install:
- git lfs pull
- sh/travis-install-stack
install:
- nix-env -iA cachix -f https://cachix.org/api/v1/install
- stack --no-terminal --install-ghc build urbit-king --only-dependencies
script:
- cachix use urbit2
- ./sh/cachix
- make build
- make release
- sh/release-king-linux64-dynamic
- sh/ci-tests
- os: osx
- os: linux
language: generic
sudo: required
env: STACK_YAML=pkg/hs/stack.yaml
before_install:
- sh/travis-install-stack
install:
- stack --no-terminal --install-ghc build urbit-king --only-dependencies
script:
- sh/release-king-darwin-dynamic
cache:
cache:
directories:
- $HOME/.ghc
- $HOME/.cabal
- $HOME/.stack
- $TRAVIS_BUILD_DIR/.stack-work
before_install:
- sh/travis-install-stack
install:
- stack --no-terminal --install-ghc build urbit-king --only-dependencies
script:
- stack test
- sh/release-king-linux64-dynamic
- os: osx
language: generic
sudo: required
env: STACK_YAML=pkg/hs/stack.yaml
cache:
directories:
- $HOME/.ghc
- $HOME/.cabal
- $HOME/.stack
- $TRAVIS_BUILD_DIR/.stack-work
before_install:
- sh/travis-install-stack
install:
- stack --no-terminal --install-ghc build urbit-king --only-dependencies
script:
- stack test
- sh/release-king-darwin-dynamic
deploy:
- skip_cleanup: true

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dd9ee3401fd2a29fc49ef84aa51754be5929f2cddbb7e378ffac4641695e886c
size 13838435
oid sha256:657e130a063598dc9e4800039f6dde1e7e4b7a3c56e57561a46a4f06641da48e
size 17337052

View File

@ -38,8 +38,9 @@ herb ./ship -p test -d ':- %renders /'
herb ./ship -d '~& %finish-test-renders ~'
# Run the test generator
herb ./ship -d '+test, =seed `@uvI`(shaz %reproducible)' |
tee test-generator-output
herb ./ship -d '+test, =seed `@uvI`(shaz %reproducible)' > test-generator-output
cat test-generator-output || true
herb ./ship -p hood -d '+hood/mass'

View File

@ -381,6 +381,7 @@
:* [%give %kick ~[[%mailbox path.act]] ~]
[%give %fact [/synced]~ %chat-hook-update !>([%initial synced])]
(pull-wire u.ship [%mailbox path.act])
(pull-wire u.ship [%store path.act])
(pull-backlog-subscriptions u.ship path.act)
==
==

View File

@ -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

View File

@ -1213,7 +1213,7 @@
::
=/ raw
~& [%hoon-compile `@p`(mug hun)]
(ride %noun hun)
(road |.((ride %noun hun)))
:: activate the new compiler gate, producing +ride
::
=/ cop .*(0 +.raw)
@ -1226,11 +1226,13 @@
::
:: hot: raw compiler formula
::
=> ?: =(nex hoon-version)
[hot=`*`raw .]
=^ hot=* cop
?: =(nex hoon-version)
[raw cop]
~& [%hoon-compile-upgrade nex]
%- road |.
=/ hot (slum cop [%noun hun])
.(cop .*(0 +.hot))
[hot .*(0 +.hot)]
:: extract the hoon core from the outer gate (+ride)
::
=/ hoc .*(cop [%0 7])
@ -1241,7 +1243,7 @@
::
=/ rav
~& [%arvo-compile `@p`(mug hyp) `@p`(mug van)]
(slum cop [hyp van])
(road |.((slum cop [hyp van])))
:: activate arvo, and extract the arvo core from the outer gate
::
=/ voc .*(hoc [%7 +.rav %0 7])

View File

@ -12035,6 +12035,15 @@
?~ a !!
~_(i.a $(a t.a))
::
++ road
|* =(trap *)
^+ $:trap
=/ res (mule trap)
?- -.res
%& p.res
%| (mean leaf+"road: new" p.res)
==
::
++ slew :: get axis in vase
|= {axe/@ vax/vase} ^- (unit vase)
?. |- ^- ?

View File

@ -970,7 +970,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 &)
@ -1027,15 +1027,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)
=^ 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
@ -1326,6 +1344,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)
@ -1487,50 +1515,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)
::
==
@ -1672,10 +1660,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)
@ -1687,6 +1677,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 ~
@ -1695,7 +1689,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)
@ -1825,7 +1825,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 &)
@ -2109,13 +2111,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
@ -2363,10 +2359,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
@ -2398,11 +2394,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]
@ -2434,7 +2428,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)
^+ ..^$

View File

@ -1214,6 +1214,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
@ -3731,62 +3734,53 @@
:: :: ++s2va:aes:crypto
++ s2va :: AES-128 S2V
~/ %s2va
|= {key/@H ads/(list @)}
=+ res=(maca key `16 0x0)
%^ maca key ~
|- ^- @uxH
|= [key=@H ads=(list @)]
?~ ads (maca key `16 0x1)
=/ res (maca key `16 0x0)
%+ maca key
|- ^- [[~ @ud] @uxH]
?~ t.ads
?: (gte (xeb i.ads) 128)
(mix i.ads res)
%+ mix
(doub res)
(mpad (met 3 i.ads) i.ads)
=/ wyt (met 3 i.ads)
?: (gte wyt 16)
[`wyt (mix i.ads res)]
[`16 (mix (doub res) (mpad wyt i.ads))]
%= $
res %+ mix
(doub res)
(maca key ~ i.ads)
ads t.ads
res (mix (doub res) (maca key ~ i.ads))
==
:: :: ++s2vb:aes:crypto
++ s2vb :: AES-192 S2V
~/ %s2vb
|= {key/@I ads/(list @)}
=+ res=(macb key `16 0x0)
%^ macb key ~
|- ^- @uxH
|= [key=@I ads=(list @)]
?~ ads (macb key `16 0x1)
=/ res (macb key `16 0x0)
%+ macb key
|- ^- [[~ @ud] @uxH]
?~ t.ads
?: (gte (xeb i.ads) 128)
(mix i.ads res)
%+ mix
(doub res)
(mpad (met 3 i.ads) i.ads)
=/ wyt (met 3 i.ads)
?: (gte wyt 16)
[`wyt (mix i.ads res)]
[`16 (mix (doub res) (mpad wyt i.ads))]
%= $
res %+ mix
(doub res)
(macb key ~ i.ads)
ads t.ads
res (mix (doub res) (macb key ~ i.ads))
==
:: :: ++s2vc:aes:crypto
++ s2vc :: AES-256 S2V
~/ %s2vc
|= {key/@I ads/(list @)}
=+ res=(macc key `16 0x0)
%^ macc key ~
|- ^- @uxH
|= [key=@I ads=(list @)]
?~ ads (macc key `16 0x1)
=/ res (macc key `16 0x0)
%+ macc key
|- ^- [[~ @ud] @uxH]
?~ t.ads
?: (gte (xeb i.ads) 128)
(mix i.ads res)
%+ mix
(doub res)
(mpad (met 3 i.ads) i.ads)
=/ wyt (met 3 i.ads)
?: (gte wyt 16)
[`wyt (mix i.ads res)]
[`16 (mix (doub res) (mpad wyt i.ads))]
%= $
res %+ mix
(doub res)
(macc key ~ i.ads)
ads t.ads
res (mix (doub res) (macc key ~ i.ads))
==
:: :: ++siva:aes:crypto
++ siva :: AES-128 SIV

View File

@ -567,6 +567,18 @@
^- (list vector-siv)
:~
::
:: failed in the wild, see https://github.com/urbit/urbit/pull/3013
::
:^ 0xfdef.6253.d284.a940.1b5d.d1b7.fbcd.4489.
3071.bf93.ace9.37da.7c5d.77d2.1f3e.cda4.
83be.1c51.a88b.c9ba.8741.e1ee.935b.c0ef.
888a.feff.0249.bdb6.1344.0ff9.4e1b.fca5
ad=~
inp=0x97.0341.38e3.960e.87e1
:+ iv=0x249f.85e3.c9a8.29b6.3122.ec22.cde6.76df
len=9
cph=0xdc.bdcd.e4f1.4fd4.2d8d
::
:: from RFC 5297, with extended key
::
:^ 0xfffe.fdfc.fbfa.f9f8.f7f6.f5f4.f3f2.f1f0.

View File

@ -146,7 +146,7 @@ export class Eyre extends Component {
const sessionItems = props.authentication.map(s => {
return (<div>
{`${s.cookie} expires ${msToDa(s.expiry)}`}
{`${s.cookie} expires ${msToDa(s.expiry)}, uses ${s.channels} channel(s)`}
</div>);
});

View File

@ -2,10 +2,6 @@
set -ex
export STACK_YAML="`pwd`/pkg/hs/stack.yaml"
stack test urbit-king
if [ "$TRAVIS_PULL_REQUEST" = false ]
then

View File

@ -2,8 +2,6 @@
set -e
stack test urbit-king --fast
pkg=$(nix-build nix/ops -A test --no-out-link "$@")
hdr () {