Adding a checksum to ICCC messages (#45)
This commit is contained in:
		
							parent
							
								
									0911c828fc
								
							
						
					
					
						commit
						b278570570
					
				@ -9,8 +9,8 @@ import (
 | 
				
			|||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The HTTP handler for the local ICCC commands. Will used in case, that another server
 | 
					// The HTTP handler for the local ICCC listeners. Will used in case, that another server
 | 
				
			||||||
// want to utelise an command from this server.
 | 
					// want to utelise an listener from this server.
 | 
				
			||||||
func ICCCHandler(response http.ResponseWriter, request *http.Request) {
 | 
					func ICCCHandler(response http.ResponseWriter, request *http.Request) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Cannot parse the form?
 | 
						// Cannot parse the form?
 | 
				
			||||||
@ -23,9 +23,9 @@ func ICCCHandler(response http.ResponseWriter, request *http.Request) {
 | 
				
			|||||||
	// Read the data out of the request:
 | 
						// Read the data out of the request:
 | 
				
			||||||
	messageData := map[string][]string(request.PostForm)
 | 
						messageData := map[string][]string(request.PostForm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The data must contain at least three fields (command, channel & communication password)
 | 
						// The data must contain at least three fields (command, channel & checksum)
 | 
				
			||||||
	if len(messageData) < 3 {
 | 
						if len(messageData) < 3 {
 | 
				
			||||||
		Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityCritical, LM.ImpactCritical, LM.MessageNameNETWORK, `The ICCC message contains not enough data: At least the channel, command and password is required!`)
 | 
							Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelERROR, LM.SeverityCritical, LM.ImpactCritical, LM.MessageNameNETWORK, `The ICCC message contains not enough data: At least the channel, command and checksum is required!`)
 | 
				
			||||||
		http.NotFound(response, request)
 | 
							http.NotFound(response, request)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -33,11 +33,17 @@ func ICCCHandler(response http.ResponseWriter, request *http.Request) {
 | 
				
			|||||||
	// Read the meta data:
 | 
						// Read the meta data:
 | 
				
			||||||
	channel := messageData[`channel`][0]
 | 
						channel := messageData[`channel`][0]
 | 
				
			||||||
	command := messageData[`command`][0]
 | 
						command := messageData[`command`][0]
 | 
				
			||||||
	password := messageData[`InternalCommPassword`][0]
 | 
						receivedChecksum := messageData[`checksum`][0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check the password:
 | 
						// Remove the checksum as preparation for the re-hash:
 | 
				
			||||||
	if password != Tools.InternalCommPassword() {
 | 
						delete(messageData, `checksum`)
 | 
				
			||||||
		Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelSECURITY, LM.SeverityCritical, LM.ImpactNone, LM.MessageNamePASSWORD, `Received a ICCC message with wrong password!`, request.RemoteAddr)
 | 
					
 | 
				
			||||||
 | 
						// Re-hash the received message:
 | 
				
			||||||
 | 
						receivedMessageHash := signMessage(messageData).Get(`checksum`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check the checksums:
 | 
				
			||||||
 | 
						if receivedChecksum != receivedMessageHash {
 | 
				
			||||||
 | 
							Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelSECURITY, LM.SeverityCritical, LM.ImpactNone, LM.MessageNamePASSWORD, `Received a ICCC message with wrong checksum!`, request.RemoteAddr, fmt.Sprintf("channel=%s", channel), fmt.Sprintf("command=%s", command))
 | 
				
			||||||
		http.NotFound(response, request)
 | 
							http.NotFound(response, request)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,6 @@ import (
 | 
				
			|||||||
	"github.com/SommerEngineering/Ocean/ICCC/Scheme"
 | 
						"github.com/SommerEngineering/Ocean/ICCC/Scheme"
 | 
				
			||||||
	"github.com/SommerEngineering/Ocean/Log"
 | 
						"github.com/SommerEngineering/Ocean/Log"
 | 
				
			||||||
	LM "github.com/SommerEngineering/Ocean/Log/Meta"
 | 
						LM "github.com/SommerEngineering/Ocean/Log/Meta"
 | 
				
			||||||
	"github.com/SommerEngineering/Ocean/Tools"
 | 
					 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
@ -12,11 +11,9 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Send a message to a listener.
 | 
					// Send a message to a listener.
 | 
				
			||||||
func sendMessage(listener Scheme.Listener, data map[string][]string) (result map[string][]string) {
 | 
					func sendMessage(listener Scheme.Listener, data map[string][]string) (result map[string][]string) {
 | 
				
			||||||
	// Convert the data and encode it:
 | 
					 | 
				
			||||||
	valuesHTTP := url.Values(data)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add the communication password:
 | 
						// Lets sign the data:
 | 
				
			||||||
	valuesHTTP.Add(`InternalCommPassword`, Tools.InternalCommPassword())
 | 
						valuesHTTP := signMessage(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Try to deliver the message:
 | 
						// Try to deliver the message:
 | 
				
			||||||
	if response, err := http.PostForm(`http://`+listener.IPAddressPort+`/ICCC`, valuesHTTP); err != nil {
 | 
						if response, err := http.PostForm(`http://`+listener.IPAddressPort+`/ICCC`, valuesHTTP); err != nil {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										47
									
								
								ICCC/SignMessage.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								ICCC/SignMessage.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					package ICCC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/sha512"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"github.com/SommerEngineering/Ocean/Tools"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sign a message to secure it.
 | 
				
			||||||
 | 
					func signMessage(data map[string][]string) (result url.Values) {
 | 
				
			||||||
 | 
						// Create the hash generator:
 | 
				
			||||||
 | 
						hash := sha512.New()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// To the start, we hash the password:
 | 
				
			||||||
 | 
						fmt.Fprintf(hash, "%s", Tools.InternalCommPassword())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Because the order of a map is random, we have to sort
 | 
				
			||||||
 | 
						// the keys beforehand. Next, we can use the ordered keys
 | 
				
			||||||
 | 
						// to access the data:
 | 
				
			||||||
 | 
						keys := []string{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get all keys:
 | 
				
			||||||
 | 
						for key := range data {
 | 
				
			||||||
 | 
							keys = append(keys, key)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Sort the keys:
 | 
				
			||||||
 | 
						sort.Strings(keys)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Now, loop over all the data:
 | 
				
			||||||
 | 
						for _, key := range keys {
 | 
				
			||||||
 | 
							// Get the value:
 | 
				
			||||||
 | 
							value := data[key]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Hash each key and value:
 | 
				
			||||||
 | 
							fmt.Fprintf(hash, "key=%s :: value=%s\n", key, value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Create the result:
 | 
				
			||||||
 | 
						result = url.Values(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Append the sign:
 | 
				
			||||||
 | 
						result.Add(`checksum`, fmt.Sprintf("%x", hash.Sum(nil)))
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user