
<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<style>
			body {
				background: black;
				color: rgb(80, 80, 80);
			}
			body, pre, #legend span {
				font-family: Menlo, monospace;
				font-weight: bold;
			}
			#topbar {
				background: black;
				position: fixed;
				top: 0; left: 0; right: 0;
				height: 42px;
				border-bottom: 1px solid rgb(80, 80, 80);
			}
			#content {
				margin-top: 50px;
			}
			#nav, #legend {
				float: left;
				margin-left: 10px;
			}
			#legend {
				margin-top: 12px;
			}
			#nav {
				margin-top: 10px;
			}
			#legend span {
				margin: 0 5px;
			}
			.cov0 { color: rgb(192, 0, 0) }
.cov1 { color: rgb(128, 128, 128) }
.cov2 { color: rgb(116, 140, 131) }
.cov3 { color: rgb(104, 152, 134) }
.cov4 { color: rgb(92, 164, 137) }
.cov5 { color: rgb(80, 176, 140) }
.cov6 { color: rgb(68, 188, 143) }
.cov7 { color: rgb(56, 200, 146) }
.cov8 { color: rgb(44, 212, 149) }
.cov9 { color: rgb(32, 224, 152) }
.cov10 { color: rgb(20, 236, 155) }

		</style>
	</head>
	<body>
		<div id="topbar">
			<div id="nav">
				<select id="files">
				
				<option value="file0">sms/auth/auth.go (79.8%)</option>
				
				<option value="file1">sms/backend/backend.go (80.0%)</option>
				
				<option value="file2">sms/backend/vault.go (68.6%)</option>
				
				<option value="file3">sms/config/config.go (78.6%)</option>
				
				<option value="file4">sms/handler/handler.go (62.0%)</option>
				
				<option value="file5">sms/log/logger.go (78.1%)</option>
				
				<option value="file6">sms/sms.go (77.8%)</option>
				
				</select>
			</div>
			<div id="legend">
				<span>not tracked</span>
			
				<span class="cov0">no coverage</span>
				<span class="cov1">low coverage</span>
				<span class="cov2">*</span>
				<span class="cov3">*</span>
				<span class="cov4">*</span>
				<span class="cov5">*</span>
				<span class="cov6">*</span>
				<span class="cov7">*</span>
				<span class="cov8">*</span>
				<span class="cov9">*</span>
				<span class="cov10">high coverage</span>
			
			</div>
		</div>
		<div id="content">
		
		<pre class="file" id="file0" style="display: none">/*
 * Copyright 2018 Intel Corporation, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package auth

import (
        "bytes"
        "crypto"
        "crypto/tls"
        "crypto/x509"
        "encoding/base64"
        "encoding/pem"
        "golang.org/x/crypto/openpgp"
        "golang.org/x/crypto/openpgp/packet"
        "io/ioutil"

        smsconfig "sms/config"
        smslogger "sms/log"
)

// GetTLSConfig initializes a tlsConfig using the CA's certificate
// This config is then used to enable the server for mutual TLS
func GetTLSConfig(caCertFile string, certFile string, keyFile string) (*tls.Config, error) <span class="cov8" title="3">{

        // Initialize tlsConfig once
        caCert, err := ioutil.ReadFile(caCertFile)

        if smslogger.CheckError(err, "Read CA Cert file") != nil </span><span class="cov1" title="1">{
                return nil, err
        }</span>

        <span class="cov5" title="2">caCertPool := x509.NewCertPool()
        caCertPool.AppendCertsFromPEM(caCert)

        tlsConfig := &amp;tls.Config{
                // Change to RequireAndVerify once we have mandatory certs
                ClientAuth: tls.VerifyClientCertIfGiven,
                ClientCAs:  caCertPool,
                MinVersion: tls.VersionTLS12,
        }

        certPEMBlk, err := readPEMBlock(certFile)
        if smslogger.CheckError(err, "Read Cert File") != nil </span><span class="cov0" title="0">{
                return nil, err
        }</span>

        <span class="cov5" title="2">keyPEMBlk, err := readPEMBlock(keyFile)
        if smslogger.CheckError(err, "Read Key File") != nil </span><span class="cov0" title="0">{
                return nil, err
        }</span>

        <span class="cov5" title="2">tlsConfig.Certificates = make([]tls.Certificate, 1)
        tlsConfig.Certificates[0], err = tls.X509KeyPair(certPEMBlk, keyPEMBlk)
        if smslogger.CheckError(err, "Load x509 cert and key") != nil </span><span class="cov0" title="0">{
                return nil, err
        }</span>

        <span class="cov5" title="2">tlsConfig.BuildNameToCertificate()
        return tlsConfig, nil</span>
}

func readPEMBlock(filename string) ([]byte, error) <span class="cov10" title="4">{

        pemData, err := ioutil.ReadFile(filename)

        if smslogger.CheckError(err, "Read PEM File") != nil </span><span class="cov0" title="0">{
                return nil, err
        }</span>

        <span class="cov10" title="4">pemBlock, rest := pem.Decode(pemData)
        if len(rest) &gt; 0 </span><span class="cov1" title="1">{
                smslogger.WriteWarn("Pemfile has extra data")
        }</span>

        <span class="cov10" title="4">if x509.IsEncryptedPEMBlock(pemBlock) </span><span class="cov1" title="1">{
                pByte, err := base64.StdEncoding.DecodeString(smsconfig.SMSConfig.Password)
                if smslogger.CheckError(err, "Decode PEM Password") != nil </span><span class="cov0" title="0">{
                        return nil, err
                }</span>

                <span class="cov1" title="1">pemData, err = x509.DecryptPEMBlock(pemBlock, pByte)
                if smslogger.CheckError(err, "Decrypt PEM Data") != nil </span><span class="cov0" title="0">{
                        return nil, err
                }</span>
                <span class="cov1" title="1">var newPEMBlock pem.Block
                newPEMBlock.Type = pemBlock.Type
                newPEMBlock.Bytes = pemData
                // Converting back to PEM from DER data you get from
                // DecryptPEMBlock
                pemData = pem.EncodeToMemory(&amp;newPEMBlock)</span>
        }

        <span class="cov10" title="4">return pemData, nil</span>
}

// GeneratePGPKeyPair produces a PGP key pair and returns
// two things:
// A base64 encoded form of the public part of the entity
// A base64 encoded form of the private key
func GeneratePGPKeyPair() (string, string, error) <span class="cov8" title="3">{

        var entity *openpgp.Entity
        config := &amp;packet.Config{
                DefaultHash: crypto.SHA256,
        }

        entity, err := openpgp.NewEntity("aaf.sms.init", "PGP Key for unsealing", "", config)
        if smslogger.CheckError(err, "Create Entity") != nil </span><span class="cov0" title="0">{
                return "", "", err
        }</span>

        // Sign the identity in the entity
        <span class="cov8" title="3">for _, id := range entity.Identities </span><span class="cov8" title="3">{
                err = id.SelfSignature.SignUserId(id.UserId.Id, entity.PrimaryKey, entity.PrivateKey, nil)
                if smslogger.CheckError(err, "Sign Entity") != nil </span><span class="cov0" title="0">{
                        return "", "", err
                }</span>
        }

        // Sign the subkey in the entity
        <span class="cov8" title="3">for _, subkey := range entity.Subkeys </span><span class="cov8" title="3">{
                err := subkey.Sig.SignKey(subkey.PublicKey, entity.PrivateKey, nil)
                if smslogger.CheckError(err, "Sign Subkey") != nil </span><span class="cov0" title="0">{
                        return "", "", err
                }</span>
        }

        <span class="cov8" title="3">buffer := new(bytes.Buffer)
        entity.Serialize(buffer)
        pbkey := base64.StdEncoding.EncodeToString(buffer.Bytes())

        buffer.Reset()
        entity.SerializePrivate(buffer, nil)
        prkey := base64.StdEncoding.EncodeToString(buffer.Bytes())

        return pbkey, prkey, nil</span>
}

// EncryptPGPString takes data and a public key and encrypts using that
// public key
func EncryptPGPString(data string, pbKey string) (string, error) <span class="cov5" title="2">{

        pbKeyBytes, err := base64.StdEncoding.DecodeString(pbKey)
        if smslogger.CheckError(err, "Decoding Base64 Public Key") != nil </span><span class="cov0" title="0">{
                return "", err
        }</span>

        <span class="cov5" title="2">dataBytes := []byte(data)

        pbEntity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(pbKeyBytes)))
        if smslogger.CheckError(err, "Reading entity from PGP key") != nil </span><span class="cov0" title="0">{
                return "", err
        }</span>

        // encrypt string
        <span class="cov5" title="2">buf := new(bytes.Buffer)
        out, err := openpgp.Encrypt(buf, []*openpgp.Entity{pbEntity}, nil, nil, nil)
        if smslogger.CheckError(err, "Creating Encryption Pipe") != nil </span><span class="cov0" title="0">{
                return "", err
        }</span>

        <span class="cov5" title="2">_, err = out.Write(dataBytes)
        if smslogger.CheckError(err, "Writing to Encryption Pipe") != nil </span><span class="cov0" title="0">{
                return "", err
        }</span>

        <span class="cov5" title="2">err = out.Close()
        if smslogger.CheckError(err, "Closing Encryption Pipe") != nil </span><span class="cov0" title="0">{
                return "", err
        }</span>

        <span class="cov5" title="2">crp := base64.StdEncoding.EncodeToString(buf.Bytes())
        return crp, nil</span>
}

// DecryptPGPString decrypts a PGP encoded input string and returns
// a base64 representation of the decoded string
func DecryptPGPString(data string, prKey string) (string, error) <span class="cov1" title="1">{

        // Convert private key to bytes from base64
        prKeyBytes, err := base64.StdEncoding.DecodeString(prKey)
        if smslogger.CheckError(err, "Decoding Base64 Private Key") != nil </span><span class="cov0" title="0">{
                return "", err
        }</span>

        <span class="cov1" title="1">dataBytes, err := base64.StdEncoding.DecodeString(data)
        if smslogger.CheckError(err, "Decoding base64 data") != nil </span><span class="cov0" title="0">{
                return "", err
        }</span>

        <span class="cov1" title="1">prEntity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(prKeyBytes)))
        if smslogger.CheckError(err, "Read Entity") != nil </span><span class="cov0" title="0">{
                return "", err
        }</span>

        <span class="cov1" title="1">prEntityList := &amp;openpgp.EntityList{prEntity}
        message, err := openpgp.ReadMessage(bytes.NewBuffer(dataBytes), prEntityList, nil, nil)
        if smslogger.CheckError(err, "Decrypting Message") != nil </span><span class="cov0" title="0">{
                return "", err
        }</span>

        <span class="cov1" title="1">var retBuf bytes.Buffer
        retBuf.ReadFrom(message.UnverifiedBody)

        return retBuf.String(), nil</span>
}

// ReadFromFile reads a file and loads the PGP key into
// a string
func ReadFromFile(fileName string) (string, error) <span class="cov1" title="1">{

        data, err := ioutil.ReadFile(fileName)
        if smslogger.CheckError(err, "Read from file") != nil </span><span class="cov1" title="1">{
                return "", err
        }</span>
        <span class="cov0" title="0">return string(data), nil</span>
}

// WriteToFile writes a PGP key into a file.
// It will truncate the file if it exists
func WriteToFile(data string, fileName string) error <span class="cov5" title="2">{

        err := ioutil.WriteFile(fileName, []byte(data), 0600)
        if smslogger.CheckError(err, "Write to file") != nil </span><span class="cov0" title="0">{
                return err
        }</span>
        <span class="cov5" title="2">return nil</span>
}
</pre>
		
		<pre class="file" id="file1" style="display: none">/*
 * Copyright 2018 Intel Corporation, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package backend

import (
        smsconfig "sms/config"
        smslogger "sms/log"
)

// SecretDomain is where Secrets are stored.
// A single domain can have any number of secrets
type SecretDomain struct {
        UUID string `json:"uuid"`
        Name string `json:"name"`
}

// Secret is the struct that defines the structure of a secret
// It consists of a name and map containing key value pairs
type Secret struct {
        Name   string                 `json:"name"`
        Values map[string]interface{} `json:"values"`
}

// SecretBackend interface that will be implemented for various secret backends
type SecretBackend interface {
        Init() error
        GetStatus() (bool, error)
        Unseal(shard string) error
        RegisterQuorum(pgpkey string) (string, error)

        GetSecret(dom string, sec string) (Secret, error)
        ListSecret(dom string) ([]string, error)

        CreateSecretDomain(name string) (SecretDomain, error)
        CreateSecret(dom string, sec Secret) error

        DeleteSecretDomain(name string) error
        DeleteSecret(dom string, name string) error
}

// InitSecretBackend returns an interface implementation
func InitSecretBackend() (SecretBackend, error) <span class="cov8" title="1">{
        backendImpl := &amp;Vault{
                vaultAddress: smsconfig.SMSConfig.BackendAddress,
                vaultToken:   smsconfig.SMSConfig.VaultToken,
        }

        err := backendImpl.Init()
        if smslogger.CheckError(err, "InitSecretBackend") != nil </span><span class="cov0" title="0">{
                return nil, err
        }</span>

        <span class="cov8" title="1">return backendImpl, nil</span>
}

// LoginBackend Interface that will be implemented for various login backends
type LoginBackend interface {
}
</pre>
		
		<pre class="file" id="file2" style="display: none">/*
 * Copyright 2018 Intel Corporation, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package backend

import (
        uuid "github.com/hashicorp/go-uuid"
        vaultapi "github.com/hashicorp/vault/api"
        smsauth "sms/auth"
        smslogger "sms/log"

        "errors"
        "fmt"
        "strings"
        "sync"
        "time"
)

// Vault is the main Struct used in Backend to initialize the struct
type Vault struct {
        sync.Mutex
        initRoleDone          bool
        policyName            string
        roleID                string
        secretID              string
        vaultAddress          string
        vaultClient           *vaultapi.Client
        vaultMountPrefix      string
        internalDomain        string
        internalDomainMounted bool
        vaultTempTokenTTL     time.Time
        vaultToken            string
        shards                []string
        prkey                 string
}

// initVaultClient will create the initial
// Vault strcuture and populate it with the
// right values and it will also create
// a vault client
func (v *Vault) initVaultClient() error <span class="cov7" title="11">{

        vaultCFG := vaultapi.DefaultConfig()
        vaultCFG.Address = v.vaultAddress
        client, err := vaultapi.NewClient(vaultCFG)
        if smslogger.CheckError(err, "Create new vault client") != nil </span><span class="cov0" title="0">{
                return err
        }</span>

        <span class="cov7" title="11">v.initRoleDone = false
        v.policyName = "smsvaultpolicy"
        v.vaultClient = client
        v.vaultMountPrefix = "sms"
        v.internalDomain = "smsinternaldomain"
        v.internalDomainMounted = false
        v.prkey = ""
        return nil</span>
}

// Init will initialize the vault connection
// It will also initialize vault if it is not
// already initialized.
// The initial policy will also be created
func (v *Vault) Init() error <span class="cov1" title="1">{

        v.initVaultClient()
        // Initialize vault if it is not already
        // Returns immediately if it is initialized
        v.initializeVault()

        err := v.initRole()
        if smslogger.CheckError(err, "InitRole First Attempt") != nil </span><span class="cov0" title="0">{
                smslogger.WriteInfo("InitRole will try again later")
        }</span>

        <span class="cov1" title="1">return nil</span>
}

// GetStatus returns the current seal status of vault
func (v *Vault) GetStatus() (bool, error) <span class="cov2" title="2">{

        sys := v.vaultClient.Sys()
        sealStatus, err := sys.SealStatus()
        if smslogger.CheckError(err, "Getting Status") != nil </span><span class="cov0" title="0">{
                return false, errors.New("Error getting status")
        }</span>

        <span class="cov2" title="2">return sealStatus.Sealed, nil</span>
}

// RegisterQuorum registers the PGP public key for a quorum client
// We will return a shard to the client that is registering
func (v *Vault) RegisterQuorum(pgpkey string) (string, error) <span class="cov0" title="0">{

        v.Lock()
        defer v.Unlock()

        if v.shards == nil </span><span class="cov0" title="0">{
                smslogger.WriteError("Invalid operation in RegisterQuorum")
                return "", errors.New("Invalid operation")
        }</span>
        // Pop the slice
        <span class="cov0" title="0">var sh string
        sh, v.shards = v.shards[len(v.shards)-1], v.shards[:len(v.shards)-1]
        if len(v.shards) == 0 </span><span class="cov0" title="0">{
                v.shards = nil
        }</span>

        // Decrypt with SMS pgp Key
        <span class="cov0" title="0">sh, _ = smsauth.DecryptPGPString(sh, v.prkey)
        // Encrypt with Quorum client pgp key
        sh, _ = smsauth.EncryptPGPString(sh, pgpkey)

        return sh, nil</span>
}

// Unseal is a passthrough API that allows any
// unseal or initialization processes for the backend
func (v *Vault) Unseal(shard string) error <span class="cov0" title="0">{

        sys := v.vaultClient.Sys()
        _, err := sys.Unseal(shard)
        if smslogger.CheckError(err, "Unseal Operation") != nil </span><span class="cov0" title="0">{
                return errors.New("Unable to execute unseal operation with specified shard")
        }</span>

        <span class="cov0" title="0">return nil</span>
}

// GetSecret returns a secret mounted on a particular domain name
// The secret itself is referenced via its name which translates to
// a mount path in vault
func (v *Vault) GetSecret(dom string, name string) (Secret, error) <span class="cov2" title="2">{

        err := v.checkToken()
        if smslogger.CheckError(err, "Tocken Check") != nil </span><span class="cov0" title="0">{
                return Secret{}, errors.New("Token check failed")
        }</span>

        <span class="cov2" title="2">dom = strings.TrimSpace(dom)
        dom = v.vaultMountPrefix + "/" + dom

        sec, err := v.vaultClient.Logical().Read(dom + "/" + name)
        if smslogger.CheckError(err, "Read Secret") != nil </span><span class="cov0" title="0">{
                return Secret{}, errors.New("Unable to read Secret at provided path")
        }</span>

        // sec and err are nil in the case where a path does not exist
        <span class="cov2" title="2">if sec == nil </span><span class="cov0" title="0">{
                smslogger.WriteWarn("Vault read was empty. Invalid Path")
                return Secret{}, errors.New("Secret not found at the provided path")
        }</span>

        <span class="cov2" title="2">return Secret{Name: name, Values: sec.Data}, nil</span>
}

// ListSecret returns a list of secret names on a particular domain
// The values of the secret are not returned
func (v *Vault) ListSecret(dom string) ([]string, error) <span class="cov2" title="2">{

        err := v.checkToken()
        if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
                return nil, errors.New("Token check failed")
        }</span>

        <span class="cov2" title="2">dom = strings.TrimSpace(dom)
        dom = v.vaultMountPrefix + "/" + dom

        sec, err := v.vaultClient.Logical().List(dom)
        if smslogger.CheckError(err, "Read Secret") != nil </span><span class="cov0" title="0">{
                return nil, errors.New("Unable to read Secret at provided path")
        }</span>

        // sec and err are nil in the case where a path does not exist
        <span class="cov2" title="2">if sec == nil </span><span class="cov0" title="0">{
                smslogger.WriteWarn("Vaultclient returned empty data")
                return nil, errors.New("Secret not found at the provided path")
        }</span>

        <span class="cov2" title="2">val, ok := sec.Data["keys"].([]interface{})
        if !ok </span><span class="cov0" title="0">{
                smslogger.WriteError("Secret not found at the provided path")
                return nil, errors.New("Secret not found at the provided path")
        }</span>

        <span class="cov2" title="2">retval := make([]string, len(val))
        for i, v := range val </span><span class="cov2" title="2">{
                retval[i] = fmt.Sprint(v)
        }</span>

        <span class="cov2" title="2">return retval, nil</span>
}

// Mounts the internal Domain if its not already mounted
func (v *Vault) mountInternalDomain(name string) error <span class="cov5" title="7">{

        if v.internalDomainMounted </span><span class="cov0" title="0">{
                return nil
        }</span>

        <span class="cov5" title="7">name = strings.TrimSpace(name)
        mountPath := v.vaultMountPrefix + "/" + name
        mountInput := &amp;vaultapi.MountInput{
                Type:        "kv",
                Description: "Mount point for domain: " + name,
                Local:       false,
                SealWrap:    false,
                Config:      vaultapi.MountConfigInput{},
        }

        err := v.vaultClient.Sys().Mount(mountPath, mountInput)
        if smslogger.CheckError(err, "Mount internal Domain") != nil </span><span class="cov0" title="0">{
                if strings.Contains(err.Error(), "existing mount") </span><span class="cov0" title="0">{
                        // It is already mounted
                        v.internalDomainMounted = true
                        return nil
                }</span>
                // Ran into some other error mounting it.
                <span class="cov0" title="0">return errors.New("Unable to mount internal Domain")</span>
        }

        <span class="cov5" title="7">v.internalDomainMounted = true
        return nil</span>
}

// Stores the UUID created for secretdomain in vault
// under v.vaultMountPrefix / smsinternal domain
func (v *Vault) storeUUID(uuid string, name string) error <span class="cov5" title="7">{

        // Check if token is still valid
        err := v.checkToken()
        if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
                return errors.New("Token Check failed")
        }</span>

        <span class="cov5" title="7">err = v.mountInternalDomain(v.internalDomain)
        if smslogger.CheckError(err, "Mount Internal Domain") != nil </span><span class="cov0" title="0">{
                return err
        }</span>

        <span class="cov5" title="7">secret := Secret{
                Name: name,
                Values: map[string]interface{}{
                        "uuid": uuid,
                },
        }

        err = v.CreateSecret(v.internalDomain, secret)
        if smslogger.CheckError(err, "Write UUID to domain") != nil </span><span class="cov0" title="0">{
                return err
        }</span>

        <span class="cov5" title="7">return nil</span>
}

// CreateSecretDomain mounts the kv backend on a path with the given name
func (v *Vault) CreateSecretDomain(name string) (SecretDomain, error) <span class="cov5" title="7">{

        // Check if token is still valid
        err := v.checkToken()
        if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
                return SecretDomain{}, errors.New("Token Check failed")
        }</span>

        <span class="cov5" title="7">name = strings.TrimSpace(name)
        mountPath := v.vaultMountPrefix + "/" + name
        mountInput := &amp;vaultapi.MountInput{
                Type:        "kv",
                Description: "Mount point for domain: " + name,
                Local:       false,
                SealWrap:    false,
                Config:      vaultapi.MountConfigInput{},
        }

        err = v.vaultClient.Sys().Mount(mountPath, mountInput)
        if smslogger.CheckError(err, "Create Domain") != nil </span><span class="cov0" title="0">{
                return SecretDomain{}, errors.New("Unable to create Secret Domain")
        }</span>

        <span class="cov5" title="7">uuid, _ := uuid.GenerateUUID()
        err = v.storeUUID(uuid, name)
        if smslogger.CheckError(err, "Store UUID") != nil </span><span class="cov0" title="0">{
                // Mount was successful at this point.
                // Rollback the mount operation since we could not
                // store the UUID for the mount.
                v.vaultClient.Sys().Unmount(mountPath)
                return SecretDomain{}, errors.New("Unable to store Secret Domain UUID. Retry")
        }</span>

        <span class="cov5" title="7">return SecretDomain{uuid, name}, nil</span>
}

// CreateSecret creates a secret mounted on a particular domain name
// The secret itself is mounted on a path specified by name
func (v *Vault) CreateSecret(dom string, sec Secret) error <span class="cov7" title="12">{

        err := v.checkToken()
        if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
                return errors.New("Token check failed")
        }</span>

        <span class="cov7" title="12">dom = strings.TrimSpace(dom)
        dom = v.vaultMountPrefix + "/" + dom

        // Vault return is empty on successful write
        // TODO: Check if values is not empty
        _, err = v.vaultClient.Logical().Write(dom+"/"+sec.Name, sec.Values)
        if smslogger.CheckError(err, "Create Secret") != nil </span><span class="cov0" title="0">{
                return errors.New("Unable to create Secret at provided path")
        }</span>

        <span class="cov7" title="12">return nil</span>
}

// DeleteSecretDomain deletes a secret domain which translates to
// an unmount operation on the given path in Vault
func (v *Vault) DeleteSecretDomain(dom string) error <span class="cov2" title="2">{

        err := v.checkToken()
        if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
                return errors.New("Token Check Failed")
        }</span>

        <span class="cov2" title="2">dom = strings.TrimSpace(dom)
        mountPath := v.vaultMountPrefix + "/" + dom

        err = v.vaultClient.Sys().Unmount(mountPath)
        if smslogger.CheckError(err, "Delete Domain") != nil </span><span class="cov0" title="0">{
                return errors.New("Unable to delete domain specified")
        }</span>

        <span class="cov2" title="2">return nil</span>
}

// DeleteSecret deletes a secret mounted on the path provided
func (v *Vault) DeleteSecret(dom string, name string) error <span class="cov2" title="2">{

        err := v.checkToken()
        if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
                return errors.New("Token check failed")
        }</span>

        <span class="cov2" title="2">dom = strings.TrimSpace(dom)
        dom = v.vaultMountPrefix + "/" + dom

        // Vault return is empty on successful delete
        _, err = v.vaultClient.Logical().Delete(dom + "/" + name)
        if smslogger.CheckError(err, "Delete Secret") != nil </span><span class="cov0" title="0">{
                return errors.New("Unable to delete Secret at provided path")
        }</span>

        <span class="cov2" title="2">return nil</span>
}

// initRole is called only once during SMS bring up
// It initially creates a role and secret id associated with
// that role. Later restarts will use the existing role-id
// and secret-id stored on disk
func (v *Vault) initRole() error <span class="cov10" title="36">{

        if v.initRoleDone </span><span class="cov9" title="28">{
                return nil
        }</span>

        // Use the root token once here
        <span class="cov6" title="8">v.vaultClient.SetToken(v.vaultToken)
        defer v.vaultClient.ClearToken()

        // Check if roleID and secretID has already been created
        rID, error := smsauth.ReadFromFile("auth/role")
        if error != nil </span><span class="cov6" title="8">{
                smslogger.WriteWarn("Unable to find RoleID. Generating...")
        }</span> else<span class="cov0" title="0"> {
                sID, error := smsauth.ReadFromFile("auth/secret")
                if error != nil </span><span class="cov0" title="0">{
                        smslogger.WriteWarn("Unable to find secretID. Generating...")
                }</span> else<span class="cov0" title="0"> {
                        v.roleID = rID
                        v.secretID = sID
                        v.initRoleDone = true
                        return nil
                }</span>
        }

        <span class="cov6" title="8">rules := `path "sms/*" { capabilities = ["create", "read", "update", "delete", "list"] }
                        path "sys/mounts/sms*" { capabilities = ["update","delete","create"] }`
        err := v.vaultClient.Sys().PutPolicy(v.policyName, rules)
        if smslogger.CheckError(err, "Creating Policy") != nil </span><span class="cov0" title="0">{
                return errors.New("Unable to create policy for approle creation")
        }</span>

        //Check if applrole is mounted
        <span class="cov6" title="8">authMounts, err := v.vaultClient.Sys().ListAuth()
        if smslogger.CheckError(err, "Mount Auth Backend") != nil </span><span class="cov0" title="0">{
                return errors.New("Unable to get mounted auth backends")
        }</span>

        <span class="cov6" title="8">approleMounted := false
        for k, v := range authMounts </span><span class="cov6" title="8">{
                if v.Type == "approle" &amp;&amp; k == "approle/" </span><span class="cov0" title="0">{
                        approleMounted = true
                        break</span>
                }
        }

        // Mount approle in case its not already mounted
        <span class="cov6" title="8">if !approleMounted </span><span class="cov6" title="8">{
                v.vaultClient.Sys().EnableAuth("approle", "approle", "")
        }</span>

        <span class="cov6" title="8">rName := v.vaultMountPrefix + "-role"
        data := map[string]interface{}{
                "token_ttl": "60m",
                "policies":  [2]string{"default", v.policyName},
        }

        // Create a role-id
        v.vaultClient.Logical().Write("auth/approle/role/"+rName, data)
        sec, err := v.vaultClient.Logical().Read("auth/approle/role/" + rName + "/role-id")
        if smslogger.CheckError(err, "Create RoleID") != nil </span><span class="cov0" title="0">{
                return errors.New("Unable to create role ID for approle")
        }</span>
        <span class="cov6" title="8">v.roleID = sec.Data["role_id"].(string)

        // Create a secret-id to go with it
        sec, err = v.vaultClient.Logical().Write("auth/approle/role/"+rName+"/secret-id",
                map[string]interface{}{})
        if smslogger.CheckError(err, "Create SecretID") != nil </span><span class="cov0" title="0">{
                return errors.New("Unable to create secret ID for role")
        }</span>

        <span class="cov6" title="8">v.secretID = sec.Data["secret_id"].(string)
        v.initRoleDone = true
        /*
        * Revoke the Root token.
        * If a new Root Token is needed, it will need to be created
        * using the unseal shards.
         */
        err = v.vaultClient.Auth().Token().RevokeSelf(v.vaultToken)
        if smslogger.CheckError(err, "Revoke Root Token") != nil </span><span class="cov0" title="0">{
                smslogger.WriteWarn("Unable to Revoke Token")
        }</span> else<span class="cov6" title="8"> {
                // Revoked successfully and clear it
                v.vaultToken = ""
        }</span>

        // Store the role-id and secret-id
        // We will need this if SMS restarts
        <span class="cov6" title="8">smsauth.WriteToFile(v.roleID, "auth/role")
        smsauth.WriteToFile(v.secretID, "auth/secret")

        return nil</span>
}

