From 774ee52a3b84646cfe84c713ddb335754b38df82 Mon Sep 17 00:00:00 2001 From: Myzel394 <50424412+Myzel394@users.noreply.github.com> Date: Sat, 14 Sep 2024 13:58:30 +0200 Subject: [PATCH] feat(sshd_config): Add indexes for all option names --- handlers/sshd_config/ast/parser_test.go | 9 ++++--- handlers/sshd_config/indexes/indexes.go | 28 ++++++++++++++++++++ handlers/sshd_config/indexes/indexes_test.go | 13 +++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/handlers/sshd_config/ast/parser_test.go b/handlers/sshd_config/ast/parser_test.go index c2135d2..5077ac6 100644 --- a/handlers/sshd_config/ast/parser_test.go +++ b/handlers/sshd_config/ast/parser_test.go @@ -136,13 +136,13 @@ Match 192.168.0.2 rawThirdEntry, _ := secondEntry.Options.Get(uint32(3)) thirdEntry := rawThirdEntry.(*SSHOption) - if !(thirdEntry.Key.Value == "PasswordAuthentication" && thirdEntry.OptionValue.Value == "yes") { + if !(thirdEntry.Key.Value == "PasswordAuthentication" && thirdEntry.OptionValue.Value == "yes" && thirdEntry.LocationRange.Start.Line == 3) { t.Errorf("Expected third entry to be 'PasswordAuthentication yes', but got: %v", thirdEntry.Value) } rawFourthEntry, _ := secondEntry.Options.Get(uint32(4)) fourthEntry := rawFourthEntry.(*SSHOption) - if !(fourthEntry.Key.Value == "AllowUsers" && fourthEntry.OptionValue.Value == "root user") { + if !(fourthEntry.Key.Value == "AllowUsers" && fourthEntry.OptionValue.Value == "root user" && fourthEntry.LocationRange.Start.Line == 4) { t.Errorf("Expected fourth entry to be 'AllowUsers root user', but got: %v", fourthEntry.Value) } @@ -154,7 +154,7 @@ Match 192.168.0.2 rawSixthEntry, _ := fifthEntry.Options.Get(uint32(7)) sixthEntry := rawSixthEntry.(*SSHOption) - if !(sixthEntry.Key.Value == "MaxAuthTries" && sixthEntry.OptionValue.Value == "3") { + if !(sixthEntry.Key.Value == "MaxAuthTries" && sixthEntry.OptionValue.Value == "3" && sixthEntry.LocationRange.Start.Line == 7) { t.Errorf("Expected sixth entry to be 'MaxAuthTries 3', but got: %v", sixthEntry.Value) } @@ -199,7 +199,8 @@ Sample rawFirstEntry, _ := p.Options.Get(uint32(1)) firstEntry := rawFirstEntry.(*SSHOption) - if !(firstEntry.Value == "PermitRootLogin no") { + firstEntryOpt, _ := p.FindOption(uint32(1)) + if !(firstEntry.Value == "PermitRootLogin no" && firstEntry.LocationRange.Start.Line == 1 && firstEntryOpt == firstEntry) { t.Errorf("Expected first entry to be 'PermitRootLogin no', but got: %v", firstEntry.Value) } diff --git a/handlers/sshd_config/indexes/indexes.go b/handlers/sshd_config/indexes/indexes.go index 3cf15f8..9cab396 100644 --- a/handlers/sshd_config/indexes/indexes.go +++ b/handlers/sshd_config/indexes/indexes.go @@ -22,14 +22,27 @@ type SSHIndexKey struct { MatchBlock *ast.SSHMatchBlock } +type SSHIndexAllOption struct { + MatchBlock *ast.SSHMatchBlock + Option *ast.SSHOption +} + type SSHIndexes struct { + // Contains a map of `Option name + MatchBlock` to a list of options with that name + // This means an option may be specified inside a match block, and to get this + // option you need to know the match block it was specified in + // If you want to get all options for a specific name, you can use the `AllOptionsPerName` field OptionsPerRelativeKey map[SSHIndexKey][]*ast.SSHOption + + // This is a map of `Option name` to a list of options with that name + AllOptionsPerName map[string][]*SSHIndexAllOption } func CreateIndexes(config ast.SSHConfig) (*SSHIndexes, []common.LSPError) { errs := make([]common.LSPError, 0) indexes := &SSHIndexes{ OptionsPerRelativeKey: make(map[SSHIndexKey][]*ast.SSHOption), + AllOptionsPerName: make(map[string][]*SSHIndexAllOption), } it := config.Options.Iterator() @@ -84,5 +97,20 @@ func addOption( i.OptionsPerRelativeKey[indexEntry] = []*ast.SSHOption{option} } + + if existingEntry, found := i.AllOptionsPerName[option.Key.Value]; found { + i.AllOptionsPerName[option.Key.Value] = append(existingEntry, &SSHIndexAllOption{ + MatchBlock: matchBlock, + Option: option, + }) + } else { + i.AllOptionsPerName[option.Key.Value] = []*SSHIndexAllOption{ + { + MatchBlock: matchBlock, + Option: option, + }, + } + } + return errs } diff --git a/handlers/sshd_config/indexes/indexes_test.go b/handlers/sshd_config/indexes/indexes_test.go index d54f573..c6901d3 100644 --- a/handlers/sshd_config/indexes/indexes_test.go +++ b/handlers/sshd_config/indexes/indexes_test.go @@ -102,4 +102,17 @@ Match Address 192.168.0.1/24 indexes.OptionsPerRelativeKey[indexEntry][2].Start.Line == 3) { t.Errorf("Expected 'Port 22' on line 1, but got %v on line %v", indexes.OptionsPerRelativeKey[indexEntry][0].Value, indexes.OptionsPerRelativeKey[indexEntry][0].Start.Line) } + + if !(len(indexes.AllOptionsPerName["PermitRootLogin"]) == 3 && + indexes.AllOptionsPerName["PermitRootLogin"][0].Option.Value == "PermitRootLogin yes" && + indexes.AllOptionsPerName["PermitRootLogin"][0].Option.Start.Line == 0 && + indexes.AllOptionsPerName["PermitRootLogin"][0].MatchBlock == nil && + indexes.AllOptionsPerName["PermitRootLogin"][1].Option.Value == "\tPermitRootLogin no" && + indexes.AllOptionsPerName["PermitRootLogin"][1].Option.Start.Line == 6 && + indexes.AllOptionsPerName["PermitRootLogin"][1].MatchBlock == firstMatchBlock && + indexes.AllOptionsPerName["PermitRootLogin"][2].Option.Value == "\tPermitRootLogin yes" && + indexes.AllOptionsPerName["PermitRootLogin"][2].Option.Start.Line == 8 && + indexes.AllOptionsPerName["PermitRootLogin"][2].MatchBlock == firstMatchBlock) { + t.Errorf("Expected 3 PermitRootLogin options, but got %v", indexes.AllOptionsPerName["PermitRootLogin"]) + } }