Skip to content

Commit

Permalink
Allow upterm host to allowlist users on self-hosted versions of VCSes
Browse files Browse the repository at this point in the history
Signed-off-by: Debayan De <[email protected]>
  • Loading branch information
debayande committed Jun 18, 2024
1 parent d520e3d commit 99061a3
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 23 deletions.
8 changes: 4 additions & 4 deletions cmd/upterm/command/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.")

Expand Down
8 changes: 4 additions & 4 deletions docs/upterm_host.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions etc/man/man1/upterm-host.1
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@ 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=""
Enforce a specified command for clients to join, and link the command's input/output to the client's terminal.

.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]
Expand All @@ -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
Expand Down
33 changes: 22 additions & 11 deletions host/authorizedkeys.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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
Expand Down
7 changes: 7 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 99061a3

Please sign in to comment.