Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
2e774e9623
|
|||
|
a016b15508
|
|||
|
c6d270fc36
|
|||
|
7dc1f9c53e
|
|||
|
6d2ab00fa7
|
|||
|
09e4a5d646
|
|||
|
904f585c4d
|
|||
|
f78e3092fb
|
@@ -18,8 +18,14 @@ jobs:
|
|||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: 1.24.x
|
go-version: 1.24.x
|
||||||
|
- name: Spell checking
|
||||||
|
uses: crate-ci/typos@v1.39.0
|
||||||
|
with:
|
||||||
|
config: ./.typos-config
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: go get -u .
|
run: go get .
|
||||||
|
- name: Run tests
|
||||||
|
run: go test ./...
|
||||||
- name: Build
|
- name: Build
|
||||||
run: CGO_ENABLED=0 GOOS=linux go build -ldflags "-s -w" -o ./bin/serve main.go
|
run: CGO_ENABLED=0 GOOS=linux go build -ldflags "-s -w" -o ./bin/serve main.go
|
||||||
- name: Release build artifacts
|
- name: Release build artifacts
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: 1.24.x
|
go-version: 1.24.x
|
||||||
- name: Spell checking
|
- name: Spell checking
|
||||||
uses: crate-ci/typos@v1.25.0
|
uses: crate-ci/typos@v1.39.0
|
||||||
with:
|
with:
|
||||||
config: ./.typos-config
|
config: ./.typos-config
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: go get -u .
|
run: go get .
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: go test ./...
|
run: go test ./...
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -7,6 +7,7 @@ require (
|
|||||||
github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309
|
github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309
|
||||||
github.com/charmbracelet/wish v1.4.7
|
github.com/charmbracelet/wish v1.4.7
|
||||||
github.com/spf13/viper v1.21.0
|
github.com/spf13/viper v1.21.0
|
||||||
|
golang.org/x/crypto v0.43.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -45,7 +46,6 @@ require (
|
|||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||||
golang.org/x/crypto v0.43.0 // indirect
|
|
||||||
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
|
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
|
||||||
golang.org/x/sys v0.37.0 // indirect
|
golang.org/x/sys v0.37.0 // indirect
|
||||||
golang.org/x/text v0.30.0 // indirect
|
golang.org/x/text v0.30.0 // indirect
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/charmbracelet/wish"
|
"github.com/charmbracelet/wish"
|
||||||
"github.com/charmbracelet/wish/activeterm"
|
"github.com/charmbracelet/wish/activeterm"
|
||||||
"github.com/charmbracelet/wish/logging"
|
"github.com/charmbracelet/wish/logging"
|
||||||
|
gossh "golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setup default logger to append or create a new log file `log` in the current
|
// Setup default logger to append or create a new log file `log` in the current
|
||||||
@@ -51,16 +52,24 @@ func setupSshServer(host string, port string, host_key_path string, users map[st
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}),
|
}),
|
||||||
|
wish.WithKeyboardInteractiveAuth(func(_ ssh.Context, _ gossh.KeyboardInteractiveChallenge) bool {
|
||||||
|
if len(users) == 0 {
|
||||||
|
// no users provided, meaning there is no user authentication, everyone is allowed to connect
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// NOTE interactive logins through keyboard challenges shall not be allowed; use
|
||||||
|
// ssh public-private key-pairs instead for limited access
|
||||||
|
return false
|
||||||
|
}),
|
||||||
ssh.AllocatePty(),
|
ssh.AllocatePty(),
|
||||||
wish.WithMiddleware(
|
wish.WithMiddleware(
|
||||||
func(next ssh.Handler) ssh.Handler {
|
func(next ssh.Handler) ssh.Handler {
|
||||||
return func(s ssh.Session) {
|
return func(s ssh.Session) {
|
||||||
cmd := wish.Command(s, name, args...)
|
provided_args := s.Command()
|
||||||
file, err := os.OpenFile("log", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
|
if len(provided_args) > 0 {
|
||||||
if err != nil {
|
args = provided_args
|
||||||
wish.Fatalln(s, err)
|
|
||||||
}
|
}
|
||||||
cmd.SetStderr(file)
|
cmd := wish.Command(s, name, args...)
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
wish.Fatalln(s, err)
|
wish.Fatalln(s, err)
|
||||||
}
|
}
|
||||||
|
|||||||
36
main.go
36
main.go
@@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"yves-biener.de/wish-serve/internal/serve"
|
"yves-biener.de/wish-serve/internal/serve"
|
||||||
@@ -15,12 +14,19 @@ func createDefaultConfig() {
|
|||||||
viper.SetDefault("key.dir", ".ssh")
|
viper.SetDefault("key.dir", ".ssh")
|
||||||
viper.SetDefault("key.name", "ssh_ed25519_key")
|
viper.SetDefault("key.name", "ssh_ed25519_key")
|
||||||
viper.SetDefault("app.name", "echo")
|
viper.SetDefault("app.name", "echo")
|
||||||
viper.SetDefault("app.args", []string{"Hello World"})
|
viper.SetDefault("app.args", []string{"Hello", "World"})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the configuration file from (`$HOME/.config/serve/config.yml` or
|
// Load the configuration file from any of the following locations (loading the
|
||||||
// `./config.yml`) if it exists. Otherwise use the default values from
|
// first one with an existing configuration):
|
||||||
// `createDefaultConfig()`.
|
// - `$HOME/.config/serve/config.yml`
|
||||||
|
// - `./config.yml`
|
||||||
|
//
|
||||||
|
// If no configuration is found in any of the defined locations the default
|
||||||
|
// values of `createDefaultConfig` will remain unchanged.
|
||||||
|
//
|
||||||
|
// Invalid configuration files will cause a fatal error causing the application
|
||||||
|
// to panic.
|
||||||
func loadConfig() {
|
func loadConfig() {
|
||||||
viper.SetConfigName("config")
|
viper.SetConfigName("config")
|
||||||
viper.SetConfigType("yml")
|
viper.SetConfigType("yml")
|
||||||
@@ -33,29 +39,9 @@ func loadConfig() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overwrite (default) configuration value for the application to serve with
|
|
||||||
// given command line arguments.
|
|
||||||
//
|
|
||||||
// NOTE: This will also overwrite the configuration for the `app` entry from the
|
|
||||||
// configuration file.
|
|
||||||
func overwriteServeCommand() {
|
|
||||||
if len(os.Args) >= 2 {
|
|
||||||
name := os.Args[1]
|
|
||||||
viper.Set("app.name", name)
|
|
||||||
if len(os.Args) >= 3 {
|
|
||||||
args := os.Args[2:]
|
|
||||||
viper.Set("app.args", args)
|
|
||||||
} else {
|
|
||||||
// no arguments provided -> clear app arguments
|
|
||||||
viper.Set("app.args", []string{})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
createDefaultConfig()
|
createDefaultConfig()
|
||||||
loadConfig()
|
loadConfig()
|
||||||
overwriteServeCommand()
|
|
||||||
|
|
||||||
serve.Serve(
|
serve.Serve(
|
||||||
viper.GetString("host"),
|
viper.GetString("host"),
|
||||||
|
|||||||
Reference in New Issue
Block a user