Explorar o código

Merge branch 'new-tls'

* new-tls:
  Cleanups and tweaks
  Add redirection middleware
  Add DowngradingListener

Conflicts:
	auto/gui.files.go
Jakob Borg %!s(int64=11) %!d(string=hai) anos
pai
achega
55ea207a55
Modificáronse 4 ficheiros con 94 adicións e 33 borrados
  1. 0 0
      auto/gui.files.go
  2. 42 25
      cmd/syncthing/gui.go
  3. 40 0
      cmd/syncthing/tls.go
  4. 12 8
      gui/app.js

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
auto/gui.files.go


+ 42 - 25
cmd/syncthing/gui.go

@@ -52,34 +52,29 @@ func init() {
 }
 
 func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) error {
-	var listener net.Listener
 	var err error
-	if cfg.UseTLS {
-		cert, err := loadCert(confDir, "https-")
-		if err != nil {
-			l.Infoln("Loading HTTPS certificate:", err)
-			l.Infoln("Creating new HTTPS certificate")
-			newCertificate(confDir, "https-")
-			cert, err = loadCert(confDir, "https-")
-		}
-		if err != nil {
-			return err
-		}
-		tlsCfg := &tls.Config{
-			Certificates: []tls.Certificate{cert},
-			ServerName:   "syncthing",
-		}
-		listener, err = tls.Listen("tcp", cfg.Address, tlsCfg)
-		if err != nil {
-			return err
-		}
-	} else {
-		listener, err = net.Listen("tcp", cfg.Address)
-		if err != nil {
-			return err
-		}
+
+	cert, err := loadCert(confDir, "https-")
+	if err != nil {
+		l.Infoln("Loading HTTPS certificate:", err)
+		l.Infoln("Creating new HTTPS certificate")
+		newCertificate(confDir, "https-")
+		cert, err = loadCert(confDir, "https-")
+	}
+	if err != nil {
+		return err
+	}
+	tlsCfg := &tls.Config{
+		Certificates: []tls.Certificate{cert},
+		ServerName:   "syncthing",
 	}
 
+	rawListener, err := net.Listen("tcp", cfg.Address)
+	if err != nil {
+		return err
+	}
+	listener := &DowngradingListener{rawListener, tlsCfg}
+
 	// The GET handlers
 	getRestMux := http.NewServeMux()
 	getRestMux.HandleFunc("/rest/completion", withModel(m, restGetCompletion))
@@ -140,6 +135,11 @@ func startGUI(cfg config.GUIConfiguration, assetDir string, m *model.Model) erro
 		handler = basicAuthAndSessionMiddleware(cfg, handler)
 	}
 
+	// Redirect to HTTPS if we are supposed to
+	if cfg.UseTLS {
+		handler = redirectToHTTPSMiddleware(handler)
+	}
+
 	go http.Serve(listener, handler)
 	return nil
 }
@@ -157,6 +157,23 @@ func getPostHandler(get, post http.Handler) http.Handler {
 	})
 }
 
+func redirectToHTTPSMiddleware(h http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		// Add a generous access-control-allow-origin header since we may be
+		// redirecting REST requests over protocols
+		w.Header().Add("Access-Control-Allow-Origin", "*")
+
+		if r.TLS == nil {
+			// Redirect HTTP requests to HTTPS
+			r.URL.Host = r.Host
+			r.URL.Scheme = "https"
+			http.Redirect(w, r, r.URL.String(), http.StatusFound)
+		} else {
+			h.ServeHTTP(w, r)
+		}
+	})
+}
+
 func noCacheMiddleware(h http.Handler) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		w.Header().Set("Cache-Control", "no-cache")

+ 40 - 0
cmd/syncthing/tls.go

@@ -5,6 +5,7 @@
 package main
 
 import (
+	"bufio"
 	"crypto/rand"
 	"crypto/rsa"
 	"crypto/sha256"
@@ -13,8 +14,10 @@ import (
 	"crypto/x509/pkix"
 	"encoding/binary"
 	"encoding/pem"
+	"io"
 	"math/big"
 	mr "math/rand"
+	"net"
 	"os"
 	"path/filepath"
 	"time"
@@ -73,3 +76,40 @@ func newCertificate(dir string, prefix string) {
 	pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
 	keyOut.Close()
 }
+
+type DowngradingListener struct {
+	net.Listener
+	TLSConfig *tls.Config
+}
+
+type WrappedConnection struct {
+	io.Reader
+	net.Conn
+}
+
+func (l *DowngradingListener) Accept() (net.Conn, error) {
+	conn, err := l.Listener.Accept()
+	if err != nil {
+		return nil, err
+	}
+
+	br := bufio.NewReader(conn)
+	bs, err := br.Peek(1)
+	if err != nil {
+		conn.Close()
+		return nil, err
+	}
+
+	wrapper := &WrappedConnection{br, conn}
+
+	// 0x16 is the first byte of a TLS handshake
+	if bs[0] == 0x16 {
+		return tls.Server(wrapper, l.TLSConfig), nil
+	}
+
+	return wrapper, nil
+}
+
+func (c *WrappedConnection) Read(b []byte) (n int, err error) {
+	return c.Reader.Read(b)
+}

+ 12 - 8
gui/app.js

@@ -153,13 +153,17 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http, $translate, $loca
             return;
         }
 
-        console.log('UIOnline');
-        $scope.init();
-        online = true;
-        restarting = false;
-        $('#networkError').modal('hide');
-        $('#restarting').modal('hide');
-        $('#shutdown').modal('hide');
+        if (restarting){
+            document.location.reload(true);
+        } else {
+            console.log('UIOnline');
+            $scope.init();
+            online = true;
+            restarting = false;
+            $('#networkError').modal('hide');
+            $('#restarting').modal('hide');
+            $('#shutdown').modal('hide');
+        }
     });
 
     $scope.$on('UIOffline', function (event, arg) {
@@ -585,7 +589,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http, $translate, $loca
 
             setTimeout(function(){
                 window.location.protocol = protocol;
-            }, 1000);
+            }, 2500);
 
             $scope.protocolChanged = false;
         }

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio