package utils import ( "fmt" "os/exec" "regexp" "strconv" "strings" "time" "github.com/Masterminds/semver" ) // GetSshVer returns an SshVerInfo. If verStr is an empty string, get the version automatically. func GetSshVer(verStr string) (ver SshVerInfo, err error) { var newVerStr string var sslVer OpenSslInfo var sslVerStr string var ptrn *regexp.Regexp var matches []string var verSlice [3]uint var n int var sver *semver.Version if verStr == "" { var out []byte cmd := exec.Command("ssh", "-V") if err = cmd.Run(); err != nil { return } if out, err = cmd.Output(); err != nil { return } verStr = string(out) } if ptrn, err = regexp.Compile(`^(?:Open|Sun_)SSH_(?P[0-9.]+)(?:p?(?P[0-9.]+))?,\s*(?P.*)?$`); err != nil { return } matches = ptrn.FindStringSubmatch(verStr) // Reformat verStr to the combined version string. newVerStr = fmt.Sprintf( "%v.%v", matches[ptrn.SubexpIndex("sshver")], matches[ptrn.SubexpIndex("patchver")], ) sslVerStr = matches[ptrn.SubexpIndex("sslverstr")] if sslVer, err = GetSslVer(sslVerStr); err != nil { return } for idx, s := range strings.Split(newVerStr, ".") { if n, err = strconv.Atoi(s); err != nil { return } verSlice[idx] = uint(n) } if sver, err = semver.NewVersion(newVerStr); err != nil { return } ver = SshVerInfo{ Major: verSlice[0], Minor: verSlice[1], Patch: verSlice[2], Raw: verStr, SslInfo: sslVer, SemVer: *sver, } return } // GetSslVer returns an OpenSslInfo. If verStr is an empty string, get the version automatically. func GetSslVer(verStr string) (ver OpenSslInfo, err error) { var matches []string var verSlice [3]uint var newVerStr string var ptrn *regexp.Regexp var sver *semver.Version // TODO: confirm the day is zero-padded. var tfmt string = `02 Jan 2006` var n int var t time.Time if verStr == "" { var out []byte cmd := exec.Command("openssl", "version") if err = cmd.Run(); err != nil { return } if out, err = cmd.Output(); err != nil { return } verStr = string(out) } if ptrn, err = regexp.Compile(`^(?:Open|Sun_)SSL\s+(FIPS\s+)?(?P[0-9.]+)(?P[A-Za-z]+)?\s+(?P