diff options
author | Unknwon <u@gogs.io> | 2016-01-15 18:39:51 +0800 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2016-01-15 18:39:51 +0800 |
commit | 7ef9a055886574655d9f2be70c957bc16bf30500 (patch) | |
tree | 0f3d46f2d09e16bae1625e6be719773557e23893 /models | |
parent | c631a4a9b988e63bd8b07dfdeee1f1d4b3ad7d45 (diff) | |
download | gitea-7ef9a055886574655d9f2be70c957bc16bf30500.tar.gz gitea-7ef9a055886574655d9f2be70c957bc16bf30500.zip |
#2179 use Go sub-repo ssh to verify public key content
Diffstat (limited to 'models')
-rw-r--r-- | models/ssh_key.go | 47 |
1 files changed, 10 insertions, 37 deletions
diff --git a/models/ssh_key.go b/models/ssh_key.go index f0db4de430..a7b1680f67 100644 --- a/models/ssh_key.go +++ b/models/ssh_key.go @@ -21,6 +21,7 @@ import ( "github.com/Unknwon/com" "github.com/go-xorm/xorm" + "golang.org/x/crypto/ssh" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/process" @@ -164,48 +165,20 @@ func CheckPublicKeyString(content string) (_ string, err error) { return "", errors.New("only a single line with a single key please") } - // write the key to a fileā¦ - tmpFile, err := ioutil.TempFile(os.TempDir(), "keytest") - if err != nil { - return "", err + fields := strings.Fields(content) + if len(fields) < 2 { + return "", errors.New("too less fields") } - tmpPath := tmpFile.Name() - defer os.Remove(tmpPath) - tmpFile.WriteString(content) - tmpFile.Close() - // Check if ssh-keygen recognizes its contents. - stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-lf", tmpPath) + key, err := base64.StdEncoding.DecodeString(fields[1]) if err != nil { - return "", errors.New("ssh-keygen -lf: " + stderr) - } else if len(stdout) < 2 { - return "", errors.New("ssh-keygen returned not enough output to evaluate the key: " + stdout) + return "", fmt.Errorf("StdEncoding.DecodeString: %v", err) } - - // The ssh-keygen in Windows does not print key type, so no need go further. - if setting.IsWindows { - return content, nil - } - - sshKeygenOutput := strings.Split(stdout, " ") - if len(sshKeygenOutput) < 4 { - return content, ErrKeyUnableVerify{stdout} - } - - // Check if key type and key size match. - if !setting.Service.DisableMinimumKeySizeCheck { - keySize := com.StrTo(sshKeygenOutput[0]).MustInt() - if keySize == 0 { - return "", errors.New("cannot get key size of the given key") - } - - keyType := strings.Trim(sshKeygenOutput[len(sshKeygenOutput)-1], " ()\n") - if minimumKeySize := setting.Service.MinimumKeySizes[keyType]; minimumKeySize == 0 { - return "", fmt.Errorf("unrecognized public key type: %s", keyType) - } else if keySize < minimumKeySize { - return "", fmt.Errorf("the minimum accepted size of a public key %s is %d", keyType, minimumKeySize) - } + pkey, err := ssh.ParsePublicKey([]byte(key)) + if err != nil { + return "", fmt.Errorf("ParsePublicKey: %v", err) } + log.Trace("Key type: %s", pkey.Type()) return content, nil } |