mirror of
https://github.com/jech/galene.git
synced 2024-12-22 23:35:46 +01:00
515c4a5cd0
Also allow selecting just a single connection.
107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
package group
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"errors"
|
|
"hash"
|
|
|
|
"golang.org/x/crypto/pbkdf2"
|
|
|
|
"github.com/jech/galene/conn"
|
|
)
|
|
|
|
type RawPassword struct {
|
|
Type string `json:"type,omitempty"`
|
|
Hash string `json:"hash,omitempty"`
|
|
Key string `json:"key"`
|
|
Salt string `json:"salt,omitempty"`
|
|
Iterations int `json:"iterations,omitempty"`
|
|
}
|
|
|
|
type Password RawPassword
|
|
|
|
func (p Password) Match(pw string) (bool, error) {
|
|
switch p.Type {
|
|
case "":
|
|
return p.Key == pw, nil
|
|
case "pbkdf2":
|
|
key, err := hex.DecodeString(p.Key)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
salt, err := hex.DecodeString(p.Salt)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
var h func() hash.Hash
|
|
switch p.Hash {
|
|
case "sha-256":
|
|
h = sha256.New
|
|
default:
|
|
return false, errors.New("unknown hash type")
|
|
}
|
|
theirKey := pbkdf2.Key(
|
|
[]byte(pw), salt, p.Iterations, len(key), h,
|
|
)
|
|
return bytes.Compare(key, theirKey) == 0, nil
|
|
default:
|
|
return false, errors.New("unknown password type")
|
|
}
|
|
}
|
|
|
|
func (p *Password) UnmarshalJSON(b []byte) error {
|
|
var k string
|
|
err := json.Unmarshal(b, &k)
|
|
if err == nil {
|
|
*p = Password{
|
|
Key: k,
|
|
}
|
|
return nil
|
|
}
|
|
var r RawPassword
|
|
err = json.Unmarshal(b, &r)
|
|
if err == nil {
|
|
*p = Password(r)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (p Password) MarshalJSON() ([]byte, error) {
|
|
if p.Type == "" && p.Hash == "" && p.Salt == "" && p.Iterations == 0 {
|
|
return json.Marshal(p.Key)
|
|
}
|
|
return json.Marshal(RawPassword(p))
|
|
}
|
|
|
|
type ClientCredentials struct {
|
|
Username string `json:"username,omitempty"`
|
|
Password *Password `json:"password,omitempty"`
|
|
}
|
|
|
|
type ClientPermissions struct {
|
|
Op bool `json:"op,omitempty"`
|
|
Present bool `json:"present,omitempty"`
|
|
Record bool `json:"record,omitempty"`
|
|
}
|
|
|
|
type Challengeable interface {
|
|
Username() string
|
|
Challenge(string, ClientCredentials) bool
|
|
}
|
|
|
|
type Client interface {
|
|
Group() *Group
|
|
Id() string
|
|
Challengeable
|
|
Permissions() ClientPermissions
|
|
SetPermissions(ClientPermissions)
|
|
Status() map[string]interface{}
|
|
OverridePermissions(*Group) bool
|
|
PushConn(g *Group, id string, conn conn.Up, tracks []conn.UpTrack, replace string) error
|
|
RequestConns(target Client, g *Group, id string) error
|
|
PushClient(id, username string, permissions *ClientPermissions, status map[string]interface{}, kind string) error
|
|
Kick(id, user, message string) error
|
|
}
|