Rod Hynes 10 лет назад
Родитель
Сommit
7b944f40b9
5 измененных файлов с 81 добавлено и 13 удалено
  1. 0 0
      Server/README.md
  2. 1 1
      psiphon/server/services.go
  3. 6 5
      psiphon/server/sshService.go
  4. 9 7
      psiphon/server/webService.go
  5. 65 0
      psiphon/utils.go

+ 0 - 0
psiphon/server/README.md → Server/README.md


+ 1 - 1
psiphon/server/services.go

@@ -57,7 +57,7 @@ func RunServices(encodedConfig []byte) error {
 	waitGroup.Add(1)
 	go func() {
 		defer waitGroup.Done()
-		err := RunSSH(config, shutdownBroadcast)
+		err := RunSSHServer(config, shutdownBroadcast)
 		select {
 		case errors <- err:
 		default:

+ 6 - 5
psiphon/server/sshService.go

@@ -39,10 +39,11 @@ type sshServer struct {
 	clients         map[string]ssh.Conn
 }
 
-func RunSSH(config *Config, shutdownBroadcast <-chan struct{}) error {
+func RunSSHServer(config *Config, shutdownBroadcast <-chan struct{}) error {
 
 	sshServer := &sshServer{
-		config: config,
+		config:  config,
+		clients: make(map[string]ssh.Conn),
 	}
 
 	sshServer.sshConfig = &ssh.ServerConfig{
@@ -147,11 +148,11 @@ func (sshServer *sshServer) passwordCallback(conn ssh.ConnMetadata, password []b
 }
 
 func (sshServer *sshServer) authLogCallback(conn ssh.ConnMetadata, method string, err error) {
-	errMsg := "success"
 	if err != nil {
-		errMsg = err.Error()
+		log.Warning("ssh: %s authentication failed %s", method, err)
+	} else {
+		log.Info("ssh: %s authentication success %s", method)
 	}
-	log.Warning("ssh: %s authentication attempt %s", method, errMsg)
 }
 
 func (sshServer *sshServer) registerClient(sshConn ssh.Conn) bool {

+ 9 - 7
psiphon/server/webService.go

@@ -65,12 +65,14 @@ func RunWebServer(config *Config, shutdownBroadcast <-chan struct{}) error {
 	logWriter := log.StandardLogger().Writer()
 	defer logWriter.Close()
 
-	httpServer := &http.Server{
-		Handler:      serveMux,
-		TLSConfig:    tlsConfig,
-		ReadTimeout:  WEB_SERVER_READ_TIMEOUT,
-		WriteTimeout: WEB_SERVER_WRITE_TIMEOUT,
-		ErrorLog:     golanglog.New(logWriter, "", 0),
+	server := &psiphon.HTTPSServer{
+		http.Server{
+			Handler:      serveMux,
+			TLSConfig:    tlsConfig,
+			ReadTimeout:  WEB_SERVER_READ_TIMEOUT,
+			WriteTimeout: WEB_SERVER_WRITE_TIMEOUT,
+			ErrorLog:     golanglog.New(logWriter, "", 0),
+		},
 	}
 
 	listener, err := net.Listen(
@@ -90,7 +92,7 @@ func RunWebServer(config *Config, shutdownBroadcast <-chan struct{}) error {
 		defer waitGroup.Done()
 
 		// Note: will be interrupted by listener.Close()
-		err := httpServer.Serve(listener)
+		err := server.ServeTLS(listener)
 
 		// Can't check for the exact error that Close() will cause in Accept(),
 		// (see: https://code.google.com/p/go/issues/detail?id=4373). So using an

+ 65 - 0
psiphon/utils.go

@@ -17,16 +17,48 @@
  *
  */
 
+/*
+Copyright (c) 2012 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 package psiphon
 
 import (
 	"crypto/rand"
+	"crypto/tls"
 	"crypto/x509"
 	"encoding/base64"
 	"errors"
 	"fmt"
 	"math/big"
 	"net"
+	"net/http"
 	"net/url"
 	"os"
 	"runtime"
@@ -249,3 +281,36 @@ func TruncateTimestampToHour(timestamp string) string {
 	}
 	return t.Truncate(1 * time.Hour).Format(time.RFC3339)
 }
+
+// HTTPSServer is a wrapper around http.Server which adds the
+// ServeTLS function.
+type HTTPSServer struct {
+	http.Server
+}
+
+// ServeTLS is a offers the equivalent interface as http.Serve.
+// The http package has both ListenAndServe and ListenAndServeTLS higher-
+// level interfaces, but only Serve (not TLS) offers a lower-level interface that
+// allows the caller to keep a refererence to the Listener, allowing for external
+// shutdown. ListenAndServeTLS also requires the TLS cert and key to be in files
+// and we avoid that here.
+// tcpKeepAliveListener is used in http.ListenAndServeTLS but not exported,
+// so we use a copy from https://golang.org/src/net/http/server.go.
+func (server *HTTPSServer) ServeTLS(listener net.Listener) error {
+	tlsListener := tls.NewListener(tcpKeepAliveListener{listener.(*net.TCPListener)}, server.TLSConfig)
+	return server.Serve(tlsListener)
+}
+
+type tcpKeepAliveListener struct {
+	*net.TCPListener
+}
+
+func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
+	tc, err := ln.AcceptTCP()
+	if err != nil {
+		return
+	}
+	tc.SetKeepAlive(true)
+	tc.SetKeepAlivePeriod(3 * time.Minute)
+	return tc, nil
+}