trzsz/trzsz-ssh

An example of using tssh `as` a library

abakum opened this issue · 5 comments

Look https://github.com/abakum/dssh
If working with ssh certificates is necessary for the development of tssh, I can do PR

Which functions do you need to expose? Focusing on tssh as a program may help me reconstruct it in the future.

First of all type SshArgs

Next secretEncodeKey as SecretEncodeKey.
And I suggest modify getPasswordAuthMethod to

func getPasswordAuthMethod(args *SshArgs, host, user string) ssh.AuthMethod {
	if strings.ToLower(getOptionConfig(args, "PasswordAuthentication")) == "no" {
		debug("disable auth method: password authentication")
		return nil
	}

	idx := 0
	rememberPassword := false
	return ssh.RetryableAuthMethod(ssh.PasswordCallback(func() (string, error) {
		idx++
		if idx == 1 {
			password := args.Option.get("Password")
			if password == "" {
				password = getSecretConfig(args.Destination, "Password")
			} else {
				encoded, err := encodeSecret([]byte(password))
				if err == nil {
					warning("insert next line\r\nIgnoreUnknown *\r\nto the beginning of the file [~/.ssh/config] and append after [Host %s] next line\r\n encPassword %s", args.Destination, encoded)
				}
			}
			if password != "" {
				rememberPassword = true
				debug("trying the password configuration for '%s'", args.Destination)
				return password, nil
			}
		} else if idx == 2 && rememberPassword {
			warning("the password configuration for '%s' is incorrect", args.Destination)
		}
		secret, err := readSecret(fmt.Sprintf("%s@%s's password: ", user, host))
		if err != nil {
			return "", err
		}
		return string(secret), nil
	}), 3)
}

  • Option 1: Change func TsshMain() int to func TsshMain(argv []string) int. You can call it like tssh.TsshMain(os.Args[1:]), or set the ssh command line arguments yourself.
  • Option 2: Expose a new function func SshLogin(args *tssh.SshArgs) (tssh.SshClient, error). tssh.SshArgs is a subset of sshArgs, only a small part of it is exposed. tssh.SshClient is sshClient, you can call the client's NewSession method to create a new session, and then call the session's Start method to execute any command on the remote server.

Before v0.1.22 is released, you can go get github.com/trzsz/trzsz-ssh@main.

Example of using tssh as a library:

package main

import (
	"log"
	"os"

	"github.com/trzsz/trzsz-ssh/tssh"
)

func main() {
	// Example 1: execute command on remote server
	client, err := tssh.SshLogin(&tssh.SshArgs{Destination: "root@192.168.0.1"})
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()
	session, err := client.NewSession()
	if err != nil {
		log.Fatal(err)
	}
	defer session.Close()
	output, err := session.CombinedOutput("whoami")
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("I'm %s", string(output))

	// Example 2: run the tssh program
	code := tssh.TsshMain([]string{"-t", "root@192.168.0.1", "bash -l"})
	os.Exit(code)
}