// Function checkToken() gets called multiple times to create
// temporary tokens
func (v *Vault) checkToken() error <span class="cov9" title="34">{

        v.Lock()
        defer v.Unlock()

        // Init Role if it is not yet done
        // Role needs to be created before token can be created
        err := v.initRole()
        if err != nil </span><span class="cov0" title="0">{
                smslogger.WriteError(err.Error())
                return errors.New("Unable to initRole in checkToken")
        }</span>

        // Return immediately if token still has life
        <span class="cov9" title="34">if v.vaultClient.Token() != "" &amp;&amp;
                time.Since(v.vaultTempTokenTTL) &lt; time.Minute*50 </span><span class="cov9" title="27">{
                return nil
        }</span>

        // Create a temporary token using our roleID and secretID
        <span class="cov5" title="7">out, err := v.vaultClient.Logical().Write("auth/approle/login",
                map[string]interface{}{"role_id": v.roleID, "secret_id": v.secretID})
        if smslogger.CheckError(err, "Create Temp Token") != nil </span><span class="cov0" title="0">{
                return errors.New("Unable to create Temporary Token for Role")
        }</span>

        <span class="cov5" title="7">tok, err := out.TokenID()

        v.vaultTempTokenTTL = time.Now()
        v.vaultClient.SetToken(tok)
        return nil</span>
}

