// // tank // // Import and Playlist Daemon for autoradio project // // // Copyright (C) 2017-2019 Christian Pointner <equinox@helsinki.at> // // This file is part of tank. // // tank is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // tank is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with tank. If not, see <http://www.gnu.org/licenses/>. // package auth import ( "crypto/sha256" "errors" "math" "time" "github.com/gorilla/securecookie" "golang.org/x/crypto/hkdf" ) const ( hkdfInfo = "aura-tank-session-keys" defaultAge = 24 * time.Hour ) type Session struct { sealer *securecookie.SecureCookie Expires time.Time Username string AllGroups bool Groups []string } func (s *Session) Seal() ([]byte, error) { return nil, errors.New("not yet implemented") } func (s *Session) Unseal([]byte) error { return errors.New("not yet implemented") } func (s *Session) Expired() bool { return s.Expires.Before(time.Now()) } type SessionManager struct { sealer *securecookie.SecureCookie maxAge time.Duration } func NewSessionManager(cfg SessionsConfig) (sm *SessionManager, err error) { var hashKey, blockKey []byte if cfg.Secret == "" { // TODO: make key size dependent on algo hashKey = securecookie.GenerateRandomKey(32) blockKey = securecookie.GenerateRandomKey(32) if hashKey == nil || blockKey == nil { return nil, errors.New("failed to generate random key") } } else { kdf := hkdf.New(sha256.New, []byte(cfg.Secret), nil, []byte(hkdfInfo)) // TODO: make key size dependent on algo hashKey = make([]byte, 32) if _, err = kdf.Read(hashKey); err != nil { return nil, errors.New("failed to derive session auth key: " + err.Error()) } // TODO: make key size dependent on algo blockKey = make([]byte, 32) if _, err = kdf.Read(blockKey); err != nil { return nil, errors.New("failed to derive session auth key: " + err.Error()) } } sm = &SessionManager{maxAge: defaultAge} if cfg.MaxAge > 0 { sm.maxAge = cfg.MaxAge } sm.sealer = securecookie.New(hashKey, blockKey) sm.sealer.MaxAge(int(math.Ceil(cfg.MaxAge.Seconds()))) return sm, nil } func (sm *SessionManager) NewSession() *Session { return &Session{sealer: sm.sealer, Expires: time.Now().Add(sm.maxAge)} }