196 lines
4.7 KiB
Go
196 lines
4.7 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/AlecAivazis/survey"
|
|
"github.com/safing/jess"
|
|
)
|
|
|
|
func newEnvelope(name string) (*jess.Envelope, error) {
|
|
// check name
|
|
name = strings.TrimSpace(name)
|
|
if name == "" {
|
|
return nil, errors.New("missing envelope name")
|
|
}
|
|
|
|
// start init process
|
|
envelope := jess.NewUnconfiguredEnvelope()
|
|
envelope.Name = name
|
|
|
|
// preset menu
|
|
var preset string
|
|
prompt := &survey.Select{
|
|
Message: "Select preset:",
|
|
Options: []string{
|
|
"Encrypt with password",
|
|
"Encrypt with keyfile",
|
|
"Encrypt for someone",
|
|
"Sign a file",
|
|
"Custom from scratch",
|
|
},
|
|
}
|
|
err := survey.AskOne(prompt, &preset, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch preset {
|
|
case "Encrypt with password":
|
|
envelope.Tools = jess.RecommendedStoragePassword
|
|
err = selectSignets(envelope, "pw")
|
|
|
|
case "Encrypt with keyfile":
|
|
envelope.Tools = jess.RecommendedStorageKey
|
|
err = selectSignets(envelope, "key")
|
|
|
|
case "Encrypt for someone":
|
|
envelope.Tools = jess.RecommendedStorageKey
|
|
err = selectSignets(envelope, "recipient")
|
|
if err == nil {
|
|
err = selectSignets(envelope, "sender")
|
|
}
|
|
|
|
case "Sign a file":
|
|
envelope.NoConfidentiality().NoIntegrity().NoRecipientAuth()
|
|
err = selectSignets(envelope, "sender")
|
|
|
|
case "Custom from scratch":
|
|
// do nothing
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return envelope, nil
|
|
}
|
|
|
|
func editEnvelope(envelope *jess.Envelope) error {
|
|
for {
|
|
// main menu
|
|
|
|
// print envelope status
|
|
session, err := envelope.Correspondence(trustStore)
|
|
if err != nil {
|
|
fmt.Printf("Envelope status: %s\n", err)
|
|
} else {
|
|
fmt.Println("Envelope status: valid.")
|
|
envelope.MinimumSecurityLevel = session.SecurityLevel
|
|
}
|
|
|
|
// sub menu
|
|
var submenu string
|
|
prompt := &survey.Select{
|
|
Message: "Select to edit",
|
|
Options: formatColumns([][]string{
|
|
{"Done", "save and return"},
|
|
{" "},
|
|
{"Requirements", formatRequirements(envelope)},
|
|
{"Tools", strings.Join(envelope.Tools, ", ")},
|
|
{"Secrets", formatSignetNames(envelope.Secrets)},
|
|
{"Recipients", formatSignetNames(envelope.Recipients)},
|
|
{"Senders", formatSignetNames(envelope.Senders)},
|
|
{" "},
|
|
{"Abort", "discard changes and return"},
|
|
{"Delete", "delete and return"},
|
|
}),
|
|
PageSize: 10,
|
|
}
|
|
err = survey.AskOne(prompt, &submenu, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
switch {
|
|
case strings.HasPrefix(submenu, "Done"):
|
|
// save
|
|
return trustStore.StoreEnvelope(envelope)
|
|
case strings.HasPrefix(submenu, "Abort"):
|
|
return nil
|
|
case strings.HasPrefix(submenu, "Delete"):
|
|
return trustStore.DeleteEnvelope(envelope.Name)
|
|
case strings.HasPrefix(submenu, "Requirements"):
|
|
err = editEnvelopeRequirements(envelope)
|
|
case strings.HasPrefix(submenu, "Tools"):
|
|
err = editEnvelopeTools(envelope)
|
|
case strings.HasPrefix(submenu, "Secrets"):
|
|
err = selectSignets(envelope, "pw/key")
|
|
case strings.HasPrefix(submenu, "Recipients"):
|
|
err = selectSignets(envelope, "recipient")
|
|
case strings.HasPrefix(submenu, "Senders"):
|
|
err = selectSignets(envelope, "sender")
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
func editEnvelopeRequirements(envelope *jess.Envelope) error {
|
|
// TODO: improve
|
|
|
|
// get reqs
|
|
requirements := envelope.Requirements()
|
|
if requirements == nil {
|
|
return errors.New("envelope requirements uninitialized")
|
|
}
|
|
|
|
// build defaults
|
|
var defaults []string
|
|
if requirements.Has(jess.Confidentiality) {
|
|
defaults = append(defaults, "Confidentiality")
|
|
}
|
|
if requirements.Has(jess.Integrity) {
|
|
defaults = append(defaults, "Integrity")
|
|
}
|
|
if requirements.Has(jess.RecipientAuthentication) {
|
|
defaults = append(defaults, "Recipient Authentication")
|
|
}
|
|
if requirements.Has(jess.SenderAuthentication) {
|
|
defaults = append(defaults, "Sender Authentication")
|
|
}
|
|
|
|
// prompt
|
|
var selected []string
|
|
prompt := &survey.MultiSelect{
|
|
Message: "Select requirements:",
|
|
Options: []string{
|
|
"Confidentiality",
|
|
"Integrity",
|
|
"Recipient Authentication",
|
|
"Sender Authentication",
|
|
},
|
|
Default: defaults,
|
|
}
|
|
err := survey.AskOne(prompt, &selected, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// parse
|
|
requirements.Remove(jess.Confidentiality)
|
|
requirements.Remove(jess.Integrity)
|
|
requirements.Remove(jess.RecipientAuthentication)
|
|
requirements.Remove(jess.SenderAuthentication)
|
|
for _, req := range selected {
|
|
switch req {
|
|
case "Confidentiality":
|
|
requirements.Add(jess.Confidentiality)
|
|
case "Integrity":
|
|
requirements.Add(jess.Integrity)
|
|
case "Recipient Authentication":
|
|
requirements.Add(jess.RecipientAuthentication)
|
|
case "Sender Authentication":
|
|
requirements.Add(jess.SenderAuthentication)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func editEnvelopeTools(envelope *jess.Envelope) (err error) {
|
|
envelope.Tools, err = pickTools(envelope.Tools, "Select tools:")
|
|
return err
|
|
}
|