Adding a checksum to ICCC messages (#45)
This commit is contained in:
parent
0911c828fc
commit
b278570570
@ -9,8 +9,8 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// The HTTP handler for the local ICCC commands. Will used in case, that another server
|
||||
// want to utelise an command from this server.
|
||||
// The HTTP handler for the local ICCC listeners. Will used in case, that another server
|
||||
// want to utelise an listener from this server.
|
||||
func ICCCHandler(response http.ResponseWriter, request *http.Request) {
|
||||
|
||||
// Cannot parse the form?
|
||||
@ -23,9 +23,9 @@ func ICCCHandler(response http.ResponseWriter, request *http.Request) {
|
||||
// Read the data out of the request:
|
||||
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 {
|
||||
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)
|
||||
return
|
||||
}
|
||||
@ -33,11 +33,17 @@ func ICCCHandler(response http.ResponseWriter, request *http.Request) {
|
||||
// Read the meta data:
|
||||
channel := messageData[`channel`][0]
|
||||
command := messageData[`command`][0]
|
||||
password := messageData[`InternalCommPassword`][0]
|
||||
receivedChecksum := messageData[`checksum`][0]
|
||||
|
||||
// Check the password:
|
||||
if password != Tools.InternalCommPassword() {
|
||||
Log.LogFull(senderName, LM.CategorySYSTEM, LM.LevelSECURITY, LM.SeverityCritical, LM.ImpactNone, LM.MessageNamePASSWORD, `Received a ICCC message with wrong password!`, request.RemoteAddr)
|
||||
// Remove the checksum as preparation for the re-hash:
|
||||
delete(messageData, `checksum`)
|
||||
|
||||
// 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)
|
||||
return
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"github.com/SommerEngineering/Ocean/ICCC/Scheme"
|
||||
"github.com/SommerEngineering/Ocean/Log"
|
||||
LM "github.com/SommerEngineering/Ocean/Log/Meta"
|
||||
"github.com/SommerEngineering/Ocean/Tools"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -12,11 +11,9 @@ import (
|
||||
|
||||
// Send a message to a listener.
|
||||
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:
|
||||
valuesHTTP.Add(`InternalCommPassword`, Tools.InternalCommPassword())
|
||||
// Lets sign the data:
|
||||
valuesHTTP := signMessage(data)
|
||||
|
||||
// Try to deliver the message:
|
||||
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