diff --git a/.gitignore b/.gitignore index fec6f2a..2ecf772 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ slack-status slack-status-cli dist/ .env +certs/ diff --git a/Makefile b/Makefile index 8eda7e6..3693728 100644 --- a/Makefile +++ b/Makefile @@ -19,23 +19,32 @@ test: pre-commit run --all-files go test -slack-status: $(GOFILES) +slack-status: $(GOFILES) certs/key.pem go build -o $(OUTPUT) .PHONY: dist dist: $(DIST_TARGETS) -$(DIST_TARGETS): $(GOFILES) +$(DIST_TARGETS): $(GOFILES) certs/key.pem @mkdir -p ./dist GOOS=$(word 3, $(subst -, ,$(@))) GOARCH=$(word 4, $(subst -, ,$(@))) \ go build \ -ldflags '-X "main.version=${VERSION}" -X "main.defaultClientID=$(CLIENT_ID)" -X "main.defaultClientSecret=$(CLIENT_SECRET)"' \ -o $@ +certs/cert.pem: certs/key.pem +certs/key.pem: + mkdir -p certs/ + openssl req -x509 -subj "/C=US/O=Slack Status CLI/CN=localhost:8888" \ + -nodes -days 365 -newkey "rsa:2048" \ + -addext "subjectAltName=DNS:localhost:8888" \ + -keyout certs/key.pem -out certs/cert.pem + .PHONY: clean clean: rm -f ./slack-status rm -fr ./dist + rm -fr ./certs .PHONY: install-hooks install-hooks: diff --git a/auth.go b/auth.go index 25a71c1..78a5e0b 100644 --- a/auth.go +++ b/auth.go @@ -2,11 +2,12 @@ package main import ( "context" + "crypto/tls" + _ "embed" "errors" "fmt" "log" "net/http" - "os/exec" "strings" "time" @@ -17,6 +18,11 @@ var ( // These are set via build flags but can be overridden via environment variables. defaultClientID = "" defaultClientSecret = "" + + //go:embed "certs/cert.pem" + certPem []byte + //go:embed "certs/key.pem" + keyPem []byte ) const ( @@ -48,12 +54,42 @@ func (app slackApp) listenForCode() (string, error) { // start an http listener and listen for the redirect and return the code from params var code string + certPath, err := getConfigFilePath("cert.pem") + if err != nil { + return "", fmt.Errorf("failed checking config path for cert: %w", err) + } + + keyPath, err := getConfigFilePath("key.pem") + if err != nil { + return "", fmt.Errorf("failed checking config path for key: %w", err) + } + + tlsCfg := &tls.Config{ + MinVersion: tls.VersionTLS12, + } + + // If config files don't exist, use embedded + if !fileExists(certPath) && !fileExists(keyPath) { + cert, err := tls.X509KeyPair(certPem, keyPem) + if err != nil { + return "", fmt.Errorf("failed loading embedded key pair: %w", err) + } + + tlsCfg.Certificates = make([]tls.Certificate, 1) + tlsCfg.Certificates[0] = cert + + // Empty out paths since they don't exist so embeded certs will be used + certPath = "" + keyPath = "" + } + // Also, should generate TLS certificate to use since https is a required scheme server := http.Server{ Addr: app.listenHost, ReadTimeout: httpReadTimeout, WriteTimeout: httpWriteTimeout, IdleTimeout: httpIdleTimeout, + TLSConfig: tlsCfg, } http.HandleFunc(app.listenPath, func(w http.ResponseWriter, r *http.Request) { @@ -74,22 +110,6 @@ func (app slackApp) listenForCode() (string, error) { }() }) - certPath, err := getConfigFilePath("cert.pem") - if err != nil { - return "", err - } - - keyPath, err := getConfigFilePath("key.pem") - if err != nil { - return "", err - } - - if !fileExists(certPath) || !fileExists(keyPath) { - if err := generateSelfSignedCertificates(certPath, keyPath); err != nil { - return "", err - } - } - if err := server.ListenAndServeTLS(certPath, keyPath); err != nil && !errors.Is(err, http.ErrServerClosed) { return "", err } @@ -97,29 +117,6 @@ func (app slackApp) listenForCode() (string, error) { return code, nil } -func generateSelfSignedCertificates(certPath, keyPath string) error { - command := exec.Command( - "openssl", - "req", - "-x509", - "-subj", - "/C=US/O=Slack Status CLI/CN=localhost:8888", - "-nodes", - "-days", - "365", - "-newkey", - "rsa:2048", - "-addext", - "subjectAltName=DNS:localhost:8888", - "-keyout", - keyPath, - "-out", - certPath, - ) - - return command.Run() -} - func authenticate() (string, error) { app := slackApp{ userScopes: []string{"dnd:write", "users.profile:write", "team:read"}, diff --git a/go.mod b/go.mod index af5cb4a..66da627 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ module github.com/iamthefij/slack-status-cli -go 1.15 +go 1.16 require github.com/slack-go/slack v0.7.4