Adding a checksum to ICCC messages (#45)

This commit is contained in:
Thorsten Sommer 2015-07-10 21:06:44 +02:00
parent 0911c828fc
commit b278570570
3 changed files with 63 additions and 13 deletions

View File

@ -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
}

View File

@ -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
View 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
}