From d3508b012c6fdf7e1a541e958bd9877a8bfa6c3d Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 14:31:40 +0200 Subject: [PATCH 01/11] Build also generate_cert utility --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 5852c8c..6539615 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,8 @@ build: mkdir -p $(BUILD_DIR) sed -e s/UNKNOWN/$(VERSION)/ $(NAME).go > $(BUILD_DIR)/$(NAME).go cd $(BUILD_DIR) && go build $(NAME).go + cp etc/generate_cert.go $(BUILD_DIR) + cd $(BUILD_DIR) && go build generate_cert.go run: clean build @echo "$(YELLOW)Run Cheese Shop$(CLEAR)" From cdaaad51072392925121a2d27e5281c65332cb1c Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 14:32:51 +0200 Subject: [PATCH 02/11] Added HTTPS support --- cheeseshop.go | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/cheeseshop.go b/cheeseshop.go index 1e05f22..d63836d 100644 --- a/cheeseshop.go +++ b/cheeseshop.go @@ -24,11 +24,14 @@ const ( var DEFAULT_CONFIG = []string{"~/.cheeseshop.yml", "/etc/cheeseshop.yml"} type Config struct { - Port int - Path string - Root string - Shop string - Auth map[string]string + Http int + Https int + Path string + Root string + Shop string + Cert string + Key string + Auth map[string]string } var config Config @@ -206,17 +209,34 @@ func checkConfig() { if !strings.HasSuffix(config.Path, "/") { config.Path = config.Path + "/" } - if config.Port > 65535 || config.Port < 0 { - log.Fatalf("Bad port number %d", config.Port) + if config.Http > 65535 || config.Http < 0 { + log.Fatalf("Bad HTTP port number %d", config.Http) + } + if config.Https > 65535 || config.Https < 0 { + log.Fatalf("Bad HTTPS port number %d", config.Https) + } + if config.Http == 0 && config.Https == 0 { + log.Fatal("At least one of HTTP or HTTPS must be enabled") } } func main() { loadConfig() checkConfig() + log.Printf("Starting CheeseShop (ports: %d & %d, path: %s, root: %s, shop: %s)", + config.Http, config.Https, config.Path, config.Root, config.Shop) http.HandleFunc(config.Path, handler) - log.Printf("Starting CheeseShop (port: %d, path: %s, root: %s, shop: %s)", - config.Port, config.Path, config.Root, config.Shop) - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", config.Port), nil)) - log.Print("Stopping CheeseShop") + if config.Http != 0 { + go func() { + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", config.Http), nil)) + }() + } + if config.Https != 0 { + go func() { + log.Fatal(http.ListenAndServeTLS(fmt.Sprintf(":%d", config.Https), + normalizeFile(config.Cert), normalizeFile(config.Key), nil)) + }() + } + wait := make(chan bool, 1) + <-wait } From e9eb815bf2c371579d7388f63914408d1a1577a8 Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 14:33:45 +0200 Subject: [PATCH 03/11] Added HTTPS configuration --- etc/cheeseshop.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/etc/cheeseshop.yml b/etc/cheeseshop.yml index aa01ec7..8ed51c6 100644 --- a/etc/cheeseshop.yml +++ b/etc/cheeseshop.yml @@ -1,11 +1,17 @@ -# The port CheeseShop is listening -port: 8000 -# The URL path -path: simple # The root directory for packages -root: repo +root: repo +# Path to the server certificate +cert: etc/cert.pem +# Path to the server key +key: etc/key.pem +# The HTTP port CheeseShop is listening +http: 80 +# The HTTPS port CheeseShop is listening +https: 443 +# The URL path +path: simple # Redirection when not found -shop: http://pypi.python.org/simple +shop: http://pypi.python.org/simple # List of users and their MD5 hashed password # To get MD5 sum for password foo, type 'echo -n foo | md5sum' # To disable auth when uploading packages, set auth to ~ From 4e1cc6dc888abba9d629264ddc202b6e3270e731 Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 14:39:22 +0200 Subject: [PATCH 04/11] Changed cert configuration --- etc/cheeseshop.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/cheeseshop.yml b/etc/cheeseshop.yml index 8ed51c6..04526f8 100644 --- a/etc/cheeseshop.yml +++ b/etc/cheeseshop.yml @@ -1,9 +1,9 @@ # The root directory for packages root: repo # Path to the server certificate -cert: etc/cert.pem +cert: /etc/ssl/certs/cheeseshop-cert.pem # Path to the server key -key: etc/key.pem +key: /etc/ssl/private/cheeseshop-key.pem # The HTTP port CheeseShop is listening http: 80 # The HTTPS port CheeseShop is listening From afcefff35381717e1946afda81c9561a8c5ea9c7 Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 14:41:30 +0200 Subject: [PATCH 05/11] Added tool to generate certificate --- gencert.go | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 gencert.go diff --git a/gencert.go b/gencert.go new file mode 100644 index 0000000..83f9916 --- /dev/null +++ b/gencert.go @@ -0,0 +1,161 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// Generate a self-signed X.509 certificate for a TLS server. Outputs to +// 'cert.pem' and 'key.pem' and will overwrite existing files. + +package main + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "flag" + "fmt" + "log" + "math/big" + "net" + "os" + "strings" + "time" +) + +var ( + host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") + validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") + validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") + isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") + rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set") + ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521") +) + +func publicKey(priv interface{}) interface{} { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &k.PublicKey + case *ecdsa.PrivateKey: + return &k.PublicKey + default: + return nil + } +} + +func pemBlockForKey(priv interface{}) *pem.Block { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} + case *ecdsa.PrivateKey: + b, err := x509.MarshalECPrivateKey(k) + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err) + os.Exit(2) + } + return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} + default: + return nil + } +} + +func main() { + flag.Parse() + + if len(*host) == 0 { + log.Fatalf("Missing required --host parameter") + } + + var priv interface{} + var err error + switch *ecdsaCurve { + case "": + priv, err = rsa.GenerateKey(rand.Reader, *rsaBits) + case "P224": + priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) + case "P256": + priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + case "P384": + priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) + case "P521": + priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) + default: + fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", *ecdsaCurve) + os.Exit(1) + } + if err != nil { + log.Fatalf("failed to generate private key: %s", err) + } + + var notBefore time.Time + if len(*validFrom) == 0 { + notBefore = time.Now() + } else { + notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) + os.Exit(1) + } + } + + notAfter := notBefore.Add(*validFor) + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + log.Fatalf("failed to generate serial number: %s", err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Acme Co"}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + hosts := strings.Split(*host, ",") + for _, h := range hosts { + if ip := net.ParseIP(h); ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } else { + template.DNSNames = append(template.DNSNames, h) + } + } + + if *isCA { + template.IsCA = true + template.KeyUsage |= x509.KeyUsageCertSign + } + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) + if err != nil { + log.Fatalf("Failed to create certificate: %s", err) + } + + certOut, err := os.Create("cert.pem") + if err != nil { + log.Fatalf("failed to open cert.pem for writing: %s", err) + } + pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + certOut.Close() + log.Print("written cert.pem\n") + + keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + log.Print("failed to open key.pem for writing:", err) + return + } + pem.Encode(keyOut, pemBlockForKey(priv)) + keyOut.Close() + log.Print("written key.pem\n") +} From a8ab59202415b977a35e8f9a7116e9ac48d768b8 Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 16:10:00 +0200 Subject: [PATCH 06/11] Removed tool to generate certificates and sample repo --- gencert.go | 161 ------------------------------------ repo/eggs/eggs-1.0.0.tar.gz | Bin 134 -> 0 bytes repo/eggs/eggs-2.0.0.tar.gz | Bin 134 -> 0 bytes repo/eggs/eggs-3.0.0.tar.gz | Bin 134 -> 0 bytes repo/spam/spam-1.0.0.tar.gz | Bin 134 -> 0 bytes repo/spam/spam-2.0.0.tar.gz | Bin 134 -> 0 bytes repo/spam/spam-3.0.0.tar.gz | Bin 134 -> 0 bytes 7 files changed, 161 deletions(-) delete mode 100644 gencert.go delete mode 100644 repo/eggs/eggs-1.0.0.tar.gz delete mode 100644 repo/eggs/eggs-2.0.0.tar.gz delete mode 100644 repo/eggs/eggs-3.0.0.tar.gz delete mode 100644 repo/spam/spam-1.0.0.tar.gz delete mode 100644 repo/spam/spam-2.0.0.tar.gz delete mode 100644 repo/spam/spam-3.0.0.tar.gz diff --git a/gencert.go b/gencert.go deleted file mode 100644 index 83f9916..0000000 --- a/gencert.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -// Generate a self-signed X.509 certificate for a TLS server. Outputs to -// 'cert.pem' and 'key.pem' and will overwrite existing files. - -package main - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "flag" - "fmt" - "log" - "math/big" - "net" - "os" - "strings" - "time" -) - -var ( - host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") - validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") - validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") - isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") - rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set") - ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521") -) - -func publicKey(priv interface{}) interface{} { - switch k := priv.(type) { - case *rsa.PrivateKey: - return &k.PublicKey - case *ecdsa.PrivateKey: - return &k.PublicKey - default: - return nil - } -} - -func pemBlockForKey(priv interface{}) *pem.Block { - switch k := priv.(type) { - case *rsa.PrivateKey: - return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} - case *ecdsa.PrivateKey: - b, err := x509.MarshalECPrivateKey(k) - if err != nil { - fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err) - os.Exit(2) - } - return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} - default: - return nil - } -} - -func main() { - flag.Parse() - - if len(*host) == 0 { - log.Fatalf("Missing required --host parameter") - } - - var priv interface{} - var err error - switch *ecdsaCurve { - case "": - priv, err = rsa.GenerateKey(rand.Reader, *rsaBits) - case "P224": - priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) - case "P256": - priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - case "P384": - priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) - case "P521": - priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) - default: - fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", *ecdsaCurve) - os.Exit(1) - } - if err != nil { - log.Fatalf("failed to generate private key: %s", err) - } - - var notBefore time.Time - if len(*validFrom) == 0 { - notBefore = time.Now() - } else { - notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) - os.Exit(1) - } - } - - notAfter := notBefore.Add(*validFor) - - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) - serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - log.Fatalf("failed to generate serial number: %s", err) - } - - template := x509.Certificate{ - SerialNumber: serialNumber, - Subject: pkix.Name{ - Organization: []string{"Acme Co"}, - }, - NotBefore: notBefore, - NotAfter: notAfter, - - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, - BasicConstraintsValid: true, - } - - hosts := strings.Split(*host, ",") - for _, h := range hosts { - if ip := net.ParseIP(h); ip != nil { - template.IPAddresses = append(template.IPAddresses, ip) - } else { - template.DNSNames = append(template.DNSNames, h) - } - } - - if *isCA { - template.IsCA = true - template.KeyUsage |= x509.KeyUsageCertSign - } - - derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) - if err != nil { - log.Fatalf("Failed to create certificate: %s", err) - } - - certOut, err := os.Create("cert.pem") - if err != nil { - log.Fatalf("failed to open cert.pem for writing: %s", err) - } - pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) - certOut.Close() - log.Print("written cert.pem\n") - - keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - log.Print("failed to open key.pem for writing:", err) - return - } - pem.Encode(keyOut, pemBlockForKey(priv)) - keyOut.Close() - log.Print("written key.pem\n") -} diff --git a/repo/eggs/eggs-1.0.0.tar.gz b/repo/eggs/eggs-1.0.0.tar.gz deleted file mode 100644 index 07d1fbc7583f1703d0a12a6f0cc082ee7a905b4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmb2|=HQT?z9W=@IW;}KSl3X`00>JGix}RX+sJ#!fPuxKf0AHM@^N7U#>fLp7Bw^- z_&0&6lc`f{<-1w>|GMY*E!WJ^+1I;t&CICY`#%MP)|L9a3<%;ge0t4G;?cF^VdtM- ke1BMAU2*)cpO^BB|L^>LotXg&4)n$K%6<)D&|qKy0GwPp9smFU diff --git a/repo/eggs/eggs-2.0.0.tar.gz b/repo/eggs/eggs-2.0.0.tar.gz deleted file mode 100644 index 07d1fbc7583f1703d0a12a6f0cc082ee7a905b4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmb2|=HQT?z9W=@IW;}KSl3X`00>JGix}RX+sJ#!fPuxKf0AHM@^N7U#>fLp7Bw^- z_&0&6lc`f{<-1w>|GMY*E!WJ^+1I;t&CICY`#%MP)|L9a3<%;ge0t4G;?cF^VdtM- ke1BMAU2*)cpO^BB|L^>LotXg&4)n$K%6<)D&|qKy0GwPp9smFU diff --git a/repo/eggs/eggs-3.0.0.tar.gz b/repo/eggs/eggs-3.0.0.tar.gz deleted file mode 100644 index 07d1fbc7583f1703d0a12a6f0cc082ee7a905b4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmb2|=HQT?z9W=@IW;}KSl3X`00>JGix}RX+sJ#!fPuxKf0AHM@^N7U#>fLp7Bw^- z_&0&6lc`f{<-1w>|GMY*E!WJ^+1I;t&CICY`#%MP)|L9a3<%;ge0t4G;?cF^VdtM- ke1BMAU2*)cpO^BB|L^>LotXg&4)n$K%6<)D&|qKy0GwPp9smFU diff --git a/repo/spam/spam-1.0.0.tar.gz b/repo/spam/spam-1.0.0.tar.gz deleted file mode 100644 index 07d1fbc7583f1703d0a12a6f0cc082ee7a905b4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmb2|=HQT?z9W=@IW;}KSl3X`00>JGix}RX+sJ#!fPuxKf0AHM@^N7U#>fLp7Bw^- z_&0&6lc`f{<-1w>|GMY*E!WJ^+1I;t&CICY`#%MP)|L9a3<%;ge0t4G;?cF^VdtM- ke1BMAU2*)cpO^BB|L^>LotXg&4)n$K%6<)D&|qKy0GwPp9smFU diff --git a/repo/spam/spam-2.0.0.tar.gz b/repo/spam/spam-2.0.0.tar.gz deleted file mode 100644 index 07d1fbc7583f1703d0a12a6f0cc082ee7a905b4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmb2|=HQT?z9W=@IW;}KSl3X`00>JGix}RX+sJ#!fPuxKf0AHM@^N7U#>fLp7Bw^- z_&0&6lc`f{<-1w>|GMY*E!WJ^+1I;t&CICY`#%MP)|L9a3<%;ge0t4G;?cF^VdtM- ke1BMAU2*)cpO^BB|L^>LotXg&4)n$K%6<)D&|qKy0GwPp9smFU diff --git a/repo/spam/spam-3.0.0.tar.gz b/repo/spam/spam-3.0.0.tar.gz deleted file mode 100644 index 07d1fbc7583f1703d0a12a6f0cc082ee7a905b4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmb2|=HQT?z9W=@IW;}KSl3X`00>JGix}RX+sJ#!fPuxKf0AHM@^N7U#>fLp7Bw^- z_&0&6lc`f{<-1w>|GMY*E!WJ^+1I;t&CICY`#%MP)|L9a3<%;ge0t4G;?cF^VdtM- ke1BMAU2*)cpO^BB|L^>LotXg&4)n$K%6<)D&|qKy0GwPp9smFU From b3e48883103ef62220cea40d584e2005f9c1a976 Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 16:12:27 +0200 Subject: [PATCH 07/11] Removed gencert build --- Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Makefile b/Makefile index 6539615..5852c8c 100644 --- a/Makefile +++ b/Makefile @@ -30,8 +30,6 @@ build: mkdir -p $(BUILD_DIR) sed -e s/UNKNOWN/$(VERSION)/ $(NAME).go > $(BUILD_DIR)/$(NAME).go cd $(BUILD_DIR) && go build $(NAME).go - cp etc/generate_cert.go $(BUILD_DIR) - cd $(BUILD_DIR) && go build generate_cert.go run: clean build @echo "$(YELLOW)Run Cheese Shop$(CLEAR)" From a0417b9c2dac99595c5a78c176bc2da80f277d50 Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 16:13:23 +0200 Subject: [PATCH 08/11] Updated for release --- CHANGELOG.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.yml b/CHANGELOG.yml index fda793f..265d996 100644 --- a/CHANGELOG.yml +++ b/CHANGELOG.yml @@ -1,5 +1,9 @@ # Semantic changelog: https://github.com/c4s4/changelog +- version: 1.4.0 + date: 2015-07-30 + summary: Added HTTPS support + - version: 1.3.1 date: 2015-07-29 summary: Improved documentation From b4ad0ea1010f052d761f25f272843a3264fb3c1e Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 16:41:16 +0200 Subject: [PATCH 09/11] Changed root to a realistic value --- etc/cheeseshop.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/cheeseshop.yml b/etc/cheeseshop.yml index 04526f8..29b41f0 100644 --- a/etc/cheeseshop.yml +++ b/etc/cheeseshop.yml @@ -1,5 +1,5 @@ # The root directory for packages -root: repo +root: /home/cheeseshop # Path to the server certificate cert: /etc/ssl/certs/cheeseshop-cert.pem # Path to the server key From a327f9d75d464724e26145b3753ee8f770e94efd Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 16:41:36 +0200 Subject: [PATCH 10/11] Updated documentation for HTTPS --- README.md | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 43c8034..ba006fb 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ CheeseShop is a Python package repository. This is a local version of the well-k To tell PIP where is your private CheeseShop, you must edit you *~/.pip/pip.conf* file: [global] - index-url = http://my.shop.host:8000/simple + index-url = http://my.shop.host/simple + trusted-host = my.shop.host Where *my.shop.host* is the hostname of the machine running CheeseShop. PIP will call your CheeseShop to get packages. If CheeseShop doesn't host this package it will redirect PIP to standard Pypi. @@ -27,14 +28,16 @@ To tell *setup.py* where to upload your package, you must edit file *~/.pypirc*: [cheeseshop] username: spam password: foo - repository: http://my.shop.host:8000/simple/ + repository: http://my.shop.host/simple/ -*setup.py* will call your CheeseShop if you tell it to use *cheeseshop* connection with following command line: +*setup.py* will call your CheeseShop if you name it on command line: $ python setup.py sdist upload -r cheeseshop Where `-r cheeseshop` is the option that indicates the connection you want to use. There must be a corresponding entry in your *~/.pypirc* configuration file. Don't forget to add *cheeseshop* in the *index-server* list at the beginning of the file. +CheeseShop is able to run on HTTP and/or HTTPS and performs basic authentication if necessary. + Installation ------------ @@ -67,14 +70,20 @@ You may also pass the path to the configuration file on the command line: This configuration file should look like this: - # The port CheeseShop is listening - port: 8000 - # The URL path - path: simple # The root directory for packages - root: repo + root: /home/cheeseshop + # Path to the server certificate + cert: /etc/ssl/certs/cheeseshop-cert.pem + # Path to the server key + key: /etc/ssl/private/cheeseshop-key.pem + # The HTTP port CheeseShop is listening + http: 80 + # The HTTPS port CheeseShop is listening + https: 443 + # The URL path + path: simple # Redirection when not found - shop: http://pypi.python.org/simple + shop: http://pypi.python.org/simple # List of users and their MD5 hashed password # To get MD5 sum for password foo, type 'echo -n foo | md5sum' # To disable auth when uploading packages, set auth to ~ @@ -91,6 +100,22 @@ To compute MD5 sum for a given password, in order to fill the authentication fil There is a sample configuration file in *etc* directory of the archive. +Of course, you must create an empty directory for the repository. Ensure that the user running CheeseShop has a right to write in this directory. + +To disable HTTP or HTTPS, you must set port to *0*. If HTTPS is disabled, you don't have to set certificate and key paths. To disable basic authentication, you must set auth to `~` (which means none in YAML). + +To generate a key, you can use openssl as follows: + + openssl genrsa -out cheeseshop-key.pem 2048 + +To generate au self signed certificate, you can type: + + openssl req -new -x509 -key cheeseshop-key.pem -out cheeseshop-cert.pem -days 3650 + +This command will ask you many fields, but the only that is necessary is the *FQDN* which is the name of the machine that is running CheeseShop. + +You should copy the certificate in directory */etc/ssl/certs* and the key in */etc/ssl/private*. + Service ------- From e430c4b7ba403babf1f90e096377cdde615be941 Mon Sep 17 00:00:00 2001 From: Michel Casabianca Date: Thu, 30 Jul 2015 16:47:49 +0200 Subject: [PATCH 11/11] Fixes --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ba006fb..6a321ba 100644 --- a/README.md +++ b/README.md @@ -106,13 +106,13 @@ To disable HTTP or HTTPS, you must set port to *0*. If HTTPS is disabled, you do To generate a key, you can use openssl as follows: - openssl genrsa -out cheeseshop-key.pem 2048 + $ openssl genrsa -out cheeseshop-key.pem 2048 To generate au self signed certificate, you can type: - openssl req -new -x509 -key cheeseshop-key.pem -out cheeseshop-cert.pem -days 3650 + $ openssl req -new -x509 -key cheeseshop-key.pem -out cheeseshop-cert.pem -days 3650 -This command will ask you many fields, but the only that is necessary is the *FQDN* which is the name of the machine that is running CheeseShop. +This command will ask you many fields, but the only that is necessary is the *FQDN* which is the hostname of the machine that is running CheeseShop. You should copy the certificate in directory */etc/ssl/certs* and the key in */etc/ssl/private*. @@ -150,7 +150,7 @@ To build CheeseShop, you must install [Goyaml](http://github.com/go-yaml/yaml) a $ go get github.com/mitchellh/gox $ gox -build-toolchain -Then you can use the make file to build the binary version for your platform: +Then you can use the makefile to build the binary version for your platform: $ make build