mirror of
https://github.com/postmannen/ctrl.git
synced 2024-12-14 12:37:31 +00:00
initial acl distribution works
This commit is contained in:
parent
e7ae3d893b
commit
9d71f11145
4 changed files with 122 additions and 15 deletions
|
@ -4,8 +4,10 @@ import (
|
|||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -42,13 +44,17 @@ type accessLists struct {
|
|||
|
||||
func newAccessLists(errorKernel *errorKernel, configuration *Configuration) *accessLists {
|
||||
a := accessLists{
|
||||
schemaMain: newSchemaMain(),
|
||||
schemaMain: newSchemaMain(configuration),
|
||||
schemaGenerated: newSchemaGenerated(),
|
||||
validator: validator.New(),
|
||||
errorKernel: errorKernel,
|
||||
configuration: configuration,
|
||||
}
|
||||
|
||||
// The main acl map gets loaded from disk in the newSchemaMain function, but since that
|
||||
// function do not have access to the generated map we have to generate it here.
|
||||
a.generateACLsForAllNodes()
|
||||
|
||||
return &a
|
||||
}
|
||||
|
||||
|
@ -60,17 +66,52 @@ type commandGroup string
|
|||
// schemaMain is the structure that holds the user editable parts for creating ACL's.
|
||||
type schemaMain struct {
|
||||
ACLMap map[Node]map[Node]map[command]struct{}
|
||||
ACLMapFilePath string
|
||||
NodeGroupMap map[nodeGroup]map[Node]struct{}
|
||||
CommandGroupMap map[commandGroup]map[command]struct{}
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func newSchemaMain() *schemaMain {
|
||||
func newSchemaMain(configuration *Configuration) *schemaMain {
|
||||
s := schemaMain{
|
||||
ACLMap: make(map[Node]map[Node]map[command]struct{}),
|
||||
ACLMapFilePath: filepath.Join(configuration.DatabaseFolder, "central_aclmap.txt"),
|
||||
NodeGroupMap: make(map[nodeGroup]map[Node]struct{}),
|
||||
CommandGroupMap: make(map[commandGroup]map[command]struct{}),
|
||||
}
|
||||
|
||||
// Load ACLMap from disk if present.
|
||||
func() {
|
||||
if _, err := os.Stat(s.ACLMapFilePath); os.IsNotExist(err) {
|
||||
er := fmt.Errorf("error: newSchemaMain: no file for ACLMap found %v: %v", s.ACLMapFilePath, err)
|
||||
log.Printf("%v\n", er)
|
||||
|
||||
// If no aclmap is present on disk we just return from this
|
||||
// function without loading any values.
|
||||
return
|
||||
}
|
||||
|
||||
fh, err := os.Open(s.ACLMapFilePath)
|
||||
if err != nil {
|
||||
er := fmt.Errorf("error: newSchemaMain: failed to open file for reading %v: %v", s.ACLMapFilePath, err)
|
||||
log.Printf("%v\n", er)
|
||||
}
|
||||
|
||||
b, err := io.ReadAll(fh)
|
||||
if err != nil {
|
||||
er := fmt.Errorf("error: newSchemaMain: failed to ReadAll file %v: %v", s.ACLMapFilePath, err)
|
||||
log.Printf("%v\n", er)
|
||||
}
|
||||
|
||||
// Unmarshal the data read from disk.
|
||||
err = json.Unmarshal(b, &s.ACLMap)
|
||||
if err != nil {
|
||||
er := fmt.Errorf("error: newSchemaMain: failed to unmarshal content from file %v: %v", s.ACLMapFilePath, err)
|
||||
log.Printf("%v\n", er)
|
||||
}
|
||||
|
||||
// Generate the aclGenerated map happens in the function where this function is called.
|
||||
}()
|
||||
return &s
|
||||
}
|
||||
|
||||
|
@ -242,6 +283,27 @@ func (a *accessLists) aclDeleteSource(host Node, source Node) error {
|
|||
// nodes.
|
||||
// The result will be written to the schemaGenerated.ACLsToConvert map.
|
||||
func (a *accessLists) generateACLsForAllNodes() error {
|
||||
// We first one to save the current main ACLMap.
|
||||
func() {
|
||||
fh, err := os.OpenFile(a.schemaMain.ACLMapFilePath, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0600)
|
||||
if err != nil {
|
||||
er := fmt.Errorf("error: generateACLsForAllNodes: opening file for writing: %v, err: %v", a.schemaMain.ACLMapFilePath, err)
|
||||
log.Printf("%v\n", er)
|
||||
return
|
||||
}
|
||||
defer fh.Close()
|
||||
|
||||
// a.schemaMain.mu.Lock()
|
||||
// defer a.schemaMain.mu.Unlock()
|
||||
enc := json.NewEncoder(fh)
|
||||
enc.Encode(a.schemaMain.ACLMap)
|
||||
if err != nil {
|
||||
er := fmt.Errorf("error: generateACLsForAllNodes: encoding json to file failed: %v, err: %v", a.schemaMain.ACLMapFilePath, err)
|
||||
log.Printf("%v\n", er)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
a.schemaGenerated.mu.Lock()
|
||||
defer a.schemaGenerated.mu.Unlock()
|
||||
|
||||
|
|
12
processes.go
12
processes.go
|
@ -178,6 +178,7 @@ func (p *processes) Start(proc process) {
|
|||
// TODO: Putting the acl publisher here.
|
||||
// Maybe we should also change the name of the configuration flag to something auth related ?
|
||||
proc.startup.pubREQAclRequestUpdate(proc)
|
||||
proc.startup.subREQAclDeliverUpdate(proc)
|
||||
}
|
||||
|
||||
if proc.configuration.IsCentralAuth {
|
||||
|
@ -342,7 +343,7 @@ func (s startup) pubREQKeysRequestUpdate(p process) {
|
|||
// and update with new keys back.
|
||||
|
||||
proc.nodeAuth.publicKeys.mu.Lock()
|
||||
fmt.Printf("\n ----> REQKeysRequestUpdate: sending our current hash: %v\n\n", []byte(proc.nodeAuth.publicKeys.keysAndHash.Hash[:]))
|
||||
fmt.Printf("\n ----> publisher REQKeysRequestUpdate: sending our current hash: %v\n\n", []byte(proc.nodeAuth.publicKeys.keysAndHash.Hash[:]))
|
||||
|
||||
m := Message{
|
||||
FileName: "publickeysget.log",
|
||||
|
@ -397,7 +398,7 @@ func (s startup) pubREQAclRequestUpdate(p process) {
|
|||
// and update with new keys back.
|
||||
|
||||
proc.nodeAuth.nodeAcl.mu.Lock()
|
||||
fmt.Printf("\n ----> REQKeysRequestUpdate: sending our current hash: %v\n\n", []byte(proc.nodeAuth.nodeAcl.aclAndHash.Hash[:]))
|
||||
fmt.Printf("\n ----> publisher REQAclRequestUpdate: sending our current hash: %v\n\n", []byte(proc.nodeAuth.nodeAcl.aclAndHash.Hash[:]))
|
||||
|
||||
m := Message{
|
||||
FileName: "aclRequestUpdate.log",
|
||||
|
@ -461,6 +462,13 @@ func (s startup) subREQAclRequestUpdate(p process) {
|
|||
go proc.spawnWorker()
|
||||
}
|
||||
|
||||
func (s startup) subREQAclDeliverUpdate(p process) {
|
||||
log.Printf("Starting Acl deliver update subscriber: %#v\n", p.node)
|
||||
sub := newSubject(REQAclDeliverUpdate, string(p.node))
|
||||
proc := newProcess(p.ctx, s.server, sub, processKindSubscriber, nil)
|
||||
go proc.spawnWorker()
|
||||
}
|
||||
|
||||
// HERE!
|
||||
|
||||
func (s startup) subREQAclAddCommand(p process) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
)
|
||||
|
@ -20,6 +21,11 @@ func (m methodREQAclRequestUpdate) getKind() Event {
|
|||
|
||||
// Handler to get all acl's from a central server.
|
||||
func (m methodREQAclRequestUpdate) handler(proc process, message Message, node string) ([]byte, error) {
|
||||
inf := fmt.Errorf("<--- subscriber methodREQAclRequestUpdate received from: %v, and the data which is the nodes current acl hash containing: %v", message.FromNode, message.MethodArgs)
|
||||
proc.errorKernel.logConsoleOnlyIfDebug(inf, proc.configuration)
|
||||
|
||||
fmt.Printf("\n --- subscriber methodREQAclRequestUpdate: the message brought to handler : %+v\n", message)
|
||||
|
||||
// Get a context with the timeout specified in message.MethodTimeout.
|
||||
ctx, _ := getContextForMethodTimeout(proc.ctx, message)
|
||||
|
||||
|
@ -47,27 +53,47 @@ func (m methodREQAclRequestUpdate) handler(proc process, message Message, node s
|
|||
proc.centralAuth.accessLists.schemaGenerated.mu.Lock()
|
||||
defer proc.centralAuth.accessLists.schemaGenerated.mu.Unlock()
|
||||
|
||||
fmt.Printf(" <---- methodREQAclRequestUpdate: received acl hash from NODE=%v, HASH=%v\n", message.FromNode, message.Data)
|
||||
// DEBUGGING:
|
||||
{
|
||||
proc.centralAuth.accessLists.schemaMain.mu.Lock()
|
||||
fmt.Printf("\n --- DEBUGGING: subscriber methodREQAclRequestUpdate: schemaGenerated contains: %v\n\n", proc.centralAuth.accessLists.schemaGenerated)
|
||||
fmt.Printf("\n --- DEBUGGING: subscriber methodREQAclRequestUpdate: schemaMain contains: %v\n\n", proc.centralAuth.accessLists.schemaMain)
|
||||
proc.centralAuth.accessLists.schemaMain.mu.Unlock()
|
||||
|
||||
// TODO: PROBLEM: The existing generated acl's are not loaded when starting, or not stored at all.
|
||||
}
|
||||
|
||||
fmt.Printf(" ---- subscriber methodREQAclRequestUpdate: got acl hash from NODE=%v, HASH=%v\n", message.FromNode, message.Data)
|
||||
|
||||
// Check if the received hash is the same as the one currently active,
|
||||
// If it is the same we exit the handler immediately.
|
||||
hash32 := proc.centralAuth.accessLists.schemaGenerated.GeneratedACLsMap[message.FromNode].Hash
|
||||
hash := hash32[:]
|
||||
fmt.Printf("\n ---- subscriber methodREQAclRequestUpdate: on central hash32=%v\n\n", hash32)
|
||||
if bytes.Equal(hash, message.Data) {
|
||||
fmt.Printf("\n ------------ NODE AND CENTRAL HAVE EQUAL ACL HASH, NOTHING TO DO, EXITING HANDLER\n\n")
|
||||
fmt.Printf("\n ---- subscriber methodREQAclRequestUpdate: NODE AND CENTRAL HAVE EQUAL ACL HASH, NOTHING TO DO, EXITING HANDLER\n\n")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\n ------------ NODE AND CENTRAL HAD NOT EQUAL ACL, PREPARING TO SEND NEW VERSION OF Acl\n\n")
|
||||
fmt.Printf("\n ---- subscriber methodREQAclRequestUpdate: NODE AND CENTRAL HAD NOT EQUAL ACL, PREPARING TO SEND NEW VERSION OF Acl\n\n")
|
||||
|
||||
fmt.Printf("\n ----> methodREQAclRequestUpdate: SENDING ACL'S TO NODE=%v\n", message.FromNode)
|
||||
// Generate JSON for Message.Data
|
||||
|
||||
js, err := json.Marshal(proc.centralAuth.accessLists.schemaGenerated.GeneratedACLsMap[message.FromNode])
|
||||
hdh := HostACLsSerializedWithHash{}
|
||||
hdh.Data = proc.centralAuth.accessLists.schemaGenerated.GeneratedACLsMap[message.FromNode].Data
|
||||
fmt.Printf("\n * DEBUGGING: before marshalling, hdh.Data=%v\n", hdh.Data)
|
||||
hdh.Hash = proc.centralAuth.accessLists.schemaGenerated.GeneratedACLsMap[message.FromNode].Hash
|
||||
fmt.Printf("\n * DEBUGGING: before marshalling, hdh.Hash=%v\n\n", hdh.Hash)
|
||||
|
||||
js, err := json.Marshal(hdh)
|
||||
if err != nil {
|
||||
er := fmt.Errorf("error: REQAclRequestUpdate : json marshal failed: %v, message: %v", err, message)
|
||||
proc.errorKernel.errSend(proc, message, er)
|
||||
log.Fatalf("%v\n", er)
|
||||
}
|
||||
|
||||
fmt.Printf("\n ----> subscriber methodREQAclRequestUpdate: SENDING ACL'S TO NODE=%v, serializedAndHash=%+v\n", message.FromNode, hdh)
|
||||
|
||||
newReplyMessage(proc, message, js)
|
||||
}()
|
||||
}
|
||||
|
@ -89,6 +115,11 @@ func (m methodREQAclDeliverUpdate) getKind() Event {
|
|||
|
||||
// Handler to receive the acls from a central server.
|
||||
func (m methodREQAclDeliverUpdate) handler(proc process, message Message, node string) ([]byte, error) {
|
||||
inf := fmt.Errorf("<--- subscriber methodREQAclDeliverUpdate received from: %v, containing: %v", message.FromNode, message.Data)
|
||||
proc.errorKernel.logConsoleOnlyIfDebug(inf, proc.configuration)
|
||||
|
||||
fmt.Printf("\n --- subscriber methodREQAclRequestUpdate: the message received on handler : %+v\n\n", message)
|
||||
|
||||
// Get a context with the timeout specified in message.MethodTimeout.
|
||||
ctx, _ := getContextForMethodTimeout(proc.ctx, message)
|
||||
|
||||
|
@ -120,27 +151,30 @@ func (m methodREQAclDeliverUpdate) handler(proc process, message Message, node s
|
|||
|
||||
err := json.Unmarshal(message.Data, &hdh)
|
||||
if err != nil {
|
||||
er := fmt.Errorf("error: REQAclDeliverUpdate : json unmarshal failed: %v, message: %v", err, message)
|
||||
er := fmt.Errorf("error: subscriber REQAclDeliverUpdate : json unmarshal failed: %v, message: %v", err, message)
|
||||
proc.errorKernel.errSend(proc, message, er)
|
||||
log.Fatalf("\n * DEBUG: ER: %v\n", er)
|
||||
}
|
||||
|
||||
mapOfFromNodeCommands := make(map[Node]map[command]struct{})
|
||||
err = cbor.Unmarshal(hdh.Data, &mapOfFromNodeCommands)
|
||||
if err != nil {
|
||||
er := fmt.Errorf("error: REQAclDeliverUpdate : json unmarshal failed: %v, message: %v", err, message)
|
||||
er := fmt.Errorf("error: subscriber REQAclDeliverUpdate : json unmarshal failed: %v, message: %v", err, message)
|
||||
proc.errorKernel.errSend(proc, message, er)
|
||||
log.Fatalf("\n * DEBUG: ER: %v\n", er)
|
||||
|
||||
}
|
||||
|
||||
proc.nodeAuth.nodeAcl.aclAndHash.Hash = hdh.Hash
|
||||
proc.nodeAuth.nodeAcl.aclAndHash.Acl = mapOfFromNodeCommands
|
||||
|
||||
fmt.Printf("\n <---- REQAclDeliverUpdate: after unmarshal, nodeAuth aclAndhash contains: %+v\n\n", proc.nodeAuth.nodeAcl.aclAndHash)
|
||||
fmt.Printf("\n <---- subscriber REQAclDeliverUpdate: after unmarshal, nodeAuth aclAndhash contains: %+v\n\n", proc.nodeAuth.nodeAcl.aclAndHash)
|
||||
|
||||
proc.nodeAuth.nodeAcl.mu.Unlock()
|
||||
|
||||
err = proc.nodeAuth.nodeAcl.saveToFile()
|
||||
if err != nil {
|
||||
er := fmt.Errorf("error: REQAclDeliverUpdate : save to file failed: %v, message: %v", err, message)
|
||||
er := fmt.Errorf("error: subscriber REQAclDeliverUpdate : save to file failed: %v, message: %v", err, message)
|
||||
proc.errorKernel.errSend(proc, message, er)
|
||||
}
|
||||
|
||||
|
@ -842,6 +876,9 @@ func (m methodREQAclExport) handler(proc process, message Message, node string)
|
|||
|
||||
// ---
|
||||
|
||||
// TODO: IMPORTANT: We also need to add importing and exporting of the groups to the
|
||||
// import and export methods.
|
||||
|
||||
type methodREQAclImport struct {
|
||||
event Event
|
||||
}
|
||||
|
|
|
@ -117,11 +117,11 @@ func (m methodREQKeysRequestUpdate) handler(proc process, message Message, node
|
|||
|
||||
// Check if the received hash is the same as the one currently active,
|
||||
if bytes.Equal(proc.centralAuth.pki.nodesAcked.keysAndHash.Hash[:], message.Data) {
|
||||
fmt.Printf("\n ------------ NODE AND CENTRAL HAVE EQUAL KEYS, NOTHING TO DO, EXITING HANDLER\n\n")
|
||||
fmt.Printf("\n --- methodREQKeysRequestUpdate: NODE AND CENTRAL HAVE EQUAL KEYS, NOTHING TO DO, EXITING HANDLER\n\n")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\n ------------ NODE AND CENTRAL HAD NOT EQUAL KEYS, PREPARING TO SEND NEW VERSION OF KEYS\n\n")
|
||||
fmt.Printf("\n ------------methodREQKeysRequestUpdate: NODE AND CENTRAL HAD NOT EQUAL KEYS, PREPARING TO SEND NEW VERSION OF KEYS\n\n")
|
||||
|
||||
fmt.Printf(" * methodREQKeysRequestUpdate: marshalling new keys and hash to send: map=%v, hash=%v\n\n", proc.centralAuth.pki.nodesAcked.keysAndHash.Keys, proc.centralAuth.pki.nodesAcked.keysAndHash.Hash)
|
||||
|
||||
|
|
Loading…
Reference in a new issue