diff --git a/CTng/config/test/monitor_pub_config.json b/CTng/config/test/monitor_pub_config.json index 1056ea9..4c18ec7 100644 --- a/CTng/config/test/monitor_pub_config.json +++ b/CTng/config/test/monitor_pub_config.json @@ -1,6 +1,6 @@ { - "CA_URLs": ["192.168.1.1", "1.0.0.1", "192.168.1.9"], - "Logger_URLs": ["192.168.1.1", "1.0.0.1", "192.168.1.9"], + "All_CA_URLs": ["192.168.1.1", "1.0.0.1", "192.168.1.9"], + "All_Logger_URLs": ["192.168.1.1", "1.0.0.1", "192.168.1.9"], "Gossip_wait_time": 3000, "MMD": 3000, "MRD": 3000, diff --git a/CTng/config/types.go b/CTng/config/types.go index 29884ce..41d551c 100644 --- a/CTng/config/types.go +++ b/CTng/config/types.go @@ -6,8 +6,8 @@ import ( // The structs that are read/written to files. type Monitor_public_config struct { - CA_URLs []string - Logger_URLs []string + All_CA_URLs []string + All_Logger_URLs []string Gossip_wait_time int MMD int MRD int diff --git a/CTng/monitor/monitor.go b/CTng/monitor/monitor.go index ea0d5d6..280d07b 100644 --- a/CTng/monitor/monitor.go +++ b/CTng/monitor/monitor.go @@ -1,6 +1,11 @@ package monitor import ( + "CTng/crypto" + "CTng/gossip" + "bytes" + "encoding/json" + "errors" "fmt" "io/ioutil" "log" @@ -70,3 +75,78 @@ func QueryAuthorities(authURLs []string) { } } + +//Accused = Domain name of the accused entity (logger etc.) +//should be a monitor functionality +func AccuseEntity(c *crypto.CryptoConfig, Accused string) (gossip.Gossip_object, error) { + // this should be a method for the monitor + // psedo code for now + msg := Accused + signature, err := c.ThresholdSign(msg) + if err != nil { + return gossip.Gossip_object{}, err + } + var sigarray [2]string + sigarray[0] = signature.String() + sigarray[1] = "" + var payloadarray [2]string + payloadarray[0] = msg + payloadarray[1] = "" + accusation := gossip.Gossip_object{ + Application: "accsuation", + Type: "http://ctng.uconn.edu/203", + Signer: c.SelfID.String(), + Signature: sigarray, + Timestamp: gossip.GetCurrentTimestamp(), + Payload: payloadarray, + } + return accusation, nil +} + +func Send_to_gossiper(c *MonitorContext, g gossip.Gossip_object) { + // Convert gossip object to JSON + msg, err := json.Marshal(g) + if err != nil { + fmt.Println(err) + } + // Send the gossip object to the gossiper. + resp, postErr := c.Client.Post("http://"+c.Config.Gossiper_URL+"/monitor/recieve-gossip", "application/json", bytes.NewBuffer(msg)) + if postErr != nil { + fmt.Printf("Error sending object to Gossiper: " + postErr.Error()) + } else { + // Close the response, mentioned by http.Post + // Alernatively, we could return the response from this function. + defer resp.Body.Close() + fmt.Println("Owner responded with " + resp.Status) + } + +} + +//this function takes the name of the entity as input and check if there is a POM against it +//this should be invoked after the monitor receives the information from its loggers and CAs prior to threshold signning it +func Check_entity_pom(c *MonitorContext, name string) error { + for _, v := range *c.Storage { + if v.Payload[0] == name && (v.Type == gossip.ACCUSATION_POM || v.Type == gossip.APPLICATION_POM || v.Type == gossip.GOSSIP_POM) { + return errors.New("There exists a proof of misbehavior against this entity") + } + } + return nil +} + +func IsLogger(c *MonitorContext, loggerURL string) bool { + for _, url := range c.Config.Public.All_Logger_URLs { + if url == loggerURL { + return true + } + } + return false +} + +func IsAuthority(c *MonitorContext, authURL string) bool { + for _, url := range c.Config.Public.All_CA_URLs { + if url == authURL { + return true + } + } + return false +} diff --git a/CTng/monitor/monitor_process.go b/CTng/monitor/monitor_process.go new file mode 100644 index 0000000..47e6e7f --- /dev/null +++ b/CTng/monitor/monitor_process.go @@ -0,0 +1,60 @@ +package monitor + +import ( + "CTng/gossip" + "fmt" + "time" +) + +//Need to discuss about this ****************************************************** +func Process_valid_object(c *MonitorContext, g gossip.Gossip_object) { + //if the valid object is from the logger in the monitor config logger URL list + //This handles the STHS + if IsLogger(c, g.Signer) && g.Type == gossip.STH { + sig_frag, err := c.Config.Crypto.ThresholdSign(g.Payload[0]) + if err != nil { + fmt.Printf(err.Error()) + } + Send_to_gossiper(c, g) + f := func() { + pom_err := Check_entity_pom(c, g.Signer) + //if there is no conflicting information/PoM send the Threshold signed version to the gossiper + if pom_err == nil { + g.Type = gossip.STH_FRAG + g.Signature[0] = sig_frag.String() + g.Signer = c.Config.Crypto.SelfID.String() + Send_to_gossiper(c, g) + } + + } + time.AfterFunc(time.Duration(c.Config.Public.Gossip_wait_time), f) + return + } + //if the object is from a CA, revocation information + //this handles revocation information + if IsAuthority(c, g.Signer) && g.Type == gossip.REVOCATION { + sig_frag, err := c.Config.Crypto.ThresholdSign(g.Payload[0]) + if err != nil { + fmt.Printf(err.Error()) + } + Send_to_gossiper(c, g) + f := func() { + pom_err := Check_entity_pom(c, g.Signer) + if pom_err == nil { + g.Type = gossip.REVOCATION_FRAG + g.Signature[0] = sig_frag.String() + g.Signer = c.Config.Crypto.SelfID.String() + Send_to_gossiper(c, g) + } + + } + time.AfterFunc(time.Duration(c.Config.Public.Gossip_wait_time), f) + return + } + //if the object is from its own gossiper + // Note didn't implement the directory separation here*************************************************************** + if g.Type == gossip.ACCUSATION_POM || g.Type == gossip.GOSSIP_POM || g.Type == gossip.APPLICATION_POM || g.Type == gossip.REVOCATION_FULL || g.Type == gossip.STH_FULL { + c.StoreObject(g) + return + } +} diff --git a/CTng/server/Monitor_ng.go b/CTng/server/Monitor_ng.go deleted file mode 100644 index 569f914..0000000 --- a/CTng/server/Monitor_ng.go +++ /dev/null @@ -1,162 +0,0 @@ -package server - -import ( - "CTng/crypto" - "CTng/gossip" - "CTng/monitor" - "bytes" - "encoding/json" - "errors" - "fmt" - "net/http" - "time" -) - -const PROTOCOL = "http://" - -//Accused = Domain name of the accused entity (logger etc.) -//should be a monitor functionality -func Monitor_accuseEntity(c *crypto.CryptoConfig, Accused string) (gossip.Gossip_object, error) { - // this should be a method for the monitor - // psedo code for now - msg := Accused - signature, err := c.ThresholdSign(msg) - if err != nil { - return gossip.Gossip_object{}, err - } - var sigarray [2]string - sigarray[0] = signature.String() - sigarray[1] = "" - var payloadarray [2]string - payloadarray[0] = msg - payloadarray[1] = "" - accusation := gossip.Gossip_object{ - Application: "accsuation", - Type: "http://ctng.uconn.edu/203", - Signer: c.SelfID.String(), - Signature: sigarray, - Timestamp: gossip.GetCurrentTimestamp(), - Payload: payloadarray, - } - return accusation, nil -} - -func Monitor_send_to_gossiper(c *monitor.MonitorContext, g gossip.Gossip_object) { - // Convert gossip object to JSON - msg, err := json.Marshal(g) - if err != nil { - fmt.Println(err) - } - // Send the gossip object to the gossiper. - resp, postErr := c.Client.Post(PROTOCOL+c.Config.Gossiper_URL+"/monitor/recieve-gossip", "application/json", bytes.NewBuffer(msg)) - if postErr != nil { - fmt.Printf("Error sending object to Gossiper: " + postErr.Error()) - } else { - // Close the response, mentioned by http.Post - // Alernatively, we could return the response from this function. - defer resp.Body.Close() - fmt.Println("Owner responded with " + resp.Status) - } - -} - -//Need to discuss about this ****************************************************** -func Monitor_process_valid_object(c *monitor.MonitorContext, g gossip.Gossip_object) { - for _, v := range c.Config.Logger_URLs { - //if the valid object is from the logger in the monitor config logger URL list - //This handles the STHS - if v == g.Signer { - sig_frag, err := c.Config.Crypto.ThresholdSign(g.Payload[0]) - if err != nil { - fmt.Printf(err.Error()) - } - Monitor_send_to_gossiper(c, g) - f := func() { - pom_err := Monitor_check_entity_pom(c, v) - //if there is no conflicting information/PoM send the Threshold signed version to the gossiper - if pom_err == nil { - g.Type = gossip.STH_FRAG - g.Signature[0] = sig_frag.String() - g.Signer = c.Config.Crypto.SelfID.String() - Monitor_send_to_gossiper(c, g) - } - - } - time.AfterFunc(time.Duration(c.Config.Public.Gossip_wait_time), f) - return - } - } - //if the object is from a CA, revocation information - //this handles revocation information - for _, v := range c.Config.CA_URLs { - if v == g.Signer { - sig_frag, err := c.Config.Crypto.ThresholdSign(g.Payload[0]) - if err != nil { - fmt.Printf(err.Error()) - } - Monitor_send_to_gossiper(c, g) - f := func() { - pom_err := Monitor_check_entity_pom(c, v) - if pom_err == nil { - g.Type = gossip.REVOCATION_FRAG - g.Signature[0] = sig_frag.String() - g.Signer = c.Config.Crypto.SelfID.String() - Monitor_send_to_gossiper(c, g) - } - - } - time.AfterFunc(time.Duration(c.Config.Public.Gossip_wait_time), f) - return - } - } - //if the object is from its own gossiper - // Note didn't implement the directory separation here*************************************************************** - if g.Type == gossip.ACCUSATION_POM || g.Type == gossip.GOSSIP_POM || g.Type == gossip.APPLICATION_POM || g.Type == gossip.REVOCATION_FULL || g.Type == gossip.STH_FULL { - c.StoreObject(g) - return - } -} - -//this function takes the name of the entity as input and check if there is a POM against it -//this should be invoked after the monitor receives the information from its loggers and CAs prior to threshold signning it -func Monitor_check_entity_pom(c *monitor.MonitorContext, name string) error { - for _, v := range *c.Storage { - if v.Payload[0] == name && (v.Type == gossip.ACCUSATION_POM || v.Type == gossip.APPLICATION_POM || v.Type == gossip.GOSSIP_POM) { - return errors.New("There exists a proof of misbehavior against this entity") - } - } - return nil -} - -func Monitor_handle_gossip(c *monitor.MonitorContext, w http.ResponseWriter, r *http.Request) { - // Parse sent object. - // Converts JSON passed in the body of a POST to a Gossip_object. - var gossip_obj gossip.Gossip_object - err := json.NewDecoder(r.Body).Decode(&gossip_obj) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - } - // Verify the object is valid. - err = gossip_obj.Verify(c.Config.Crypto) - if err != nil { - fmt.Println("Recieved invalid object from " + getSenderURL(r) + ".") - obj, err := Monitor_accuseEntity(c.Config.Crypto, gossip_obj.Signer) - Monitor_send_to_gossiper(c, obj) - http.Error(w, err.Error(), http.StatusOK) - return - } - // Check for duplicate object. - _, found := c.GetObject(gossip_obj.GetID(int64(c.Config.Public.Gossip_wait_time))) - if found { - // If the object is already stored, still return OK.{ - fmt.Println("Duplicate:", gossip_obj.Type, getSenderURL(r)+".") - http.Error(w, "Gossip object already stored.", http.StatusOK) - // processDuplicateObject(c, gossip_obj, stored_obj) - return - } else { - fmt.Println("Recieved new, valid", gossip_obj.Type, "from "+getSenderURL(r)+".") - Monitor_process_valid_object(c, gossip_obj) - c.SaveStorage() - } - http.Error(w, "Gossip object Processed.", http.StatusOK) -} diff --git a/CTng/server/Monitor_server.go b/CTng/server/Monitor_server.go index 02ef6e9..5d4c7db 100644 --- a/CTng/server/Monitor_server.go +++ b/CTng/server/Monitor_server.go @@ -28,7 +28,7 @@ func handleMonitorRequests(c *monitor.MonitorContext) { gorillaRouter := mux.NewRouter().StrictSlash(true) // POST functions - gorillaRouter.HandleFunc("/gossip/push-data", bindMonitorContext(c, receiveGossip)).Methods("POST") + gorillaRouter.HandleFunc("/gossip/push-data", bindMonitorContext(c, handle_gossip)).Methods("POST") gorillaRouter.HandleFunc("/submit-pom", bindMonitorContext(c, receivePOM)).Methods("POST") // GET functions @@ -131,6 +131,39 @@ func getPOM(c *monitor.MonitorContext, w http.ResponseWriter, r *http.Request) { // if POM found, send to requester } +func handle_gossip(c *monitor.MonitorContext, w http.ResponseWriter, r *http.Request) { + // Parse sent object. + // Converts JSON passed in the body of a POST to a Gossip_object. + var gossip_obj gossip.Gossip_object + err := json.NewDecoder(r.Body).Decode(&gossip_obj) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + } + // Verify the object is valid. + err = gossip_obj.Verify(c.Config.Crypto) + if err != nil { + fmt.Println("Recieved invalid object from " + getSenderURL(r) + ".") + obj, err := monitor.AccuseEntity(c.Config.Crypto, gossip_obj.Signer) + monitor.Send_to_gossiper(c, obj) + http.Error(w, err.Error(), http.StatusOK) + return + } + // Check for duplicate object. + _, found := c.GetObject(gossip_obj.GetID(int64(c.Config.Public.Gossip_wait_time))) + if found { + // If the object is already stored, still return OK.{ + fmt.Println("Duplicate:", gossip_obj.Type, getSenderURL(r)+".") + http.Error(w, "Gossip object already stored.", http.StatusOK) + // processDuplicateObject(c, gossip_obj, stored_obj) + return + } else { + fmt.Println("Recieved new, valid", gossip_obj.Type, "from "+getSenderURL(r)+".") + monitor.Process_valid_object(c, gossip_obj) + c.SaveStorage() + } + http.Error(w, "Gossip object Processed.", http.StatusOK) +} + func StartMonitorServer(c *monitor.MonitorContext) { // Check if the storage file exists in this directory err := c.LoadStorage()