Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
IRMA
Github mirrors
irmago
Commits
46d4f765
Commit
46d4f765
authored
Oct 14, 2017
by
Sietse Ringers
Browse files
Ensure that non-accepted sessions are always DELETEd exactly once
parent
60bf8f54
Changes
1
Hide whitespace changes
Inline
Side-by-side
session.go
View file @
46d4f765
...
...
@@ -36,6 +36,10 @@ type Handler interface {
RequestPin
(
remainingAttempts
int
,
callback
PinHandler
)
}
type
SessionDismisser
interface
{
Dismiss
()
}
// A session is an IRMA session.
type
session
struct
{
Action
Action
...
...
@@ -50,6 +54,7 @@ type session struct {
transport
*
HTTPTransport
choice
*
DisclosureChoice
downloaded
*
IrmaIdentifierSet
deleted
bool
}
// We implement the handler for the keyshare protocol
...
...
@@ -96,7 +101,7 @@ func calcVersion(qr *Qr) (string, error) {
}
// NewSession creates and starts a new IRMA session.
func
(
cm
*
CredentialManager
)
NewSession
(
qr
*
Qr
,
handler
Handler
)
{
func
(
cm
*
CredentialManager
)
NewSession
(
qr
*
Qr
,
handler
Handler
)
SessionDismisser
{
session
:=
&
session
{
Action
:
Action
(
qr
.
Type
),
ServerURL
:
qr
.
URL
,
...
...
@@ -107,7 +112,7 @@ func (cm *CredentialManager) NewSession(qr *Qr, handler Handler) {
version
,
err
:=
calcVersion
(
qr
)
if
err
!=
nil
{
session
.
fail
(
&
SessionError
{
ErrorType
:
ErrorProtocolVersionNotSupported
,
Err
:
err
})
return
return
nil
}
session
.
Version
=
Version
(
version
)
...
...
@@ -121,7 +126,7 @@ func (cm *CredentialManager) NewSession(qr *Qr, handler Handler) {
fallthrough
default
:
session
.
fail
(
&
SessionError
{
ErrorType
:
ErrorUnknownAction
,
Info
:
string
(
session
.
Action
)})
return
return
nil
}
if
!
strings
.
HasSuffix
(
session
.
ServerURL
,
"/"
)
{
...
...
@@ -130,43 +135,7 @@ func (cm *CredentialManager) NewSession(qr *Qr, handler Handler) {
go
session
.
start
()
return
}
func
handlePanic
(
callback
func
(
*
SessionError
))
{
if
e
:=
recover
();
e
!=
nil
{
var
info
string
switch
x
:=
e
.
(
type
)
{
case
string
:
info
=
x
case
error
:
info
=
x
.
Error
()
case
fmt
.
Stringer
:
info
=
x
.
String
()
default
:
// nop
}
fmt
.
Printf
(
"Recovered from panic: '%v'
\n
%s
\n
"
,
e
,
info
)
if
callback
!=
nil
{
callback
(
&
SessionError
{
ErrorType
:
ErrorPanic
,
Info
:
info
})
}
}
}
func
(
session
*
session
)
fail
(
err
*
SessionError
)
{
session
.
transport
.
Delete
()
err
.
Err
=
errors
.
Wrap
(
err
.
Err
,
0
)
if
session
.
downloaded
!=
nil
&&
!
session
.
downloaded
.
Empty
()
{
session
.
credManager
.
handler
.
UpdateConfigurationStore
(
session
.
downloaded
)
}
session
.
Handler
.
Failure
(
session
.
Action
,
err
)
}
func
(
session
*
session
)
cancel
()
{
session
.
transport
.
Delete
()
if
session
.
downloaded
!=
nil
&&
!
session
.
downloaded
.
Empty
()
{
session
.
credManager
.
handler
.
UpdateConfigurationStore
(
session
.
downloaded
)
}
session
.
Handler
.
Cancelled
(
session
.
Action
)
return
session
}
// start retrieves the first message in the IRMA protocol, checks if we can perform
...
...
@@ -222,7 +191,7 @@ func (session *session) start() {
distributed
:=
manager
.
Distributed
()
_
,
enrolled
:=
session
.
credManager
.
keyshareServers
[
id
]
if
distributed
&&
!
enrolled
{
session
.
transport
.
D
elete
()
session
.
d
elete
()
session
.
Handler
.
MissingKeyshareEnrollment
(
id
)
return
}
...
...
@@ -424,3 +393,57 @@ func (session *session) managerSession() {
})
return
}
// Session lifetime functions
func
handlePanic
(
callback
func
(
*
SessionError
))
{
if
e
:=
recover
();
e
!=
nil
{
var
info
string
switch
x
:=
e
.
(
type
)
{
case
string
:
info
=
x
case
error
:
info
=
x
.
Error
()
case
fmt
.
Stringer
:
info
=
x
.
String
()
default
:
// nop
}
fmt
.
Printf
(
"Recovered from panic: '%v'
\n
%s
\n
"
,
e
,
info
)
if
callback
!=
nil
{
callback
(
&
SessionError
{
ErrorType
:
ErrorPanic
,
Info
:
info
})
}
}
}
// Idempotently send DELETE to remote server, returning whether or not we did something
func
(
session
*
session
)
delete
()
bool
{
if
!
session
.
deleted
{
session
.
transport
.
Delete
()
session
.
deleted
=
true
return
true
}
return
false
}
func
(
session
*
session
)
fail
(
err
*
SessionError
)
{
if
session
.
delete
()
{
err
.
Err
=
errors
.
Wrap
(
err
.
Err
,
0
)
if
session
.
downloaded
!=
nil
&&
!
session
.
downloaded
.
Empty
()
{
session
.
credManager
.
handler
.
UpdateConfigurationStore
(
session
.
downloaded
)
}
session
.
Handler
.
Failure
(
session
.
Action
,
err
)
}
}
func
(
session
*
session
)
cancel
()
{
if
session
.
delete
()
{
if
session
.
downloaded
!=
nil
&&
!
session
.
downloaded
.
Empty
()
{
session
.
credManager
.
handler
.
UpdateConfigurationStore
(
session
.
downloaded
)
}
session
.
Handler
.
Cancelled
(
session
.
Action
)
}
}
func
(
session
*
session
)
Dismiss
()
{
session
.
cancel
()
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment