Ejemplo n.º 1
0
func main() {
	config := ssh.ServerConfig{
		PublicKeyCallback: keyAuth,
	}
	config.AddHostKey(hostPrivateKeySigner)

	port := "2222"
	if os.Getenv("PORT") != "" {
		port = os.Getenv("PORT")
	}
	socket, err := net.Listen("tcp", ":"+port)
	if err != nil {
		panic(err)
	}

	for {
		conn, err := socket.Accept()
		if err != nil {
			panic(err)
		}

		// From a standard TCP connection to an encrypted SSH connection
		sshConn, _, _, err := ssh.NewServerConn(conn, &config)
		if err != nil {
			panic(err)
		}

		log.Println("Connection from", sshConn.RemoteAddr())
		sshConn.Close()
	}
}
Ejemplo n.º 2
0
func main() {
	mylogger = logger.NewLogger("", 0)

	configPath := flag.String("config", "", "fssh config file")
	flag.Parse()

	if _, err := toml.DecodeFile(*configPath, &config); err != nil {
		mylogger.Fatal(err)
	}

	sshConfig := ssh.ServerConfig{
		PublicKeyCallback: keyHandler,
		PasswordCallback:  passwdHandler,
	}
	sshConfig.AddHostKey(readSecretKey(config.Key))

	s, err := net.Listen("tcp", config.Address+":"+strconv.Itoa(config.Port))
	if err != nil {
		mylogger.Fatal(err)
	}
	defer s.Close()

	for {
		c, err := s.Accept()
		if err != nil {
			mylogger.Fatal(err)
		}

		ssh.NewServerConn(c, &sshConfig)
	}
}
Ejemplo n.º 3
0
func (s *Server) serve(conn net.Conn) error {
	config := ssh.ServerConfig{
		PublicKeyCallback: s.config.PublicKeyCallback.wrap(),
		PasswordCallback:  s.config.PasswordCallback.wrap(),
	}

	for _, hostKey := range s.config.HostKeys {
		config.AddHostKey(hostKey)
	}

	serverConn, channelRequestCh, globalRequestCh, err := ssh.NewServerConn(conn, &config)
	if err != nil {
		return err
	}

	// connection succeeded at this point. create the ssh connection and start the go procs.
	newConn := sshConn{
		handler:    s.config.Handler,
		conn:       serverConn,
		newChannel: channelRequestCh,
		requests:   globalRequestCh,
	}
	go newConn.processChannelRequests()
	go newConn.processGlobalRequests()
	return nil
}
Ejemplo n.º 4
0
// TestServer tests the SSH server.
//
// This listens on the non-standard port 2244 of localhost. This will generate
// an entry in your known_hosts file, and will tie that to the testing key
// used here. It's not recommended that you try to start another SSH server on
// the same port (at a later time) or else you will have key issues that you
// must manually resolve.
func TestServer(t *testing.T) {
	key, err := sshTestingHostKey()
	if err != nil {
		t.Fatal(err)
	}

	cfg := ssh.ServerConfig{
		NoClientAuth: true,
	}
	cfg.AddHostKey(key)

	c := NewCircuit()
	cxt := runServer(&cfg, c, t)

	// Give server time to initialize.
	time.Sleep(200 * time.Millisecond)

	if c.State() != ClosedState {
		t.Fatalf("circuit was not in closed state")
	}

	// Connect to the server and issue env var set. This should return true.
	client, err := ssh.Dial("tcp", testingServerAddr, &ssh.ClientConfig{})
	if err != nil {
		t.Fatalf("Failed to connect client to local server: %s", err)
	}
	sess, err := client.NewSession()
	if err != nil {
		t.Fatalf("Failed to create client session: %s", err)
	}
	defer sess.Close()

	if err := sess.Setenv("HELLO", "world"); err != nil {
		t.Fatal(err)
	}

	if out, err := sess.Output("ping"); err != nil {
		t.Errorf("Output '%s' Error %s", out, err)
	} else if string(out) != "pong" {
		t.Errorf("Expected 'pong', got '%s'", out)
	}

	// Create a new session because the success of the last one closed the
	// connection.
	sess, err = client.NewSession()
	if err != nil {
		t.Fatalf("Failed to create client session: %s", err)
	}
	if err := sess.Run("illegal"); err == nil {
		t.Fatalf("expected a failed run with command 'illegal'")
	}
	if err := sess.Run("illegal command"); err == nil {
		t.Fatalf("expected a failed run with command 'illegal command'")
	}

	closer := cxt.Get("sshd.Closer", nil).(chan interface{})
	closer <- true
}
Ejemplo n.º 5
0
func basicServerConfig() *ssh.ServerConfig {
	config := ssh.ServerConfig{
		Config: ssh.Config{
			MACs: []string{"hmac-sha1"},
		},
		PasswordCallback:  pwAuth,
		PublicKeyCallback: keyAuth,
	}
	config.AddHostKey(hostPrivateKeySigner)
	return &config
}
Ejemplo n.º 6
0
func TestSetupForwardAgent(t *testing.T) {
	a, b, err := netPipe()
	if err != nil {
		t.Fatalf("netPipe: %v", err)
	}

	defer a.Close()
	defer b.Close()

	_, socket, cleanup := startAgent(t)
	defer cleanup()

	serverConf := ssh.ServerConfig{
		NoClientAuth: true,
	}
	serverConf.AddHostKey(testSigners["rsa"])
	incoming := make(chan *ssh.ServerConn, 1)
	go func() {
		conn, _, _, err := ssh.NewServerConn(a, &serverConf)
		if err != nil {
			t.Fatalf("Server: %v", err)
		}
		incoming <- conn
	}()

	conf := ssh.ClientConfig{}
	conn, chans, reqs, err := ssh.NewClientConn(b, "", &conf)
	if err != nil {
		t.Fatalf("NewClientConn: %v", err)
	}
	client := ssh.NewClient(conn, chans, reqs)

	if err := ForwardToRemote(client, socket); err != nil {
		t.Fatalf("SetupForwardAgent: %v", err)
	}

	server := <-incoming
	ch, reqs, err := server.OpenChannel(channelType, nil)
	if err != nil {
		t.Fatalf("OpenChannel(%q): %v", channelType, err)
	}
	go ssh.DiscardRequests(reqs)

	agentClient := NewClient(ch)
	testAgentInterface(t, agentClient, testPrivateKeys["rsa"], nil, 0)
	conn.Close()
}
Ejemplo n.º 7
0
// startServer runs in a goroutine, configures the new server then listens for incoming connections
func startServer(port string, errChan chan error) {

	config := ssh.ServerConfig{
		PasswordCallback:  authPassword,
		PublicKeyCallback: authKey,
		ServerVersion:     "SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u2",
	}

	// generate a new private key each startcso it looks like a new server.
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		errChan <- err
		return
	}

	privateKeyDer := x509.MarshalPKCS1PrivateKey(privateKey)
	privateKeyBlock := pem.Block{
		Type:    "RSA PRIVATE KEY",
		Headers: nil,
		Bytes:   privateKeyDer,
	}

	hostPrivateKeySigner, err := ssh.ParsePrivateKey(pem.EncodeToMemory(&privateKeyBlock))
	if err != nil {
		errChan <- err
		return
	}
	config.AddHostKey(hostPrivateKeySigner)

	socket, err := net.Listen("tcp", ":"+port)
	if err != nil {
		errChan <- err
		return
	}

	for {
		conn, err := socket.Accept()
		if err != nil {
			break
		}
		// handle each incoming request in its own goroutine
		go handleSSH(conn, config)
	}
	// exit goroutine and advise the world
	errChan <- err
	return
}
Ejemplo n.º 8
0
func startSSH(port string, b *batcher) (*SSHServer, error) {

	var err error

	s := &SSHServer{
		port: port,
		b:    b,
	}

	// start the ssh server listening
	config := ssh.ServerConfig{
		PasswordCallback:  authPassword,
		PublicKeyCallback: authKey,
		ServerVersion:     "SSH-2.0-OpenSSH_6.7p1 Debian-5",
	}

	// generate a new private key each startcso it looks like a new server.
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		return nil, err
	}

	privateKeyDer := x509.MarshalPKCS1PrivateKey(privateKey)
	privateKeyBlock := pem.Block{
		Type:    "RSA PRIVATE KEY",
		Headers: nil,
		Bytes:   privateKeyDer,
	}

	hostPrivateKeySigner, err := ssh.ParsePrivateKey(pem.EncodeToMemory(&privateKeyBlock))
	if err != nil {
		return nil, err
	}
	config.AddHostKey(hostPrivateKeySigner)

	s.socket, err = net.Listen("tcp", ":"+s.port)
	if err != nil {
		return nil, err
	}

	go s.listenForConn(config)

	return s, nil
}
Ejemplo n.º 9
0
func TestAuth(t *testing.T) {
	a, b, err := netPipe()
	if err != nil {
		t.Fatalf("netPipe: %v", err)
	}

	defer a.Close()
	defer b.Close()

	agent, _, cleanup := startAgent(t)
	defer cleanup()

	if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys["rsa"], Comment: "comment"}); err != nil {
		t.Errorf("Add: %v", err)
	}

	serverConf := ssh.ServerConfig{}
	serverConf.AddHostKey(testSigners["rsa"])
	serverConf.PublicKeyCallback = func(c ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
		if bytes.Equal(key.Marshal(), testPublicKeys["rsa"].Marshal()) {
			return nil, nil
		}

		return nil, errors.New("pubkey rejected")
	}

	go func() {
		conn, _, _, err := ssh.NewServerConn(a, &serverConf)
		if err != nil {
			t.Fatalf("Server: %v", err)
		}
		conn.Close()
	}()

	conf := ssh.ClientConfig{}
	conf.Auth = append(conf.Auth, ssh.PublicKeysCallback(agent.Signers))
	conn, _, _, err := ssh.NewClientConn(b, "", &conf)
	if err != nil {
		t.Fatalf("NewClientConn: %v", err)
	}
	conn.Close()
}
Ejemplo n.º 10
0
//DialServerConn serves in place of ssh.NewServerConn
func DialServerConn(ds time.Duration, con net.Conn, conf *ssh.ServerConfig) (sc *ssh.ServerConn, cs <-chan ssh.NewChannel, rs <-chan *ssh.Request, ex error) {

	done := make(chan struct{})
	reset := make(chan struct{})

	authlog := conf.AuthLogCallback
	logger := func(conn ssh.ConnMetadata, method string, err error) {
		flux.GoDefer("AuthLogCallback", func() {
			flux.GoDefer("AuthLog", func() {
				if authlog != nil {
					authlog(conn, method, err)
				}
			})
			reset <- struct{}{}
		})
	}

	conf.AuthLogCallback = logger

	flux.GoDefer("NewServerConn", func() {
		defer close(done)
		sc, cs, rs, ex = ssh.NewServerConn(con, conf)
		return
	})

	expiration := threshold(ds)

	func() {

	nsloop:
		for {
			select {
			case <-done:
				expiration = nil
				break nsloop
			case <-reset:
				expiration = threshold(ds)
			case <-expiration:
				if sc != nil {
					sc.Close()
				}
				sc = nil
				cs = nil
				rs = nil
				ex = fmt.Errorf("Expired NewServerConn call for ip:%+s ", con.RemoteAddr())
				break nsloop
			}
		}

	}()
	return
}
Ejemplo n.º 11
0
func setupHostKey(config *ssh.ServerConfig) {
	var signers []ssh.Signer
	if keyEnv := os.Getenv("SSH_PRIVATE_KEYS"); keyEnv != "" {
		for _, block := range decodePemBlocks([]byte(keyEnv)) {
			signer, _ := signerFromBlock(block)
			if signer != nil {
				signers = append(signers, signer)
			}
		}
	}
	if *hostKey != "" {
		pemBytes, err := ioutil.ReadFile(*hostKey)
		if err != nil {
			debug("host key file error:", err)
		}
		for _, block := range decodePemBlocks(pemBytes) {
			signer, _ := signerFromBlock(block)
			if signer != nil {
				signers = append(signers, signer)
			}
		}
	}
	if len(signers) > 0 {
		for _, signer := range signers {
			config.AddHostKey(signer)
		}
	} else {
		debug("no host key provided, generating host key")
		key, err := rsa.GenerateKey(rand.Reader, 768)
		if err != nil {
			log.Fatalln("failed key generate:", err)
		}
		signer, err := ssh.NewSignerFromKey(key)
		if err != nil {
			log.Fatalln("failed signer:", err)
		}
		config.AddHostKey(signer)
	}
}
Ejemplo n.º 12
0
func addKey(conf *ssh.ServerConfig, block *pem.Block) (err error) {
	var key interface{}
	switch block.Type {
	case "RSA PRIVATE KEY":
		key, err = x509.ParsePKCS1PrivateKey(block.Bytes)
	case "EC PRIVATE KEY":
		key, err = x509.ParseECPrivateKey(block.Bytes)
	case "DSA PRIVATE KEY":
		key, err = ssh.ParseDSAPrivateKey(block.Bytes)
	default:
		return fmt.Errorf("unsupported key type %q", block.Type)
	}
	if err != nil {
		return err
	}
	signer, err := ssh.NewSignerFromKey(key)
	if err != nil {
		return err
	}
	conf.AddHostKey(signer)
	return nil
}
Ejemplo n.º 13
0
Archivo: sshd.go Proyecto: bachue/pages
func getSshServerConfig(sshdConfig *config.Sshd) (*ssh.ServerConfig, error) {
	// In the latest version of crypto/ssh (after Go 1.3), the SSH server type has been removed
	// in favour of an SSH connection type. A ssh.ServerConn is created by passing an existing
	// net.Conn and a ssh.ServerConfig to ssh.NewServerConn, in effect, upgrading the net.Conn
	// into an ssh.ServerConn

	serverConfig := ssh.ServerConfig{
		//Define a function to run when a client attempts a password login
		// TODO: Avoid Login by Password
		PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
			// Should use constant-time compare (or better, salt+hash) in a production setting.
			if c.User() == "foo" && string(pass) == "bar" {
				return nil, nil
			}
			return nil, fmt.Errorf("password rejected for %q", c.User())
		},
		// TODO: Use PublicKeyCallback instead
		// PublicKeyCallback: func(conn ssh.ConnMetadata, key crypto.PublicKey) (*ssh.Permissions, error) {
		// TODO
		// }
		// TODO:
		// AuthLogCallback: func(conn ssh.ConnMetadata, method string, err error) {
		// TODO
		// }
		//
		// You may also explicitly allow anonymous client authentication, though anon bash
		// sessions may not be a wise idea
		// NoClientAuth: true,
	}
	private_key, err := getPrivateKey(sshdConfig)
	if err != nil {
		return nil, err
	}
	serverConfig.AddHostKey(private_key)
	return &serverConfig, nil
}
	"github.com/cloudfoundry-incubator/diego-ssh/test_helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/pivotal-golang/lager/lagertest"
	"golang.org/x/crypto/ssh"
)

