2 * Copyright 2018 TechMahindra
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 uuid "github.com/hashicorp/go-uuid"
34 func loadPGPKeys(prKeyPath string, pbKeyPath string) (string, string, error) {
36 var pbkey, prkey string
38 prkey, err := smsauth.ReadFromFile(prKeyPath)
40 smslogger.WriteWarn("No Private Key found. Generating...")
41 pbkey, prkey, _ = smsauth.GeneratePGPKeyPair()
44 pbkey, err = smsauth.ReadFromFile(pbKeyPath)
46 smslogger.WriteWarn("No Public Key found. Generating...")
47 pbkey, prkey, _ = smsauth.GeneratePGPKeyPair()
52 // Storing the keys to file to allow for recovery during restarts
54 smsauth.WriteToFile(prkey, prKeyPath)
55 smsauth.WriteToFile(pbkey, pbKeyPath)
58 return pbkey, prkey, nil
62 //This application checks the backend status and
63 //calls necessary initialization endpoints on the
66 idFilePath := "auth/myid"
67 pbKeyPath := "auth/pbkey"
68 prKeyPath := "auth/prkey"
69 shardPath := "auth/shard"
72 smslogger.WriteInfo("Starting Log for Quorum Client")
75 myID is used to uniquely identify the quorum client
76 Using any other information such as hostname is not
77 guaranteed to be unique.
78 In Kubernetes, pod restarts will also change the hostname
80 myID, err := smsauth.ReadFromFile(idFilePath)
82 smslogger.WriteWarn("Unable to find an ID for this client. Generating...")
83 myID, _ = uuid.GenerateUUID()
84 smsauth.WriteToFile(myID, idFilePath)
88 readMyShard will read the shard from disk when this client
89 instance restarts. It will return err when a shard is not found.
90 This is the case for first startup
92 registrationDone := true
93 myShard, err := smsauth.ReadFromFile(shardPath)
95 smslogger.WriteWarn("Unable to find a shard file. Registering with SMS...")
96 registrationDone = false
99 pbkey, prkey, _ := loadPGPKeys(prKeyPath, pbKeyPath)
101 //Struct to read json configuration file
103 BackEndURL string `json:"url"`
104 CAFile string `json:"cafile"`
105 ClientCert string `json:"clientcert"`
106 ClientKey string `json:"clientkey"`
107 TimeOut string `json:"timeout"`
108 DisableTLS bool `json:"disable_tls"`
111 //Load the config File for reading
112 vcf, err := os.Open("config.json")
114 log.Fatalf("Error reading config file %v", err)
118 err = json.NewDecoder(vcf).Decode(&cfg)
120 log.Fatalf("Error while parsing config file %v", err)
123 transport := http.Transport{}
125 if cfg.DisableTLS == false {
126 // Read the CA cert. This can be the self-signed CA
127 // or CA cert provided by AAF
128 caCert, err := ioutil.ReadFile(cfg.CAFile)
130 log.Fatalf("Error while reading CA file %v ", err)
133 caCertPool := x509.NewCertPool()
134 caCertPool.AppendCertsFromPEM(caCert)
136 // Load the client certificate files
137 //cert, err := tls.LoadX509KeyPair(cfg.ClientCert, cfg.ClientKey)
139 // log.Fatalf("Error while loading key pair %v ", err)
142 transport.TLSClientConfig = &tls.Config{
143 MinVersion: tls.VersionTLS12,
145 //Enable once we have proper client certificates
146 //Certificates: []tls.Certificate{cert},
150 client := &http.Client{
151 Transport: &transport,
154 duration, _ := time.ParseDuration(cfg.TimeOut)
155 ticker := time.NewTicker(duration)
157 for _ = range ticker.C {
159 //URL and Port is configured in config file
160 response, err := client.Get(cfg.BackEndURL + "/v1/sms/quorum/status")
162 smslogger.WriteError("Unable to connect to SMS. Retrying...")
167 Seal bool `json:"sealstatus"`
169 err = json.NewDecoder(response.Body).Decode(&data)
173 // Unseal the vault if sealed
175 //Register with SMS if not already done so
176 if !registrationDone {
177 body := strings.NewReader(`{"pgpkey":"` + pbkey + `","quorumid":"` + myID + `"}`)
178 res, err := client.Post(cfg.BackEndURL+"/v1/sms/quorum/register", "application/json", body)
180 smslogger.WriteError("Ran into error during registration. Retrying...")
183 registrationDone = true
185 Shard string `json:"shard"`
187 json.NewDecoder(res.Body).Decode(&data)
189 smsauth.WriteToFile(myShard, shardPath)
192 decShard, err := smsauth.DecryptPGPString(myShard, prkey)
193 body := strings.NewReader(`{"unsealshard":"` + decShard + `"}`)
194 //URL and PORT is configured via config file
195 response, err = client.Post(cfg.BackEndURL+"/v1/sms/quorum/unseal", "application/json", body)
197 smslogger.WriteError("Error unsealing vault. Retrying... " + err.Error())