// vaultInit() is used to initialize the vault in cases where it is not
// initialized. This happens once during intial bring up.
func (v *Vault) initializeVault() error <span class="cov2" title="2">{

        // Check for vault init status and don't exit till it is initialized
        for </span><span class="cov2" title="2">{
                init, err := v.vaultClient.Sys().InitStatus()
                if smslogger.CheckError(err, "Get Vault Init Status") != nil </span><span class="cov0" title="0">{
                        smslogger.WriteInfo("Trying again in 10s...")
                        time.Sleep(time.Second * 10)
                        continue</span>
                }
                // Did not get any error
                <span class="cov2" title="2">if init == true </span><span class="cov1" title="1">{
                        smslogger.WriteInfo("Vault is already Initialized")
                        return nil
                }</span>

                // init status is false
                // break out of loop and finish initialization
                <span class="cov1" title="1">smslogger.WriteInfo("Vault is not initialized. Initializing...")
                break</span>
        }

        // Hardcoded this to 3. We should make this configurable
        // in the future
        <span class="cov1" title="1">initReq := &amp;vaultapi.InitRequest{
                SecretShares:    3,
                SecretThreshold: 3,
        }

        pbkey, prkey, err := smsauth.GeneratePGPKeyPair()

        if smslogger.CheckError(err, "Generating PGP Keys") != nil </span><span class="cov0" title="0">{
                smslogger.WriteError("Error Generating PGP Keys. Vault Init will not use encryption!")
        }</span> else<span class="cov1" title="1"> {
                initReq.PGPKeys = []string{pbkey, pbkey, pbkey}
                initReq.RootTokenPGPKey = pbkey
        }</span>

        <span class="cov1" title="1">resp, err := v.vaultClient.Sys().Init(initReq)
        if smslogger.CheckError(err, "Initialize Vault") != nil </span><span class="cov0" title="0">{
                return errors.New("FATAL: Unable to initialize Vault")
        }</span>

        <span class="cov1" title="1">if resp != nil </span><span class="cov1" title="1">{
                v.prkey = prkey
                v.shards = resp.KeysB64
                v.vaultToken, _ = smsauth.DecryptPGPString(resp.RootToken, prkey)
                return nil
        }</span>

        <span class="cov0" title="0">return errors.New("FATAL: Init response was empty")</span>
}
</pre>
		
		<pre class="file" id="file3" style="display: none">/*
 * Copyright 2018 Intel Corporation, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package config

import (
        "encoding/json"
        "os"
        smslogger "sms/log"
)

// SMSConfiguration loads up all the values that are used to configure
// backend implementations
// TODO: Review these and see if they can be created/discovered dynamically
type SMSConfiguration struct {
        CAFile     string `json:"cafile"`
        ServerCert string `json:"servercert"`
        ServerKey  string `json:"serverkey"`
        Password   string `json:"password"`

        BackendAddress            string `json:"smsdbaddress"`
        VaultToken                string `json:"vaulttoken"`
        DisableTLS                bool   `json:"disable_tls"`
        BackendAddressEnvVariable string `json:"smsdburlenv"`
}

// SMSConfig is the structure that stores the configuration
var SMSConfig *SMSConfiguration

// ReadConfigFile reads the specified smsConfig file to setup some env variables
func ReadConfigFile(file string) (*SMSConfiguration, error) <span class="cov10" title="3">{
        if SMSConfig == nil </span><span class="cov10" title="3">{
                f, err := os.Open(file)
                if err != nil </span><span class="cov1" title="1">{
                        return nil, err
                }</span>
                <span class="cov6" title="2">defer f.Close()

                // Default behaviour is to enable TLS
                SMSConfig = &amp;SMSConfiguration{DisableTLS: false}
                decoder := json.NewDecoder(f)
                err = decoder.Decode(SMSConfig)
                if err != nil </span><span class="cov0" title="0">{
                        return nil, err
                }</span>

                <span class="cov6" title="2">if SMSConfig.BackendAddress == "" &amp;&amp; SMSConfig.BackendAddressEnvVariable != "" </span><span class="cov0" title="0">{
                        // Get the value from ENV variable
                        smslogger.WriteInfo("Using Environment Variable: " + SMSConfig.BackendAddressEnvVariable)
                        SMSConfig.BackendAddress = os.Getenv(SMSConfig.BackendAddressEnvVariable)
                }</span>
        }

        <span class="cov6" title="2">return SMSConfig, nil</span>
}
</pre>
		
		<pre class="file" id="file4" style="display: none">/*
 * Copyright 2018 Intel Corporation, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package handler

import (
        "encoding/json"
        "github.com/gorilla/mux"
        "net/http"

        uuid "github.com/hashicorp/go-uuid"
        smsbackend "sms/backend"
        smslogger "sms/log"
)

// handler stores two interface implementations that implement
// the backend functionality
type handler struct {
        secretBackend smsbackend.SecretBackend
        loginBackend  smsbackend.LoginBackend
}

// createSecretDomainHandler creates a secret domain with a name provided
func (h handler) createSecretDomainHandler(w http.ResponseWriter, r *http.Request) <span class="cov6" title="2">{
        var d smsbackend.SecretDomain

        err := json.NewDecoder(r.Body).Decode(&amp;d)
        if smslogger.CheckError(err, "CreateSecretDomainHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusBadRequest)
                return
        }</span>

        <span class="cov6" title="2">dom, err := h.secretBackend.CreateSecretDomain(d.Name)
        if smslogger.CheckError(err, "CreateSecretDomainHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        <span class="cov6" title="2">w.Header().Set("Content-Type", "application/json")
        w.WriteHeader(http.StatusCreated)
        err = json.NewEncoder(w).Encode(dom)
        if smslogger.CheckError(err, "CreateSecretDomainHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>
}

// deleteSecretDomainHandler deletes a secret domain with the name provided
func (h handler) deleteSecretDomainHandler(w http.ResponseWriter, r *http.Request) <span class="cov6" title="2">{
        vars := mux.Vars(r)
        domName := vars["domName"]

        err := h.secretBackend.DeleteSecretDomain(domName)
        if smslogger.CheckError(err, "DeleteSecretDomainHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        <span class="cov6" title="2">w.WriteHeader(http.StatusNoContent)</span>
}

// createSecretHandler handles creation of secrets on a given domain name
func (h handler) createSecretHandler(w http.ResponseWriter, r *http.Request) <span class="cov6" title="2">{
        // Get domain name from URL
        vars := mux.Vars(r)
        domName := vars["domName"]

        // Get secrets to be stored from body
        var b smsbackend.Secret
        err := json.NewDecoder(r.Body).Decode(&amp;b)
        if smslogger.CheckError(err, "CreateSecretHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusBadRequest)
                return
        }</span>

        <span class="cov6" title="2">err = h.secretBackend.CreateSecret(domName, b)
        if smslogger.CheckError(err, "CreateSecretHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        <span class="cov6" title="2">w.WriteHeader(http.StatusCreated)</span>
}

// getSecretHandler handles reading a secret by given domain name and secret name
func (h handler) getSecretHandler(w http.ResponseWriter, r *http.Request) <span class="cov6" title="2">{
        vars := mux.Vars(r)
        domName := vars["domName"]
        secName := vars["secretName"]

        sec, err := h.secretBackend.GetSecret(domName, secName)
        if smslogger.CheckError(err, "GetSecretHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        <span class="cov6" title="2">w.Header().Set("Content-Type", "application/json")
        err = json.NewEncoder(w).Encode(sec)
        if smslogger.CheckError(err, "GetSecretHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>
}

// listSecretHandler handles listing all secrets under a particular domain name
func (h handler) listSecretHandler(w http.ResponseWriter, r *http.Request) <span class="cov6" title="2">{
        vars := mux.Vars(r)
        domName := vars["domName"]

        secList, err := h.secretBackend.ListSecret(domName)
        if smslogger.CheckError(err, "ListSecretHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        // Creating an anonymous struct to store the returned list of data
        <span class="cov6" title="2">var retStruct = struct {
                SecretNames []string `json:"secretnames"`
        }{
                secList,
        }

        w.Header().Set("Content-Type", "application/json")
        err = json.NewEncoder(w).Encode(retStruct)
        if smslogger.CheckError(err, "ListSecretHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>
}

// deleteSecretHandler handles deleting a secret by given domain name and secret name
func (h handler) deleteSecretHandler(w http.ResponseWriter, r *http.Request) <span class="cov6" title="2">{
        vars := mux.Vars(r)
        domName := vars["domName"]
        secName := vars["secretName"]

        err := h.secretBackend.DeleteSecret(domName, secName)
        if smslogger.CheckError(err, "DeleteSecretHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        <span class="cov6" title="2">w.WriteHeader(http.StatusNoContent)</span>
}

// statusHandler returns information related to SMS and SMS backend services
func (h handler) statusHandler(w http.ResponseWriter, r *http.Request) <span class="cov10" title="3">{
        s, err := h.secretBackend.GetStatus()
        if smslogger.CheckError(err, "StatusHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        <span class="cov10" title="3">status := struct {
                Seal bool `json:"sealstatus"`
        }{
                s,
        }

        w.Header().Set("Content-Type", "application/json")
        err = json.NewEncoder(w).Encode(status)
        if smslogger.CheckError(err, "StatusHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>
}

// loginHandler handles login via password and username
func (h handler) loginHandler(w http.ResponseWriter, r *http.Request) {<span class="cov0" title="0">

}</span>

// unsealHandler is a pass through that sends requests from quorum client
// to the backend.
func (h handler) unsealHandler(w http.ResponseWriter, r *http.Request) <span class="cov0" title="0">{
        // Get shards to be used for unseal
        type unsealStruct struct {
                UnsealShard string `json:"unsealshard"`
        }

        var inp unsealStruct
        decoder := json.NewDecoder(r.Body)
        decoder.DisallowUnknownFields()
        err := decoder.Decode(&amp;inp)
        if smslogger.CheckError(err, "UnsealHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, "Bad input JSON", http.StatusBadRequest)
                return
        }</span>

        <span class="cov0" title="0">err = h.secretBackend.Unseal(inp.UnsealShard)
        if smslogger.CheckError(err, "UnsealHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>
}

// registerHandler allows the quorum clients to register with SMS
// with their PGP public keys that are then used by sms for backend
// initialization
func (h handler) registerHandler(w http.ResponseWriter, r *http.Request) <span class="cov1" title="1">{

        // Get shards to be used for unseal
        type registerStruct struct {
                PGPKey   string `json:"pgpkey"`
                QuorumID string `json:"quorumid"`
        }

        var inp registerStruct
        decoder := json.NewDecoder(r.Body)
        decoder.DisallowUnknownFields()
        err := decoder.Decode(&amp;inp)
        if smslogger.CheckError(err, "RegisterHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, "Bad input JSON", http.StatusBadRequest)
                return
        }</span>

        <span class="cov1" title="1">sh, err := h.secretBackend.RegisterQuorum(inp.PGPKey)
        if smslogger.CheckError(err, "RegisterHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        // Creating a struct for return data
        <span class="cov1" title="1">shStruct := struct {
                Shard string `json:"shard"`
        }{
                sh,
        }

        w.Header().Set("Content-Type", "application/json")
        err = json.NewEncoder(w).Encode(shStruct)
        if smslogger.CheckError(err, "RegisterHandler") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>
}

// healthCheckHandler runs a few commands on the backend and returns
// OK or not depending on the status of the backend
func (h handler) healthCheckHandler(w http.ResponseWriter, r *http.Request) <span class="cov1" title="1">{

        sealed, err := h.secretBackend.GetStatus()
        if smslogger.CheckError(err, "HealthCheck") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        // backend is sealed
        <span class="cov1" title="1">if sealed == true </span><span class="cov0" title="0">{
                http.Error(w, "Secret Backend is not ready for operations", http.StatusInternalServerError)
                return
        }</span>

        // backend is not sealed
        <span class="cov1" title="1">dname, _ := uuid.GenerateUUID()
        dom, err := h.secretBackend.CreateSecretDomain(dname)
        if smslogger.CheckError(err, "HealthCheck Create Domain") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        <span class="cov1" title="1">err = h.secretBackend.DeleteSecretDomain(dom.UUID)
        if smslogger.CheckError(err, "HealthCheck Delete Domain") != nil </span><span class="cov0" title="0">{
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
        }</span>

        <span class="cov1" title="1">w.WriteHeader(http.StatusOK)</span>
}

// CreateRouter returns an http.Handler for the registered URLs
// Takes an interface implementation as input
func CreateRouter(b smsbackend.SecretBackend) http.Handler <span class="cov6" title="2">{
        h := handler{secretBackend: b}

        // Create a new mux to handle URL endpoints
        router := mux.NewRouter()

        router.HandleFunc("/v1/sms/login", h.loginHandler).Methods("POST")

        // Initialization APIs which will be used by quorum client
        // to unseal and to provide root token to sms service
        router.HandleFunc("/v1/sms/quorum/status", h.statusHandler).Methods("GET")
        router.HandleFunc("/v1/sms/quorum/unseal", h.unsealHandler).Methods("POST")
        router.HandleFunc("/v1/sms/quorum/register", h.registerHandler).Methods("POST")

        router.HandleFunc("/v1/sms/healthcheck", h.healthCheckHandler).Methods("GET")
        router.HandleFunc("/v1/sms/domain", h.createSecretDomainHandler).Methods("POST")
        router.HandleFunc("/v1/sms/domain/{domName}", h.deleteSecretDomainHandler).Methods("DELETE")

        router.HandleFunc("/v1/sms/domain/{domName}/secret", h.createSecretHandler).Methods("POST")
        router.HandleFunc("/v1/sms/domain/{domName}/secret", h.listSecretHandler).Methods("GET")
        router.HandleFunc("/v1/sms/domain/{domName}/secret/{secretName}", h.getSecretHandler).Methods("GET")
        router.HandleFunc("/v1/sms/domain/{domName}/secret/{secretName}", h.deleteSecretHandler).Methods("DELETE")

        return router
}</span>
</pre>
		
		<pre class="file" id="file5" style="display: none">/*
 * Copyright 2018 Intel Corporation, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package log

import (
        "fmt"
        "log"
        "os"
)

var errL, warnL, infoL *log.Logger
var stdErr, stdWarn, stdInfo *log.Logger

// Init will be called by sms.go before any other packages use it
func Init(filePath string) <span class="cov1" title="1">{

        stdErr = log.New(os.Stderr, "ERROR: ", log.Lshortfile|log.LstdFlags)
        stdWarn = log.New(os.Stdout, "WARNING: ", log.Lshortfile|log.LstdFlags)
        stdInfo = log.New(os.Stdout, "INFO: ", log.Lshortfile|log.LstdFlags)

        if filePath == "" </span><span class="cov0" title="0">{
                // We will just to std streams
                return
        }</span>

        <span class="cov1" title="1">f, err := os.Create(filePath)
        if err != nil </span><span class="cov0" title="0">{
                stdErr.Println("Unable to create log file: " + err.Error())
                return
        }</span>

        <span class="cov1" title="1">errL = log.New(f, "ERROR: ", log.Lshortfile|log.LstdFlags)
        warnL = log.New(f, "WARNING: ", log.Lshortfile|log.LstdFlags)
        infoL = log.New(f, "INFO: ", log.Lshortfile|log.LstdFlags)</span>
}

// WriteError writes output to the writer we have
// defined during its creation with ERROR prefix
func WriteError(msg string) <span class="cov0" title="0">{
        if errL != nil </span><span class="cov0" title="0">{
                errL.Output(2, fmt.Sprintln(msg))
        }</span>
        <span class="cov0" title="0">if stdErr != nil </span><span class="cov0" title="0">{
                stdErr.Output(2, fmt.Sprintln(msg))
        }</span>
}

// WriteWarn writes output to the writer we have
// defined during its creation with WARNING prefix
func WriteWarn(msg string) <span class="cov2" title="2">{
        if warnL != nil </span><span class="cov2" title="2">{
                warnL.Output(2, fmt.Sprintln(msg))
        }</span>
        <span class="cov2" title="2">if stdWarn != nil </span><span class="cov2" title="2">{
                stdWarn.Output(2, fmt.Sprintln(msg))
        }</span>
}

// WriteInfo writes output to the writer we have
// defined during its creation with INFO prefix
func WriteInfo(msg string) <span class="cov1" title="1">{
        if infoL != nil </span><span class="cov1" title="1">{
                infoL.Output(2, fmt.Sprintln(msg))
        }</span>
        <span class="cov1" title="1">if stdInfo != nil </span><span class="cov1" title="1">{
                stdInfo.Output(2, fmt.Sprintln(msg))
        }</span>
}

//CheckError is a helper function to reduce
//repetition of error checking blocks of code
func CheckError(err error, topic string) error <span class="cov10" title="55">{
        if err != nil </span><span class="cov1" title="1">{
                msg := topic + ": " + err.Error()
                if errL != nil </span><span class="cov1" title="1">{
                        errL.Output(2, fmt.Sprintln(msg))
                }</span>
                <span class="cov1" title="1">if stdErr != nil </span><span class="cov1" title="1">{
                        stdErr.Output(2, fmt.Sprintln(msg))
                }</span>
                <span class="cov1" title="1">return err</span>
        }
        <span class="cov9" title="54">return nil</span>
}
</pre>
		
		<pre class="file" id="file6" style="display: none">/*
 * Copyright 2018 Intel Corporation, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
        "context"
        "log"
        "net/http"
        "os"
        "os/signal"

        smsauth "sms/auth"
        smsbackend "sms/backend"
        smsconfig "sms/config"
        smshandler "sms/handler"
        smslogger "sms/log"
)

func main() <span class="cov8" title="1">{
        // Initialize logger
        smslogger.Init("sms.log")

        // Read Configuration File
        smsConf, err := smsconfig.ReadConfigFile("smsconfig.json")
        if err != nil </span><span class="cov0" title="0">{
                log.Fatal(err)
        }</span>

        <span class="cov8" title="1">backendImpl, err := smsbackend.InitSecretBackend()
        if err != nil </span><span class="cov0" title="0">{
                log.Fatal(err)
        }</span>

        <span class="cov8" title="1">httpRouter := smshandler.CreateRouter(backendImpl)

        httpServer := &amp;http.Server{
                Handler: httpRouter,
                Addr:    ":10443",
        }

        // Listener for SIGINT so that it returns cleanly
        connectionsClose := make(chan struct{})
        go func() </span><span class="cov8" title="1">{
                c := make(chan os.Signal, 1)
                signal.Notify(c, os.Interrupt)
                &lt;-c
                httpServer.Shutdown(context.Background())
                close(connectionsClose)
        }</span>()

        // Start in TLS mode by default
        <span class="cov8" title="1">if smsConf.DisableTLS == true </span><span class="cov0" title="0">{
                smslogger.WriteWarn("TLS is Disabled")
                err = httpServer.ListenAndServe()
        }</span> else<span class="cov8" title="1"> {
                // Populate TLSConfig with the certificates and privatekey
                // information
                tlsConfig, err := smsauth.GetTLSConfig(smsConf.CAFile, smsConf.ServerCert, smsConf.ServerKey)
                if smslogger.CheckError(err, "Get TLS Configuration") != nil </span><span class="cov0" title="0">{
                        log.Fatal(err)
                }</span>

                <span class="cov8" title="1">httpServer.TLSConfig = tlsConfig
                // empty strings because tlsconfig already has this information
                err = httpServer.ListenAndServeTLS("", "")</span>
        }

        <span class="cov8" title="1">if err != nil &amp;&amp; err != http.ErrServerClosed </span><span class="cov0" title="0">{
                log.Fatal(err)
        }</span>

        <span class="cov8" title="1">&lt;-connectionsClose</span>
}
</pre>
		
		</div>
	</body>
	<script>
	(function() {
		var files = document.getElementById('files');
		var visible;
		files.addEventListener('change', onChange, false);
		function select(part) {
			if (visible)
				visible.style.display = 'none';
			visible = document.getElementById(part);
			if (!visible)
				return;
			files.value = part;
			visible.style.display = 'block';
			location.hash = part;
		}
		function onChange() {
			select(files.value);
			window.scrollTo(0, 0);
		}
		if (location.hash != "") {
			select(location.hash.substr(1));
		}
		if (!visible) {
			select("file0");
		}
	})();
	</script>
</html>
