This field is ignored except for the start of the ca. If the type is linked and the token is not passed, it will fail with an error.
134 lines
3.6 KiB
Go
134 lines
3.6 KiB
Go
package commands
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"unicode"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/smallstep/certificates/authority/config"
|
|
"github.com/smallstep/certificates/ca"
|
|
"github.com/smallstep/certificates/pki"
|
|
"github.com/urfave/cli"
|
|
"go.step.sm/cli-utils/errs"
|
|
)
|
|
|
|
// AppCommand is the action used as the top action.
|
|
var AppCommand = cli.Command{
|
|
Name: "start",
|
|
Action: appAction,
|
|
UsageText: `**step-ca** <config>
|
|
[**--password-file**=<file>] [**--issuer-password-file**=<file>] [**--resolver**=<addr>]`,
|
|
Flags: []cli.Flag{
|
|
cli.StringFlag{
|
|
Name: "password-file",
|
|
Usage: `path to the <file> containing the password to decrypt the
|
|
intermediate private key.`,
|
|
},
|
|
cli.StringFlag{
|
|
Name: "issuer-password-file",
|
|
Usage: `path to the <file> containing the password to decrypt the
|
|
certificate issuer private key used in the RA mode.`,
|
|
},
|
|
cli.StringFlag{
|
|
Name: "resolver",
|
|
Usage: "address of a DNS resolver to be used instead of the default.",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "token",
|
|
Usage: "token used to enable the linked ca.",
|
|
EnvVar: "STEP_CA_TOKEN",
|
|
},
|
|
},
|
|
}
|
|
|
|
// AppAction is the action used when the top command runs.
|
|
func appAction(ctx *cli.Context) error {
|
|
passFile := ctx.String("password-file")
|
|
issuerPassFile := ctx.String("issuer-password-file")
|
|
resolver := ctx.String("resolver")
|
|
token := ctx.String("token")
|
|
|
|
// If zero cmd line args show help, if >1 cmd line args show error.
|
|
if ctx.NArg() == 0 {
|
|
return cli.ShowAppHelp(ctx)
|
|
}
|
|
if err := errs.NumberOfArguments(ctx, 1); err != nil {
|
|
return err
|
|
}
|
|
|
|
configFile := ctx.Args().Get(0)
|
|
config, err := config.LoadConfiguration(configFile)
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
if config.AuthorityConfig != nil {
|
|
if token == "" && strings.EqualFold(config.AuthorityConfig.DeploymentType, pki.LinkedDeployment.String()) {
|
|
return errors.New(`'step-ca' requires the '--token' flag for linked deploy type.
|
|
|
|
To get a linked authority token:
|
|
1. Log in or create a Certificate Manager account at ` + "\033[1mhttps://u.step.sm/linked\033[0m" + `
|
|
2. Add a new authority with "linked" type
|
|
3. Follow instructions in browser to start 'step-ca' using the '--token' flag
|
|
`)
|
|
}
|
|
}
|
|
|
|
var password []byte
|
|
if passFile != "" {
|
|
if password, err = ioutil.ReadFile(passFile); err != nil {
|
|
fatal(errors.Wrapf(err, "error reading %s", passFile))
|
|
}
|
|
password = bytes.TrimRightFunc(password, unicode.IsSpace)
|
|
}
|
|
|
|
var issuerPassword []byte
|
|
if issuerPassFile != "" {
|
|
if issuerPassword, err = ioutil.ReadFile(issuerPassFile); err != nil {
|
|
fatal(errors.Wrapf(err, "error reading %s", issuerPassFile))
|
|
}
|
|
issuerPassword = bytes.TrimRightFunc(issuerPassword, unicode.IsSpace)
|
|
}
|
|
|
|
// replace resolver if requested
|
|
if resolver != "" {
|
|
net.DefaultResolver.PreferGo = true
|
|
net.DefaultResolver.Dial = func(ctx context.Context, network, address string) (net.Conn, error) {
|
|
return net.Dial(network, resolver)
|
|
}
|
|
}
|
|
|
|
srv, err := ca.New(config,
|
|
ca.WithConfigFile(configFile),
|
|
ca.WithPassword(password),
|
|
ca.WithIssuerPassword(issuerPassword),
|
|
ca.WithLinkedCAToken(token))
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
go ca.StopReloaderHandler(srv)
|
|
if err = srv.Run(); err != nil && err != http.ErrServerClosed {
|
|
fatal(err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// fatal writes the passed error on the standard error and exits with the exit
|
|
// code 1. If the environment variable STEPDEBUG is set to 1 it shows the
|
|
// stack trace of the error.
|
|
func fatal(err error) {
|
|
if os.Getenv("STEPDEBUG") == "1" {
|
|
fmt.Fprintf(os.Stderr, "%+v\n", err)
|
|
} else {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
}
|
|
os.Exit(2)
|
|
}
|