package hotline
import (
- "github.com/jhalter/mobius/concat"
+ "encoding/binary"
+ "golang.org/x/crypto/bcrypt"
+ "log"
)
const GuestAccount = "guest" // default account used when no login is provided for a connection
type Account struct {
- Login string `yaml:"Login"`
- Name string `yaml:"Name"`
- Password string `yaml:"Password"`
- Access *[]byte `yaml:"Access"` // 8 byte bitmap
+ Login string `yaml:"Login"`
+ Name string `yaml:"Name"`
+ Password string `yaml:"Password"`
+ Access accessBitmap `yaml:"Access"`
}
-// MarshalBinary marshals an Account to byte slice
-func (a *Account) MarshalBinary() (out []byte) {
- return concat.Slices(
- []byte{0x00, 0x3}, // param count -- always 3
- NewField(fieldUserName, []byte(a.Name)).Payload(),
- NewField(fieldUserLogin, negateString([]byte(a.Login))).Payload(),
- NewField(fieldUserAccess, *a.Access).Payload(),
- )
+// Read implements io.Reader interface for Account
+func (a *Account) Read(p []byte) (n int, err error) {
+ fields := []Field{
+ NewField(fieldUserName, []byte(a.Name)),
+ NewField(fieldUserLogin, negateString([]byte(a.Login))),
+ NewField(fieldUserAccess, a.Access[:]),
+ }
+
+ if bcrypt.CompareHashAndPassword([]byte(a.Password), []byte("")) != nil {
+ fields = append(fields, NewField(fieldUserPassword, []byte("x")))
+ }
+
+ fieldCount := make([]byte, 2)
+ binary.BigEndian.PutUint16(fieldCount, uint16(len(fields)))
+
+ p = append(p, fieldCount...)
+
+ for _, field := range fields {
+ p = append(p, field.Payload()...)
+ }
+
+ return len(p), nil
+}
+
+// hashAndSalt generates a password hash from a users obfuscated plaintext password
+func hashAndSalt(pwd []byte) string {
+ hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost)
+ if err != nil {
+ log.Println(err)
+ }
+
+ return string(hash)
}