From 99061a3f960b36989122d96a96adb41f851154e8 Mon Sep 17 00:00:00 2001 From: Debayan De Date: Tue, 18 Jun 2024 19:21:55 +0100 Subject: [PATCH] Allow `upterm host` to allowlist users on self-hosted versions of VCSes Signed-off-by: Debayan De --- cmd/upterm/command/host.go | 8 ++++---- docs/upterm_host.md | 8 ++++---- etc/man/man1/upterm-host.1 | 8 ++++---- host/authorizedkeys.go | 33 ++++++++++++++++++++++----------- utils/utils.go | 7 +++++++ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/cmd/upterm/command/host.go b/cmd/upterm/command/host.go index b5c8438b1..8002cca30 100644 --- a/cmd/upterm/command/host.go +++ b/cmd/upterm/command/host.go @@ -74,10 +74,10 @@ private key. To authorize client connections, specify a authorized_key file with cmd.PersistentFlags().StringSliceVarP(&flagPrivateKeys, "private-key", "i", defaultPrivateKeys(homeDir), "Specify private key files for public key authentication with the upterm server (required).") cmd.PersistentFlags().StringVarP(&flagKnownHostsFilename, "known-hosts", "", defaultKnownHost(homeDir), "Specify a file containing known keys for remote hosts (required).") cmd.PersistentFlags().StringVar(&flagAuthorizedKeys, "authorized-keys", "", "Specify a authorize_keys file listing authorized public keys for connection.") - cmd.PersistentFlags().StringSliceVar(&flagCodebergUsers, "codeberg-user", nil, "Authorize specified Codeberg users by allowing their public keys to connect.") - cmd.PersistentFlags().StringSliceVar(&flagGitHubUsers, "github-user", nil, "Authorize specified GitHub users by allowing their public keys to connect. Configure GitHub CLI environment variables as needed; see https://cli.github.com/manual/gh_help_environment for details.") - cmd.PersistentFlags().StringSliceVar(&flagGitLabUsers, "gitlab-user", nil, "Authorize specified GitLab users by allowing their public keys to connect.") - cmd.PersistentFlags().StringSliceVar(&flagSourceHutUsers, "srht-user", nil, "Authorize specified SourceHut users by allowing their public keys to connect.") + cmd.PersistentFlags().StringSliceVar(&flagCodebergUsers, "codeberg-user", nil, "Authorize specified Codeberg users by allowing their public keys to connect. For self-hosted installations, set CODEBERG_HOST, along with the protocol prefix (e.g., https://git.example.com).") + cmd.PersistentFlags().StringSliceVar(&flagGitHubUsers, "github-user", nil, "Authorize specified GitHub users by allowing their public keys to connect. Configure GitHub CLI environment variables as needed; see https://cli.github.com/manual/gh_help_environment for details. For self-hosted installations, set GITHUB_HOST, along with the protocol prefix (e.g., https://git.example.com).") + cmd.PersistentFlags().StringSliceVar(&flagGitLabUsers, "gitlab-user", nil, "Authorize specified GitLab users by allowing their public keys to connect. For self-hosted installations, set GITLAB_HOST, along with the protocol prefix (e.g., https://git.example.com).") + cmd.PersistentFlags().StringSliceVar(&flagSourceHutUsers, "srht-user", nil, "Authorize specified SourceHut users by allowing their public keys to connect. For self-hosted installations, set SOURCEHUT_HOST, along with the protocol prefix (e.g., https://git.example.com).") cmd.PersistentFlags().BoolVar(&flagAccept, "accept", false, "Automatically accept client connections without prompts.") cmd.PersistentFlags().BoolVarP(&flagReadOnly, "read-only", "r", false, "Host a read-only session, preventing client interaction.") diff --git a/docs/upterm_host.md b/docs/upterm_host.md index c604bbe34..8be25af58 100644 --- a/docs/upterm_host.md +++ b/docs/upterm_host.md @@ -41,16 +41,16 @@ upterm host [flags] ``` --accept Automatically accept client connections without prompts. --authorized-keys string Specify a authorize_keys file listing authorized public keys for connection. - --codeberg-user strings Authorize specified Codeberg users by allowing their public keys to connect. + --codeberg-user strings Authorize specified Codeberg users by allowing their public keys to connect. For self-hosted installations, set CODEBERG_HOST, along with the protocol prefix (e.g., https://git.example.com). -f, --force-command string Enforce a specified command for clients to join, and link the command's input/output to the client's terminal. - --github-user strings Authorize specified GitHub users by allowing their public keys to connect. Configure GitHub CLI environment variables as needed; see https://cli.github.com/manual/gh_help_environment for details. - --gitlab-user strings Authorize specified GitLab users by allowing their public keys to connect. + --github-user strings Authorize specified GitHub users by allowing their public keys to connect. Configure GitHub CLI environment variables as needed; see https://cli.github.com/manual/gh_help_environment for details. For self-hosted installations, set GITHUB_HOST, along with the protocol prefix (e.g., https://git.example.com). + --gitlab-user strings Authorize specified GitLab users by allowing their public keys to connect. For self-hosted installations, set GITLAB_HOST, along with the protocol prefix (e.g., https://git.example.com). -h, --help help for host --known-hosts string Specify a file containing known keys for remote hosts (required). (default "/Users/owen/.ssh/known_hosts") -i, --private-key strings Specify private key files for public key authentication with the upterm server (required). (default [/Users/owen/.ssh/id_ed25519]) -r, --read-only Host a read-only session, preventing client interaction. --server string Specify the upterm server address (required). Supported protocols: ssh, ws, wss. (default "ssh://uptermd.upterm.dev:22") - --srht-user strings Authorize specified SourceHut users by allowing their public keys to connect. + --srht-user strings Authorize specified SourceHut users by allowing their public keys to connect. For self-hosted installations, set SOURCEHUT_HOST, along with the protocol prefix (e.g., https://git.example.com). ``` ### SEE ALSO diff --git a/etc/man/man1/upterm-host.1 b/etc/man/man1/upterm-host.1 index f26d69479..32c4df626 100644 --- a/etc/man/man1/upterm-host.1 +++ b/etc/man/man1/upterm-host.1 @@ -31,7 +31,7 @@ private key. To authorize client connections, specify a authorized_key file with .PP \fB--codeberg-user\fP=[] - Authorize specified Codeberg users by allowing their public keys to connect. + Authorize specified Codeberg users by allowing their public keys to connect. For self-hosted installations, set CODEBERG_HOST, along with the protocol prefix (e.g., https://git.example.com). .PP \fB-f\fP, \fB--force-command\fP="" @@ -39,11 +39,11 @@ private key. To authorize client connections, specify a authorized_key file with .PP \fB--github-user\fP=[] - Authorize specified GitHub users by allowing their public keys to connect. Configure GitHub CLI environment variables as needed; see https://cli.github.com/manual/gh_help_environment for details. + Authorize specified GitHub users by allowing their public keys to connect. Configure GitHub CLI environment variables as needed; see https://cli.github.com/manual/gh_help_environment for details. For self-hosted installations, set GITHUB_HOST, along with the protocol prefix (e.g., https://git.example.com). .PP \fB--gitlab-user\fP=[] - Authorize specified GitLab users by allowing their public keys to connect. + Authorize specified GitLab users by allowing their public keys to connect. For self-hosted installations, set GITLAB_HOST, along with the protocol prefix (e.g., https://git.example.com). .PP \fB-h\fP, \fB--help\fP[=false] @@ -67,7 +67,7 @@ private key. To authorize client connections, specify a authorized_key file with .PP \fB--srht-user\fP=[] - Authorize specified SourceHut users by allowing their public keys to connect. + Authorize specified SourceHut users by allowing their public keys to connect. For self-hosted installations, set SOURCEHUT_HOST, along with the protocol prefix (e.g., https://git.example.com). .SH EXAMPLE diff --git a/host/authorizedkeys.go b/host/authorizedkeys.go index 906daac6b..a99800b38 100644 --- a/host/authorizedkeys.go +++ b/host/authorizedkeys.go @@ -10,22 +10,33 @@ import ( "time" "github.com/cli/go-gh/v2/pkg/api" + "github.com/owenthereal/upterm/utils" "github.com/sirupsen/logrus" "golang.org/x/crypto/ssh" ) -const ( - codebergKeysUrlFmt = "https://codeberg.org/%s" - gitHubKeysUrlFmt = "https://github.com/%s" - gitLabKeysUrlFmt = "https://gitlab.com/%s" - sourceHutKeysUrlFmt = "https://meta.sr.ht/~%s" -) - type AuthorizedKey struct { PublicKeys []ssh.PublicKey Comment string } +func GetUrlFmt(service string) string { + serviceAttrsMap := map[string][]string{ + "Codeberg": {"CODEBERG_HOST", "https://codeberg.org"}, + "GitHub": {"GITHUB_HOST", "https://github.com"}, + "GitLab": {"GITLAB_HOST", "https://gitlab.com"}, + "SourceHut": {"SOURCEHUT_HOST", "https://meta.sr.ht"}, + } + + serviceUrl := utils.GetEnvWithDefault(serviceAttrsMap[service][0], serviceAttrsMap[service][1]) + + if service == "SourceHut" { + return (serviceUrl + "/~%s") + } + + return (serviceUrl + "/%s") +} + func AuthorizedKeysFromFile(file string) (*AuthorizedKey, error) { authorizedKeysBytes, err := os.ReadFile(file) if err != nil { @@ -36,7 +47,7 @@ func AuthorizedKeysFromFile(file string) (*AuthorizedKey, error) { } func CodebergUserAuthorizedKeys(usernames []string) ([]*AuthorizedKey, error) { - return usersPublicKeys(codebergKeysUrlFmt, usernames) + return usersPublicKeys(GetUrlFmt("Codeberg"), usernames) } func GitHubUserAuthorizedKeys(usernames []string, logger *logrus.Logger) ([]*AuthorizedKey, error) { @@ -66,11 +77,11 @@ func GitHubUserAuthorizedKeys(usernames []string, logger *logrus.Logger) ([]*Aut } func GitLabUserAuthorizedKeys(usernames []string) ([]*AuthorizedKey, error) { - return usersPublicKeys(gitLabKeysUrlFmt, usernames) + return usersPublicKeys(GetUrlFmt("GitLab"), usernames) } func SourceHutUserAuthorizedKeys(usernames []string) ([]*AuthorizedKey, error) { - return usersPublicKeys(sourceHutKeysUrlFmt, usernames) + return usersPublicKeys(GetUrlFmt("SourceHut"), usernames) } func parseAuthorizedKeys(keysBytes []byte, comment string) (*AuthorizedKey, error) { @@ -97,7 +108,7 @@ func githubUserPublicKeys(username string, logger *logrus.Logger) ([]byte, error if strings.Contains(err.Error(), "authentication token not found for host") { // fallback to use the public GH API logger.WithError(err).Warn("no GitHub token found, falling back to public API") - return userPublicKeys(gitHubKeysUrlFmt, username) + return userPublicKeys(GetUrlFmt("GitHub"), username) } return nil, err diff --git a/utils/utils.go b/utils/utils.go index 47dbcd883..70f93026a 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -27,6 +27,13 @@ func UptermDir() (string, error) { return filepath.Join(homedir, ".upterm"), nil } +func GetEnvWithDefault(envVar, defaultValue string) string { + if v, ok := os.LookupEnv(envVar); ok && len(v) > 0 { + return v + } + return defaultValue +} + func CreateUptermDir() (string, error) { dir, err := UptermDir() if err != nil {