Skip to content

Instantly share code, notes, and snippets.

@syossan27
Last active December 22, 2018 08:39
Show Gist options
  • Save syossan27/036a2a7e7ccb33d8bb0af0057455fd20 to your computer and use it in GitHub Desktop.
Save syossan27/036a2a7e7ccb33d8bb0af0057455fd20 to your computer and use it in GitHub Desktop.
func (c *Connection) Connect() {
// 接続情報を用いてセッションの確立
session, err := connect(c.User, c.Password, c.Host, 22)
if err != nil {
foundation.PrintError("Failed to connect.\nReason: " + err.Error())
}
defer session.Close()
// SSH擬似端末をrawモードで立ち上げる
fd := int(os.Stdin.Fd())
oldState, err := terminal.MakeRaw(fd)
if err != nil {
foundation.PrintError("Failed to put the terminal into raw mode")
}
defer terminal.Restore(fd, oldState)
// セッションの出入力先を標準出入力に設定
session.Stdout = os.Stdout
session.Stderr = os.Stderr
session.Stdin = os.Stdin
// 現在のターミナルサイズに合わせて、SSH擬似端末のサイズを変更
termWidth, termHeight, err := terminal.GetSize(fd)
if err != nil {
foundation.PrintError("Failed to get terminal size")
}
// Terminal Modeの設定
// Terminal ModeについてはRFC4254のセクション8参照
// 今回は端末エコーバックON https://qiita.com/angel_p_57/items/ff1c0d054714b7982ca5
// I/Oのbaud rateを14.4kbps https://www.ietf.org/rfc/rfc4254.txt
modes := ssh.TerminalModes{
ssh.ECHO: 1,
ssh.TTY_OP_ISPEED: 14400,
ssh.TTY_OP_OSPEED: 14400,
}
// SSHセッションとSSH擬似端末を関連付ける
if err := session.RequestPty("xterm-256color", termHeight, termWidth, modes); err != nil {
foundation.PrintError("Failed to requests the association of a pty with the session")
}
// リモートホスト上でのログインシェルの起動
err = session.Shell()
if err != nil {
foundation.PrintError("Failed to login shell")
}
// コマンドの待ち受け
err = session.Wait()
if err != nil {
// 端末の復元
terminal.Restore(fd, oldState)
foundation.PrintError("Failed to command completes successfully")
}
}
func connect(user, password, host string, port int) (*ssh.Session, error) {
var (
auth []ssh.AuthMethod
addr string
clientConfig *ssh.ClientConfig
client *ssh.Client
session *ssh.Session
err error
)
// 認証に使うパスワードを設定
auth = make([]ssh.AuthMethod, 0)
auth = append(auth, ssh.Password(password))
// SSHクライアント設定
clientConfig = &ssh.ClientConfig{
User: user,
Auth: auth,
Timeout: 30 * time.Second,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
// セッションの確立
addr = fmt.Sprintf("%s:%d", host, port)
if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
return nil, err
}
if session, err = client.NewSession(); err != nil {
return nil, err
}
return session, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment