@@ -9,41 +9,52 @@ import (
9
9
10
10
"github.com/hairyhenderson/gomplate/v3"
11
11
"github.com/hairyhenderson/gomplate/v3/data"
12
+ log "github.com/sirupsen/logrus"
12
13
"golang.org/x/crypto/ssh"
13
- "golang.org/x/exp/slices"
14
14
)
15
15
16
16
// importing Default Config template at compile time
17
17
//
18
18
//go:embed ssh_keys.go.tpl
19
19
var SROSSSHKeysTemplate string
20
20
21
- // filterSSHPubKeys returns marshalled SSH keys that match either of the
22
- // provided key algorithms.
21
+ // filterSSHPubKeys returns rsa and ecdsa keys from the list of ssh keys stored at s.sshPubKeys.
23
22
// Since SR OS supports only certain key types, we need to filter out the rest.
24
- func (s * vrSROS ) filterSSHPubKeys (sshKeyAlgos []string ) []string {
25
- keyValues := make ([]string , 0 , len (s .sshPubKeys ))
23
+ func (s * vrSROS ) filterSSHPubKeys (supportedSSHKeyAlgos map [string ]struct {}) (rsaKeys []string , ecdsaKeys []string ) {
24
+ rsaKeys = make ([]string , 0 , len (s .sshPubKeys ))
25
+ ecdsaKeys = make ([]string , 0 , len (s .sshPubKeys ))
26
26
27
27
for _ , k := range s .sshPubKeys {
28
- if slices .Contains (sshKeyAlgos , k .Type ()) {
29
-
30
- keyType := k .Type ()
31
- keyString := string (ssh .MarshalAuthorizedKey (k ))
32
-
33
- // Remove the key type prefix
34
- keyString = strings .TrimPrefix (keyString , keyType + " " )
28
+ if _ , ok := supportedSSHKeyAlgos [k .Type ()]; ! ok {
29
+ log .Debugf ("unsupported SSH Key Algo %q, skipping key" , k .Type ())
30
+ continue
31
+ }
35
32
36
- // Remove the suffix (usually a comment or username)
37
- parts := strings .Fields (keyString )
38
- if len (parts ) > 1 {
39
- keyString = parts [0 ]
40
- }
33
+ // extract the fields
34
+ // <keytype> <key> <comment>
35
+ keyFields := strings .Fields (string (ssh .MarshalAuthorizedKey (k )))
41
36
42
- keyValues = append (keyValues , keyString )
37
+ switch {
38
+ case isRSAKey (k ):
39
+ rsaKeys = append (rsaKeys , keyFields [1 ])
40
+ case isECDSAKey (k ):
41
+ ecdsaKeys = append (ecdsaKeys , keyFields [1 ])
43
42
}
44
43
}
45
44
46
- return keyValues
45
+ return rsaKeys , ecdsaKeys
46
+ }
47
+
48
+ func isRSAKey (key ssh.PublicKey ) bool {
49
+ return key .Type () == ssh .KeyAlgoRSA
50
+ }
51
+
52
+ func isECDSAKey (key ssh.PublicKey ) bool {
53
+ kType := key .Type ()
54
+
55
+ return kType == ssh .KeyAlgoECDSA521 ||
56
+ kType == ssh .KeyAlgoECDSA384 ||
57
+ kType == ssh .KeyAlgoECDSA256
47
58
}
48
59
49
60
// SROSTemplateData holds ssh keys for template generation.
@@ -59,13 +70,15 @@ func (s *vrSROS) configureSSHPublicKeys(
59
70
username , password string , pubKeys []ssh.PublicKey ) error {
60
71
tplData := SROSTemplateData {}
61
72
62
- // creating a list of ECDSA Key Types
63
- rsaKeyTypes := []string {"ssh-rsa" }
64
- ecdsaKeyTypes := []string {"ssh-ed25519" , "ecdsa-sha2-nistp256" , "ecdsa-sha2-nistp384" , "ecdsa-sha2-nistp521" }
73
+ // a map of supported SSH key algorithms
74
+ supportedSSHKeyAlgos := map [string ]struct {}{
75
+ ssh .KeyAlgoRSA : {},
76
+ ssh .KeyAlgoECDSA521 : {},
77
+ ssh .KeyAlgoECDSA384 : {},
78
+ ssh .KeyAlgoECDSA256 : {},
79
+ }
65
80
66
- // checking on existence of SSH Public Keys and populating tplData
67
- tplData .SSHPubKeysRSA = s .filterSSHPubKeys (rsaKeyTypes )
68
- tplData .SSHPubKeysECDSA = s .filterSSHPubKeys (ecdsaKeyTypes )
81
+ tplData .SSHPubKeysRSA , tplData .SSHPubKeysECDSA = s .filterSSHPubKeys (supportedSSHKeyAlgos )
69
82
70
83
t , err := template .New ("SSHKeys" ).Funcs (
71
84
gomplate .CreateFuncs (context .Background (), new (data.Data ))).Parse (SROSSSHKeysTemplate )
0 commit comments