~sircmpwn/core-go

1063e5b6eca536af07040ba929e872c3fc256444 — Simon Ser 5 months ago 583d0b1
email: make PGP private key optional

Services other than meta.sr.ht don't really have a use for the
private PGP key.

Add a CanPGPSign method so that meta.sr.ht can emit a warning or
error when the PGP key is missing.
1 files changed, 38 insertions(+), 23 deletions(-)

M email/worker.go
M email/worker.go => email/worker.go +38 -23
@@ 134,9 134,13 @@ func EnqueueStd(ctx context.Context, header mail.Header,
				strings.Join(rcpts, ", "), err.Error())
		}

		cleartext, err = prepareSigned(header, &buf, queue.entity)
		if err != nil {
			log.Fatalf("Signing mail failed: %v", err)
		if queue.entity != nil {
			cleartext, err = prepareSigned(header, &buf, queue.entity)
			if err != nil {
				log.Fatalf("Signing mail failed: %v", err)
			}
		} else {
			cleartext = nopWriteCloser{&buf}
		}
	}
	defer cleartext.Close()


@@ 157,6 161,14 @@ func EnqueueStd(ctx context.Context, header mail.Header,
	return queue.Enqueue(NewTask(&buf, rcpts))
}

type nopWriteCloser struct {
	io.Writer
}

func (nopWriteCloser) Close() error {
	return nil
}

type Queue struct {
	*work.Queue
	smtpFrom     *mail.Address


@@ 164,6 176,11 @@ type Queue struct {
	entity       *openpgp.Entity
}

// CanPGPSign checks whether emails sent via the queue are signed via OpenPGP.
func (q *Queue) CanPGPSign() bool {
	return q.entity != nil
}

// Creates a new email processing queue.
func NewQueue(conf ini.File) *Queue {
	smtpFrom, ok := conf.Get("mail", "smtp-from")


@@ 187,27 204,25 @@ func NewQueue(conf ini.File) *Queue {
		Address: ownerEmail,
	}

	privKeyPath, ok := conf.Get("mail", "pgp-privkey")
	if !ok {
		panic("Expected [mail]pgp-privkey in config")
	}

	privKeyFile, err := os.Open(privKeyPath)
	if err != nil {
		panic(fmt.Errorf("Failed to open [mail]pgp-privkey: %v", err))
	}
	defer privKeyFile.Close()
	var entity *openpgp.Entity
	if privKeyPath, ok := conf.Get("mail", "pgp-privkey"); ok {
		privKeyFile, err := os.Open(privKeyPath)
		if err != nil {
			panic(fmt.Errorf("Failed to open [mail]pgp-privkey: %v", err))
		}
		defer privKeyFile.Close()

	keyring, err := openpgp.ReadArmoredKeyRing(privKeyFile)
	if err != nil {
		panic(fmt.Errorf("Failed to read PGP key ring from [mail]pgp-privkey: %v", err))
	}
	if len(keyring) != 1 {
		panic("Expected [mail]pgp-privkey to contain one key")
	}
	entity := keyring[0]
	if entity.PrivateKey == nil || entity.PrivateKey.Encrypted {
		panic("Failed to load [mail]pgp-privkey for email signature")
		keyring, err := openpgp.ReadArmoredKeyRing(privKeyFile)
		if err != nil {
			panic(fmt.Errorf("Failed to read PGP key ring from [mail]pgp-privkey: %v", err))
		}
		if len(keyring) != 1 {
			panic("Expected [mail]pgp-privkey to contain one key")
		}
		entity = keyring[0]
		if entity.PrivateKey == nil || entity.PrivateKey.Encrypted {
			panic("Failed to load [mail]pgp-privkey for email signature")
		}
	}

	return &Queue{