As we reevaluate how to best support and maintain Staging Ref in the future, we encourage development teams using this environment to highlight their use cases in the following issue: https://gitlab.com/gitlab-com/gl-infra/software-delivery/framework/software-delivery-framework-issue-tracker/-/issues/36.

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • idrozdov/gitlab-shell
  • mmj/gitlab-shell
2 results
Show changes
Commits on Source (1)
Showing
with 121 additions and 70 deletions
Loading
@@ -43,7 +43,7 @@ func main() {
Loading
@@ -43,7 +43,7 @@ func main() {
ctx, finished := command.Setup(executable.Name, config) ctx, finished := command.Setup(executable.Name, config)
defer finished() defer finished()
if err = cmd.Execute(ctx); err != nil { if _, err = cmd.Execute(ctx); err != nil {
fmt.Fprintf(readWriter.ErrOut, "%v\n", err) fmt.Fprintf(readWriter.ErrOut, "%v\n", err)
os.Exit(1) os.Exit(1)
} }
Loading
Loading
Loading
@@ -46,7 +46,7 @@ func main() {
Loading
@@ -46,7 +46,7 @@ func main() {
ctx, finished := command.Setup(executable.Name, config) ctx, finished := command.Setup(executable.Name, config)
defer finished() defer finished()
if err = cmd.Execute(ctx); err != nil { if _, err = cmd.Execute(ctx); err != nil {
console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) console.DisplayWarningMessage(err.Error(), readWriter.ErrOut)
os.Exit(1) os.Exit(1)
} }
Loading
Loading
Loading
@@ -46,7 +46,7 @@ func main() {
Loading
@@ -46,7 +46,7 @@ func main() {
ctx, finished := command.Setup(executable.Name, config) ctx, finished := command.Setup(executable.Name, config)
defer finished() defer finished()
if err = cmd.Execute(ctx); err != nil { if _, err = cmd.Execute(ctx); err != nil {
console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) console.DisplayWarningMessage(err.Error(), readWriter.ErrOut)
os.Exit(1) os.Exit(1)
} }
Loading
Loading
package command package command
import ( import (
"strings"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/discover"
Loading
@@ -17,6 +19,32 @@ import (
Loading
@@ -17,6 +19,32 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/sshenv"
) )
type MetaData struct {
Username string `json:"username"`
Project string `json:"project,omitempty"`
RootNamespace string `json:"root_namespace,omitempty"`
}
func NewMetaData(project, username string) MetaData {
rootNameSpace := ""
if len(project) > 0 {
splitFn := func(c rune) bool {
return c == '/'
}
m := strings.FieldsFunc(project, splitFn)
if len(m) > 0 {
rootNameSpace = m[0]
}
}
return MetaData{
Username: username,
Project: project,
RootNamespace: rootNameSpace,
}
}
func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) { func New(arguments []string, env sshenv.Env, config *config.Config, readWriter *readwriter.ReadWriter) (command.Command, error) {
args, err := Parse(arguments, env) args, err := Parse(arguments, env)
if err != nil { if err != nil {
Loading
Loading
Loading
@@ -76,7 +76,7 @@ func main() {
Loading
@@ -76,7 +76,7 @@ func main() {
ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command") ctxlog.WithFields(log.Fields{"env": env, "command": cmdName}).Info("gitlab-shell: main: executing command")
fips.Check() fips.Check()
if err := cmd.Execute(ctx); err != nil { if _, err := cmd.Execute(ctx); err != nil {
ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed") ctxlog.WithError(err).Warn("gitlab-shell: main: command execution failed")
if grpcstatus.Convert(err).Code() != grpccodes.Internal { if grpcstatus.Convert(err).Code() != grpccodes.Internal {
console.DisplayWarningMessage(err.Error(), readWriter.ErrOut) console.DisplayWarningMessage(err.Error(), readWriter.ErrOut)
Loading
Loading
Loading
@@ -7,6 +7,7 @@ import (
Loading
@@ -7,6 +7,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/authorizedkeys"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline"
Loading
@@ -18,21 +19,21 @@ type Command struct {
Loading
@@ -18,21 +19,21 @@ type Command struct {
ReadWriter *readwriter.ReadWriter ReadWriter *readwriter.ReadWriter
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
// Do and return nothing when the expected and actual user don't match. // Do and return nothing when the expected and actual user don't match.
// This can happen when the user in sshd_config doesn't match the user // This can happen when the user in sshd_config doesn't match the user
// trying to login. When nothing is printed, the user will be denied access. // trying to login. When nothing is printed, the user will be denied access.
if c.Args.ExpectedUser != c.Args.ActualUser { if c.Args.ExpectedUser != c.Args.ActualUser {
// TODO: Log this event once we have a consistent way to log in Go. // TODO: Log this event once we have a consistent way to log in Go.
// See https://gitlab.com/gitlab-org/gitlab-shell/issues/192 for more info. // See https://gitlab.com/gitlab-org/gitlab-shell/issues/192 for more info.
return nil return nil, nil
} }
if err := c.printKeyLine(ctx); err != nil { if err := c.printKeyLine(ctx); err != nil {
return err return nil, err
} }
return nil return nil, nil
} }
func (c *Command) printKeyLine(ctx context.Context) error { func (c *Command) printKeyLine(ctx context.Context) error {
Loading
Loading
Loading
@@ -6,6 +6,7 @@ import (
Loading
@@ -6,6 +6,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/keyline"
) )
Loading
@@ -16,12 +17,12 @@ type Command struct {
Loading
@@ -16,12 +17,12 @@ type Command struct {
ReadWriter *readwriter.ReadWriter ReadWriter *readwriter.ReadWriter
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
if err := c.printPrincipalLines(); err != nil { if err := c.printPrincipalLines(); err != nil {
return err return nil, err
} }
return nil return nil, nil
} }
func (c *Command) printPrincipalLines() error { func (c *Command) printPrincipalLines() error {
Loading
Loading
Loading
@@ -3,13 +3,14 @@ package command
Loading
@@ -3,13 +3,14 @@ package command
import ( import (
"context" "context"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/labkit/correlation" "gitlab.com/gitlab-org/labkit/correlation"
"gitlab.com/gitlab-org/labkit/tracing" "gitlab.com/gitlab-org/labkit/tracing"
) )
type Command interface { type Command interface {
Execute(ctx context.Context) error Execute(ctx context.Context) (*accessverifier.Response, error)
} }
// Setup() initializes tracing from the configuration file and generates a // Setup() initializes tracing from the configuration file and generates a
Loading
Loading
Loading
@@ -6,6 +6,7 @@ import (
Loading
@@ -6,6 +6,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/discover"
) )
Loading
@@ -16,10 +17,10 @@ type Command struct {
Loading
@@ -16,10 +17,10 @@ type Command struct {
ReadWriter *readwriter.ReadWriter ReadWriter *readwriter.ReadWriter
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
response, err := c.getUserInfo(ctx) response, err := c.getUserInfo(ctx)
if err != nil { if err != nil {
return fmt.Errorf("Failed to get username: %v", err) return nil, fmt.Errorf("Failed to get username: %v", err)
} }
if response.IsAnonymous() { if response.IsAnonymous() {
Loading
@@ -28,7 +29,7 @@ func (c *Command) Execute(ctx context.Context) error {
Loading
@@ -28,7 +29,7 @@ func (c *Command) Execute(ctx context.Context) error {
fmt.Fprintf(c.ReadWriter.Out, "Welcome to GitLab, @%s!\n", response.Username) fmt.Fprintf(c.ReadWriter.Out, "Welcome to GitLab, @%s!\n", response.Username)
} }
return nil return nil, nil
} }
func (c *Command) getUserInfo(ctx context.Context) (*discover.Response, error) { func (c *Command) getUserInfo(ctx context.Context) (*discover.Response, error) {
Loading
Loading
Loading
@@ -5,6 +5,7 @@ import (
Loading
@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/healthcheck"
) )
Loading
@@ -19,20 +20,20 @@ type Command struct {
Loading
@@ -19,20 +20,20 @@ type Command struct {
ReadWriter *readwriter.ReadWriter ReadWriter *readwriter.ReadWriter
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
response, err := c.runCheck(ctx) response, err := c.runCheck(ctx)
if err != nil { if err != nil {
return fmt.Errorf("%v: FAILED - %v", apiMessage, err) return nil, fmt.Errorf("%v: FAILED - %v", apiMessage, err)
} }
fmt.Fprintf(c.ReadWriter.Out, "%v: OK\n", apiMessage) fmt.Fprintf(c.ReadWriter.Out, "%v: OK\n", apiMessage)
if !response.Redis { if !response.Redis {
return fmt.Errorf("%v: FAILED", redisMessage) return nil, fmt.Errorf("%v: FAILED", redisMessage)
} }
fmt.Fprintf(c.ReadWriter.Out, "%v: OK\n", redisMessage) fmt.Fprintf(c.ReadWriter.Out, "%v: OK\n", redisMessage)
return nil return nil, nil
} }
func (c *Command) runCheck(ctx context.Context) (*healthcheck.Response, error) { func (c *Command) runCheck(ctx context.Context) (*healthcheck.Response, error) {
Loading
Loading
Loading
@@ -37,10 +37,10 @@ type Payload struct {
Loading
@@ -37,10 +37,10 @@ type Payload struct {
ExpiresIn int `json:"expires_in,omitempty"` ExpiresIn int `json:"expires_in,omitempty"`
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
args := c.Args.SshArgs args := c.Args.SshArgs
if len(args) < 3 { if len(args) < 3 {
return disallowedcommand.Error return nil, disallowedcommand.Error
} }
// e.g. git-lfs-authenticate user/repo.git download // e.g. git-lfs-authenticate user/repo.git download
Loading
@@ -49,12 +49,12 @@ func (c *Command) Execute(ctx context.Context) error {
Loading
@@ -49,12 +49,12 @@ func (c *Command) Execute(ctx context.Context) error {
action, err := actionFromOperation(operation) action, err := actionFromOperation(operation)
if err != nil { if err != nil {
return err return nil, err
} }
accessResponse, err := c.verifyAccess(ctx, action, repo) accessResponse, err := c.verifyAccess(ctx, action, repo)
if err != nil { if err != nil {
return err return nil, err
} }
payload, err := c.authenticate(ctx, operation, repo, accessResponse.UserId) payload, err := c.authenticate(ctx, operation, repo, accessResponse.UserId)
Loading
@@ -65,12 +65,12 @@ func (c *Command) Execute(ctx context.Context) error {
Loading
@@ -65,12 +65,12 @@ func (c *Command) Execute(ctx context.Context) error {
log.Fields{"operation": operation, "repo": repo, "user_id": accessResponse.UserId}, log.Fields{"operation": operation, "repo": repo, "user_id": accessResponse.UserId},
).WithError(err).Debug("lfsauthenticate: execute: LFS authentication failed") ).WithError(err).Debug("lfsauthenticate: execute: LFS authentication failed")
return nil return accessResponse, nil
} }
fmt.Fprintf(c.ReadWriter.Out, "%s\n", payload) fmt.Fprintf(c.ReadWriter.Out, "%s\n", payload)
return nil return accessResponse, nil
} }
func actionFromOperation(operation string) (commandargs.CommandType, error) { func actionFromOperation(operation string) (commandargs.CommandType, error) {
Loading
Loading
Loading
@@ -12,6 +12,7 @@ import (
Loading
@@ -12,6 +12,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/personalaccesstoken"
) )
Loading
@@ -34,10 +35,10 @@ type tokenArgs struct {
Loading
@@ -34,10 +35,10 @@ type tokenArgs struct {
ExpiresDate string // Calculated, a TTL is passed from command-line. ExpiresDate string // Calculated, a TTL is passed from command-line.
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
err := c.parseTokenArgs() err := c.parseTokenArgs()
if err != nil { if err != nil {
return err return nil, err
} }
log.WithContextFields(ctx, log.Fields{ log.WithContextFields(ctx, log.Fields{
Loading
@@ -46,13 +47,14 @@ func (c *Command) Execute(ctx context.Context) error {
Loading
@@ -46,13 +47,14 @@ func (c *Command) Execute(ctx context.Context) error {
response, err := c.getPersonalAccessToken(ctx) response, err := c.getPersonalAccessToken(ctx)
if err != nil { if err != nil {
return err return nil, err
} }
fmt.Fprint(c.ReadWriter.Out, "Token: "+response.Token+"\n") fmt.Fprint(c.ReadWriter.Out, "Token: "+response.Token+"\n")
fmt.Fprint(c.ReadWriter.Out, "Scopes: "+strings.Join(response.Scopes, ",")+"\n") fmt.Fprint(c.ReadWriter.Out, "Scopes: "+strings.Join(response.Scopes, ",")+"\n")
fmt.Fprint(c.ReadWriter.Out, "Expires: "+response.ExpiresAt+"\n") fmt.Fprint(c.ReadWriter.Out, "Expires: "+response.ExpiresAt+"\n")
return nil
return nil, nil
} }
func (c *Command) parseTokenArgs() error { func (c *Command) parseTokenArgs() error {
Loading
Loading
Loading
@@ -18,16 +18,16 @@ type Command struct {
Loading
@@ -18,16 +18,16 @@ type Command struct {
ReadWriter *readwriter.ReadWriter ReadWriter *readwriter.ReadWriter
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
args := c.Args.SshArgs args := c.Args.SshArgs
if len(args) != 2 { if len(args) != 2 {
return disallowedcommand.Error return nil, disallowedcommand.Error
} }
repo := args[1] repo := args[1]
response, err := c.verifyAccess(ctx, repo) response, err := c.verifyAccess(ctx, repo)
if err != nil { if err != nil {
return err return nil, err
} }
if response.IsCustomAction() { if response.IsCustomAction() {
Loading
@@ -42,7 +42,7 @@ func (c *Command) Execute(ctx context.Context) error {
Loading
@@ -42,7 +42,7 @@ func (c *Command) Execute(ctx context.Context) error {
Response: response, Response: response,
} }
return cmd.Execute(ctx) return response, cmd.Execute(ctx)
} }
customAction := customaction.Command{ customAction := customaction.Command{
Loading
@@ -50,10 +50,10 @@ func (c *Command) Execute(ctx context.Context) error {
Loading
@@ -50,10 +50,10 @@ func (c *Command) Execute(ctx context.Context) error {
ReadWriter: c.ReadWriter, ReadWriter: c.ReadWriter,
EOFSent: true, EOFSent: true,
} }
return customAction.Execute(ctx, response) return response, customAction.Execute(ctx, response)
} }
return c.performGitalyCall(ctx, response) return response, c.performGitalyCall(ctx, response)
} }
func (c *Command) verifyAccess(ctx context.Context, repo string) (*accessverifier.Response, error) { func (c *Command) verifyAccess(ctx context.Context, repo string) (*accessverifier.Response, error) {
Loading
Loading
Loading
@@ -10,6 +10,7 @@ import (
Loading
@@ -10,6 +10,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorrecover"
) )
Loading
@@ -22,7 +23,7 @@ type Command struct {
Loading
@@ -22,7 +23,7 @@ type Command struct {
ReadWriter *readwriter.ReadWriter ReadWriter *readwriter.ReadWriter
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
ctxlog := log.ContextLogger(ctx) ctxlog := log.ContextLogger(ctx)
ctxlog.Debug("twofactorrecover: execute: Waiting for user input") ctxlog.Debug("twofactorrecover: execute: Waiting for user input")
Loading
@@ -34,7 +35,7 @@ func (c *Command) Execute(ctx context.Context) error {
Loading
@@ -34,7 +35,7 @@ func (c *Command) Execute(ctx context.Context) error {
fmt.Fprintln(c.ReadWriter.Out, "\nNew recovery codes have *not* been generated. Existing codes will remain valid.") fmt.Fprintln(c.ReadWriter.Out, "\nNew recovery codes have *not* been generated. Existing codes will remain valid.")
} }
return nil return nil, nil
} }
func (c *Command) getUserAnswer(ctx context.Context) string { func (c *Command) getUserAnswer(ctx context.Context) string {
Loading
Loading
Loading
@@ -10,6 +10,7 @@ import (
Loading
@@ -10,6 +10,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/commandargs"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/accessverifier"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/twofactorverify"
) )
Loading
@@ -25,10 +26,10 @@ type Command struct {
Loading
@@ -25,10 +26,10 @@ type Command struct {
ReadWriter *readwriter.ReadWriter ReadWriter *readwriter.ReadWriter
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
client, err := twofactorverify.NewClient(c.Config) client, err := twofactorverify.NewClient(c.Config)
if err != nil { if err != nil {
return err return nil, err
} }
ctx, cancel := context.WithTimeout(ctx, timeout) ctx, cancel := context.WithTimeout(ctx, timeout)
Loading
@@ -67,7 +68,7 @@ func (c *Command) Execute(ctx context.Context) error {
Loading
@@ -67,7 +68,7 @@ func (c *Command) Execute(ctx context.Context) error {
log.WithContextFields(ctx, log.Fields{"message": message}).Info("Two factor verify command finished") log.WithContextFields(ctx, log.Fields{"message": message}).Info("Two factor verify command finished")
fmt.Fprintf(c.ReadWriter.Out, "\n%v\n", message) fmt.Fprintf(c.ReadWriter.Out, "\n%v\n", message)
return nil return nil, nil
} }
func (c *Command) getOTP(ctx context.Context) (string, error) { func (c *Command) getOTP(ctx context.Context) (string, error) {
Loading
Loading
Loading
@@ -16,19 +16,19 @@ type Command struct {
Loading
@@ -16,19 +16,19 @@ type Command struct {
ReadWriter *readwriter.ReadWriter ReadWriter *readwriter.ReadWriter
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
args := c.Args.SshArgs args := c.Args.SshArgs
if len(args) != 2 { if len(args) != 2 {
return disallowedcommand.Error return nil, disallowedcommand.Error
} }
repo := args[1] repo := args[1]
response, err := c.verifyAccess(ctx, repo) response, err := c.verifyAccess(ctx, repo)
if err != nil { if err != nil {
return err return nil, err
} }
return c.performGitalyCall(ctx, response) return response, c.performGitalyCall(ctx, response)
} }
func (c *Command) verifyAccess(ctx context.Context, repo string) (*accessverifier.Response, error) { func (c *Command) verifyAccess(ctx context.Context, repo string) (*accessverifier.Response, error) {
Loading
Loading
Loading
@@ -17,16 +17,16 @@ type Command struct {
Loading
@@ -17,16 +17,16 @@ type Command struct {
ReadWriter *readwriter.ReadWriter ReadWriter *readwriter.ReadWriter
} }
func (c *Command) Execute(ctx context.Context) error { func (c *Command) Execute(ctx context.Context) (*accessverifier.Response, error) {
args := c.Args.SshArgs args := c.Args.SshArgs
if len(args) != 2 { if len(args) != 2 {
return disallowedcommand.Error return nil, disallowedcommand.Error
} }
repo := args[1] repo := args[1]
response, err := c.verifyAccess(ctx, repo) response, err := c.verifyAccess(ctx, repo)
if err != nil { if err != nil {
return err return nil, err
} }
if response.IsCustomAction() { if response.IsCustomAction() {
Loading
@@ -35,10 +35,10 @@ func (c *Command) Execute(ctx context.Context) error {
Loading
@@ -35,10 +35,10 @@ func (c *Command) Execute(ctx context.Context) error {
ReadWriter: c.ReadWriter, ReadWriter: c.ReadWriter,
EOFSent: false, EOFSent: false,
} }
return customAction.Execute(ctx, response) return response, customAction.Execute(ctx, response)
} }
return c.performGitalyCall(ctx, response) return response, c.performGitalyCall(ctx, response)
} }
func (c *Command) verifyAccess(ctx context.Context, repo string) (*accessverifier.Response, error) { func (c *Command) verifyAccess(ctx context.Context, repo string) (*accessverifier.Response, error) {
Loading
Loading
Loading
@@ -14,6 +14,7 @@ import (
Loading
@@ -14,6 +14,7 @@ import (
grpcstatus "google.golang.org/grpc/status" grpcstatus "google.golang.org/grpc/status"
"gitlab.com/gitlab-org/gitlab-shell/v14/client" "gitlab.com/gitlab-org/gitlab-shell/v14/client"
"gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/shared/disallowedcommand"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics"
Loading
@@ -36,7 +37,7 @@ type connection struct {
Loading
@@ -36,7 +37,7 @@ type connection struct {
remoteAddr string remoteAddr string
} }
type channelHandler func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) error type channelHandler func(*ssh.ServerConn, ssh.Channel, <-chan *ssh.Request) (command.MetaData, error)
func newConnection(cfg *config.Config, nconn net.Conn) *connection { func newConnection(cfg *config.Config, nconn net.Conn) *connection {
maxSessions := cfg.Server.ConcurrentSessionsLimit maxSessions := cfg.Server.ConcurrentSessionsLimit
Loading
@@ -50,12 +51,14 @@ func newConnection(cfg *config.Config, nconn net.Conn) *connection {
Loading
@@ -50,12 +51,14 @@ func newConnection(cfg *config.Config, nconn net.Conn) *connection {
} }
} }
func (c *connection) handle(ctx context.Context, srvCfg *ssh.ServerConfig, handler channelHandler) { func (c *connection) handle(ctx context.Context, srvCfg *ssh.ServerConfig, handler channelHandler) command.MetaData {
metaData := command.MetaData{}
log.WithContextFields(ctx, log.Fields{}).Info("server: handleConn: start") log.WithContextFields(ctx, log.Fields{}).Info("server: handleConn: start")
sconn, chans, err := c.initServerConn(ctx, srvCfg) sconn, chans, err := c.initServerConn(ctx, srvCfg)
if err != nil { if err != nil {
return return metaData
} }
if c.cfg.Server.ClientAliveInterval > 0 { if c.cfg.Server.ClientAliveInterval > 0 {
Loading
@@ -64,10 +67,12 @@ func (c *connection) handle(ctx context.Context, srvCfg *ssh.ServerConfig, handl
Loading
@@ -64,10 +67,12 @@ func (c *connection) handle(ctx context.Context, srvCfg *ssh.ServerConfig, handl
go c.sendKeepAliveMsg(ctx, sconn, ticker) go c.sendKeepAliveMsg(ctx, sconn, ticker)
} }
c.handleRequests(ctx, sconn, chans, handler) metaData = c.handleRequests(ctx, sconn, chans, handler)
reason := sconn.Wait() reason := sconn.Wait()
log.WithContextFields(ctx, log.Fields{"reason": reason}).Info("server: handleConn: done") log.WithContextFields(ctx, log.Fields{"reason": reason}).Info("server: handleConn: done")
return metaData
} }
func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) { func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfig) (*ssh.ServerConn, <-chan ssh.NewChannel, error) {
Loading
@@ -94,7 +99,8 @@ func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfi
Loading
@@ -94,7 +99,8 @@ func (c *connection) initServerConn(ctx context.Context, srvCfg *ssh.ServerConfi
return sconn, chans, err return sconn, chans, err
} }
func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, handler channelHandler) { func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn, chans <-chan ssh.NewChannel, handler channelHandler) command.MetaData {
metaData := command.MetaData{}
ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr}) ctxlog := log.WithContextFields(ctx, log.Fields{"remote_addr": c.remoteAddr})
for newChannel := range chans { for newChannel := range chans {
Loading
@@ -134,7 +140,7 @@ func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn,
Loading
@@ -134,7 +140,7 @@ func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn,
}() }()
metrics.SliSshdSessionsTotal.Inc() metrics.SliSshdSessionsTotal.Inc()
err := handler(sconn, channel, requests) metaData, err = handler(sconn, channel, requests)
if err != nil { if err != nil {
c.trackError(ctxlog, err) c.trackError(ctxlog, err)
} }
Loading
@@ -148,6 +154,8 @@ func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn,
Loading
@@ -148,6 +154,8 @@ func (c *connection) handleRequests(ctx context.Context, sconn *ssh.ServerConn,
ctx, cancel := context.WithTimeout(ctx, EOFTimeout) ctx, cancel := context.WithTimeout(ctx, EOFTimeout)
defer cancel() defer cancel()
c.concurrentSessions.Acquire(ctx, c.maxSessions) c.concurrentSessions.Acquire(ctx, c.maxSessions)
return metaData
} }
func (c *connection) sendKeepAliveMsg(ctx context.Context, sconn *ssh.ServerConn, ticker *time.Ticker) { func (c *connection) sendKeepAliveMsg(ctx context.Context, sconn *ssh.ServerConn, ticker *time.Ticker) {
Loading
Loading
Loading
@@ -49,7 +49,8 @@ type exitStatusReq struct {
Loading
@@ -49,7 +49,8 @@ type exitStatusReq struct {
ExitStatus uint32 ExitStatus uint32
} }
func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) error { func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) (shellCmd.MetaData, error) {
metaData := shellCmd.MetaData{}
ctxlog := log.ContextLogger(ctx) ctxlog := log.ContextLogger(ctx)
ctxlog.Debug("session: handle: entering request loop") ctxlog.Debug("session: handle: entering request loop")
Loading
@@ -70,13 +71,13 @@ func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) erro
Loading
@@ -70,13 +71,13 @@ func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) erro
case "exec": case "exec":
// The command has been executed as `ssh user@host command` or `exec` channel has been used // The command has been executed as `ssh user@host command` or `exec` channel has been used
// in the app implementation // in the app implementation
shouldContinue, err = s.handleExec(ctx, req) metaData, shouldContinue, err = s.handleExec(ctx, req)
case "shell": case "shell":
// The command has been entered into the shell or `shell` channel has been used // The command has been entered into the shell or `shell` channel has been used
// in the app implementation // in the app implementation
shouldContinue = false shouldContinue = false
var status uint32 var status uint32
status, err = s.handleShell(ctx, req) metaData, status, err = s.handleShell(ctx, req)
s.exit(ctx, status) s.exit(ctx, status)
default: default:
// Ignore unknown requests but don't terminate the session // Ignore unknown requests but don't terminate the session
Loading
@@ -99,7 +100,7 @@ func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) erro
Loading
@@ -99,7 +100,7 @@ func (s *session) handle(ctx context.Context, requests <-chan *ssh.Request) erro
ctxlog.Debug("session: handle: exiting request loop") ctxlog.Debug("session: handle: exiting request loop")
return err return metaData, err
} }
func (s *session) handleEnv(ctx context.Context, req *ssh.Request) (bool, error) { func (s *session) handleEnv(ctx context.Context, req *ssh.Request) (bool, error) {
Loading
@@ -132,21 +133,24 @@ func (s *session) handleEnv(ctx context.Context, req *ssh.Request) (bool, error)
Loading
@@ -132,21 +133,24 @@ func (s *session) handleEnv(ctx context.Context, req *ssh.Request) (bool, error)
return true, nil return true, nil
} }
func (s *session) handleExec(ctx context.Context, req *ssh.Request) (bool, error) { func (s *session) handleExec(ctx context.Context, req *ssh.Request) (shellCmd.MetaData, bool, error) {
metaData := shellCmd.MetaData{}
var execRequest execRequest var execRequest execRequest
if err := ssh.Unmarshal(req.Payload, &execRequest); err != nil { if err := ssh.Unmarshal(req.Payload, &execRequest); err != nil {
return false, err return metaData, false, err
} }
s.execCmd = execRequest.Command s.execCmd = execRequest.Command
status, err := s.handleShell(ctx, req) metaData, status, err := s.handleShell(ctx, req)
s.exit(ctx, status) s.exit(ctx, status)
return false, err return metaData, false, err
} }
func (s *session) handleShell(ctx context.Context, req *ssh.Request) (uint32, error) { func (s *session) handleShell(ctx context.Context, req *ssh.Request) (shellCmd.MetaData, uint32, error) {
metaData := shellCmd.MetaData{}
ctxlog := log.ContextLogger(ctx) ctxlog := log.ContextLogger(ctx)
if req.WantReply { if req.WantReply {
Loading
@@ -183,7 +187,7 @@ func (s *session) handleShell(ctx context.Context, req *ssh.Request) (uint32, er
Loading
@@ -183,7 +187,7 @@ func (s *session) handleShell(ctx context.Context, req *ssh.Request) (uint32, er
s.toStderr(ctx, "ERROR: Failed to parse command: %v\n", err.Error()) s.toStderr(ctx, "ERROR: Failed to parse command: %v\n", err.Error())
} }
return 128, err return metaData, 128, err
} }
cmdName := reflect.TypeOf(cmd).String() cmdName := reflect.TypeOf(cmd).String()
Loading
@@ -194,18 +198,19 @@ func (s *session) handleShell(ctx context.Context, req *ssh.Request) (uint32, er
Loading
@@ -194,18 +198,19 @@ func (s *session) handleShell(ctx context.Context, req *ssh.Request) (uint32, er
}).Info("session: handleShell: executing command") }).Info("session: handleShell: executing command")
metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration) metrics.SshdSessionEstablishedDuration.Observe(establishSessionDuration)
if err := cmd.Execute(ctx); err != nil { verifyResponse, err := cmd.Execute(ctx)
if err != nil {
grpcStatus := grpcstatus.Convert(err) grpcStatus := grpcstatus.Convert(err)
if grpcStatus.Code() != grpccodes.Internal { if grpcStatus.Code() != grpccodes.Internal {
s.toStderr(ctx, "ERROR: %v\n", grpcStatus.Message()) s.toStderr(ctx, "ERROR: %v\n", grpcStatus.Message())
} }
return 1, err return metaData, 1, err
} }
ctxlog.Info("session: handleShell: command executed successfully") ctxlog.Info("session: handleShell: command executed successfully")
return 0, nil return shellCmd.NewMetaData(verifyResponse.Gitaly.Repo.GlProjectPath, verifyResponse.Username), 0, nil
} }
func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) { func (s *session) toStderr(ctx context.Context, format string, args ...interface{}) {
Loading
Loading
Loading
@@ -13,6 +13,7 @@ import (
Loading
@@ -13,6 +13,7 @@ import (
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"gitlab.com/gitlab-org/gitlab-shell/v14/client" "gitlab.com/gitlab-org/gitlab-shell/v14/client"
shellCmd "gitlab.com/gitlab-org/gitlab-shell/v14/cmd/gitlab-shell/command"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics" "gitlab.com/gitlab-org/gitlab-shell/v14/internal/metrics"
Loading
@@ -193,7 +194,7 @@ func (s *Server) handleConn(ctx context.Context, nconn net.Conn) {
Loading
@@ -193,7 +194,7 @@ func (s *Server) handleConn(ctx context.Context, nconn net.Conn) {
started := time.Now() started := time.Now()
conn := newConnection(s.Config, nconn) conn := newConnection(s.Config, nconn)
conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { metaData := conn.handle(ctx, s.serverConfig.get(ctx), func(sconn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) (shellCmd.MetaData, error) {
session := &session{ session := &session{
cfg: s.Config, cfg: s.Config,
channel: channel, channel: channel,
Loading
@@ -206,7 +207,7 @@ func (s *Server) handleConn(ctx context.Context, nconn net.Conn) {
Loading
@@ -206,7 +207,7 @@ func (s *Server) handleConn(ctx context.Context, nconn net.Conn) {
return session.handle(ctx, requests) return session.handle(ctx, requests)
}) })
ctxlog.WithFields(log.Fields{"duration_s": time.Since(started).Seconds()}).Info("access: finish") ctxlog.WithFields(log.Fields{"duration_s": time.Since(started).Seconds(), "meta": metaData}).Info("access: finish")
} }
func (s *Server) proxyPolicy() (proxyproto.PolicyFunc, error) { func (s *Server) proxyPolicy() (proxyproto.PolicyFunc, error) {
Loading
Loading