summaryrefslogtreecommitdiffstats
path: root/sms-service/src/quorumclient
diff options
context:
space:
mode:
authorKiran Kamineni <kiran.k.kamineni@intel.com>2018-03-21 09:13:26 -0700
committerKiran Kamineni <kiran.k.kamineni@intel.com>2018-04-13 17:22:02 -0700
commitce74c5ac55fdb51582268046632943e510a19f00 (patch)
treea0beb2382abe73f4db19c58aaa625f818a010800 /sms-service/src/quorumclient
parent2dd9f3de5b33d6acbcb641566b9e7d3ccbe91d8c (diff)
Adding secure init code for backend
Changes to allow quorum client to SMS communication Introducing a registration api for quorum clients to get their shard piece in PGP encrypted form from SMS Tested with 3 quorum clients. This is now ready for review. Issue-ID: AAF-168 Change-Id: I7a6ade792c1e5ebcf00cbc8c4a1f1942c006e7c7 Signed-off-by: Kiran Kamineni <kiran.k.kamineni@intel.com>
Diffstat (limited to 'sms-service/src/quorumclient')
-rw-r--r--sms-service/src/quorumclient/Gopkg.toml24
-rw-r--r--sms-service/src/quorumclient/Makefile7
-rw-r--r--sms-service/src/quorumclient/config.json10
-rw-r--r--sms-service/src/quorumclient/quorumclient.go127
4 files changed, 135 insertions, 33 deletions
diff --git a/sms-service/src/quorumclient/Gopkg.toml b/sms-service/src/quorumclient/Gopkg.toml
new file mode 100644
index 0000000..7641eef
--- /dev/null
+++ b/sms-service/src/quorumclient/Gopkg.toml
@@ -0,0 +1,24 @@
+# Gopkg.toml example
+#
+# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
+# for detailed Gopkg.toml documentation.
+#
+# required = ["github.com/user/thing/cmd/thing"]
+# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
+#
+# [[constraint]]
+# name = "github.com/user/project"
+# version = "1.0.0"
+#
+# [[constraint]]
+# name = "github.com/user/project2"
+# branch = "dev"
+# source = "github.com/myfork/project2"
+#
+# [[override]]
+# name = "github.com/x/y"
+# version = "2.4.0"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/hashicorp/go-uuid" \ No newline at end of file
diff --git a/sms-service/src/quorumclient/Makefile b/sms-service/src/quorumclient/Makefile
index 720be29..00e12a7 100644
--- a/sms-service/src/quorumclient/Makefile
+++ b/sms-service/src/quorumclient/Makefile
@@ -1,13 +1,14 @@
GOPATH := $(shell realpath "$(CURDIR)/../../")
BINARY := quorumclient
PLATFORM := linux
+DEPENDENCIES := github.com/golang/dep/cmd/dep
export GOPATH ...
all: test build
deploy: test build
-build: format
+build: deps format
CGO_ENABLED=0 GOOS=$(PLATFORM) go build -a \
-ldflags '-extldflags "-static"' \
-o $(GOPATH)/target/$(BINARY) -v quorumclient.go
@@ -22,4 +23,8 @@ test:
format:
go fmt ./...
+deps:
+ go get -u $(DEPENDENCIES)
+ $(GOPATH)/bin/dep ensure
+
.PHONY: test
diff --git a/sms-service/src/quorumclient/config.json b/sms-service/src/quorumclient/config.json
index 89979d5..a096968 100644
--- a/sms-service/src/quorumclient/config.json
+++ b/sms-service/src/quorumclient/config.json
@@ -1,9 +1,7 @@
{
- "url":"https://localhost:10443/",
- "cafile": "selfsignedca.pem",
- "clientcert":"client.crt",
+ "url":"https://aaf-sms:10443",
+ "cafile": "auth/selfsignedca.pem",
+ "clientcert":"client.cert",
"clientkey":"client.key",
- "key":"UHFFY0l6WDhZVlErbGxvWitFVWpUL3FCV083NXRra1B2TDVBblN4VE5mYz0=",
- "timeout":"60s",
- "disable_tls":false
+ "timeout":"10s"
} \ No newline at end of file
diff --git a/sms-service/src/quorumclient/quorumclient.go b/sms-service/src/quorumclient/quorumclient.go
index e3e6e40..7244720 100644
--- a/sms-service/src/quorumclient/quorumclient.go
+++ b/sms-service/src/quorumclient/quorumclient.go
@@ -19,8 +19,8 @@ package main
import (
"crypto/tls"
"crypto/x509"
- "encoding/base64"
"encoding/json"
+ uuid "github.com/hashicorp/go-uuid"
"io/ioutil"
"log"
"net/http"
@@ -31,11 +31,72 @@ import (
"time"
)
+func loadPGPKeys(prKeyPath string, pbKeyPath string) (string, string, error) {
+
+ var pbkey, prkey string
+ generated := false
+ prkey, err := smsauth.ReadFromFile(prKeyPath)
+ if err != nil {
+ smslogger.WriteWarn("No Private Key found. Generating...")
+ pbkey, prkey, _ = smsauth.GeneratePGPKeyPair()
+ generated = true
+ } else {
+ pbkey, err = smsauth.ReadFromFile(pbKeyPath)
+ if err != nil {
+ smslogger.WriteWarn("No Public Key found. Generating...")
+ pbkey, prkey, _ = smsauth.GeneratePGPKeyPair()
+ generated = true
+ }
+ }
+
+ // Storing the keys to file to allow for recovery during restarts
+ if generated {
+ smsauth.WriteToFile(prkey, prKeyPath)
+ smsauth.WriteToFile(pbkey, pbKeyPath)
+ }
+
+ return pbkey, prkey, nil
+
+}
+
//This application checks the backend status and
//calls necessary initialization endpoints on the
//SMS webservice
func main() {
- smslogger.Init("quorumclient.log")
+ idFilePath := "auth/myid"
+ pbKeyPath := "auth/pbkey"
+ prKeyPath := "auth/prkey"
+ shardPath := "auth/shard"
+
+ smslogger.Init("")
+ smslogger.WriteInfo("Starting Log for Quorum Client")
+
+ /*
+ myID is used to uniquely identify the quorum client
+ Using any other information such as hostname is not
+ guaranteed to be unique.
+ In Kubernetes, pod restarts will also change the hostname
+ */
+ myID, err := smsauth.ReadFromFile(idFilePath)
+ if err != nil {
+ smslogger.WriteWarn("Unable to find an ID for this client. Generating...")
+ myID, _ = uuid.GenerateUUID()
+ smsauth.WriteToFile(myID, idFilePath)
+ }
+
+ /*
+ readMyShard will read the shard from disk when this client
+ instance restarts. It will return err when a shard is not found.
+ This is the case for first startup
+ */
+ registrationDone := true
+ myShard, err := smsauth.ReadFromFile(shardPath)
+ if err != nil {
+ smslogger.WriteWarn("Unable to find a shard file. Registering with SMS...")
+ registrationDone = false
+ }
+
+ pbkey, prkey, _ := loadPGPKeys(prKeyPath, pbKeyPath)
//Struct to read json configuration file
type config struct {
@@ -43,7 +104,6 @@ func main() {
CAFile string `json:"cafile"`
ClientCert string `json:"clientcert"`
ClientKey string `json:"clientkey"`
- B64Key string `json:"key"`
TimeOut string `json:"timeout"`
DisableTLS bool `json:"disable_tls"`
}
@@ -55,15 +115,14 @@ func main() {
}
cfg := config{}
- decoder := json.NewDecoder(vcf)
- err = decoder.Decode(&cfg)
+ err = json.NewDecoder(vcf).Decode(&cfg)
if err != nil {
log.Fatalf("Error while parsing config file %v", err)
}
transport := http.Transport{}
- if cfg.DisableTLS {
+ if cfg.DisableTLS == false {
// Read the CA cert. This can be the self-signed CA
// or CA cert provided by AAF
caCert, err := ioutil.ReadFile(cfg.CAFile)
@@ -75,14 +134,16 @@ func main() {
caCertPool.AppendCertsFromPEM(caCert)
// Load the client certificate files
- cert, err := tls.LoadX509KeyPair(cfg.ClientCert, cfg.ClientKey)
- if err != nil {
- log.Fatalf("Error while loading key pair %v ", err)
- }
+ //cert, err := tls.LoadX509KeyPair(cfg.ClientCert, cfg.ClientKey)
+ //if err != nil {
+ // log.Fatalf("Error while loading key pair %v ", err)
+ //}
transport.TLSClientConfig = &tls.Config{
- RootCAs: caCertPool,
- Certificates: []tls.Certificate{cert},
+ MinVersion: tls.VersionTLS12,
+ RootCAs: caCertPool,
+ //Enable once we have proper client certificates
+ //Certificates: []tls.Certificate{cert},
}
}
@@ -90,36 +151,50 @@ func main() {
Transport: &transport,
}
- smsauth.GeneratePGPKeyPair()
-
duration, _ := time.ParseDuration(cfg.TimeOut)
ticker := time.NewTicker(duration)
for _ = range ticker.C {
//URL and Port is configured in config file
- response, err := client.Get(cfg.BackEndURL + "/v1/sms/status")
+ response, err := client.Get(cfg.BackEndURL + "/v1/sms/quorum/status")
if err != nil {
- log.Fatalf("Error while connecting to SMS webservice %v", err)
+ smslogger.WriteError("Unable to connect to SMS. Retrying...")
+ continue
}
- responseData, err := ioutil.ReadAll(response.Body)
- if err != nil {
- log.Fatalf("Error while reading response %v", err)
+ var data struct {
+ Seal bool `json:"sealstatus"`
}
+ err = json.NewDecoder(response.Body).Decode(&data)
- var data map[string]interface{}
- json.Unmarshal(responseData, &data)
- sealed := data["sealed"].(bool)
+ sealed := data.Seal
// Unseal the vault if sealed
if sealed {
- decdB64Key, _ := base64.StdEncoding.DecodeString(cfg.B64Key)
- body := strings.NewReader(`{"key":"` + string(decdB64Key) + `"}`)
+ //Register with SMS if not already done so
+ if !registrationDone {
+ body := strings.NewReader(`{"pgpkey":"` + pbkey + `","quorumid":"` + myID + `"}`)
+ res, err := client.Post(cfg.BackEndURL+"/v1/sms/quorum/register", "application/json", body)
+ if err != nil {
+ smslogger.WriteError("Ran into error during registration. Retrying...")
+ continue
+ }
+ registrationDone = true
+ var data struct {
+ Shard string `json:"shard"`
+ }
+ json.NewDecoder(res.Body).Decode(&data)
+ myShard = data.Shard
+ smsauth.WriteToFile(myShard, shardPath)
+ }
+
+ decShard, err := smsauth.DecryptPGPString(myShard, prkey)
+ body := strings.NewReader(`{"unsealshard":"` + decShard + `"}`)
//URL and PORT is configured via config file
- response, err = client.Post(cfg.BackEndURL+"/v1/sms/unseal", "application/json", body)
+ response, err = client.Post(cfg.BackEndURL+"/v1/sms/quorum/unseal", "application/json", body)
if err != nil {
- log.Fatalf("Error while unsealing %v", err)
+ smslogger.WriteError("Error unsealing vault. Retrying... " + err.Error())
}
}
}