File: main.go

package info (click to toggle)
ssh-tools 1.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,328 kB
  • sloc: sh: 1,403; perl: 785; makefile: 5
file content (180 lines) | stat: -rw-r--r-- 3,747 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"strings"
)

var options struct {
	version   bool
	namespace string
	keyfile   string
	sigfile   string
}

var key_names = [...]string{

	"id_ed25519",
	"id_ecdsa",
	"id_rsa",
	"id_dsa",
	"id_ed25519.pub",
	"id_ecdsa.pub",
	"id_rsa.pub",
	"id_dsa.pub",
}

var usage = `
  Make ssh-keygen -Y simpler

  Usage: %s COMMAND OPTION

  OPTIONS:

      -h     --help
             --version

  COMMANDS:

      sign   create signature
      check  check  signature

  HELP:

      sign     --help
      check    --help

  EXAMPLES:

      %s sign file.txt
      %s check -s file.txt.sig < file.txt

      cat file.txt | %s sign   > file.txt.sig
      cat file.txt | %s check -s file.txt.sig

      # Sign multiple files
      %s sign file1.txt file2.txt [...]

      # Use another key for signing
      %s sign -f ~/.ssh/id_rsa file.txt

      # Use a public key. Private Key for signing then comes from ssh-agent
      %s sign -f ~/.ssh/id_rsa.pub file.txt
`
var warning = `
    Missing command or option!

    %s --help

`

var Version string = "ssh-sig (ssh-tools) 1.9"

func printVersion() {
	fmt.Printf("%s\n", strings.TrimSpace(Version))
}

func main() {

	exeName := filepath.Base(os.Args[0])

	usage = strings.ReplaceAll(usage, "%s", exeName)
	warning = strings.ReplaceAll(warning, "%s", exeName)

	// Exit early if there is no ssh-keygen
	binary, err := exec.LookPath("ssh-keygen")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	// Find SSH Keyfiles of the current user
	// Use the first we can find
	usr, _ := user.Current()
	homedir := usr.HomeDir

	for _, key_name := range key_names {
		key_file := filepath.Join(homedir, ".ssh", key_name)
		if _, err := os.Stat(key_file); !os.IsNotExist(err) {
			options.keyfile = key_file
			break // use first keyfile we find
		}
	}

	// Set of flags for subcommand sign
	sign := flag.NewFlagSet("sign", flag.ExitOnError)
	sign.StringVar(&options.namespace, "n", "file", "namespace")
	sign.StringVar(&options.keyfile, "f", options.keyfile, "Private or Public SSH Key")

	// Set of flags for subcommand check
	check := flag.NewFlagSet("check", flag.ExitOnError)
	check.StringVar(&options.sigfile, "s", "", "sigfile")
	check.StringVar(&options.namespace, "n", "file", "namespace")

	// Switch on subcommands, then apply the desired set of flags.
	if len(os.Args) < 2 {
		fmt.Fprintln(os.Stderr, warning)
		os.Exit(0)
	}

	switch os.Args[1] {
	case "--help", "-h":
		fmt.Fprintf(flag.CommandLine.Output(), usage)
		os.Exit(0)
	case "--version":
		printVersion()
		os.Exit(0)
	case "sign":
		if err := sign.Parse(os.Args[2:]); err == nil {

			args := []string{"-Y", "sign", "-n", options.namespace, "-f", options.keyfile}
			for _, file := range sign.Args() {
				args = append(args, file)
			}

			fmt.Fprintln(os.Stderr, "namespace :", options.namespace)
			fmt.Fprintln(os.Stderr, "keyfile   :", options.keyfile)
			fmt.Fprintln(os.Stderr)

			cmd := exec.Command(binary, args...)
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			cmd.Stdin = os.Stdin

			execErr := cmd.Run()

			if execErr != nil {
				panic(execErr)
			}
		}
	case "check":
		if err := check.Parse(os.Args[2:]); err == nil {

			args := []string{"-Y", "check-novalidate", "-n", options.namespace, "-s", options.sigfile}

			fmt.Fprintln(os.Stderr, "namespace :", options.namespace)
			fmt.Fprintln(os.Stderr, "sigfile   :", options.sigfile)
			fmt.Fprintln(os.Stderr)

			cmd := exec.Command(binary, args...)
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			cmd.Stdin = os.Stdin

			execErr := cmd.Run()

			if execErr != nil {
				panic(execErr)
			}
		}
	default:
		fmt.Fprintln(os.Stderr, warning)
		os.Exit(0)
	}

}