fix for waveterm environment variables leaking from prod to dev (#1153)

This commit is contained in:
Mike Sawka 2024-10-27 13:12:41 -07:00 committed by GitHub
parent cbb825982b
commit 7e6f96348f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 114 additions and 76 deletions

View File

@ -185,8 +185,8 @@ tasks:
generate:
desc: Generate Typescript bindings for the Go backend.
cmds:
- NO_PANIC=1 go run cmd/generatets/main-generatets.go
- NO_PANIC=1 go run cmd/generatego/main-generatego.go
- go run cmd/generatets/main-generatets.go
- go run cmd/generatego/main-generatego.go
sources:
- "cmd/generatego/*.go"
- "cmd/generatets/*.go"

View File

@ -10,7 +10,6 @@ import (
"os"
"os/signal"
"runtime/debug"
"strconv"
"runtime"
"sync"
@ -46,8 +45,6 @@ const InitialTelemetryWait = 10 * time.Second
const TelemetryTick = 2 * time.Minute
const TelemetryInterval = 4 * time.Hour
const ReadySignalPidVarName = "WAVETERM_READY_SIGNAL_PID"
var shutdownOnce sync.Once
func doShutdown(reason string) {
@ -166,15 +163,31 @@ func createMainWshClient() {
wshutil.DefaultRouter.RegisterRoute(wshutil.MakeConnectionRouteId(wshrpc.LocalConnName), localConnWsh, true)
}
func grabAndRemoveEnvVars() error {
err := authkey.SetAuthKeyFromEnv()
if err != nil {
return fmt.Errorf("setting auth key: %v", err)
}
err = wavebase.CacheAndRemoveEnvVars()
if err != nil {
return err
}
err = wcloud.CacheAndRemoveEnvVars()
if err != nil {
return err
}
return nil
}
func main() {
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
log.SetPrefix("[wavesrv] ")
wavebase.WaveVersion = WaveVersion
wavebase.BuildTime = BuildTime
err := authkey.SetAuthKeyFromEnv()
err := grabAndRemoveEnvVars()
if err != nil {
log.Printf("error setting auth key: %v\n", err)
log.Printf("[error] %v\n", err)
return
}
err = service.ValidateServiceMap()
@ -279,17 +292,11 @@ func main() {
return
}
go func() {
pidStr := os.Getenv(ReadySignalPidVarName)
if pidStr != "" {
_, err := strconv.Atoi(pidStr)
if err == nil {
if BuildTime == "" {
BuildTime = "0"
}
// use fmt instead of log here to make sure it goes directly to stderr
fmt.Fprintf(os.Stderr, "WAVESRV-ESTART ws:%s web:%s version:%s buildtime:%s\n", wsListener.Addr(), webListener.Addr(), WaveVersion, BuildTime)
}
if BuildTime == "" {
BuildTime = "0"
}
// use fmt instead of log here to make sure it goes directly to stderr
fmt.Fprintf(os.Stderr, "WAVESRV-ESTART ws:%s web:%s version:%s buildtime:%s\n", wsListener.Addr(), webListener.Addr(), WaveVersion, BuildTime)
}()
go wshutil.RunWshRpcOverListener(unixListener)
web.RunWebServer(webListener) // blocking

View File

@ -5,7 +5,7 @@ import { ipcMain } from "electron";
import { getWebServerEndpoint, getWSServerEndpoint } from "../frontend/util/endpoints";
const AuthKeyHeader = "X-AuthKey";
export const AuthKeyEnv = "AUTH_KEY";
export const WaveAuthKeyEnv = "WAVETERM_AUTH_KEY";
export const AuthKey = crypto.randomUUID();
ipcMain.on("get-auth-key", (event) => {

View File

@ -5,7 +5,7 @@ import * as electron from "electron";
import * as child_process from "node:child_process";
import * as readline from "readline";
import { WebServerEndpointVarName, WSServerEndpointVarName } from "../frontend/util/endpoints";
import { AuthKey, AuthKeyEnv } from "./authkey";
import { AuthKey, WaveAuthKeyEnv } from "./authkey";
import { setForceQuit } from "./emain-activity";
import { WaveAppPathVarName } from "./emain-util";
import {
@ -19,8 +19,6 @@ import {
} from "./platform";
import { updater } from "./updater";
export const WaveSrvReadySignalPidVarName = "WAVETERM_READY_SIGNAL_PID";
let isWaveSrvDead = false;
let waveSrvProc: child_process.ChildProcessWithoutNullStreams | null = null;
let WaveVersion = "unknown"; // set by WAVESRV-ESTART
@ -56,8 +54,7 @@ export function runWaveSrv(handleWSEvent: (evtMsg: WSEventType) => void): Promis
});
const envCopy = { ...process.env };
envCopy[WaveAppPathVarName] = getElectronAppUnpackedBasePath();
envCopy[WaveSrvReadySignalPidVarName] = process.pid.toString();
envCopy[AuthKeyEnv] = AuthKey;
envCopy[WaveAuthKeyEnv] = AuthKey;
envCopy[WaveDataHomeVarName] = getWaveDataDir();
envCopy[WaveConfigHomeVarName] = getWaveConfigDir();
const waveSrvCmd = getWaveSrvPath();

View File

@ -11,7 +11,7 @@ import (
var authkey string
const AuthKeyEnv = "AUTH_KEY"
const WaveAuthKeyEnv = "WAVETERM_AUTH_KEY"
const AuthKeyHeader = "X-AuthKey"
func ValidateIncomingRequest(r *http.Request) error {
@ -26,11 +26,11 @@ func ValidateIncomingRequest(r *http.Request) error {
}
func SetAuthKeyFromEnv() error {
authkey = os.Getenv(AuthKeyEnv)
authkey = os.Getenv(WaveAuthKeyEnv)
if authkey == "" {
return fmt.Errorf("no auth key found in environment variables")
}
os.Setenv(AuthKeyEnv, "")
os.Unsetenv(WaveAuthKeyEnv)
return nil
}

View File

@ -1,15 +0,0 @@
package panic
import (
"log"
"os"
)
var shouldPanic = len(os.Getenv("NO_PANIC")) == 0
// Wraps log.Panic, ignored if NO_PANIC is set
func Panic(message string) {
if shouldPanic {
log.Panic(message)
}
}

View File

@ -17,17 +17,25 @@ import (
"strings"
"sync"
"time"
"github.com/wavetermdev/waveterm/pkg/util/panic"
)
// set by main-server.go
var WaveVersion = "0.0.0"
var BuildTime = "0"
const WaveConfigHomeEnvVar = "WAVETERM_CONFIG_HOME"
const WaveDataHomeEnvVar = "WAVETERM_DATA_HOME"
const WaveDevVarName = "WAVETERM_DEV"
const (
WaveConfigHomeEnvVar = "WAVETERM_CONFIG_HOME"
WaveDataHomeEnvVar = "WAVETERM_DATA_HOME"
WaveAppPathVarName = "WAVETERM_APP_PATH"
WaveDevVarName = "WAVETERM_DEV"
WaveDevViteVarName = "WAVETERM_DEV_VITE"
)
var ConfigHome_VarCache string // caches WAVETERM_CONFIG_HOME
var DataHome_VarCache string // caches WAVETERM_DATA_HOME
var AppPath_VarCache string // caches WAVETERM_APP_PATH
var Dev_VarCache string // caches WAVETERM_DEV
const WaveLockFile = "wave.lock"
const DomainSocketBaseName = "wave.sock"
const RemoteDomainSocketBaseName = "wave-remote.sock"
@ -37,7 +45,6 @@ const ConfigDir = "config"
var RemoteWaveHome = ExpandHomeDirSafe("~/.waveterm")
const WaveAppPathVarName = "WAVETERM_APP_PATH"
const AppPathBinDir = "bin"
var baseLock = &sync.Mutex{}
@ -47,13 +54,39 @@ type FDLock interface {
Close() error
}
func CacheAndRemoveEnvVars() error {
ConfigHome_VarCache = os.Getenv(WaveConfigHomeEnvVar)
if ConfigHome_VarCache == "" {
return fmt.Errorf(WaveConfigHomeEnvVar + " not set")
}
os.Unsetenv(WaveConfigHomeEnvVar)
DataHome_VarCache = os.Getenv(WaveDataHomeEnvVar)
if DataHome_VarCache == "" {
return fmt.Errorf("%s not set", WaveDataHomeEnvVar)
}
os.Unsetenv(WaveDataHomeEnvVar)
AppPath_VarCache = os.Getenv(WaveAppPathVarName)
os.Unsetenv(WaveAppPathVarName)
Dev_VarCache = os.Getenv(WaveDevVarName)
os.Unsetenv(WaveDevVarName)
os.Unsetenv(WaveDevViteVarName)
return nil
}
func IsDevMode() bool {
pdev := os.Getenv(WaveDevVarName)
return pdev != ""
return Dev_VarCache != ""
}
func GetWaveAppPath() string {
return os.Getenv(WaveAppPathVarName)
return AppPath_VarCache
}
func GetWaveDataDir() string {
return DataHome_VarCache
}
func GetWaveConfigDir() string {
return ConfigHome_VarCache
}
func GetWaveAppBinPath() string {
@ -108,22 +141,6 @@ func GetRemoteDomainSocketName() string {
return filepath.Join(RemoteWaveHome, RemoteDomainSocketBaseName)
}
func GetWaveDataDir() string {
retVal, found := os.LookupEnv(WaveDataHomeEnvVar)
if !found {
panic.Panic(WaveDataHomeEnvVar + " not set")
}
return retVal
}
func GetWaveConfigDir() string {
retVal, found := os.LookupEnv(WaveConfigHomeEnvVar)
if !found {
panic.Panic(WaveConfigHomeEnvVar + " not set")
}
return retVal
}
func EnsureWaveDataDir() error {
return CacheEnsureDir(GetWaveDataDir(), "wavehome", 0700, "wave home directory")
}

View File

@ -27,6 +27,9 @@ const WCloudEndpointVarName = "WCLOUD_ENDPOINT"
const WCloudWSEndpoint = "wss://wsapi.waveterm.dev/"
const WCloudWSEndpointVarName = "WCLOUD_WS_ENDPOINT"
var WCloudWSEndpoint_VarCache string
var WCloudEndpoint_VarCache string
const APIVersion = 1
const MaxPtyUpdateSize = (128 * 1024)
const MaxUpdatesPerReq = 10
@ -43,15 +46,48 @@ const TelemetryUrl = "/telemetry"
const NoTelemetryUrl = "/no-telemetry"
const WebShareUpdateUrl = "/auth/web-share-update"
func CacheAndRemoveEnvVars() error {
WCloudEndpoint_VarCache = os.Getenv(WCloudEndpointVarName)
err := checkEndpointVar(WCloudEndpoint_VarCache, "wcloud endpoint", WCloudEndpointVarName)
if err != nil {
return err
}
os.Unsetenv(WCloudEndpointVarName)
WCloudWSEndpoint_VarCache = os.Getenv(WCloudWSEndpointVarName)
err = checkWSEndpointVar(WCloudWSEndpoint_VarCache, "wcloud ws endpoint", WCloudWSEndpointVarName)
if err != nil {
return err
}
os.Unsetenv(WCloudWSEndpointVarName)
return nil
}
func checkEndpointVar(endpoint string, debugName string, varName string) error {
if !wavebase.IsDevMode() {
return nil
}
if endpoint == "" || !strings.HasPrefix(endpoint, "https://") {
return fmt.Errorf("invalid %s, %s not set or invalid", debugName, varName)
}
return nil
}
func checkWSEndpointVar(endpoint string, debugName string, varName string) error {
if !wavebase.IsDevMode() {
return nil
}
log.Printf("checking endpoint %q\n", endpoint)
if endpoint == "" || !strings.HasPrefix(endpoint, "wss://") {
return fmt.Errorf("invalid %s, %s not set or invalid", debugName, varName)
}
return nil
}
func GetEndpoint() string {
if !wavebase.IsDevMode() {
return WCloudEndpoint
}
endpoint := os.Getenv(WCloudEndpointVarName)
if endpoint == "" || !strings.HasPrefix(endpoint, "https://") {
log.Printf("Invalid wcloud dev endpoint, WCLOUD_ENDPOINT not set or invalid\n")
return ""
}
endpoint := WCloudEndpoint_VarCache
return endpoint
}
@ -59,11 +95,7 @@ func GetWSEndpoint() string {
if !wavebase.IsDevMode() {
return WCloudWSEndpoint
}
endpoint := os.Getenv(WCloudWSEndpointVarName)
if endpoint == "" || !strings.HasPrefix(endpoint, "wss://") {
log.Printf("Invalid wcloud ws dev endpoint, WCLOUD_WS_ENDPOINT not set or invalid\n")
return ""
}
endpoint := WCloudWSEndpoint_VarCache
return endpoint
}