You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by mi...@apache.org on 2018/07/10 21:50:09 UTC

[trafficcontrol] branch master updated: Add TO Go deliveryservices/sslkeys/delete

This is an automated email from the ASF dual-hosted git repository.

mitchell852 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new dce4aae  Add TO Go deliveryservices/sslkeys/delete
dce4aae is described below

commit dce4aaea5d4e51bf43ee4832911f9634923bd03b
Author: Robert Butts <ro...@apache.org>
AuthorDate: Mon Jun 18 11:23:44 2018 -0600

    Add TO Go deliveryservices/sslkeys/delete
---
 .../keys.go}                                       | 265 +++++++++++----------
 .../keys_test.go}                                  |   2 +-
 traffic_ops/traffic_ops_golang/riaksvc/dsutil.go   |  24 ++
 traffic_ops/traffic_ops_golang/routes.go           |   8 +-
 4 files changed, 171 insertions(+), 128 deletions(-)

diff --git a/traffic_ops/traffic_ops_golang/deliveryservices_keys.go b/traffic_ops/traffic_ops_golang/deliveryservice/keys.go
similarity index 87%
rename from traffic_ops/traffic_ops_golang/deliveryservices_keys.go
rename to traffic_ops/traffic_ops_golang/deliveryservice/keys.go
index 50d4f5f..5352da7 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservices_keys.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/keys.go
@@ -1,4 +1,4 @@
-package main
+package deliveryservice
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -37,124 +37,8 @@ import (
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
 )
 
