From 321150ac84687a930f325e8e405073f6efa5672b Mon Sep 17 00:00:00 2001 From: postmannen Date: Wed, 18 May 2022 14:43:35 +0200 Subject: [PATCH] added initial REQ for aclDeleteCommand --- central_auth_acl_handling.go | 4 +- central_auth_test.go | 64 ++++++++++++------------- processes.go | 16 +++++-- requests-acl.go | 92 +++++++++++++++++++++++++++++++++--- requests.go | 11 +++-- 5 files changed, 140 insertions(+), 47 deletions(-) diff --git a/central_auth_acl_handling.go b/central_auth_acl_handling.go index da58f81..8b2cc69 100644 --- a/central_auth_acl_handling.go +++ b/central_auth_acl_handling.go @@ -144,11 +144,11 @@ func (a *accessLists) commandAsSlice(c command) []command { return commands } -// aclAdd will add a command for a fromNode. +// aclAddCommand will add a command for a fromNode. // If the node or the fromNode do not exist they will be created. // The json encoded schema for a node and the hash of those data // will also be generated. -func (a *accessLists) aclAdd(host Node, source Node, cmd command) { +func (a *accessLists) aclAddCommand(host Node, source Node, cmd command) { a.schemaMain.mu.Lock() defer a.schemaMain.mu.Unlock() diff --git a/central_auth_test.go b/central_auth_test.go index fb4ef40..b4f2602 100644 --- a/central_auth_test.go +++ b/central_auth_test.go @@ -17,8 +17,8 @@ func TestACLSingleNode(t *testing.T) { } a := newAccessLists() - a.aclAdd("ship101", "admin", "HORSE") - a.aclAdd("ship101", "admin", "PIG") + a.aclAddCommand("ship101", "admin", "HORSE") + a.aclAddCommand("ship101", "admin", "PIG") // --- TESTS --- @@ -59,10 +59,10 @@ func TestACLWithGroups(t *testing.T) { a.groupCommandsAddCommand(grp_commands_commandset1, "dmesg") a.groupCommandsAddCommand(grp_commands_commandset1, "date") - a.aclAdd(grp_nodes_ships, "admin", "useradd -m kongen") - a.aclAdd("ship101", "admin", "HORSE") + a.aclAddCommand(grp_nodes_ships, "admin", "useradd -m kongen") + a.aclAddCommand("ship101", "admin", "HORSE") - a.aclAdd(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) + a.aclAddCommand(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) mapOfFromNodeCommands := make(map[Node]map[command]struct{}) err := cbor.Unmarshal(a.schemaGenerated.GeneratedACLsMap["ship101"].Data, &mapOfFromNodeCommands) @@ -118,10 +118,10 @@ func TestACLNodesGroupDeleteNode(t *testing.T) { a.groupCommandsAddCommand(grp_commands_commandset1, "dmesg") a.groupCommandsAddCommand(grp_commands_commandset1, "date") - a.aclAdd(grp_nodes_ships, "admin", "useradd -m kongen") - a.aclAdd("ship101", "admin", "HORSE") + a.aclAddCommand(grp_nodes_ships, "admin", "useradd -m kongen") + a.aclAddCommand("ship101", "admin", "HORSE") - a.aclAdd(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) + a.aclAddCommand(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) a.groupNodesDeleteNode(grp_nodes_ships, "ship101") @@ -175,10 +175,10 @@ func TestGroupNodesDeleteGroup(t *testing.T) { a.groupCommandsAddCommand(grp_commands_commandset1, "dmesg") a.groupCommandsAddCommand(grp_commands_commandset1, "date") - a.aclAdd(grp_nodes_ships, "admin", "useradd -m kongen") - a.aclAdd("ship101", "admin", "HORSE") + a.aclAddCommand(grp_nodes_ships, "admin", "useradd -m kongen") + a.aclAddCommand("ship101", "admin", "HORSE") - a.aclAdd(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) + a.aclAddCommand(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) a.groupNodesDeleteGroup(grp_nodes_operators) @@ -232,10 +232,10 @@ func TestGroupCommandDeleteGroup(t *testing.T) { a.groupCommandsAddCommand(grp_commands_commandset1, "dmesg") a.groupCommandsAddCommand(grp_commands_commandset1, "date") - a.aclAdd(grp_nodes_ships, "admin", "useradd -m kongen") - a.aclAdd("ship101", "admin", "HORSE") + a.aclAddCommand(grp_nodes_ships, "admin", "useradd -m kongen") + a.aclAddCommand("ship101", "admin", "HORSE") - a.aclAdd(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) + a.aclAddCommand(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) a.groupCommandDeleteGroup(grp_commands_commandset1) @@ -274,14 +274,14 @@ func TestACLGenerated(t *testing.T) { a := newAccessLists() - a.aclAdd("ship101", "admin", "HORSE") + a.aclAddCommand("ship101", "admin", "HORSE") a.groupNodesAddNode("grp_nodes_ships", "ship101") - a.aclAdd("grp_nodes_ships", "admin", "HEN") + a.aclAddCommand("grp_nodes_ships", "admin", "HEN") a.groupCommandsAddCommand("grp_commands_test", "echo") a.groupCommandsAddCommand("grp_commands_test", "dmesg") - a.aclAdd("grp_nodes_ships", "admin", "grp_commands_test") + a.aclAddCommand("grp_nodes_ships", "admin", "grp_commands_test") a.groupCommandsDeleteCommand("grp_commands_test", "echo") @@ -325,8 +325,8 @@ func TestACLSchemaMainACLMap(t *testing.T) { //a.aclNodeFromnodeCommandAdd("ship101", "admin", "PIG") // fmt.Printf("---------------ADDING COMMAND-------------\n") - a.aclAdd("ship0", "admin", "systemctl") - a.aclAdd("ship1", "admin", "tcpdump") + a.aclAddCommand("ship0", "admin", "systemctl") + a.aclAddCommand("ship1", "admin", "tcpdump") if _, ok := a.schemaMain.ACLMap["ship0"]["admin"]["systemctl"]; !ok { t.Fatalf(" \U0001F631 [FAILED]: missing map entry: ship0, admin, systemctl") @@ -338,14 +338,14 @@ func TestACLSchemaMainACLMap(t *testing.T) { // fmt.Printf("---------------ADDING COMMAND-------------\n") a.groupNodesAddNode("grp_nodes_ships", "ship1") a.groupNodesAddNode("grp_nodes_ships", "ship2") - a.aclAdd("grp_nodes_ships", "admin", "dmesg") + a.aclAddCommand("grp_nodes_ships", "admin", "dmesg") if _, ok := a.schemaMain.ACLMap["grp_nodes_ships"]["admin"]["dmesg"]; !ok { t.Fatalf(" \U0001F631 [FAILED]: missing map entry: ship1, admin, tcpdump") } // fmt.Printf("---------------ADDING COMMAND-------------\n") - a.aclAdd("ship2", "admin", "echo") + a.aclAddCommand("ship2", "admin", "echo") if _, ok := a.schemaMain.ACLMap["ship2"]["admin"]["echo"]; !ok { t.Fatalf(" \U0001F631 [FAILED]: missing map entry: ship1, admin, tcpdump") @@ -402,10 +402,10 @@ func TestACLHash(t *testing.T) { a := newAccessLists() - a.aclAdd("ship101", "admin", "HORSE") + a.aclAddCommand("ship101", "admin", "HORSE") a.groupNodesAddNode("grp_nodes_ships", "ship101") - a.aclAdd("grp_nodes_ships", "admin", "HEN") + a.aclAddCommand("grp_nodes_ships", "admin", "HEN") hash := [32]uint8{0xa4, 0x99, 0xbd, 0xa3, 0x18, 0x26, 0x52, 0xc2, 0x92, 0x60, 0x23, 0x19, 0x3c, 0xa, 0x7, 0xa9, 0xb7, 0x77, 0x4f, 0x11, 0x34, 0xd5, 0x2d, 0xd1, 0x8d, 0xab, 0x6c, 0x4b, 0x2, 0xfa, 0x5c, 0x7a} value := a.schemaGenerated.GeneratedACLsMap["ship101"].Hash @@ -427,12 +427,12 @@ func TestACLConcurrent(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - a.aclAdd("ship1", "operator2", "rm -rf") - a.aclAdd("ship1", "operator1", "ls -lt") - a.aclAdd("ship1", "operator1", "ls -lt") - a.aclAdd("ship1", "operator2", "ls -l") - a.aclAdd("ship3", "operator3", "ls -lt") - a.aclAdd("ship3", "operator3", "vi /etc/hostname") + a.aclAddCommand("ship1", "operator2", "rm -rf") + a.aclAddCommand("ship1", "operator1", "ls -lt") + a.aclAddCommand("ship1", "operator1", "ls -lt") + a.aclAddCommand("ship1", "operator2", "ls -l") + a.aclAddCommand("ship3", "operator3", "ls -lt") + a.aclAddCommand("ship3", "operator3", "vi /etc/hostname") a.aclDeleteCommand("ship3", "operator2", "ls -lt") a.aclDeleteSource("ship3", "operator3") }() @@ -477,10 +477,10 @@ func TestExportACLs(t *testing.T) { a.groupCommandsAddCommand(grp_commands_commandset1, "dmesg") a.groupCommandsAddCommand(grp_commands_commandset1, "date") - a.aclAdd(grp_nodes_ships, "admin", "useradd -m kongen") - a.aclAdd("ship101", "admin", "HORSE") + a.aclAddCommand(grp_nodes_ships, "admin", "useradd -m kongen") + a.aclAddCommand("ship101", "admin", "HORSE") - a.aclAdd(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) + a.aclAddCommand(grp_nodes_ships, grp_nodes_operators, grp_commands_commandset1) js, err := a.exportACLs() if err != nil { diff --git a/processes.go b/processes.go index cc64aeb..839413f 100644 --- a/processes.go +++ b/processes.go @@ -173,7 +173,8 @@ func (p *processes) Start(proc process) { if proc.configuration.IsCentralAuth { proc.startup.subREQPublicKeysGet(proc) proc.startup.subREQPublicKeysAllow(proc) - proc.startup.subREQAclAddAccessList(proc) + proc.startup.subREQAclAddCommand(proc) + proc.startup.subREQAclDeleteCommand(proc) } if proc.configuration.StartSubREQPublicKeysToNode { @@ -376,9 +377,16 @@ func (s startup) subREQPublicKeysToNode(p process) { go proc.spawnWorker() } -func (s startup) subREQAclAddAccessList(p process) { - log.Printf("Starting Add Access List subscriber: %#v\n", p.node) - sub := newSubject(REQAclAddAccessList, string(p.node)) +func (s startup) subREQAclAddCommand(p process) { + log.Printf("Starting Acl Add Command subscriber: %#v\n", p.node) + sub := newSubject(REQAclAddCommand, string(p.node)) + proc := newProcess(p.ctx, s.server, sub, processKindSubscriber, nil) + go proc.spawnWorker() +} + +func (s startup) subREQAclDeleteCommand(p process) { + log.Printf("Starting Acl Delete Command subscriber: %#v\n", p.node) + sub := newSubject(REQAclDeleteCommand, string(p.node)) proc := newProcess(p.ctx, s.server, sub, processKindSubscriber, nil) go proc.spawnWorker() } diff --git a/requests-acl.go b/requests-acl.go index 648be37..7612bf3 100644 --- a/requests-acl.go +++ b/requests-acl.go @@ -6,16 +6,16 @@ import ( // --- -type methodREQAclAddAccessList struct { +type methodREQAclAddCommand struct { event Event } -func (m methodREQAclAddAccessList) getKind() Event { +func (m methodREQAclAddCommand) getKind() Event { return m.event } -func (m methodREQAclAddAccessList) handler(proc process, message Message, node string) ([]byte, error) { - inf := fmt.Errorf("<--- methodREQAclAddAccessList received from: %v, containing: %v", message.FromNode, message.MethodArgs) +func (m methodREQAclAddCommand) handler(proc process, message Message, node string) ([]byte, error) { + inf := fmt.Errorf("<--- methodREQAclAddCommand received from: %v, containing: %v", message.FromNode, message.MethodArgs) proc.errorKernel.logConsoleOnlyIfDebug(inf, proc.configuration) proc.processes.wg.Add(1) @@ -43,7 +43,7 @@ func (m methodREQAclAddAccessList) handler(proc process, message Message, node s source := message.MethodArgs[1] cmd := message.MethodArgs[2] - proc.centralAuth.accessLists.aclAdd(Node(host), Node(source), command(cmd)) + proc.centralAuth.accessLists.aclAddCommand(Node(host), Node(source), command(cmd)) // Just print out for testing. proc.centralAuth.accessLists.schemaMain.mu.Lock() @@ -51,7 +51,87 @@ func (m methodREQAclAddAccessList) handler(proc process, message Message, node s proc.centralAuth.accessLists.schemaMain.mu.Unlock() proc.centralAuth.accessLists.schemaGenerated.mu.Lock() - fmt.Printf("\n ---------- content of generated acl map: %s-----------\n", proc.centralAuth.accessLists.schemaGenerated.GeneratedACLsMap) + fmt.Printf("\n ---------- content of generated acl map: %v-----------\n", proc.centralAuth.accessLists.schemaGenerated.GeneratedACLsMap) + proc.centralAuth.accessLists.schemaGenerated.mu.Unlock() + + outString := fmt.Sprintf("acl added: host=%v, source=%v, command=%v\n", host, source, cmd) + out := []byte(outString) + + select { + case outCh <- out: + case <-ctx.Done(): + return + } + }() + + select { + case <-ctx.Done(): + + cancel() + er := fmt.Errorf("error: methodREQAclAddAccessList: method timed out: %v", message.MethodArgs) + proc.errorKernel.errSend(proc, message, er) + + case out := <-outCh: + + // Prepare and queue for sending a new message with the output + // of the action executed. + newReplyMessage(proc, message, out) + } + + }() + + ackMsg := []byte("confirmed from: " + node + ": " + fmt.Sprint(message.ID)) + return ackMsg, nil +} + +// --- + +type methodREQAclDeleteCommand struct { + event Event +} + +func (m methodREQAclDeleteCommand) getKind() Event { + return m.event +} + +func (m methodREQAclDeleteCommand) handler(proc process, message Message, node string) ([]byte, error) { + inf := fmt.Errorf("<--- methodREQAclAddAccessList received from: %v, containing: %v", message.FromNode, message.MethodArgs) + proc.errorKernel.logConsoleOnlyIfDebug(inf, proc.configuration) + + proc.processes.wg.Add(1) + go func() { + defer proc.processes.wg.Done() + + switch { + case len(message.MethodArgs) < 3: + er := fmt.Errorf("error: methodREQAclAddAccessList: got <3 number methodArgs, want 3") + proc.errorKernel.errSend(proc, message, er) + + return + } + + // Get a context with the timeout specified in message.MethodTimeout. + ctx, cancel := getContextForMethodTimeout(proc.ctx, message) + + outCh := make(chan []byte) + + proc.processes.wg.Add(1) + go func() { + defer proc.processes.wg.Done() + + host := message.MethodArgs[0] + source := message.MethodArgs[1] + cmd := message.MethodArgs[2] + + proc.centralAuth.accessLists.aclDeleteCommand(Node(host), Node(source), command(cmd)) + + // Just print out for testing. + proc.centralAuth.accessLists.schemaMain.mu.Lock() + fmt.Printf("\n ---------- content of main acl map: %v-----------\n", proc.centralAuth.accessLists.schemaMain.ACLMap) + proc.centralAuth.accessLists.schemaMain.mu.Unlock() + + proc.centralAuth.accessLists.schemaGenerated.mu.Lock() + fmt.Printf("\n ---------- content of generated acl map: %v-----------\n", proc.centralAuth.accessLists.schemaGenerated.GeneratedACLsMap) proc.centralAuth.accessLists.schemaGenerated.mu.Unlock() outString := fmt.Sprintf("acl added: host=%v, source=%v, command=%v\n", host, source, cmd) diff --git a/requests.go b/requests.go index e51b2b9..dcf199a 100644 --- a/requests.go +++ b/requests.go @@ -144,8 +144,10 @@ const ( REQPublicKeysToNode Method = "REQPublicKeysToNode" // REQAuthPublicKeysAllow REQPublicKeysAllow Method = "REQPublicKeysAllow" - // REQAclAddAcl - REQAclAddAccessList = "REQAclAddAccessList" + // REQAclAddCommand + REQAclAddCommand = "REQAclAddCommand" + // REQAclDeleteCommand + REQAclDeleteCommand = "REQAclDeleteCommand" ) // The mapping of all the method constants specified, what type @@ -236,7 +238,10 @@ func (m Method) GetMethodsAvailable() MethodsAvailable { REQPublicKeysAllow: methodREQPublicKeysAllow{ event: EventACK, }, - REQAclAddAccessList: methodREQAclAddAccessList{ + REQAclAddCommand: methodREQAclAddCommand{ + event: EventACK, + }, + REQAclDeleteCommand: methodREQAclDeleteCommand{ event: EventACK, }, },