예제 #1
0
// 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
}
예제 #2
0
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

}