Archived
Implement HTTPS for GUI
This commit is contained in:
1 parent
30837a7d95
commit
7c8652b600
6 files changed
+43
-14
No files matched your search
+1
-1
@@ -18,7 +18,7 @@ func init() {
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["angular.min.js"] = bs
|
||||
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffd43c5d73dbb6b2eff915a89a965422534eeebd9d3b56944eeba41d9f3489276ef2e2fa811221893105aa24185be3eabf9f5d00240102a4683b6953cf9c131b58ec2e7617fb05b0e3471ff324669cccb2f42aa7d911e1594147649e321eb382967f6f9222c7ffc9bfc9a3f183f1a36592cec2843c3c228b30c9012864cb220933f537023df00af825e7593ce7dee4c1834f6146f22d9bf355cc96645aae08d6695424d4f7aa396f44ce2f8613b1a0c892590868a6c4cb682ef0547001329aa5494233df3b2b478f7996008645017fc72923fec37c9e6e80c3872bce374372f380c00fe2de64f4d38b9023f2c34935baa4fced2b18c2bdd6a3483cccb8e45c6c1138c149891d59615410cc01e06637694c2ee2a53dbede9ebcc09d79c6284b238a48ce2f1c484e186ed4604fcdd32c4b33c7ba9c52f612e76c4a20799ad86c65749396bb10e3e331390335b2654e6674916694ccd234c94992a69730c239cd4c8a9c0b60e0458cdfc4d111f17e8b734e192002edc00ee7602b426be4344b793a4f132221c84f5104e2ce690e807cbb013bf438bde6f097d28234c4dd4843fe3abc3ea32c7a35dbe41afab7055fa6a8b377a8e6dfe275cc89ff2afe799c0f6bdcac58cf68d689fd1de00bd909838d7e0a93338d829c21e514f16f8d59598e1bb99abc3bfed3300be18024efe89f0500e9c20191111010ac649190510dd21f3f20395ec149a60dc923f25fe28412392b15d05ff41a855f85a7f989b1972c9c2534d288c8290273299c765ae345f3ec64fbb774de8253ccdc05e5198eff2c3da96ee1384cea711d9db1fefd293bb5d991230427dd8b2f4c3fb42ce233f7f153a74a17dffb93fb1cb9f7e64611db4f055f51081ef350b8def7c696f7223c0df3fc2acda26ea41a9442bca9475cc84b095511013cfc59319f531ad1c82f0302fec40be27f23fcbf3eaa49376631f7871373caf7be6594030397c2cd7a43f4ab61e27bab38a25e03da8e2ef8b33358a863cd2dd9a8177633e10a66262b3b5b64bf84709c6d79b5339b515e64ac6d936e31b7c9f26616ce2fa32cdd80ba811e180328fb926e676998452ae7d8b588ba6b8355c45bc03e56085ca50d3a6f22750800a15fe6238f8937ceb77076d6c0638ed694e77ebd380a79d8dc9c697613976225466003d76b2c0f6574f7dddc29e4a582f475f5ef6f671f21900420b3dcd7e3fc308080fe329caf34e4716429c62900913ffc8868a61e0c50368781f7ef4e8ed3f52665706611535ff168621078cfe3e8c292447357faef6e1eb5c4acb7a630e163e91550c7f41012b22b7f3832207804933ec21c5469e4908cc993c3c34313328e94fb297fb4ac13d63bcd2066104cebacb4319b16bc9a36e64191a83b1233d22660e1e170325885f9db2b06a9d786667c2b14e580c79fb21c9858b33b6b8467db162c4814555a6dee75c857c13abcf60f47e4ffc923a9090171c27ede729aff9e7288c4078e0cdb8242d1f36868736850ae04d74e1af2a13eb40db056e23b02216bbe223e6d13ad2594c3be5b7000dada30cce9f1b441cec6601a98be400e35cea1cb38cd3aa8e9c6f61d5659c3f43ea7cdcac74d6e3779d0ac6e2029e3456eb87b1c6ec636cc2fd285e995100efcd2148aa98245741133c8d7dca10f52247609679c797af43128d8a8413790e7c329fe0649b4623ee3e96603949d9845a5cda58ff1d0333bc888f97a75092efe3d3fbc0878fa1e0864c7a01a08368fe504e8650605bdff643831f7a1964fc9002b3a480606e4afbf483d7a122574d0dc8b9c06331b107f507389f5fd29cde6103fc225558a794c06df0d07cedd2a91681b6a06f74d7a9c408ef8e5f51db345fa05941d6109957d365d1b0af362504d2b65750ebdb62cae46934bbdb762da64f13accb64e4c0ef1992a344de28beb11a278db861dd295ad30110f04fec37e580d0d6ea0c69f22044423a799e0b19224c62e008d874953ac22da2d9214f24720e3768ad8737238451c3e5e18993d728b4e1ee01cc1512d08dec0bf272f2e4c9b43c0a66ccaf10073c6840ab2284410852b68969672c2084ac46b442442b1f7d8be4c3927e2e34169928500f4ddb089b1c3e1782fe25cedbd72c40eb19ecc714bff06a1a697b795a7aa9b6e23b435a49279bbb46c47fdd58acbf68dbd64663bc2bd32d3fda22d32ecddfccd12538c09a1a9d651975fffb143df9ac8ffb12d349c40678c6adfca07ba570dc88cc9a93034ed3aa0854d05f1896639e076f1f725c593c410783fb4d3dea36788b51112b6a4636e1777b0c68249dc7ee897218021e1546f7f20bf2559568b9248ac13a3d4c02d2abc4142d992af20dd224f5a765c25071d1b55d8204d6e358637e1dade6f9735007c0b473a480753a68acb4c1d2adc1fdc219fafe2fc8d8bd3a64e98545d6399df90b0cab92470af2c6be017b23c128bcce4be29a27df2e9239cde92a151ccb5267a4b4bd0f7be2d2fbafab62945537ae84c70c34f743f49e74560a3bd6900056f37e2fc07b2cdaf5cb5e1226ca8339e05f92689b9ef8d7067e1463b78d7dac1bb0e38c43230044765bf4973ab0f07a4401cff397bfb26c8c57562bcd8fa0627c311b959d130025773446ebce394013ffce077b02d0f441a6e802d790d30fe98a7ccdb19845d1a1960ff7bd0d60910adeb56791b6d72b361dfd66dcf57e995b75f186aa901b9e796b7c17bbe2a788467a7bb656d512ed7397b2c56814ef9eff19aa605f7cd46b90f8a7afa7f876d8dd8db6d058f9b333c34dc6589b6c832300ab5e26140afc14622ff66372a5da0cd0a92003dbdbc060377aad3003ba3c942b6771b91da08d4f67e6bc682ea3e0d0e139956beb91a0e3ea63183f3451c2680c02f8193340b1e82064e33c1b4e170d1fc4ab1ddc9f9981a08233b3eef95fc8dbe4720196d59b8069abb1ed277fb2c53fc6e98bf5f385064534ebbe5e3a268ddbc89debb5b24fbafce5c72e8972639436669d3dfd446ad9baf9ced71ba0564930fad3728ae24308990d712f2c6c9ddc51573a2d9dcc0d998e8b1cb7becb4b95b5bf27bc2ef3f11fd9ab10192894e7b2db33a70492312a58c8e483cb9ed467bd9bca2425cb2b7a02a47dbcc65c10292704efd311903c31e90ab460eca11958a58382b2fe572c3774c752a22283b5b34f21e4e5cd290983c33cfa8ac4060e2f163571f42873d8f2ff42ad1144ac7f569b9b8def1c402559c9b61b0fc996534bcecd19f90b78980a9e548cb1d6f0a4818ecd0dce2d3823ccdb85fb606c28cded5f57c0d2731e52b9a957cb625997a81dfeac77bbb71cc4d6cc7dd52fb757a881812aaa62bbf8355b3868ac0302796d9b39eed107df3ed06ead8719824dd7a287da26651b5f69a8e4519b555120fade6bbb24a0747e2d6122bae9ea6216f396ddb682b8b6980b93b796ebd03dd6b1df38486d9cbf252b53325d41f971a7c9e9b5cabbecb01797221d8da1b30c5bab1e0c47373b9Line truncated
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffd43c5b73db3697eff915a89a965422534e76b7b363c5e9b44edaf5e6e68993bcb87ea04448624c812a09dad6b8faefdf390048020448d176d2a69ef9bed8b89c3bce0d60c78f3ee749cc389966e9554eb303c2b3828ec82c653c66052dff5e27458eff937f9347e307e3478b249d8609797840e66192c3a2902d8a24ccd4dfb8e88157c02f39cfe219f7260f1e5c8619c9376cc697315b90c37247b04aa322a1be57cd792372763e9c880d45964c43007348bc8ce6024eb52e4042b3344968e67ba7e5e811cf1280302fe0ef3865c47f98cfd23550f870c9f97a486e1e10f841d8eb8c5ebe083902df9f54a30bcadfbd8221e4b51e45e461c625e58245a0042725742485518130870537db4963721e2fecf1d5e6f80572e619a32c8d2802393b77003966c8a8419e9aa75996668e7d39a5ec25ced99840f234b1c9cae83a2db910e3e331390535b2454ea6749e66944cd334c94992a61730c239cd4c8c9c8bc5408b18bf89a303e2bd8e734e190002ed008733b015a1357292a53c9da509912bc82f5104e2ce690e0bf9660d76e8717acde12fa5056988db9106fc4d787d4a59f46abace35f0ef0abe485167ef51cdafe355cc89ff2afe759c0f6bd8ac584d69d609fd3dc00bd93103462fc3e454c32067483945fc5b435696e306ae26ef0eff24cc423820c97bfa67018b74e180c808080876b248c8a85ed21f3e00395ac249a60dc923f0dfe28412392b15d05ff41a86df85a7f985b1972c9c2634d290c8290273299c765ac345f3ec24fb753a6b812966ee02f214c77f959e54b7701c26f5b80eced8fff1849dd8e4c8118293eecde7a61f5a14f1a9fbf8a953a58befe3f17d8edc47935184f64bc1971482c72c14aef7a3c1f24e8027619e5fa559d40d545ba500afeb914e6a3fbcd60f170c90fffbf0e1e49480472380a897ae4b7157e105c2c569319b511ad1c82fa30bfec473e27f2782893eaaa92a6631f7871373caf7be6794033717c2677b4374d261e27bcb38a25e63b51daaf0676b905007ae5b92516fec26c215194d52b6b6c87e0bc137d8f26a2736a3bcc8581b936e31b7c9f2661ace2ea22c5d83aa011f581628fb826ea66998452a81d9b688ba8bc12a7cce818f252eae72109d3691870400d02f939bc7c41be71b38882ba031476bca73bfde1c853c6c32679addc4a5580911c8c0fd1ac943992af86eea14f05241fabefaf777d3cf1095029059eeeb49c33080b3f4329c2d35e0716429c62900918cfc8c600e3d18a06c06031fdf1f1fa5ab75cac00120a4bee2d1c420e09ec5d1b925892657faef6e1ab52cafb7a6307b64e91560c75c13b2bb2b7f383256f008267d5cb357e5a44332264ff6f7f7cd9571a4dc4ff9a3a5b0b0df69063183c85ca7b88dd9b4e0d5b4318f4e11244e6246da042c3c1c4e06cb307f77c5208f5bd38c6f84a21cebf1a7ac2d26d6ecd61ae1d9a6050a22459556ccbd09f9325885d7fefe88fc2f79243521561cb35f379ce61f520e617dcf91ae5bab50f43c1ada141a982bc1b5a386e4aa0f6e63592bf22d81f8375b129fb689d612ca7e5f161c0b6d6d18e6f4f8b081ce86601a98be410e35cea1cb38cda2aae9c6761d565910f53ea7cd32ca8d6e3b79d02c9520c3e3456eb87b1c6ec636cc2dd2b9e995701df8a543a8cc0a16d179cc20f973873e4858d8059c71e6e9d1c7c0608306dd40d100a7f83b44d10af994a7eb3560764216653b973ec643cfec4023e6ebdde572f1efd9fe79c0d38f80203b02d540b0792c27402fd39c67fe93e1c4e4436d3f24032c0f21191890bffe22f5e87194d0419317390d663620fea0a6129b0527349b41fc08175429e63119fc301c38b95522d1186a06f7757a9440c2f9f5f51db379fa15941d613d967d315d1b0af362504d2b66750ebdb62cae06934bbdb7425a67f12acc364e480ef1992a344de2abeb11a2781bc30ee9cabe9a880702fe7e3fa88606d7330e5cc10a88464e33c16325518c5d0b341a264db18a68374f52c81f018ddb296203cbe11471f8686e64f6482d3a7958e7088e6a43f016fe3d7e716eda1c2e6ccaa61c0f30674ca8408b420451b882666929c78ca044bc464422141b99eddb9473223e1e94265a08403f0c9b103b1c8ef722ce15ef95237688f578862cfd1b849a5edc569eaa6eba8dd056904ae6edd2b21df5372b2edb37f69299ed0877ca4cf78bb6c8b011f4374b4c112684a6fa505d7efde70e7d6b22ffc758683881ce18d5ceca27ba530d488c49a93034ed6ea1854cb5e2926639c076d1f735c593c410783fb5e3dea16788b51122b6a463b28b1cacb060125729facd0a404838d5db1f486f8996d5a22412eac428359045053748285bf025a45be4490bc75572d0c1a882066972ab31bc0d5736bf5dd600eb5b28d297741065aab8ccd4a1c2fdc91df2f932cedfba286dea8449d535b6f90d09ab9c4b2eee95650dfc429647629399dc3745b44b3e7d84d35b32348ab9d6916f6909fadef7e5ad59df36a5684a0f9d096e784977a374de2a36da9bc6a2e0dd5a9cff40de1928576db8087bd529cf827c9dc4dcf746c859b8d60edeb576f0ae030eb10c0cc151d9afd3dceac3012a10c7ff9fbe7b1be4e26e329e6f7c8392e188dc2c691881ab392037de51ca801ebef7016ccb0391866b204bde298c3fe729f3b60662974606d8ff1eb4750244ebba55de469bdc6cd8b775dbf3657ae5ed1686da6aacdc7165dca03d5f163cc2b3d3ddb2b63097fb9c3d16ab40a7fc43bca269c17db351ee83a29efecf7e5b23f676ace07173868786bb2cc116590646a1763c0ce835d848e4df6c47a50bb4494114a0a797d760e04e751acb4e693297eddd46a43602b5cd6f4d58505dcec1612287956fae8683cf69cce07c118709e0e29740499a050f4103279920da70b8687ea5d8eee47c4c0d84911d9f774afe46e71150461b16ae00e7b687f4dd3ecb14bf7bcddf2f1c28b229a7ddf27161b46ede44efdd2d92dd57672e39f44b939c21b3b4e9ef6aa3d6cd57cef638dd6265930ead3728ae24308990d712f2c6c9ddc51573a2d9dc80d998e8c1e53d386d726b4b7e47f8fd27a25f33364032d169af6556072e6944a294d1118927b765b497cd2b2cc4257b6b55e5689bb92c584012cea83f266320d80374d5c85e39a252110b66e5a55c6ef88ea94e850465678b46dec3894b1a129367e6199515084c3c7eecea43e86bcfe273bd4a3485d2717d5a6eae399e584b15e566182c7fa6190d2f7af427e46d22406a39d292e3750109831d9a5b7c5a90a719f7cbd64098d1bbba9e6fe124a67c49b392ceb624532ff05bfd786f378eb989edb85b6abf4e0f114342d574e577b06ad6501118e6c4327bd6b31da233df6ea00e8ec324e9d643e913358baab5d7742ccaa8ad92786835df95553a2812b7965871f5340d79cb69db465b594c03ccddc973eb51e94eeb982534cc5e9697aa9d29a1fe52d5a0f3cca45af5Line truncated
|
||||
gr, _ = gzip.NewReader(bytes.NewBuffer(bs))
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["app.js"] = bs
|
||||
|
||||
+25
-3
@@ -13,6 +13,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"crypto/tls"
|
||||
"code.google.com/p/go.crypto/bcrypt"
|
||||
"github.com/calmh/syncthing/config"
|
||||
"github.com/calmh/syncthing/logger"
|
||||
@@ -42,9 +43,30 @@ func init() {
|
||||
}
|
||||
|
||||
func startGUI(cfg config.GUIConfiguration, m *model.Model) error {
|
||||
listener, err := net.Listen("tcp", cfg.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
var listener net.Listener
|
||||
var err error
|
||||
if cfg.UseTLS {
|
||||
cert, err := loadCert(confDir, "https-")
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
router := martini.NewRouter()
|
||||
|
||||
+10
-5
@@ -144,10 +144,10 @@ func main() {
|
||||
// Ensure that our home directory exists and that we have a certificate and key.
|
||||
|
||||
ensureDir(confDir, 0700)
|
||||
cert, err := loadCert(confDir)
|
||||
cert, err := loadCert(confDir, "")
|
||||
if err != nil {
|
||||
newCertificate(confDir)
|
||||
cert, err = loadCert(confDir)
|
||||
newCertificate(confDir, "")
|
||||
cert, err = loadCert(confDir, "")
|
||||
l.FatalErr(err)
|
||||
}
|
||||
|
||||
@@ -272,13 +272,18 @@ func main() {
|
||||
hostShow = hostOpen
|
||||
}
|
||||
|
||||
l.Infof("Starting web GUI on http://%s:%d/", hostShow, addr.Port)
|
||||
var proto = "http"
|
||||
if cfg.GUI.UseTLS {
|
||||
proto = "https"
|
||||
}
|
||||
|
||||
l.Infof("Starting web GUI on %s://%s:%d/", proto, hostShow, addr.Port)
|
||||
err := startGUI(cfg.GUI, m)
|
||||
if err != nil {
|
||||
l.Fatalln("Cannot start GUI:", err)
|
||||
}
|
||||
if cfg.Options.StartBrowser && len(os.Getenv("STRESTART")) == 0 {
|
||||
openURL(fmt.Sprintf("http://%s:%d", hostOpen, addr.Port))
|
||||
openURL(fmt.Sprintf("%s://%s:%d", proto, hostOpen, addr.Port))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ const (
|
||||
tlsName = "syncthing"
|
||||
)
|
||||
|
||||
func loadCert(dir string) (tls.Certificate, error) {
|
||||
return tls.LoadX509KeyPair(filepath.Join(dir, "cert.pem"), filepath.Join(dir, "key.pem"))
|
||||
func loadCert(dir string, prefix string) (tls.Certificate, error) {
|
||||
return tls.LoadX509KeyPair(filepath.Join(dir, prefix+"cert.pem"), filepath.Join(dir, prefix+"key.pem"))
|
||||
}
|
||||
|
||||
func certID(bs []byte) string {
|
||||
@@ -40,7 +40,7 @@ func certSeed(bs []byte) int64 {
|
||||
return int64(binary.BigEndian.Uint64(id))
|
||||
}
|
||||
|
||||
func newCertificate(dir string) {
|
||||
func newCertificate(dir string, prefix string) {
|
||||
l.Infoln("Generating RSA certificate and key...")
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, tlsRSABits)
|
||||
@@ -65,13 +65,13 @@ func newCertificate(dir string) {
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||
l.FatalErr(err)
|
||||
|
||||
certOut, err := os.Create(filepath.Join(dir, "cert.pem"))
|
||||
certOut, err := os.Create(filepath.Join(dir, prefix+"cert.pem"))
|
||||
l.FatalErr(err)
|
||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||
certOut.Close()
|
||||
l.Okln("Created RSA certificate file")
|
||||
|
||||
keyOut, err := os.OpenFile(filepath.Join(dir, "key.pem"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
keyOut, err := os.OpenFile(filepath.Join(dir, prefix+"key.pem"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
l.FatalErr(err)
|
||||
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||||
keyOut.Close()
|
||||
|
||||
@@ -73,6 +73,7 @@ type GUIConfiguration struct {
|
||||
Address string `xml:"address" default:"127.0.0.1:8080"`
|
||||
User string `xml:"user,omitempty"`
|
||||
Password string `xml:"password,omitempty"`
|
||||
UseTLS bool `xml:"tls,attr"`
|
||||
}
|
||||
|
||||
func setDefaults(data interface{}) error {
|
||||
|
||||
@@ -40,6 +40,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
|
||||
{id: 'Address', descr: 'GUI Listen Addresses', type: 'text', restart: true},
|
||||
{id: 'User', descr: 'GUI Authentication User', type: 'text', restart: true},
|
||||
{id: 'Password', descr: 'GUI Authentication Password', type: 'password', restart: true},
|
||||
{id: 'UseTLS', descr: 'Use HTTPS for GUI', type: 'bool', restart: true},
|
||||
];
|
||||
|
||||
function getSucceeded() {
|
||||
|
||||
Reference in new issue
Block a user