MFA fix, added IP blacklist, update webmail client
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package webui
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/ProtonMail/go-crypto/openpgp"
|
||||
)
|
||||
|
||||
// pgpKeyCache holds unlocked PGP identities for the rest of a login session —
|
||||
// mirrors smimeKeyCache (webmail_smime_cache.go), but caches the whole *openpgp.Entity
|
||||
// (not just a raw private key) since decrypting a PGP message needs subkey lookup on
|
||||
// the entity itself, not a bare key value. Kept as its own type rather than
|
||||
// generalizing smimeKeyCache into an any-typed cache — both stay simply and
|
||||
// correctly typed.
|
||||
type pgpKeyCache struct {
|
||||
mu sync.Mutex
|
||||
byTok map[string]map[int64]*openpgp.Entity
|
||||
}
|
||||
|
||||
func newPGPKeyCache() *pgpKeyCache {
|
||||
return &pgpKeyCache{byTok: map[string]map[int64]*openpgp.Entity{}}
|
||||
}
|
||||
|
||||
func (c *pgpKeyCache) get(token string, identityID int64) (*openpgp.Entity, bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
keys, ok := c.byTok[token]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
entity, ok := keys[identityID]
|
||||
return entity, ok
|
||||
}
|
||||
|
||||
func (c *pgpKeyCache) put(token string, identityID int64, entity *openpgp.Entity) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.byTok[token] == nil {
|
||||
c.byTok[token] = map[int64]*openpgp.Entity{}
|
||||
}
|
||||
c.byTok[token][identityID] = entity
|
||||
}
|
||||
|
||||
// clearSession drops every unlocked identity for one session — called on logout so
|
||||
// a key never outlives the session it was unlocked in. Same ponytail-flagged
|
||||
// simplification as smimeKeyCache.clearSession: memory-bounded by active sessions,
|
||||
// not TTL'd against a session that expires without an explicit logout.
|
||||
func (c *pgpKeyCache) clearSession(token string) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
delete(c.byTok, token)
|
||||
}
|
||||
|
||||
// sessionToken reads the raw webmail session cookie value, used as the PGP key
|
||||
// cache's key — separate from mailboxFromContext, which only exposes the resolved
|
||||
// *db.Mailbox, not the token itself.
|
||||
func sessionToken(r *http.Request) string {
|
||||
c, err := r.Cookie(mailboxSessionCookieName)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return c.Value
|
||||
}
|
||||
Reference in New Issue
Block a user