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},