// Convert simplified credentials into something useful for the ssh package func get_auth(creds *Creds) ([]ssh.AuthMethod, error) { auth := []ssh.AuthMethod{} // Passwords. This isn't enough for a typical SSH server (which will usually // be configured for KeyboardInteractive, not Password) but fine for XR. if creds.Password != "" { auth = append(auth, ssh.Password(creds.Password)) } // Keys if creds.Keypathname != "" { buf, err := ioutil.ReadFile(creds.Keypathname) if err != nil { return nil, errors.New("Can't read private key file: " + err.Error()) } key, err := ssh.ParsePrivateKey(buf) if err != nil { return nil, errors.New("Can't parse private key: " + err.Error()) } auth = append(auth, ssh.PublicKeys(key)) } return auth, nil }
func (s *SftpSession) initSftpSession() error { var err error s.fileregexp, err = regexp.Compile(s.section.MatchRegExp) if err != nil { return err } if s.section.LogFile != "" { err = s.setLog(s.section.LogFile) if err != nil { return err } } // initialise good/bad slices - capacity 128 by default s.Good = make([]string, 0, 128) s.Bad = make([]FileError, 0, 128) // set ssh auth methods var auths []ssh.AuthMethod if aconn, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil { auths = append(auths, ssh.PublicKeysCallback(agent.NewClient(aconn).Signers)) } // if key is set, add to allowed auths if s.section.Key != "" { err := s.getKeyFile(s.section.Key) if err != nil { return fmt.Errorf("error : cannot read ssh key file %s, %s", s.section.Key, err) } else { //auths = append(auths, ssh.PublicKeys(s.sshkeychain)) //auths = append(auths, ssh.PublicKeys(s.sshkey)) auths = []ssh.AuthMethod{ssh.PublicKeys(s.sshkey)} } } // add a password if set if s.section.Password != "" { auths = append(auths, ssh.Password(s.section.Password)) } // configure ssh sshCommonConfig := ssh.Config{} if s.section.InsecureCiphers { sshCommonConfig = ssh.Config{Ciphers: ssh.AllSupportedCiphers()} if debug { log.Printf("DEBUG insecureciphers is set : using weaker ciphers.\n") } } sshCommonConfig.SetDefaults() s.sshConfig = ssh.ClientConfig{ User: s.section.Username, Auth: auths, Config: sshCommonConfig, } // test for local directory if _, err := os.Stat(s.section.LocalDir); err != nil { if os.IsNotExist(err) { // file does not exist return fmt.Errorf("error : local directory does not exist : %s", s.section.LocalDir) } } if archive { // test for archive directory if _, err := os.Stat(s.section.ArchiveDir); err != nil { if os.IsNotExist(err) { // file does not exist return fmt.Errorf("error : archive directory does not exist : %s", s.section.ArchiveDir) } } } // grab lock directory if debug { log.Printf("DEBUG mklockdir: %s\n", s.section.LockDir) } err = os.Mkdir(s.section.LockDir, 0700) if err != nil { return fmt.Errorf("mkLockDir error : %s", err) } // check pgp gumpf if s.section.Encrypt { s.Ecryptregexp, err = regexp.Compile(s.section.EncryptRegExp) if err != nil { return err } // open public keyring kr, err := os.Open(s.section.PublicKeyRing) if err != nil { return fmt.Errorf("open public keyring error: %s\n", err.Error()) } defer kr.Close() // read public keyring eList, err := openpgp.ReadKeyRing(kr) if err != nil { return fmt.Errorf("read public keyring error: %s\n", err.Error()) } // look for public key s.encryptEntity = s.getKeyByIdShortString(eList, s.section.EncryptKeyId) if s.encryptEntity == nil { return fmt.Errorf("cannot find encryption key with ID : %s\n", s.section.EncryptKeyId) } } if s.section.Decrypt { s.entityList = make([]*openpgp.Entity, 0, 50) s.Dcryptregexp, err = regexp.Compile(s.section.DecryptRegExp) if err != nil { return err } // Open the private key file kr, err := os.Open(s.section.PrivateKeyRing) if err != nil { return err } defer kr.Close() s.entityList, err = openpgp.ReadKeyRing(kr) if err != nil { return err } dcryptkidlen := len(s.section.DecryptKeyId) dcryptpplen := len(s.section.DecryptPassphrase) if debug { krlen := len(s.entityList) log.Printf("keyring count: %d\n", krlen) for i := range s.entityList { kid := s.entityList[i].PrimaryKey.KeyIdShortString() log.Printf("read key string %d : %s\n", i, kid) } } s.decryptEntity = make([]*openpgp.Entity, dcryptkidlen, dcryptkidlen) if dcryptkidlen != dcryptpplen { return fmt.Errorf("you must provide the same number of decryption key ids and decryption key passphrases.\ncheck your config file.\n") } for i := range s.section.DecryptKeyId { s.decryptEntity[i] = s.getKeyByIdShortString(s.entityList, s.section.DecryptKeyId[i]) if s.decryptEntity[i] == nil { return fmt.Errorf("cannot find decryption key with ID : %s\n", s.section.DecryptKeyId[i]) } // Get the passphrase and read the private key. passphrase := []byte(s.section.DecryptPassphrase[i]) s.decryptEntity[i].PrivateKey.Decrypt(passphrase) for _, subkey := range s.decryptEntity[i].Subkeys { err := subkey.PrivateKey.Decrypt(passphrase) if err != nil { log.Printf("warning: cannot decrypt key %s, incorrect passphrase?\n", s.section.DecryptKeyId[i]) } } } } return nil }