-// Delivery Services: SSL Keys.
-
-// returns the cdn_id found by domainname.
-func getCDNIDByDomainname(domainName string, tx *sql.Tx) (int64, bool, error) {
-	cdnID := int64(0)
-	if err := tx.QueryRow(`SELECT id from cdn WHERE domain_name = $1`, domainName).Scan(&cdnID); err != nil {
-		if err == sql.ErrNoRows {
-			return 0, false, nil
-		}
-		return 0, false, err
-	}
-	return cdnID, true, nil
-}
-
-// returns a delivery service xmlId for a cdn by host regex.
-func getXMLID(cdnID int64, hostRegex string, tx *sql.Tx) (string, bool, error) {
-	q := `
-SELECT ds.xml_id from deliveryservice ds
-JOIN deliveryservice_regex dr on ds.id = dr.deliveryservice AND ds.cdn_id = $1
-JOIN regex r on r.id = dr.regex
-WHERE r.pattern = $2
-`
-	xmlID := ""
-	if err := tx.QueryRow(q, cdnID, hostRegex).Scan(&xmlID); err != nil {
-		if err == sql.ErrNoRows {
-			return "", false, nil
-		}
-		return "", false, errors.New("querying xml id: " + err.Error())
-	}
-	return xmlID, true, nil
-}
-
-// verify the server certificate chain and return the
-// certificate and its chain in the proper order. Returns a  verified,
-// ordered, and base64 encoded certificate and CA chain.
-func verifyAndEncodeCertificate(certificate string, rootCA string) (string, error) {
-	var pemEncodedChain string
-	var b64crt string
-
-	// strip newlines from encoded crt and decode it from base64.
-	crtArr := strings.Split(certificate, "\\n")
-	for i := 0; i < len(crtArr); i++ {
-		b64crt += crtArr[i]
-	}
-	pemCerts := make([]byte, base64.StdEncoding.EncodedLen(len(b64crt)))
-	_, err := base64.StdEncoding.Decode(pemCerts, []byte(b64crt))
-	if err != nil {
-		return "", fmt.Errorf("could not base64 decode the certificate %v", err)
-	}
-
-	// decode, verify, and order certs for storgae
-	var bundle string
-	certs := strings.SplitAfter(string(pemCerts), "-----END CERTIFICATE-----")
-	if len(certs) > 1 {
-		// decode and verify the server certificate
-		block, _ := pem.Decode([]byte(certs[0]))
-		cert, err := x509.ParseCertificate(block.Bytes)
-		if err != nil {
-			return "", fmt.Errorf("could not parse the server certificate %v", err)
-		}
-		if !(cert.KeyUsage&x509.KeyUsageKeyEncipherment > 0) {
-			return "", fmt.Errorf("no key encipherment usage for the server certificate")
-		}
-		for i := 0; i < len(certs)-1; i++ {
-			bundle += certs[i]
-		}
-
-		var opts x509.VerifyOptions
-
-		rootPool := x509.NewCertPool()
-		if rootCA != "" {
-			if !rootPool.AppendCertsFromPEM([]byte(rootCA)) {
-				return "", fmt.Errorf("root  CA certificate is empty, %v", err)
-			}
-		}
-
-		intermediatePool := x509.NewCertPool()
-		if !intermediatePool.AppendCertsFromPEM([]byte(bundle)) {
-			return "", fmt.Errorf("certificate CA bundle is empty, %v", err)
-		}
-
-		if rootCA != "" {
-			// verify the certificate chain.
-			opts = x509.VerifyOptions{
-				Intermediates: intermediatePool,
-				Roots:         rootPool,
-			}
-		} else {
-			opts = x509.VerifyOptions{
-				Intermediates: intermediatePool,
-			}
-		}
-
-		chain, err := cert.Verify(opts)
-		if err != nil {
-			return "", fmt.Errorf("could verify the certificate chain %v", err)
-		}
-		if len(chain) > 0 {
-			for _, link := range chain[0] {
-				// Only print non-self signed elements of the chain
-				if link.AuthorityKeyId != nil && !bytes.Equal(link.AuthorityKeyId, link.SubjectKeyId) {
-					block := &pem.Block{Type: "CERTIFICATE", Bytes: link.Raw}
-					pemEncodedChain += string(pem.EncodeToMemory(block))
-				}
-			}
-		} else {
-			return "", fmt.Errorf("Can't find valid chain for cert in file in request")
-		}
-	} else {
-		return "", fmt.Errorf("ERROR: no certificate chain to verify")
-	}
-
-	base64EncodedStr := base64.StdEncoding.EncodeToString([]byte(pemEncodedChain))
-
-	return base64EncodedStr, nil
-}
-
-func addDeliveryServiceSSLKeysHandler(w http.ResponseWriter, r *http.Request) {
+// AddSSLKeys adds the given ssl keys to the given delivery service.
+func AddSSLKeys(w http.ResponseWriter, r *http.Request) {
 	inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil)
 	if userErr != nil || sysErr != nil {
 		api.HandleErr(w, r, errCode, userErr, sysErr)
@@ -188,8 +72,8 @@ func addDeliveryServiceSSLKeysHandler(w http.ResponseWriter, r *http.Request) {
 	api.WriteRespRaw(w, r, keysObj)
 }
 
-// fetch the ssl keys for a deliveryservice specified by the fully qualified hostname
-func getDeliveryServiceSSLKeysByHostNameHandler(w http.ResponseWriter, r *http.Request) {
+// GetSSLKeysByHostName fetches the ssl keys for a deliveryservice specified by the fully qualified hostname
+func GetSSLKeysByHostName(w http.ResponseWriter, r *http.Request) {
 	inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"hostName"}, nil)
 	if userErr != nil || sysErr != nil {
 		api.HandleErr(w, r, errCode, userErr, sysErr)
@@ -241,7 +125,6 @@ func getDeliveryServiceSSLKeysByHostNameHandler(w http.ResponseWriter, r *http.R
 		api.HandleErr(w, r, errCode, userErr, sysErr)
 		return
 	}
-
 	keyObj, ok, err := riaksvc.GetDeliveryServiceSSLKeysObj(xmlID, version, inf.Tx.Tx, inf.Config.RiakAuthOptions)
 	if err != nil {
 		api.HandleErr(w, r, http.StatusInternalServerError, nil, errors.New("getting ssl keys: "+err.Error()))
@@ -255,8 +138,8 @@ func getDeliveryServiceSSLKeysByHostNameHandler(w http.ResponseWriter, r *http.R
 	api.WriteResp(w, r, keyObj)
 }
 
-// getDeliveryServiceSSLKeysByXMLIDHandler fetches the deliveryservice ssl keys by the specified xmlID.
-func getDeliveryServiceSSLKeysByXMLIDHandler(w http.ResponseWriter, r *http.Request) {
+// GetSSLKeysByXMLID fetches the deliveryservice ssl keys by the specified xmlID.
+func GetSSLKeysByXMLID(w http.ResponseWriter, r *http.Request) {
 	inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"xmlID"}, nil)
 	if userErr != nil || sysErr != nil {
 		api.HandleErr(w, r, errCode, userErr, sysErr)
@@ -285,3 +168,137 @@ func getDeliveryServiceSSLKeysByXMLIDHandler(w http.ResponseWriter, r *http.Requ
 	*inf.CommitTx = true
 	api.WriteResp(w, r, keyObj)
 }
+
+func DeleteSSLKeys(w http.ResponseWriter, r *http.Request) {
+	inf, userErr, sysErr, errCode := api.NewInfo(r, []string{"name"}, nil)
+	if userErr != nil || sysErr != nil {
+		api.HandleErr(w, r, errCode, userErr, sysErr)
+		return
+	}
+	defer inf.Close()
+	if inf.Config.RiakEnabled == false {
+		api.HandleErr(w, r, http.StatusInternalServerError, userErr, errors.New("deliveryservice.DeleteSSLKeys: Riak is not configured!"))
+		return
+	}
+	ds := tc.DeliveryServiceName(inf.Params["name"])
+	if err := riaksvc.DeleteDSSSLKeys(inf.Tx.Tx, inf.Config.RiakAuthOptions, ds, inf.Params["version"]); err != nil {
+		api.HandleErr(w, r, http.StatusInternalServerError, userErr, errors.New("deliveryservice.DeleteSSLKeys: deleting SSL keys: "+err.Error()))
+		return
+	}
+	api.WriteResp(w, r, "Successfully deleted ssl keys for "+string(ds))
+}
+
+// returns the cdn_id found by domainname.
+func getCDNIDByDomainname(domainName string, tx *sql.Tx) (int64, bool, error) {
+	cdnID := int64(0)
+	if err := tx.QueryRow(`SELECT id from cdn WHERE domain_name = $1`, domainName).Scan(&cdnID); err != nil {
+		if err == sql.ErrNoRows {
+			return 0, false, nil
+		}
+		return 0, false, err
+	}
+	return cdnID, true, nil
+}
+
+// returns a delivery service xmlId for a cdn by host regex.
+func getXMLID(cdnID int64, hostRegex string, tx *sql.Tx) (string, bool, error) {
+	q := `
+SELECT ds.xml_id from deliveryservice ds
+JOIN deliveryservice_regex dr on ds.id = dr.deliveryservice AND ds.cdn_id = $1
+JOIN regex r on r.id = dr.regex
+WHERE r.pattern = $2
+`
+	xmlID := ""
+	if err := tx.QueryRow(q, cdnID, hostRegex).Scan(&xmlID); err != nil {
+		if err == sql.ErrNoRows {
+			return "", false, nil
+		}
+		return "", false, errors.New("querying xml id: " + err.Error())
+	}
+	return xmlID, true, nil
+}
+
+// verify the server certificate chain and return the
+// certificate and its chain in the proper order. Returns a  verified,
+// ordered, and base64 encoded certificate and CA chain.
+func verifyAndEncodeCertificate(certificate string, rootCA string) (string, error) {
+	var pemEncodedChain string
+	var b64crt string
+
+	// strip newlines from encoded crt and decode it from base64.
+	crtArr := strings.Split(certificate, "\\n")
+	for i := 0; i < len(crtArr); i++ {
+		b64crt += crtArr[i]
+	}
+	pemCerts := make([]byte, base64.StdEncoding.EncodedLen(len(b64crt)))
+	_, err := base64.StdEncoding.Decode(pemCerts, []byte(b64crt))
+	if err != nil {
+		return "", fmt.Errorf("could not base64 decode the certificate %v", err)
+	}
+
+	// decode, verify, and order certs for storgae
+	var bundle string
+	certs := strings.SplitAfter(string(pemCerts), "-----END CERTIFICATE-----")
+	if len(certs) > 1 {
+		// decode and verify the server certificate
+		block, _ := pem.Decode([]byte(certs[0]))
+		cert, err := x509.ParseCertificate(block.Bytes)
+		if err != nil {
+			return "", fmt.Errorf("could not parse the server certificate %v", err)
+		}
+		if !(cert.KeyUsage&x509.KeyUsageKeyEncipherment > 0) {
+			return "", fmt.Errorf("no key encipherment usage for the server certificate")
+		}
+		for i := 0; i < len(certs)-1; i++ {
+			bundle += certs[i]
+		}
+
+		var opts x509.VerifyOptions
+
+		rootPool := x509.NewCertPool()
+		if rootCA != "" {
+			if !rootPool.AppendCertsFromPEM([]byte(rootCA)) {
+				return "", fmt.Errorf("root  CA certificate is empty, %v", err)
+			}
+		}
+
+		intermediatePool := x509.NewCertPool()
+		if !intermediatePool.AppendCertsFromPEM([]byte(bundle)) {
+			return "", fmt.Errorf("certificate CA bundle is empty, %v", err)
+		}
+
+		if rootCA != "" {
+			// verify the certificate chain.
+			opts = x509.VerifyOptions{
+				Intermediates: intermediatePool,
+				Roots:         rootPool,
+			}
+		} else {
+			opts = x509.VerifyOptions{
+				Intermediates: intermediatePool,
+			}
+		}
+
+		chain, err := cert.Verify(opts)
+		if err != nil {
+			return "", fmt.Errorf("could verify the certificate chain %v", err)
+		}
+		if len(chain) > 0 {
+			for _, link := range chain[0] {
+				// Only print non-self signed elements of the chain
+				if link.AuthorityKeyId != nil && !bytes.Equal(link.AuthorityKeyId, link.SubjectKeyId) {
+					block := &pem.Block{Type: "CERTIFICATE", Bytes: link.Raw}
+					pemEncodedChain += string(pem.EncodeToMemory(block))
+				}
+			}
+		} else {
+			return "", fmt.Errorf("Can't find valid chain for cert in file in request")
+		}
+	} else {
+		return "", fmt.Errorf("ERROR: no certificate chain to verify")
+	}
+
+	base64EncodedStr := base64.StdEncoding.EncodeToString([]byte(pemEncodedChain))
+
+	return base64EncodedStr, nil
+}
diff --git a/traffic_ops/traffic_ops_golang/deliveryservices_keys_test.go b/traffic_ops/traffic_ops_golang/deliveryservice/keys_test.go
similarity index 99%
rename from traffic_ops/traffic_ops_golang/deliveryservices_keys_test.go
rename to traffic_ops/traffic_ops_golang/deliveryservice/keys_test.go
index e5d2246..8c92aa9 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservices_keys_test.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/keys_test.go
@@ -1,4 +1,4 @@
-package main
+package deliveryservice
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
diff --git a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
index 2d04234..639f6f5 100644
--- a/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
+++ b/traffic_ops/traffic_ops_golang/riaksvc/dsutil.go
@@ -242,3 +242,27 @@ func GetBucketKey(tx *sql.Tx, authOpts *riak.AuthOptions, bucket string, key str
 	}
 	return val, found, nil
 }
+
+func DeleteDSSSLKeys(tx *sql.Tx, authOpts *riak.AuthOptions, ds tc.DeliveryServiceName, version string) error {
+	if version == "" {
+		version = "latest"
+	}
+	key := string(ds) + "-" + version
+
+	cluster, err := GetRiakClusterTx(tx, authOpts)
+	if err != nil {
+		return errors.New("getting riak cluster: " + err.Error())
+	}
+	if err = cluster.Start(); err != nil {
+		return errors.New("starting riak cluster: " + err.Error())
+	}
+	defer func() {
+		if err := cluster.Stop(); err != nil {
+			log.Errorln("stopping Riak cluster: " + err.Error())
+		}
+	}()
+	if err := DeleteObject(key, DeliveryServiceSSLKeysBucket, cluster); err != nil {
+		return errors.New("deleting SSL keys: " + err.Error())
+	}
+	return nil
+}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index bcf0777..301d5d6 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -344,9 +344,11 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.1, http.MethodPut, `snapshot/{cdn}/?$`, crconfig.SnapshotHandler(d.DB, d.Config), auth.PrivLevelOperations, Authenticated, nil},
 
 		//SSLKeys deliveryservice endpoints here that are marked  marked as '-wip' need to have tenancy checks added
-		{1.3, http.MethodGet, `deliveryservices-wip/xmlId/{xmlID}/sslkeys$`, getDeliveryServiceSSLKeysByXMLIDHandler, auth.PrivLevelAdmin, Authenticated, nil},
-		{1.3, http.MethodGet, `deliveryservices-wip/hostname/{hostName}/sslkeys$`, getDeliveryServiceSSLKeysByHostNameHandler, auth.PrivLevelAdmin, Authenticated, nil},
-		{1.3, http.MethodPost, `deliveryservices-wip/hostname/{hostName}/sslkeys/add$`, addDeliveryServiceSSLKeysHandler, auth.PrivLevelAdmin, Authenticated, nil},
+
+		{1.3, http.MethodGet, `deliveryservices-wip/xmlId/{xmlID}/sslkeys$`, deliveryservice.GetSSLKeysByXMLID, auth.PrivLevelAdmin, Authenticated, nil},
+		{1.3, http.MethodGet, `deliveryservices-wip/hostname/{hostName}/sslkeys$`, deliveryservice.GetSSLKeysByHostName, auth.PrivLevelAdmin, Authenticated, nil},
+		{1.3, http.MethodPost, `deliveryservices-wip/hostname/{hostName}/sslkeys/add$`, deliveryservice.AddSSLKeys, auth.PrivLevelAdmin, Authenticated, nil},
+		{1.3, http.MethodGet, `deliveryservices/xmlId/{name}/sslkeys/delete$`, deliveryservice.DeleteSSLKeys, auth.PrivLevelAdmin, Authenticated, nil},
 
 		////DeliveryServices
 		{1.3, http.MethodGet, `deliveryservices/?(\.json)?$`, api.ReadHandler(deliveryservice.GetTypeV13Factory()), auth.PrivLevelReadOnly, Authenticated, nil},