var _ = Describe("SessionChannelHandler", func() {
	var (
		sshd   *daemon.Daemon
		client *ssh.Client

		logger          *lagertest.TestLogger
		serverSSHConfig *ssh.ServerConfig

		runner                *fakes.FakeRunner
		shellLocator          *fakes.FakeShellLocator
		sessionChannelHandler *handlers.SessionChannelHandler

		newChannelHandlers map[string]handlers.NewChannelHandler
		defaultEnv         map[string]string
		connectionFinished chan struct{}
	)

	BeforeEach(func() {
		logger = lagertest.NewTestLogger("test")
		serverSSHConfig = &ssh.ServerConfig{
			NoClientAuth: true,
		}
		serverSSHConfig.AddHostKey(TestHostKey)
Ejemplo n.º 15
0
	"github.com/cloudfoundry-incubator/diego-ssh/handlers"
	"github.com/cloudfoundry-incubator/diego-ssh/handlers/fake_handlers"
	"github.com/cloudfoundry-incubator/diego-ssh/test_helpers"
	"github.com/cloudfoundry-incubator/diego-ssh/test_helpers/fake_net"
	"github.com/pivotal-golang/lager"
	"github.com/pivotal-golang/lager/lagertest"
	"golang.org/x/crypto/ssh"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Daemon", func() {
	var (
		logger lager.Logger
		sshd   *daemon.Daemon

		serverSSHConfig *ssh.ServerConfig
	)

	BeforeEach(func() {
		logger = lagertest.NewTestLogger("test")
		serverSSHConfig = &ssh.ServerConfig{
			NoClientAuth: true,
		}
		serverSSHConfig.AddHostKey(TestHostKey)
	})

	Describe("HandleConnection", func() {
		var fakeConn *fake_net.FakeConn

		Context("when the function returns", func() {
Ejemplo n.º 16
0
	BeforeEach(func() {
		logger = lagertest.NewTestLogger("test")
	})

	Describe("HandleConnection", func() {
		var (
			proxyAuthenticator *fake_authenticators.FakePasswordAuthenticator
			proxySSHConfig     *ssh.ServerConfig
			sshProxy           *proxy.Proxy

			daemonTargetConfig          proxy.TargetConfig
			daemonAuthenticator         *fake_authenticators.FakePasswordAuthenticator
			daemonSSHConfig             *ssh.ServerConfig
			daemonGlobalRequestHandlers map[string]handlers.GlobalRequestHandler
			daemonNewChannelHandlers    map[string]handlers.NewChannelHandler
			sshDaemon                   *daemon.Daemon

			proxyListener net.Listener
			sshdListener  net.Listener

			proxyAddress  string
			daemonAddress string

			proxyServer *server.Server
			sshdServer  *server.Server
		)

		BeforeEach(func() {
			fakeLogSender = fake_logs.NewFakeLogSender()
			logs.Initialize(fakeLogSender)
Ejemplo n.º 17
0
func main() {

	//SSH goroutine

	go func() {
		config := ssh.ServerConfig{
			PublicKeyCallback: keyAuth,
		}
		config.AddHostKey(hostPrivateKeySigner)

		port := strconv.Itoa(hostSSHPort)

		socket, err := net.Listen("tcp", ":"+port)
		if err != nil {
			panic(err)
		}

		for {
			conn, err := socket.Accept()
			if err != nil {
				panic(err)
			}

			// From a standard TCP connection to an encrypted SSH connection
			sshConn, chans, reqs, err := ssh.NewServerConn(conn, &config)
			if err != nil {
				log.Println("Error accepting ssh connection: ", err)
				continue
			}

			log.Println("Connection from", sshConn.RemoteAddr())

			// Print incoming out-of-band Requests
			go handleRequests(reqs)
			// Accept all channels
			go handleChannels(chans)
		}
	}()

	//

	// Garbage collecting goroutine
	// For testing, a stop-the-world gc using mutexes shall be 'nuff
	go func() {

		for {
			authRequestMap.Lock()

			for k, v := range authRequestMap.timestamps {

				killtime := time.Now().Add(-5 * time.Minute)

				if v.Before(killtime) {
					log.Debugf("Garbage collected key %s, %v old", k, time.Now().Sub(v))
					delete(authRequestMap.timestamps, k)
					delete(authRequestMap.matches, k)
				}

			}

			authRequestMap.Unlock()
			time.Sleep(2 * time.Minute)
		}

	}()

	templateStart, err = template.New("index.html").ParseFiles("index.html")
	if err != nil {
		panic(err)
	}

	templateAuth, err = template.New("auth.html").ParseFiles("auth.html")
	if err != nil {
		panic(err)
	}

	http.HandleFunc("/auth", authRequestHandler)
	http.HandleFunc("/", startHandler)

	weblogOptions := &weblogs.Options{

		Writer: nil,
		Logger: customLogger{},
	}

	csrfHandler := nosurf.New(http.DefaultServeMux)

	csrfHandler.SetBaseCookie(http.Cookie{HttpOnly: true, Secure: sslEnabled})

	handler := context.ClearHandler(weblogs.HandlerWithOptions(csrfHandler, weblogOptions))

	if sslEnabled {
		go http.ListenAndServe(":"+strconv.Itoa(hostHTTPPort), handler)
		http.ListenAndServeTLS(":"+strconv.Itoa(hostTLSPort), sslCertPath, sslKeyPath, handler)
	} else {
		http.ListenAndServe(":"+strconv.Itoa(hostHTTPPort), handler)
	}
}