Merge branch 'new-tls'

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

Conflicts:
	auto/gui.files.go
This commit is contained in:
Jakob Borg 2014-09-15 00:19:07 +02:00
commit 55ea207a55
4 changed files with 95 additions and 34 deletions

File diff suppressed because one or more lines are too long

View File

@ -52,33 +52,28 @@ 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()
@ -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")

View File

@ -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)
}

View File

@ -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;
}