mirror of
https://github.com/Luzifer/cloudkeys-go.git
synced 2024-11-14 00:42:44 +00:00
Knut Ahlers
a1df72edc5
commitf0db1ff1f8
Author: Knut Ahlers <knut@ahlers.me> Date: Sun Dec 24 12:19:56 2017 +0100 Mark option as deprecated Signed-off-by: Knut Ahlers <knut@ahlers.me> commit9891df2a16
Author: Knut Ahlers <knut@ahlers.me> Date: Sun Dec 24 12:11:56 2017 +0100 Fix: Typo Signed-off-by: Knut Ahlers <knut@ahlers.me> commit836006de64
Author: Knut Ahlers <knut@ahlers.me> Date: Sun Dec 24 12:04:20 2017 +0100 Add new dependencies Signed-off-by: Knut Ahlers <knut@ahlers.me> commitd64fee60c8
Author: Knut Ahlers <knut@ahlers.me> Date: Sun Dec 24 11:55:52 2017 +0100 Replace insecure password hashing Prior this commit passwords were hashed with a static salt and using the SHA1 hashing function. This could lead to passwords being attackable in case someone gets access to the raw data stored inside the database. This commit introduces password hashing using bcrypt hashing function which addresses this issue. Old passwords are not automatically re-hashed as they are unknown. Replacing the old password scheme is not that easy and needs #10 to be solved. Therefore the old hashing scheme is kept for compatibility reason. Signed-off-by: Knut Ahlers <knut@ahlers.me> Signed-off-by: Knut Ahlers <knut@ahlers.me> closes #14 closes #15
160 lines
3.4 KiB
Go
160 lines
3.4 KiB
Go
// Copyright 2011 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package packet
|
|
|
|
import (
|
|
"io"
|
|
"io/ioutil"
|
|
"strings"
|
|
)
|
|
|
|
// UserId contains text that is intended to represent the name and email
|
|
// address of the key holder. See RFC 4880, section 5.11. By convention, this
|
|
// takes the form "Full Name (Comment) <email@example.com>"
|
|
type UserId struct {
|
|
Id string // By convention, this takes the form "Full Name (Comment) <email@example.com>" which is split out in the fields below.
|
|
|
|
Name, Comment, Email string
|
|
}
|
|
|
|
func hasInvalidCharacters(s string) bool {
|
|
for _, c := range s {
|
|
switch c {
|
|
case '(', ')', '<', '>', 0:
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// NewUserId returns a UserId or nil if any of the arguments contain invalid
|
|
// characters. The invalid characters are '\x00', '(', ')', '<' and '>'
|
|
func NewUserId(name, comment, email string) *UserId {
|
|
// RFC 4880 doesn't deal with the structure of userid strings; the
|
|
// name, comment and email form is just a convention. However, there's
|
|
// no convention about escaping the metacharacters and GPG just refuses
|
|
// to create user ids where, say, the name contains a '('. We mirror
|
|
// this behaviour.
|
|
|
|
if hasInvalidCharacters(name) || hasInvalidCharacters(comment) || hasInvalidCharacters(email) {
|
|
return nil
|
|
}
|
|
|
|
uid := new(UserId)
|
|
uid.Name, uid.Comment, uid.Email = name, comment, email
|
|
uid.Id = name
|
|
if len(comment) > 0 {
|
|
if len(uid.Id) > 0 {
|
|
uid.Id += " "
|
|
}
|
|
uid.Id += "("
|
|
uid.Id += comment
|
|
uid.Id += ")"
|
|
}
|
|
if len(email) > 0 {
|
|
if len(uid.Id) > 0 {
|
|
uid.Id += " "
|
|
}
|
|
uid.Id += "<"
|
|
uid.Id += email
|
|
uid.Id += ">"
|
|
}
|
|
return uid
|
|
}
|
|
|
|
func (uid *UserId) parse(r io.Reader) (err error) {
|
|
// RFC 4880, section 5.11
|
|
b, err := ioutil.ReadAll(r)
|
|
if err != nil {
|
|
return
|
|
}
|
|
uid.Id = string(b)
|
|
uid.Name, uid.Comment, uid.Email = parseUserId(uid.Id)
|
|
return
|
|
}
|
|
|
|
// Serialize marshals uid to w in the form of an OpenPGP packet, including
|
|
// header.
|
|
func (uid *UserId) Serialize(w io.Writer) error {
|
|
err := serializeHeader(w, packetTypeUserId, len(uid.Id))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = w.Write([]byte(uid.Id))
|
|
return err
|
|
}
|
|
|
|
// parseUserId extracts the name, comment and email from a user id string that
|
|
// is formatted as "Full Name (Comment) <email@example.com>".
|
|
func parseUserId(id string) (name, comment, email string) {
|
|
var n, c, e struct {
|
|
start, end int
|
|
}
|
|
var state int
|
|
|
|
for offset, rune := range id {
|
|
switch state {
|
|
case 0:
|
|
// Entering name
|
|
n.start = offset
|
|
state = 1
|
|
fallthrough
|
|
case 1:
|
|
// In name
|
|
if rune == '(' {
|
|
state = 2
|
|
n.end = offset
|
|
} else if rune == '<' {
|
|
state = 5
|
|
n.end = offset
|
|
}
|
|
case 2:
|
|
// Entering comment
|
|
c.start = offset
|
|
state = 3
|
|
fallthrough
|
|
case 3:
|
|
// In comment
|
|
if rune == ')' {
|
|
state = 4
|
|
c.end = offset
|
|
}
|
|
case 4:
|
|
// Between comment and email
|
|
if rune == '<' {
|
|
state = 5
|
|
}
|
|
case 5:
|
|
// Entering email
|
|
e.start = offset
|
|
state = 6
|
|
fallthrough
|
|
case 6:
|
|
// In email
|
|
if rune == '>' {
|
|
state = 7
|
|
e.end = offset
|
|
}
|
|
default:
|
|
// After email
|
|
}
|
|
}
|
|
switch state {
|
|
case 1:
|
|
// ended in the name
|
|
n.end = len(id)
|
|
case 3:
|
|
// ended in comment
|
|
c.end = len(id)
|
|
case 6:
|
|
// ended in email
|
|
e.end = len(id)
|
|
}
|
|
|
|
name = strings.TrimSpace(id[n.start:n.end])
|
|
comment = strings.TrimSpace(id[c.start:c.end])
|
|
email = strings.TrimSpace(id[e.start:e.end])
|
|
return
|
|
}
|