Пример #1
0
func Example() {
	app := cli.NewApp()
	app.Name = "todo"
	app.Usage = "task list on the command line"
	app.Commands = []cli.Command{
		{
			Name:      "add",
			ShortName: "a",
			Usage:     "add a task to the list",
			Action: func(c *cli.Context) {
				println("added task: ", c.Args().First())
			},
		},
		{
			Name:      "complete",
			ShortName: "c",
			Usage:     "complete a task on the list",
			Action: func(c *cli.Context) {
				println("completed task: ", c.Args().First())
			},
		},
	}

	app.Run(os.Args)
}
Пример #2
0
func ExampleAppBashComplete() {
	// set args for examples sake
	os.Args = []string{"greet", "--generate-bash-completion"}

	app := cli.NewApp()
	app.Name = "greet"
	app.EnableBashCompletion = true
	app.Commands = []cli.Command{
		{
			Name:        "describeit",
			ShortName:   "d",
			Usage:       "use it to see a description",
			Description: "This is how we describe describeit the function",
			Action: func(c *cli.Context) {
				fmt.Printf("i like to describe things")
			},
		}, {
			Name:        "next",
			Usage:       "next example",
			Description: "more stuff to see when generating bash completion",
			Action: func(c *cli.Context) {
				fmt.Printf("the next example")
			},
		},
	}

	app.Run(os.Args)
	// Output:
	// describeit
	// d
	// next
	// help
	// h
}
Пример #3
0
func TestApp_DefaultStdout(t *testing.T) {
	app := cli.NewApp()

	if app.Writer != os.Stdout {
		t.Error("Default output writer not set.")
	}
}
Пример #4
0
func ExampleAppHelp() {
	// set args for examples sake
	os.Args = []string{"greet", "h", "describeit"}

	app := cli.NewApp()
	app.Name = "greet"
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
	}
	app.Commands = []cli.Command{
		{
			Name:        "describeit",
			ShortName:   "d",
			Usage:       "use it to see a description",
			Description: "This is how we describe describeit the function",
			Action: func(c *cli.Context) {
				fmt.Printf("i like to describe things")
			},
		},
	}
	app.Run(os.Args)
	// Output:
	// NAME:
	//    describeit - use it to see a description
	//
	// USAGE:
	//    command describeit [arguments...]
	//
	// DESCRIPTION:
	//    This is how we describe describeit the function
}
Пример #5
0
func TestGlobalFlagsInSubcommands(t *testing.T) {
	subcommandRun := false
	app := cli.NewApp()

	app.Flags = []cli.Flag{
		cli.BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
	}

	app.Commands = []cli.Command{
		cli.Command{
			Name: "foo",
			Subcommands: []cli.Command{
				{
					Name: "bar",
					Action: func(c *cli.Context) {
						if c.GlobalBool("debug") {
							subcommandRun = true
						}
					},
				},
			},
		},
	}

	app.Run([]string{"command", "-d", "foo", "bar"})

	expect(t, subcommandRun, true)
}
Пример #6
0
func TestApp_RunAsSubcommandParseFlags(t *testing.T) {
	var context *cli.Context

	a := cli.NewApp()
	a.Commands = []cli.Command{
		{
			Name: "foo",
			Action: func(c *cli.Context) {
				context = c
			},
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "lang",
					Value: "english",
					Usage: "language for the greeting",
				},
			},
			Before: func(_ *cli.Context) error { return nil },
		},
	}
	a.Run([]string{"", "foo", "--lang", "spanish", "abcd"})

	expect(t, context.Args().Get(0), "abcd")
	expect(t, context.String("lang"), "spanish")
}
Пример #7
0
func TestApp_ParseSliceFlags(t *testing.T) {
	var parsedOption, firstArg string
	var parsedIntSlice []int
	var parsedStringSlice []string

	app := cli.NewApp()
	command := cli.Command{
		Name: "cmd",
		Flags: []cli.Flag{
			cli.IntSliceFlag{Name: "p", Value: &cli.IntSlice{}, Usage: "set one or more ip addr"},
			cli.StringSliceFlag{Name: "ip", Value: &cli.StringSlice{}, Usage: "set one or more ports to open"},
		},
		Action: func(c *cli.Context) {
			parsedIntSlice = c.IntSlice("p")
			parsedStringSlice = c.StringSlice("ip")
			parsedOption = c.String("option")
			firstArg = c.Args().First()
		},
	}
	app.Commands = []cli.Command{command}

	app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})

	IntsEquals := func(a, b []int) bool {
		if len(a) != len(b) {
			return false
		}
		for i, v := range a {
			if v != b[i] {
				return false
			}
		}
		return true
	}

	StrsEquals := func(a, b []string) bool {
		if len(a) != len(b) {
			return false
		}
		for i, v := range a {
			if v != b[i] {
				return false
			}
		}
		return true
	}
	var expectedIntSlice = []int{22, 80}
	var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"}

	if !IntsEquals(parsedIntSlice, expectedIntSlice) {
		t.Errorf("%v does not match %v", parsedIntSlice, expectedIntSlice)
	}

	if !StrsEquals(parsedStringSlice, expectedStringSlice) {
		t.Errorf("%v does not match %v", parsedStringSlice, expectedStringSlice)
	}
}
Пример #8
0
func TestApp_Command(t *testing.T) {
	app := cli.NewApp()
	fooCommand := cli.Command{Name: "foobar", ShortName: "f"}
	batCommand := cli.Command{Name: "batbaz", ShortName: "b"}
	app.Commands = []cli.Command{
		fooCommand,
		batCommand,
	}

	for _, test := range commandAppTests {
		expect(t, app.Command(test.name) != nil, test.expected)
	}
}
Пример #9
0
func TestApp_Float64Flag(t *testing.T) {
	var meters float64

	app := cli.NewApp()
	app.Flags = []cli.Flag{
		cli.Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"},
	}
	app.Action = func(c *cli.Context) {
		meters = c.Float64("height")
	}

	app.Run([]string{"", "--height", "1.93"})
	expect(t, meters, 1.93)
}
Пример #10
0
func TestApp_Run(t *testing.T) {
	s := ""

	app := cli.NewApp()
	app.Action = func(c *cli.Context) {
		s = s + c.Args().First()
	}

	err := app.Run([]string{"command", "foo"})
	expect(t, err, nil)
	err = app.Run([]string{"command", "bar"})
	expect(t, err, nil)
	expect(t, s, "foobar")
}
Пример #11
0
func TestAppNoHelpFlag(t *testing.T) {
	oldFlag := cli.HelpFlag
	defer func() {
		cli.HelpFlag = oldFlag
	}()

	cli.HelpFlag = cli.BoolFlag{}

	app := cli.NewApp()
	err := app.Run([]string{"test", "-h"})

	if err != flag.ErrHelp {
		t.Errorf("expected error about missing help flag, but got: %s (%T)", err, err)
	}
}
Пример #12
0
func ExampleApp() {
	// set args for examples sake
	os.Args = []string{"greet", "--name", "Jeremy"}

	app := cli.NewApp()
	app.Name = "greet"
	app.Flags = []cli.Flag{
		cli.StringFlag{Name: "name", Value: "bob", Usage: "a name to say"},
	}
	app.Action = func(c *cli.Context) {
		fmt.Printf("Hello %v\n", c.String("name"))
	}
	app.Run(os.Args)
	// Output:
	// Hello Jeremy
}
Пример #13
0
// NewAppShell creates a basic AppShell object containing CLI metadata
func NewAppShell(name string) (shell *AppShell) {
	app := cli.NewApp()

	app.Name = name
	app.Version = "0.0.0"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "config",
			Value:  "config.json",
			EnvVar: "BOULDER_CONFIG",
		},
	}

	return &AppShell{app: app}
}
Пример #14
0
func TestApp_SetStdout(t *testing.T) {
	w := &mockWriter{}

	app := cli.NewApp()
	app.Name = "test"
	app.Writer = w

	err := app.Run([]string{"help"})

	if err != nil {
		t.Fatalf("Run error: %s", err)
	}

	if len(w.written) == 0 {
		t.Error("App did not write output to desired writer.")
	}
}
Пример #15
0
// NewAppShell creates a basic AppShell object containing CLI metadata
func NewAppShell(name string) (shell *AppShell) {
	app := cli.NewApp()

	app.Name = name
	app.Version = fmt.Sprintf("0.1.0 [%s]", core.GetBuildID())

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "config",
			Value:  "config.json",
			EnvVar: "BOULDER_CONFIG",
			Usage:  "Path to Config JSON",
		},
	}

	return &AppShell{App: app}
}
Пример #16
0
func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) {
	var args []string

	app := cli.NewApp()
	command := cli.Command{
		Name: "cmd",
		Action: func(c *cli.Context) {
			args = c.Args()
		},
	}
	app.Commands = []cli.Command{command}

	app.Run([]string{"", "cmd", "my-arg", "--", "notAFlagAtAll"})

	expect(t, args[0], "my-arg")
	expect(t, args[1], "--")
	expect(t, args[2], "notAFlagAtAll")
}
Пример #17
0
func TestAppHelpPrinter(t *testing.T) {
	oldPrinter := cli.HelpPrinter
	defer func() {
		cli.HelpPrinter = oldPrinter
	}()

	var wasCalled = false
	cli.HelpPrinter = func(template string, data interface{}) {
		wasCalled = true
	}

	app := cli.NewApp()
	app.Run([]string{"-h"})

	if wasCalled == false {
		t.Errorf("Help printer expected to be called, but was not")
	}
}
Пример #18
0
func TestCommandDoNotIgnoreFlags(t *testing.T) {
	app := cli.NewApp()
	set := flag.NewFlagSet("test", 0)
	test := []string{"blah", "blah", "-break"}
	set.Parse(test)

	c := cli.NewContext(app, set, set)

	command := cli.Command{
		Name:        "test-cmd",
		ShortName:   "tc",
		Usage:       "this is for testing",
		Description: "testing",
		Action:      func(_ *cli.Context) {},
	}
	err := command.Run(c)

	expect(t, err.Error(), "flag provided but not defined: -break")
}
Пример #19
0
func TestAppVersionPrinter(t *testing.T) {
	oldPrinter := cli.VersionPrinter
	defer func() {
		cli.VersionPrinter = oldPrinter
	}()

	var wasCalled = false
	cli.VersionPrinter = func(c *cli.Context) {
		wasCalled = true
	}

	app := cli.NewApp()
	ctx := cli.NewContext(app, nil, nil)
	cli.ShowVersion(ctx)

	if wasCalled == false {
		t.Errorf("Version printer expected to be called, but was not")
	}
}
Пример #20
0
// NewAppShell creates a basic AppShell object containing CLI metadata
func NewAppShell(name, usage string) (shell *AppShell) {
	app := cli.NewApp()

	app.Name = name
	app.Usage = usage
	app.Version = Version()
	app.Author = "Boulder contributors"
	app.Email = "*****@*****.**"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "config",
			Value:  "config.json",
			EnvVar: "BOULDER_CONFIG",
			Usage:  "Path to Config JSON",
		},
	}

	return &AppShell{App: app}
}
Пример #21
0
func TestCommandIgnoreFlags(t *testing.T) {
	app := cli.NewApp()
	set := flag.NewFlagSet("test", 0)
	test := []string{"blah", "blah"}
	set.Parse(test)

	c := cli.NewContext(app, set, set)

	command := cli.Command{
		Name:            "test-cmd",
		ShortName:       "tc",
		Usage:           "this is for testing",
		Description:     "testing",
		Action:          func(_ *cli.Context) {},
		SkipFlagParsing: true,
	}
	err := command.Run(c)

	expect(t, err, nil)
}
Пример #22
0
func TestApp_CommandWithArgBeforeFlags(t *testing.T) {
	var parsedOption, firstArg string

	app := cli.NewApp()
	command := cli.Command{
		Name: "cmd",
		Flags: []cli.Flag{
			cli.StringFlag{Name: "option", Value: "", Usage: "some option"},
		},
		Action: func(c *cli.Context) {
			parsedOption = c.String("option")
			firstArg = c.Args().First()
		},
	}
	app.Commands = []cli.Command{command}

	app.Run([]string{"", "cmd", "my-arg", "--option", "my-option"})

	expect(t, parsedOption, "my-option")
	expect(t, firstArg, "my-arg")
}
Пример #23
0
func TestAppCommandNotFound(t *testing.T) {
	beforeRun, subcommandRun := false, false
	app := cli.NewApp()

	app.CommandNotFound = func(c *cli.Context, command string) {
		beforeRun = true
	}

	app.Commands = []cli.Command{
		cli.Command{
			Name: "bar",
			Action: func(c *cli.Context) {
				subcommandRun = true
			},
		},
	}

	app.Run([]string{"command", "foo"})

	expect(t, beforeRun, true)
	expect(t, subcommandRun, false)
}
Пример #24
0
func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) {
	var parsedOption string
	var args []string

	app := cli.NewApp()
	command := cli.Command{
		Name: "cmd",
		Flags: []cli.Flag{
			cli.StringFlag{Name: "option", Value: "", Usage: "some option"},
		},
		Action: func(c *cli.Context) {
			parsedOption = c.String("option")
			args = c.Args()
		},
	}
	app.Commands = []cli.Command{command}

	app.Run([]string{"", "cmd", "my-arg", "--option", "my-option", "--", "--notARealFlag"})

	expect(t, parsedOption, "my-option")
	expect(t, args[0], "my-arg")
	expect(t, args[1], "--")
	expect(t, args[2], "--notARealFlag")
}
Пример #25
0
func ExampleAppSubcommand() {
	// set args for examples sake
	os.Args = []string{"say", "hi", "english", "--name", "Jeremy"}
	app := cli.NewApp()
	app.Name = "say"
	app.Commands = []cli.Command{
		{
			Name:        "hello",
			ShortName:   "hi",
			Usage:       "use it to see a description",
			Description: "This is how we describe hello the function",
			Subcommands: []cli.Command{
				{
					Name:        "english",
					ShortName:   "en",
					Usage:       "sends a greeting in english",
					Description: "greets someone in english",
					Flags: []cli.Flag{
						cli.StringFlag{
							Name:  "name",
							Value: "Bob",
							Usage: "Name of the person to greet",
						},
					},
					Action: func(c *cli.Context) {
						fmt.Println("Hello,", c.String("name"))
					},
				},
			},
		},
	}

	app.Run(os.Args)
	// Output:
	// Hello, Jeremy
}
Пример #26
0
func main() {
	app := cli.NewApp()
	app.Name = "policy-loader"
	app.Usage = "Loads/dumps rules into/from the policy database"
	app.Version = cmd.Version()
	app.Author = "Boulder contributors"
	app.Email = "*****@*****.**"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "config",
			Value:  "config.json",
			EnvVar: "BOULDER_CONFIG",
			Usage:  "Path to Boulder JSON configuration file",
		},
		cli.StringFlag{
			Name:   "rule-file",
			Value:  "rules.json",
			EnvVar: "BOULDER_POLICY_RULES",
			Usage:  "Path to Boulder policy whitelist and blacklist rule file",
		},
	}

	app.Commands = append(app.Commands, []cli.Command{
		cli.Command{
			Name:  "dump-rules",
			Usage: "Write out whitelist and blacklist from database to a rule file",
			Action: func(c *cli.Context) {
				padb, ruleFile := setupFromContext(c)
				ruleSet, err := padb.DumpRules()
				cmd.FailOnError(err, "Couldn't retrieve whitelist rules")
				var rules struct {
					Blacklist []string
					Whitelist []string
				}
				for _, r := range ruleSet.Blacklist {
					rules.Blacklist = append(rules.Blacklist, r.Host)
				}
				for _, r := range ruleSet.Whitelist {
					rules.Whitelist = append(rules.Whitelist, r.Host)
				}
				rulesJSON, err := json.Marshal(rules)
				cmd.FailOnError(err, "Couldn't marshal rule list")
				err = ioutil.WriteFile(ruleFile, rulesJSON, os.ModePerm)
				cmd.FailOnError(err, "Failed to write the rule file")
				fmt.Printf("# Saved rule list to %s\n", ruleFile)
			},
		},
		cli.Command{
			Name:  "load-rules",
			Usage: "Load whitelist and blacklist into database from a rule file",
			Action: func(c *cli.Context) {
				padb, ruleFile := setupFromContext(c)

				rulesJSON, err := ioutil.ReadFile(ruleFile)
				cmd.FailOnError(err, "Couldn't read configuration file")
				rules := policy.RawRuleSet{}
				err = json.Unmarshal(rulesJSON, &rules)
				cmd.FailOnError(err, "Couldn't unmarshal rules list")
				rs := policy.RuleSet{}
				for _, r := range rules.Blacklist {
					rs.Blacklist = append(rs.Blacklist, policy.BlacklistRule{
						Host: strings.ToLower(r),
					})
				}
				for _, r := range rules.Whitelist {
					rs.Whitelist = append(rs.Whitelist, policy.WhitelistRule{
						Host: strings.ToLower(r),
					})
				}

				err = padb.LoadRules(rs)
				cmd.FailOnError(err, "Couldn't load rules")

				fmt.Println("# Loaded whitelist and blacklist into database")
			},
		},
	}...)

	app.Run(os.Args)
}
Пример #27
0
func main() {
	app := cli.NewApp()
	app.Name = "admin-revoker"
	app.Usage = "Revokes issued certificates"
	app.Version = cmd.Version()
	app.Author = "Boulder contributors"
	app.Email = "*****@*****.**"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "config",
			Value:  "config.json",
			EnvVar: "BOULDER_CONFIG",
			Usage:  "Path to Boulder JSON configuration file",
		},
		cli.BoolFlag{
			Name:  "deny",
			Usage: "Add certificate DNS names to the denied list",
		},
	}
	app.Commands = []cli.Command{
		{
			Name:  "serial-revoke",
			Usage: "Revoke a single certificate by the hex serial number",
			Action: func(c *cli.Context) {
				// 1: serial,  2: reasonCode (3: deny flag)
				serial := c.Args().First()
				reasonCode, err := strconv.Atoi(c.Args().Get(1))
				cmd.FailOnError(err, "Reason code argument must be a integer")
				deny := c.GlobalBool("deny")

				cac, auditlogger, dbMap, _ := setupContext(c)

				tx, err := dbMap.Begin()
				if err != nil {
					tx.Rollback()
				}
				cmd.FailOnError(err, "Couldn't begin transaction")

				err = revokeBySerial(serial, core.RevocationCode(reasonCode), deny, cac, auditlogger, tx)
				if err != nil {
					tx.Rollback()
				}
				cmd.FailOnError(err, "Couldn't revoke certificate")

				err = tx.Commit()
				cmd.FailOnError(err, "Couldn't cleanly close transaction")
			},
		},
		{
			Name:  "reg-revoke",
			Usage: "Revoke all certificates associated with a registration ID",
			Action: func(c *cli.Context) {
				// 1: registration ID,  2: reasonCode (3: deny flag)
				regID, err := strconv.ParseInt(c.Args().First(), 10, 64)
				cmd.FailOnError(err, "Registration ID argument must be a integer")
				reasonCode, err := strconv.Atoi(c.Args().Get(1))
				cmd.FailOnError(err, "Reason code argument must be a integer")
				deny := c.GlobalBool("deny")

				cac, auditlogger, dbMap, sac := setupContext(c)
				// AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3
				defer auditlogger.AuditPanic()

				tx, err := dbMap.Begin()
				if err != nil {
					tx.Rollback()
				}
				cmd.FailOnError(err, "Couldn't begin transaction")

				_, err = sac.GetRegistration(regID)
				if err != nil {
					cmd.FailOnError(err, "Couldn't fetch registration")
				}

				err = revokeByReg(regID, core.RevocationCode(reasonCode), deny, cac, auditlogger, tx)
				if err != nil {
					tx.Rollback()
				}
				cmd.FailOnError(err, "Couldn't revoke certificate")

				err = tx.Commit()
				cmd.FailOnError(err, "Couldn't cleanly close transaction")
			},
		},
		{
			Name:  "list-reasons",
			Usage: "List all revocation reason codes",
			Action: func(c *cli.Context) {
				var codes core.RevocationCodes
				for k := range core.RevocationReasons {
					codes = append(codes, k)
				}
				sort.Sort(codes)
				fmt.Printf("Revocation reason codes\n-----------------------\n\n")
				for _, k := range codes {
					fmt.Printf("%d: %s\n", k, core.RevocationReasons[k])
				}
			},
		},
	}

	err := app.Run(os.Args)
	cmd.FailOnError(err, "Failed to run application")
}
Пример #28
0
func main() {
	app := cli.NewApp()
	app.Name = "single-ocsp"
	app.Usage = `Creates a single OCSP response.

   According to the BRs, the OCSP responses for intermediate certificate must
   be issued once per year.  So there's a need to issue OCSP responses for
   these certificates, but it doesn't make sense to use all the infrastructure
   that the "ocsp-updater" tool requires.  This tool allows an administrator
   to manually generate an OCSP response for an intermediate certificate.
`
	app.Version = cmd.Version()
	app.Author = "Boulder contributors"
	app.Email = "*****@*****.**"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "issuer",
			Usage: "Issuer certificate (DER)",
		},
		cli.StringFlag{
			Name:  "responder",
			Usage: "OCSP responder certificate (DER)",
		},
		cli.StringFlag{
			Name:  "target",
			Usage: "Certificate whose status is being reported (DER)",
		},
		cli.StringFlag{
			Name: "template",
			Usage: `OCSP template file (JSON), e.g.:

                {
                  "Status": 0, // Good
                  "ThisUpdate": "2015-08-26T00:00:00Z",
                  "NextUpdate": "2016-08-26T00:00:00Z"
                }

                {
                  "Status": 1, // Revoked
                  "ThisUpdate": "2015-08-26T00:00:00Z",
                  "NextUpdate": "2016-08-26T00:00:00Z",
                  "RevokedAt": "2015-08-20T00:00:00Z",
                  "RevocationReason": 1 // Key compromise
                }
`,
		},
		cli.StringFlag{
			Name: "pkcs11",
			Usage: `PKCS#11 configuration (JSON), e.g.:

                {
                  "Module": "/Library/OpenSC/lib/opensc-pkcs11.so",
                  "Token": "Yubico Yubikey NEO CCID",
                  "Label": "PIV AUTH key",
                  "PIN": "123456"
                }
`,
		},
		cli.StringFlag{
			Name:  "out",
			Usage: "File to which the OCSP response will be written",
		},
	}

	app.Action = func(c *cli.Context) {
		issuer, responder, target, template, pkcs11, err := readFiles(c)
		cmd.FailOnError(err, "Failed to read files")

		// Instantiate the private key from PKCS11
		priv, err := pkcs11key.New(pkcs11.Module, pkcs11.TokenLabel, pkcs11.PIN, pkcs11.PrivateKeyLabel, int(pkcs11.SlotID))
		cmd.FailOnError(err, "Failed to load PKCS#11 key")

		// Populate the remaining fields in the template
		template.SerialNumber = target.SerialNumber
		template.Certificate = responder

		// Sign the OCSP response
		responseBytes, err := ocsp.CreateResponse(issuer, responder, template, priv)
		cmd.FailOnError(err, "Failed to sign OCSP response")

		// Write the OCSP response to stdout
		outFile := c.GlobalString("out")
		if len(outFile) == 0 {
			cmd.FailOnError(fmt.Errorf(""), "No output file provided")
		}
		ioutil.WriteFile(outFile, responseBytes, 0666)
	}

	err := app.Run(os.Args)
	cmd.FailOnError(err, "Failed to run application")
}
Пример #29
0
func main() {
	app := cli.NewApp()
	app.Name = "jose-util"
	app.Usage = "command-line utility to deal with JOSE objects"
	app.Version = "0.0.2"
	app.Author = ""
	app.Email = ""

	app.Commands = []cli.Command{
		{
			Name:  "encrypt",
			Usage: "encrypt a plaintext",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "key, k",
					Usage: "Path to key file (PEM/DER)",
				},
				cli.StringFlag{
					Name:  "input, in",
					Usage: "Path to input file (stdin if missing)",
				},
				cli.StringFlag{
					Name:  "output, out",
					Usage: "Path to output file (stdout if missing)",
				},
				cli.StringFlag{
					Name:  "algorithm, alg",
					Usage: "Key management algorithm (e.g. RSA-OAEP)",
				},
				cli.StringFlag{
					Name:  "encryption, enc",
					Usage: "Content encryption algorithm (e.g. A128GCM)",
				},
				cli.BoolFlag{
					Name:  "full, f",
					Usage: "Use full serialization format (instead of compact)",
				},
			},
			Action: func(c *cli.Context) {
				keyBytes, err := ioutil.ReadFile(requiredFlag(c, "key"))
				exitOnError(err, "unable to read key file")

				pub, err := jose.LoadPublicKey(keyBytes)
				exitOnError(err, "unable to read public key")

				alg := jose.KeyAlgorithm(requiredFlag(c, "alg"))
				enc := jose.ContentEncryption(requiredFlag(c, "enc"))

				crypter, err := jose.NewEncrypter(alg, enc, pub)
				exitOnError(err, "unable to instantiate encrypter")

				obj, err := crypter.Encrypt(readInput(c.String("input")))
				exitOnError(err, "unable to encrypt")

				var msg string
				if c.Bool("full") {
					msg = obj.FullSerialize()
				} else {
					msg, err = obj.CompactSerialize()
					exitOnError(err, "unable to serialize message")
				}

				writeOutput(c.String("output"), []byte(msg))
			},
		},
		{
			Name:  "decrypt",
			Usage: "decrypt a ciphertext",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "key, k",
					Usage: "Path to key file (PEM/DER)",
				},
				cli.StringFlag{
					Name:  "input, in",
					Usage: "Path to input file (stdin if missing)",
				},
				cli.StringFlag{
					Name:  "output, out",
					Usage: "Path to output file (stdout if missing)",
				},
			},
			Action: func(c *cli.Context) {
				keyBytes, err := ioutil.ReadFile(requiredFlag(c, "key"))
				exitOnError(err, "unable to read private key")

				priv, err := jose.LoadPrivateKey(keyBytes)
				exitOnError(err, "unable to read private key")

				obj, err := jose.ParseEncrypted(string(readInput(c.String("input"))))
				exitOnError(err, "unable to parse message")

				plaintext, err := obj.Decrypt(priv)
				exitOnError(err, "unable to decrypt message")

				writeOutput(c.String("output"), plaintext)
			},
		},
		{
			Name:  "sign",
			Usage: "sign a plaintext",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "algorithm, alg",
					Usage: "Signing algorithm (e.g. PS256)",
				},
				cli.StringFlag{
					Name:  "key, k",
					Usage: "Path to key file (PEM/DER)",
				},
				cli.StringFlag{
					Name:  "input, in",
					Usage: "Path to input file (stdin if missing)",
				},
				cli.StringFlag{
					Name:  "output, out",
					Usage: "Path to output file (stdout if missing)",
				},
				cli.BoolFlag{
					Name:  "full, f",
					Usage: "Use full serialization format (instead of compact)",
				},
			},
			Action: func(c *cli.Context) {
				keyBytes, err := ioutil.ReadFile(requiredFlag(c, "key"))
				exitOnError(err, "unable to read key file")

				signingKey, err := jose.LoadPrivateKey(keyBytes)
				exitOnError(err, "unable to read private key")

				alg := jose.SignatureAlgorithm(requiredFlag(c, "algorithm"))
				signer, err := jose.NewSigner(alg, signingKey)
				exitOnError(err, "unable to make signer")

				obj, err := signer.Sign(readInput(c.String("input")))
				exitOnError(err, "unable to sign")

				var msg string
				if c.Bool("full") {
					msg = obj.FullSerialize()
				} else {
					msg, err = obj.CompactSerialize()
					exitOnError(err, "unable to serialize message")
				}

				writeOutput(c.String("output"), []byte(msg))
			},
		},
		{
			Name:  "verify",
			Usage: "verify a signature",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "key, k",
					Usage: "Path to key file (PEM/DER)",
				},
				cli.StringFlag{
					Name:  "input, in",
					Usage: "Path to input file (stdin if missing)",
				},
				cli.StringFlag{
					Name:  "output, out",
					Usage: "Path to output file (stdout if missing)",
				},
			},
			Action: func(c *cli.Context) {
				keyBytes, err := ioutil.ReadFile(requiredFlag(c, "key"))
				exitOnError(err, "unable to read key file")

				verificationKey, err := jose.LoadPublicKey(keyBytes)
				exitOnError(err, "unable to read private key")

				obj, err := jose.ParseSigned(string(readInput(c.String("input"))))
				exitOnError(err, "unable to parse message")

				plaintext, err := obj.Verify(verificationKey)
				exitOnError(err, "invalid signature")

				writeOutput(c.String("output"), plaintext)
			},
		},
		{
			Name:  "expand",
			Usage: "expand compact message to full format",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "input, in",
					Usage: "Path to input file (stdin if missing)",
				},
				cli.StringFlag{
					Name:  "output, out",
					Usage: "Path to output file (stdout if missing)",
				},
				cli.StringFlag{
					Name:  "format, f",
					Usage: "Message format (JWE/JWS, defaults to JWE)",
				},
			},
			Action: func(c *cli.Context) {
				input := string(readInput(c.String("input")))

				var serialized string
				var err error
				switch c.String("format") {
				case "", "JWE":
					var jwe *jose.JsonWebEncryption
					jwe, err = jose.ParseEncrypted(input)
					if err == nil {
						serialized = jwe.FullSerialize()
					}
				case "JWS":
					var jws *jose.JsonWebSignature
					jws, err = jose.ParseSigned(input)
					if err == nil {
						serialized = jws.FullSerialize()
					}
				}

				exitOnError(err, "unable to expand message")
				writeOutput(c.String("output"), []byte(serialized))
			},
		},
	}

	err := app.Run(os.Args)
	exitOnError(err, "unable to run application")
}
Пример #30
0
func main() {
	app := cli.NewApp()
	app.Name = "orphan-finder"
	app.Usage = "Reads orphaned certificates from a boulder-ca log or a der file and add them to the database"
	app.Version = cmd.Version()
	app.Author = "Boulder contributors"
	app.Email = "*****@*****.**"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "config",
			Value:  "config.json",
			EnvVar: "BOULDER_CONFIG",
			Usage:  "Path to Boulder JSON configuration file",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:  "parse-ca-log",
			Usage: "Parses boulder-ca logs to add multiple orphaned certificates",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "log-file",
					Usage: "Path to boulder-ca log file to parse",
				},
			},
			Action: func(c *cli.Context) {
				stats, logger, sa := setup(c)
				logPath := c.String("log-file")
				if logPath == "" {
					fmt.Println("log file path must be provided")
					os.Exit(1)
				}

				logData, err := ioutil.ReadFile(logPath)
				cmd.FailOnError(err, "Failed to read log file")

				orphansFound := int64(0)
				orphansAdded := int64(0)
				for _, line := range strings.Split(string(logData), "\n") {
					found, added := parseLogLine(sa, logger, line)
					if found {
						orphansFound++
						if added {
							orphansAdded++
						}
					}
				}
				logger.Info(fmt.Sprintf("Found %d orphans and added %d to the database\n", orphansFound, orphansAdded))
				stats.Inc("orphaned-certificates.found", orphansFound, 1.0)
				stats.Inc("orphaned-certificates.added", orphansAdded, 1.0)
				stats.Inc("orphaned-certificates.adding-failed", orphansFound-orphansAdded, 1.0)
			},
		},
		{
			Name:  "parse-der",
			Usage: "Parses a single orphaned DER certificate file and adds it to the database",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "der-file",
					Usage: "Path to DER certificate file",
				},
				cli.IntFlag{
					Name:  "regID",
					Usage: "Registration ID of user who requested the certificate",
				},
			},
			Action: func(c *cli.Context) {
				_, _, sa := setup(c)
				derPath := c.String("der-file")
				if derPath == "" {
					fmt.Println("der file path must be provided")
					os.Exit(1)
				}
				regID := c.Int("regID")
				if regID == 0 {
					fmt.Println("--regID must be non-zero")
					os.Exit(1)
				}
				der, err := ioutil.ReadFile(derPath)
				cmd.FailOnError(err, "Failed to read DER file")
				err = checkDER(sa, der)
				cmd.FailOnError(err, "Pre-AddCertificate checks failed")
				_, err = sa.AddCertificate(der, int64(regID))
				cmd.FailOnError(err, "Failed to add certificate to database")
			},
		},
	}

	app.Run(os.Args)
}