Move key generation to app from keys.sh

This eliminates an external dependency needed for install, and ensures
the app can run on Windows.
This commit is contained in:
Matt Baer 2018-11-11 17:52:24 -05:00
parent 96c197453d
commit 7bc873580c
6 changed files with 65 additions and 33 deletions

View File

@ -20,8 +20,8 @@ run:
deps :
$(GOGET) -v ./...
install :
./keys.sh
install : build
cmd/writefreely/$(BINARY_NAME) --gen-keys
cd less/; $(MAKE) install $(MFLAGS)
ui : force_look

View File

@ -52,8 +52,8 @@ mysql -u YOURUSERNAME -p writefreely < schema.sql
# 3) Configure your blog
./writefreely --config
# 4) Generate data encryption keys (especially for production)
./keys.sh
# 4) Generate data encryption keys
./writefreely --gen-keys
# 5) Run
./writefreely
@ -79,9 +79,7 @@ Ready to hack on your site? Here's a quick overview.
go get github.com/writeas/writefreely/cmd/writefreely
```
Create your database, import the schema, and configure your site [as shown above](#quick-start).
Now generate the CSS:
Create your database, import the schema, and configure your site [as shown above](#quick-start). Then generate the remaining files you'll need:
```bash
make install # Generates encryption keys; installs LESS compiler

18
app.go
View File

@ -124,6 +124,7 @@ func Serve() {
debugPtr := flag.Bool("debug", false, "Enables debug logging.")
createConfig := flag.Bool("create-config", false, "Creates a basic configuration and exits")
doConfig := flag.Bool("config", false, "Run the configuration process")
genKeys := flag.Bool("gen-keys", false, "Generate encryption and authentication keys")
flag.Parse()
debugging = *debugPtr
@ -167,6 +168,23 @@ func Serve() {
log.Info("Done!")
}
os.Exit(0)
} else if *genKeys {
errStatus := 0
err := generateKey(emailKeyPath)
if err != nil {
errStatus = 1
}
err = generateKey(cookieAuthKeyPath)
if err != nil {
errStatus = 1
}
err = generateKey(cookieKeyPath)
if err != nil {
errStatus = 1
}
os.Exit(errStatus)
}
log.Info("Initializing...")

41
keys.go
View File

@ -1,12 +1,17 @@
package writefreely
import (
"crypto/rand"
"github.com/writeas/web-core/log"
"io/ioutil"
"os"
"path/filepath"
)
const (
keysDir = "keys"
encKeysBytes = 32
)
var (
@ -40,3 +45,39 @@ func initKeys(app *app) error {
return nil
}
// generateKey generates a key at the given path used for the encryption of
// certain user data. Because user data becomes unrecoverable without these
// keys, this won't overwrite any existing key, and instead outputs a message.
func generateKey(path string) error {
// Check if key file exists
if _, err := os.Stat(path); !os.IsNotExist(err) {
log.Info("%s already exists. rm the file if you understand the consquences.", path)
return nil
}
log.Info("Generating %s.", path)
b, err := generateBytes(encKeysBytes)
if err != nil {
log.Error("FAILED. %s. Run writefreely --gen-keys again.", err)
return err
}
err = ioutil.WriteFile(path, b, 0600)
if err != nil {
log.Error("FAILED writing file: %s", err)
return err
}
log.Info("Success.")
return nil
}
// generateBytes returns securely generated random bytes.
func generateBytes(n int) ([]byte, error) {
b := make([]byte, n)
_, err := rand.Read(b)
if err != nil {
return nil, err
}
return b, nil
}

25
keys.sh
View File

@ -1,25 +0,0 @@
#!/bin/bash
#
# keys.sh generates keys used for the encryption of certain user data. Because
# user data becomes unrecoverable without these keys, the script and won't
# overwrite any existing keys unless you explicitly delete them.
#
# Generate cookie encryption and authentication keys
if [[ ! -e "$(pwd)/keys/cookies_enc.aes256" ]]; then
dd of=$(pwd)/keys/cookies_enc.aes256 if=/dev/urandom bs=32 count=1
else
echo "cookies key already exists! rm keys/cookies_enc.aes256 if you understand the consquences."
fi
if [[ ! -e "$(pwd)/keys/cookies_auth.aes256" ]]; then
dd of=$(pwd)/keys/cookies_auth.aes256 if=/dev/urandom bs=32 count=1
else
echo "cookies authentication key already exists! rm keys/cookies_auth.aes256 if you understand the consquences."
fi
# Generate email encryption key
if [[ ! -e "$(pwd)/keys/email.aes256" ]]; then
dd of=$(pwd)/keys/email.aes256 if=/dev/urandom bs=32 count=1
else
echo "email key already exists! rm keys/email.aes256 if you understand the consquences."
fi

View File

@ -1,4 +1,4 @@
Keys
====
Contains keys for encrypting database and session data. Generate necessary keys by running (from the root of the project) `./keys.sh`.
Contains keys for encrypting database and session data. Generate necessary keys by running (from the root of the project) `writefreely --gen-keys`.