func credentialsCallback(url string, username string, allowedTypes git.CredType) (git.ErrorCode, *git.Cred) { u, err := user.Current() if err != nil { log.Fatal(err) } uname := "git" publickey := path.Join(u.HomeDir, ".ssh/id_rsa.pub") privatekey := path.Join(u.HomeDir, ".ssh/id_rsa") passphrase := "" ret, cred := git.NewCredSshKey(uname, publickey, privatekey, passphrase) return git.ErrorCode(ret), &cred }
// makeRemoteCallbacks constructs the remote callbacks for libgit2 // remote operations. Currently the remote callbacks are trivial // (empty) except when using an SSH remote. // // cleanupFuncs's run method should be called when the RemoteCallbacks // struct is done being used. It is OK to ignore the error return. func makeRemoteCallbacks(url string, opt vcs.RemoteOpts) (rc *git2go.RemoteCallbacks, cfs cleanupFuncs, err error) { defer func() { // Clean up if error; don't expect the caller to clean up if // we have a non-nil error. if err != nil { cfs.run() } }() if opt.SSH != nil { var privkeyFilename, pubkeyFilename string var privkeyFile, pubkeyFile *os.File var err error if opt.SSH.PrivateKey != nil { privkeyFilename, privkeyFile, err = util.WriteKeyTempFile(url, opt.SSH.PrivateKey) if err != nil { return nil, nil, err } cfs = append(cfs, privkeyFile.Close) cfs = append(cfs, func() error { return os.Remove(privkeyFile.Name()) }) // Derive public key from private key if empty. if opt.SSH.PublicKey == nil { privKey, err := ssh.ParsePrivateKey(opt.SSH.PrivateKey) if err != nil { return nil, cfs, err } opt.SSH.PublicKey = ssh.MarshalAuthorizedKey(privKey.PublicKey()) } pubkeyFilename, pubkeyFile, err = util.WriteKeyTempFile(url, opt.SSH.PublicKey) if err != nil { return nil, cfs, err } cfs = append(cfs, pubkeyFile.Close) cfs = append(cfs, func() error { return os.Remove(pubkeyFile.Name()) }) } rc = &git2go.RemoteCallbacks{ CredentialsCallback: git2go.CredentialsCallback(func(url string, usernameFromURL string, allowedTypes git2go.CredType) (git2go.ErrorCode, *git2go.Cred) { var username string if usernameFromURL != "" { username = usernameFromURL } else if opt.SSH.User != "" { username = opt.SSH.User } else { if username == "" { u, err := user.Current() if err == nil { username = u.Username } } } if allowedTypes&git2go.CredTypeSshKey != 0 && opt.SSH.PrivateKey != nil { rv, cred := git2go.NewCredSshKey(username, pubkeyFilename, privkeyFilename, "") return git2go.ErrorCode(rv), &cred } log.Printf("No authentication available for git URL %q.", url) rv, cred := git2go.NewCredDefault() return git2go.ErrorCode(rv), &cred }), CertificateCheckCallback: git2go.CertificateCheckCallback(func(cert *git2go.Certificate, valid bool, hostname string) git2go.ErrorCode { // libgit2 currently always returns valid=false. It // may return valid=true in the future if it checks // host keys using known_hosts, but let's ignore valid // so we don't get that behavior unexpectedly. if InsecureSkipCheckVerifySSH { return git2go.ErrOk } if cert == nil { return git2go.ErrNotFound } if cert.Hostkey.Kind&git2go.HostkeyMD5 > 0 { keys, found := standardKnownHosts.Lookup(hostname) if found { hostFingerprint := md5String(cert.Hostkey.HashMD5) for _, key := range keys { knownFingerprint := md5String(md5.Sum(key.Marshal())) if hostFingerprint == knownFingerprint { return git2go.ErrOk } } } } log.Printf("Invalid certificate for SSH host %s: %v.", hostname, cert) return git2go.ErrGeneric }), } } return rc, cfs, nil }
func credentialsCallback(url string, username string, allowedTypes git.CredType) (git.ErrorCode, *git.Cred) { ret, cred := git.NewCredSshKey("git", "/Users/realbot/.ssh/id_rsa.pub", "/Users/realbot/.ssh/id_rsa", "") return git.ErrorCode(ret), &cred }
// LibgitCred returns a git2go *Cred struct, which is used for remote // operations over ssh. func (c *Credentials) LibgitCred() (git.ErrorCode, *git.Cred) { returnCode, credentials := git.NewCredSshKey(c.Username, c.Publickey, c.Privatekey, c.Passphrase) return git.ErrorCode(returnCode), &credentials }