-
Notifications
You must be signed in to change notification settings - Fork 16
/
ssh_key_parser.go
59 lines (53 loc) · 1.64 KB
/
ssh_key_parser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package metadata
import (
"encoding/json"
"errors"
"fmt"
"github.com/digitalocean/droplet-agent/internal/sysaccess"
"regexp"
"strings"
)
const (
osUserRegex = `-os_user=(\S+)`
)
// SSHKeyParser is used for parsing different type of SSH Keys from metadata
type SSHKeyParser struct {
pubKeyOSUserRegex *regexp.Regexp
}
// NewSSHKeyParser returns a new SSH Key parser
func NewSSHKeyParser() *SSHKeyParser {
return &SSHKeyParser{
pubKeyOSUserRegex: regexp.MustCompile(osUserRegex),
}
}
// FromPublicKey parses a string public key and attempts to convert it to a SSHKey object
func (p *SSHKeyParser) FromPublicKey(key string) (*sysaccess.SSHKey, error) {
ret := &sysaccess.SSHKey{
PublicKey: strings.Trim(key, " \t\r\n"),
Type: sysaccess.SSHKeyTypeDroplet,
}
match := p.pubKeyOSUserRegex.FindAllStringSubmatch(key, -1)
if len(match) != 0 {
// trying to find "-os_user" flag from the key
// if not presented, default user will be used
// if multiple os_user flags presented, the last one will be used because the backend service always append the
// os_user to the end of the key
lastIdx := len(match) - 1
if len(match[lastIdx]) != 2 {
// this should never happen, but just in case
return nil, errors.New("invalid os_user")
}
ret.OSUser = match[lastIdx][1]
}
return ret, nil
}
// FromDOTTYKey parses a string dotty key and converts it into a SSHKey object
func (p *SSHKeyParser) FromDOTTYKey(key string) (*sysaccess.SSHKey, error) {
ret := &sysaccess.SSHKey{
Type: sysaccess.SSHKeyTypeDOTTY,
}
if err := json.Unmarshal([]byte(key), ret); err != nil {
return nil, fmt.Errorf("%w:invalid key", err)
}
return ret, nil
}