--- /dev/null
+# $OpenBSD: sshd_config,v 1.102 2018/02/16 02:32:40 djm Exp $
+
+# This is the sshd server system-wide configuration file. See
+# sshd_config(5) for more information.
+
+# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/bin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented. Uncommented options override the
+# default value.
+
+#Port 22222
+#AddressFamily any
+#ListenAddress 0.0.0.0
+#ListenAddress ::
+
+#HostKey /tmp/sshtest/ssh_host_rsa_key
+#HostKey /tmp/sshtest/ssh_host_ecdsa_key
+#HostKey /tmp/sshtest/ssh_host_ed25519_key
+
+# Ciphers and keying
+#RekeyLimit default none
+
+# Logging
+#SyslogFacility AUTH
+#LogLevel INFO
+
+# Authentication:
+
+#LoginGraceTime 2m
+#PermitRootLogin prohibit-password
+StrictModes no
+#MaxAuthTries 6
+#MaxSessions 10
+
+PubkeyAuthentication yes
+
+# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
+# but this is overridden so installations will only check .ssh/authorized_keys
+#AuthorizedKeysFile /tmp/sshtest/authorized_keys
+
+#AuthorizedPrincipalsFile none
+
+#AuthorizedKeysCommand none
+#AuthorizedKeysCommandUser nobody
+
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# HostbasedAuthentication
+IgnoreUserKnownHosts yes
+# Don't read the user's ~/.rhosts and ~/.shosts files
+IgnoreRhosts yes
+
+# To disable tunneled clear text passwords, change to no here!
+PasswordAuthentication yes
+PermitEmptyPasswords yes
+
+# Change to no to disable s/key passwords
+ChallengeResponseAuthentication no
+# Kerberos options
+#KerberosAuthentication no
+#KerberosOrLocalPasswd yes
+#KerberosTicketCleanup yes
+#KerberosGetAFSToken no
+
+# GSSAPI options
+#GSSAPIAuthentication no
+#GSSAPICleanupCredentials yes
+
+# Set this to 'yes' to enable PAM authentication, account processing,
+# and session processing. If this is enabled, PAM authentication will
+# be allowed through the ChallengeResponseAuthentication and
+# PasswordAuthentication. Depending on your PAM configuration,
+# PAM authentication via ChallengeResponseAuthentication may bypass
+# the setting of "PermitRootLogin without-password".
+# If you just want the PAM account and session checks to run without
+# PAM authentication, then enable this but set PasswordAuthentication
+# and ChallengeResponseAuthentication to 'no'.
+UsePAM yes
+
+#AllowAgentForwarding yes
+#AllowTcpForwarding yes
+#GatewayPorts no
+#X11Forwarding no
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+#PermitTTY yes
+PrintMotd no # pam does that
+#PrintLastLog yes
+#TCPKeepAlive yes
+#UseLogin no
+PermitUserEnvironment yes
+#Compression delayed
+#ClientAliveInterval 0
+#ClientAliveCountMax 3
+#UseDNS no
+#PidFile /run/sshd.pid
+#MaxStartups 10:30:100
+#PermitTunnel no
+#ChrootDirectory none
+#VersionAddendum none
+
+# no default banner path
+#Banner none
+
+# override default of no subsystems
+Subsystem sftp /usr/lib/ssh/sftp-server
+
+# Example of overriding settings on a per-user basis
+#Match User anoncvs
+# X11Forwarding no
+# AllowTcpForwarding no
+# PermitTTY no
+# ForceCommand cvs server
package xdsservertest
import (
+ "bytes"
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "path"
+ "regexp"
"strconv"
"strings"
"testing"
"time"
+ common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git/golib"
"gerrit.automotivelinux.org/gerrit/src/xds/xds-server/lib/xsapiv1"
"github.com/stretchr/testify/assert"
)
-/*flush channel with timeout*/
-func flushChannelTerm(channel chan xsapiv1.TerminalOutMsg, ms time.Duration) {
- timeoutB := false
- for !timeoutB {
+func launchSSHd(sshDir string, proc **os.Process, sshdCmd string) (*os.File, string) {
+ port := "22222"
+ argsProcessSSHd := []string{
+ sshdCmd,
+ "-f",
+ sshDir + "/sshd_config",
+ "-D",
+ "-h",
+ sshDir + "/ssh_host_rsa_key",
+ "-o",
+ "AuthorizedKeysFile=" + sshDir + "/authorized_keys",
+ "-p",
+ port,
+ }
+ logFile := logDir + logFileSSHd
+ file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY, 0644)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer file.Close()
+ tmpProc, err := os.StartProcess(argsProcessSSHd[0], argsProcessSSHd, &os.ProcAttr{
+ Files: []*os.File{os.Stdin, file, file},
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ *proc = tmpProc
+ return file, port
+}
+
+func InitSSH(t *testing.T, procSSHd **os.Process) (string, string) {
+ Debug(t, "Initialise ssh with local user")
+ sshDir := path.Join(os.Getenv(envRootCfgDir), "ssh")
+ cmd := exec.Command("cp", "-r", sshFixturesDir, sshDir)
+ var out bytes.Buffer
+ cmd.Stdout = &out
+ assert.Nil(t, cmd.Run())
+
+ cmd = exec.Command("ls", sshDir)
+ cmd.Stdout = &out
+ assert.Nil(t, cmd.Run())
+
+ files := strings.Split(fmt.Sprint(cmd.Stdout), "\n")
+
+ for _, f := range files {
+ if f != "" {
+ file := sshDir + "/" + f
+ cmd = exec.Command("chmod", "600", file)
+ cmd.Stdout = &out
+ assert.Nil(t, cmd.Run())
+ }
+ }
+
+ var outSSHd bytes.Buffer
+ var sshdCmd string
+ cmd = exec.Command("which", "sshd")
+ cmd.Stdout = &outSSHd
+ if cmd.Run() != nil {
+ if common.Exists("/usr/sbin/sshd") {
+ sshdCmd = "/usr/sbin/sshd"
+ } else if common.Exists("/usr/bin/sshd") {
+ sshdCmd = "/usr/sbin/sshd"
+ } else {
+ assert.FailNow(t, "Cannot find sshd command, please install it or set in your PATH")
+ }
+ } else {
+ sshdCmd = strings.TrimSpace(fmt.Sprint(cmd.Stdout))
+ }
+
+ var port string
+ _, port = launchSSHd(sshDir, procSSHd, sshdCmd)
+ go func(p *os.Process) {
+ Debug(t, "sshd is launching")
+ if status, err := p.Wait(); err != nil {
+ log.Fatalf("status=%v\n err=%v\n", status, err)
+ }
+ }(*procSSHd)
+ return sshDir, port
+}
+
+/*wait for terminal prompt*/
+func waitForPrompt(t *testing.T, channel chan xsapiv1.TerminalOutMsg, prompt string) string {
+ step := 1 * time.Millisecond
+ timeout := 10 * time.Second
+ current := 0 * time.Second
+ out := ""
+ re := regexp.MustCompile("^" + prompt)
+
+ for {
select {
- case <-channel:
- case <-time.After(ms * time.Millisecond):
- timeoutB = true
+ case outMsg := <-channel:
+ out += string(outMsg.Stdout)
+ if string(outMsg.Stderr) != "" {
+ out += string(outMsg.Stderr)
+ }
+ for _, line := range strings.Split(out, "\n") {
+ if re.MatchString(line) {
+ return line
+ }
+ }
+ case <-time.After(step):
+ current = current + step
+ if current >= timeout {
+ assert.FailNow(t, "Never received prompt message from terminal (output:"+out+")")
+ }
}
}
}
return listID
}
-func AddTerms(t *testing.T, nbTerms int, listID []string, chTermEvt chan xsapiv1.TerminalConfig) {
+func AddTerms(t *testing.T, nbTerms int, listID []string, chTermEvt chan xsapiv1.TerminalConfig, sshDir string, port string) {
for j := 0; j < len(listID); j++ {
listTermsID := make([]string, nbTerms)
for i := 0; i < nbTerms; i++ {
term := xsapiv1.TerminalConfig{
Name: "terminal" + strconv.Itoa(i),
Type: xsapiv1.TypeTermSSH,
+ Options: []string{
+ "-p",
+ port,
+ "-i",
+ sshDir + "/ssh",
+ "-o",
+ "StrictHostKeyChecking=no",
+ },
}
/*add terminal on target*/
assert.Nil(t, HTTPCli.Post("/targets/"+listID[j]+"/terminals", term, &term))
}
}
-func PostTerms(t *testing.T, post string, chTermEvt chan xsapiv1.TerminalConfig) {
+func PostTerms(t *testing.T, post string, chTermEvt chan xsapiv1.TerminalConfig, chTerm chan xsapiv1.TerminalOutMsg,
+ prompt string) {
var status string
switch post {
case "open":
assert.Nil(t, HTTPCli.Post("/targets/"+targets[i].ID+"/terminals/"+terms[j].ID+"/"+post, terms[j], &term))
Debugf(t, "%v terminal %v", post, term.Name)
termEvt := <-chTermEvt //waiting for event terminalStateChange
+ if post == "open" {
+ data := []byte("PS1=" + prompt + " bash -norc\n")
+ assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
+ waitForPrompt(t, chTerm, prompt)
+ }
assert.Equal(t, term.ID, termEvt.ID)
assert.Equal(t, term.Status, status)
assert.Equal(t, termEvt.Status, status)
}
}
func TestTarget(t *testing.T) {
- nbTargets := 3
- nbTermsByTarget := 3
+ prompt := "--PROMPT--"
+ var procSSHd *os.Process
+ sshDir, port := InitSSH(t, &procSSHd)
+ defer procSSHd.Kill()
+
+ nbTargets := 2
+ nbTermsByTarget := 2
/*channel for target events*/
chTarget := make(chan xsapiv1.TargetConfig)
defer close(chTarget)
assert.Equal(t, len(targetArray), 0)
listID := AddTargets(t, nbTargets, chTarget)
- AddTerms(t, nbTermsByTarget, listID, chTermEvt)
-
- ///*channel for TerminalOutMsg*/
- //chTerm := make(chan xsapiv1.TerminalOutMsg)
- //defer close(chTerm)
-
- ///*connect on terminalOutMsg event*/
- //sCli.Conn.On(xsapiv1.TerminalOutEvent, func(ev xsapiv1.TerminalOutMsg) {
- // chTerm <- ev
- //})
-
- ///*just for the first term*/
- //var terms []xsapiv1.TerminalConfig
- //var term xsapiv1.TerminalConfig
- //assert.Nil(t, HTTPCli.Get("/targets/"+listID[0]+"/terminals", &terms))
- //assert.Nil(t, HTTPCli.Post("/targets/"+listID[0]+"/terminals/"+terms[0].ID+"/open", terms[0], &term))
- //<-chTermEvt //waiting for event terminalStateChange
- //termOut := <-chTerm //waiting for terminalOutMsg
- //flushChannelTerm(chTerm, 50) //flushing all terminalOutMsg
- //stdoutMsg := string(termOut.Stdout)
- //if strings.Contains(stdoutMsg, "Connection refused") {
- // t.Fatalf("%vYou may have to launch ssh server", stdoutMsg)
- //} else if strings.Contains(stdoutMsg, "password") {
- // t.Fatalf("%vcopy your pub key in authorized_keys\ncat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys", stdoutMsg)
- //}
- //assert.True(t, strings.Contains(stdoutMsg, "Last login")) //first terminal msg should be Last Login
- //assert.Nil(t, HTTPCli.Post("/targets/"+listID[0]+"/terminals/"+terms[0].ID+"/close", terms[0], &term))
- //<-chTermEvt //waiting for event terminalStateChange
-
- ///*open terminals*/
- //PostTerms(t, "open", chTermEvt)
- //termOut = <-chTerm //waiting for terminalOutMsg
- //flushChannelTerm(chTerm, 50) //flushing all terminalOutMsg
- //stdoutMsg = string(termOut.Stdout)
- //if strings.Contains(stdoutMsg, "Connection refused") {
- // t.Fatalf("%vYou may have to launch ssh server", stdoutMsg)
- //} else if strings.Contains(stdoutMsg, "password") {
- // t.Fatalf("%vcopy your pub key in authorized_keys\ncat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys", stdoutMsg)
- //}
- //assert.True(t, strings.Contains(stdoutMsg, "Last login")) //first terminal msg should be Last Login
-
- ///*create toto file through terminals*/
- //rootCfgDir := os.Getenv(envRootCfgDir)
- //totoFile := path.Join(rootCfgDir, "toto")
-
- ///*test with 2 terminals*/
- //for i := 0; i < 2; i++ {
- // totoFileCurrent := totoFile + strconv.Itoa(i)
- // /*send cmd though term*/
- // data := []byte("echo helloWorld" + strconv.Itoa(i) + " >> " + totoFileCurrent + "\n")
- // Debugf(t, "send following command through terminal: %v", string(data))
- // assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
- // flushChannelTerm(chTerm, 50) //waiting for terminal msg
-
- // /*check that toto file is created*/
- // _, err := os.Stat(totoFileCurrent)
- // assert.Nil(t, err)
-
- // /*send cmd though term*/
- // data = []byte("cat " + totoFileCurrent + "\n")
- // Debugf(t, "send following command through terminal: %v", string(data))
- // assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
-
- // <-chTerm //cmd sent
- // termOut = <-chTerm //result of cat cmd
- // flushChannelTerm(chTerm, 50) //flushing what remains
- // /*check that terminal msg is what was written before*/
- // assert.Equal(t, string(termOut.Stdout), "helloWorld"+strconv.Itoa(i)+"\r\n")
- // Debugf(t, "check terminal output msg: %v", string(termOut.Stdout))
- //}
-
- //PostTerms(t, "close", chTermEvt)
+ AddTerms(t, nbTermsByTarget, listID, chTermEvt, sshDir, port)
+
+ /*channel for TerminalOutMsg*/
+ chTerm := make(chan xsapiv1.TerminalOutMsg)
+ defer close(chTerm)
+
+ /*connect on terminalOutMsg event*/
+ sCli.Conn.On(xsapiv1.TerminalOutEvent, func(ev xsapiv1.TerminalOutMsg) {
+ chTerm <- ev
+ })
+
+ /*open terminals*/
+ PostTerms(t, "open", chTermEvt, chTerm, prompt)
+
+ /*create toto file through terminals*/
+ rootCfgDir := os.Getenv(envRootCfgDir)
+ totoFile := path.Join(rootCfgDir, "toto")
+
+ /*test with 2 terminals*/
+ for i := 0; i < 2; i++ {
+ totoFileCurrent := totoFile + strconv.Itoa(i)
+ /*send cmd though term*/
+ data := []byte("echo helloWorld" + strconv.Itoa(i) + " >> " + totoFileCurrent + "\n")
+ Debugf(t, "send following command through terminal: %v", string(data))
+ assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
+ waitForPrompt(t, chTerm, prompt) //waiting for terminal prompt
+
+ /*check that toto file is created*/
+ _, err := os.Stat(totoFileCurrent)
+ assert.Nil(t, err)
+
+ /*send cmd though term*/
+ data = []byte("cat " + totoFileCurrent + "\n")
+ Debugf(t, "send following command through terminal: %v", string(data))
+ assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
+
+ <-chTerm //cmd sent
+ termOut := <-chTerm //result of cat cmd
+ waitForPrompt(t, chTerm, prompt) //wait for terminal prompt
+ /*check that terminal msg is what was written before*/
+ assert.Equal(t, string(termOut.Stdout), "helloWorld"+strconv.Itoa(i)+"\r\n")
+ Debugf(t, "check terminal output msg: %v", string(termOut.Stdout))
+ }
+
+ PostTerms(t, "close", chTermEvt, nil, prompt)
/*remove targets and terms*/
RemoveTermsTargets(t, chTarget, chTermEvt)