Skip to content

Commit

Permalink
added packet replay detection
Browse files Browse the repository at this point in the history
  • Loading branch information
greenstatic committed Aug 24, 2018
1 parent eecf0e8 commit 05217b6
Show file tree
Hide file tree
Showing 18 changed files with 110 additions and 30 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ go get -u ./...
```

## TODO
- [ ] Implement packet replay detection
- [ ] Improve the firewalltracker package
- [ ] OpenSPA Client support for encrypted private keys
- [ ] OpenSPA Server public IP resolver
Expand Down
2 changes: 1 addition & 1 deletion cmd/openspa-client/cmd/getip.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package cmd

import (
"github.com/spf13/cobra"
"github.com/greenstatic/openspa/internal/cmdimpl"
"github.com/greenstatic/openspa/internal/ipresolver"
"github.com/spf13/cobra"
"os"
)

Expand Down
8 changes: 4 additions & 4 deletions cmd/openspa-client/cmd/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package cmd

import (
"crypto/rsa"
"github.com/greenstatic/openspa/internal/client"
"github.com/greenstatic/openspa/internal/ipresolver"
"github.com/greenstatic/openspa/internal/ospa"
"github.com/greenstatic/openspalib/cryptography"
"github.com/greenstatic/openspalib/response"
"github.com/greenstatic/openspalib/tools"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"io/ioutil"
"net"
"github.com/greenstatic/openspa/internal/client"
"github.com/greenstatic/openspa/internal/ipresolver"
"github.com/greenstatic/openspa/internal/ospa"
"os"
"strconv"
"time"
Expand Down Expand Up @@ -399,7 +399,7 @@ func request(clientPrivKey *rsa.PrivateKey, clientPubKey *rsa.PublicKey, serverP
}

log.WithFields(log.Fields{
"protocol": tools.ConvertProtoByteToStr(resp.Payload.Protocol),
"protocol": tools.ConvertProtoByteToStr(resp.Payload.Protocol),
"startPort": resp.Payload.StartPort,
"endPort": resp.Payload.EndPort,
"duration": resp.Payload.Duration,
Expand Down
2 changes: 1 addition & 1 deletion cmd/openspa-client/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package cmd
import (
"bytes"
"fmt"
"github.com/greenstatic/openspa/internal/client"
"github.com/greenstatic/openspalib"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/greenstatic/openspa/internal/client"
"os"
)

Expand Down
2 changes: 1 addition & 1 deletion cmd/openspa-server/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package cmd
import (
"bytes"
"fmt"
"github.com/greenstatic/openspa/internal/server"
"github.com/greenstatic/openspalib"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/greenstatic/openspa/internal/server"
"os"
)

Expand Down
15 changes: 9 additions & 6 deletions cmd/openspa-server/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package cmd

import (
"errors"
"github.com/greenstatic/openspalib/cryptography"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"net"
"github.com/greenstatic/openspa/internal/extensionScripts"
"github.com/greenstatic/openspa/internal/firewalltracker"
"github.com/greenstatic/openspa/internal/ipresolver"
"github.com/greenstatic/openspa/internal/ospa"
"github.com/greenstatic/openspa/internal/server"
"github.com/greenstatic/openspalib/cryptography"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"net"
"os"
"os/signal"
"syscall"
Expand Down Expand Up @@ -88,6 +88,8 @@ var serverCmd = &cobra.Command{
}

fwState := firewalltracker.Create(es.GetRuleAdd(), es.GetRuleRemove())
replay := server.ReplayDetect{}
replay.Setup()

bindIp := net.ParseIP(viper.GetString("bind"))
binPort := uint16(viper.GetInt("port"))
Expand All @@ -98,7 +100,8 @@ var serverCmd = &cobra.Command{
privKey,
pubKey,
es,
fwState}
fwState,
&replay}

log.WithFields(log.Fields{"bindIp": bindIp, "port": binPort}).Info("Starting server")

Expand Down
2 changes: 1 addition & 1 deletion cmd/openspa-tools/cmd/genClient.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package cmd

import (
"github.com/greenstatic/openspa/internal/genOspa"
"github.com/greenstatic/openspalib/cryptography"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/greenstatic/openspa/internal/genOspa"
"os"
"path/filepath"
)
Expand Down
2 changes: 1 addition & 1 deletion cmd/openspa-tools/cmd/genServerKey.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package cmd
import (
"crypto/x509"
"encoding/pem"
"github.com/greenstatic/openspa/internal/genOspa"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/greenstatic/openspa/internal/genOspa"
"os"
"path/filepath"
)
Expand Down
2 changes: 1 addition & 1 deletion internal/cmdimpl/getip.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package cmdimpl

import (
"fmt"
log "github.com/sirupsen/logrus"
"github.com/greenstatic/openspa/internal/ipresolver"
log "github.com/sirupsen/logrus"
"strconv"
)

Expand Down
2 changes: 1 addition & 1 deletion internal/extensionScripts/ruleAdd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package extensionScripts
import (
"bytes"
"errors"
log "github.com/sirupsen/logrus"
"github.com/greenstatic/openspa/internal/firewalltracker"
log "github.com/sirupsen/logrus"
"os/exec"
"strconv"
)
Expand Down
2 changes: 1 addition & 1 deletion internal/extensionScripts/ruleRemove.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package extensionScripts
import (
"bytes"
"errors"
log "github.com/sirupsen/logrus"
"github.com/greenstatic/openspa/internal/firewalltracker"
log "github.com/sirupsen/logrus"
"os/exec"
"strconv"
)
Expand Down
4 changes: 2 additions & 2 deletions internal/genOspa/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"github.com/greenstatic/openspa/internal/client"
"github.com/greenstatic/openspa/internal/ospa"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
)

// Encodes the RSA private key to a PEM formatted byte slice
Expand Down
4 changes: 2 additions & 2 deletions internal/genOspa/walkthrough.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import (
"crypto/rsa"
"errors"
"fmt"
"github.com/greenstatic/openspa/internal/ipresolver"
"github.com/greenstatic/openspa/internal/ospa"
"github.com/greenstatic/openspalib/cryptography"
"github.com/satori/go.uuid"
log "github.com/sirupsen/logrus"
"io/ioutil"
"net"
"github.com/greenstatic/openspa/internal/ipresolver"
"github.com/greenstatic/openspa/internal/ospa"
"os"
"path/filepath"
"regexp"
Expand Down
4 changes: 2 additions & 2 deletions internal/ospa/ospa.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package ospa

import (
"errors"
"github.com/greenstatic/openspa/internal/client"
"github.com/greenstatic/openspa/internal/ipresolver"
"github.com/satori/go.uuid"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"net"
"github.com/greenstatic/openspa/internal/client"
"github.com/greenstatic/openspa/internal/ipresolver"
"regexp"
"strconv"
)
Expand Down
27 changes: 25 additions & 2 deletions internal/server/receiving.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package server
import (
"crypto/rsa"
"errors"
"github.com/greenstatic/openspa/internal/firewalltracker"
"github.com/greenstatic/openspalib/cryptography"
"github.com/greenstatic/openspalib/request"
"github.com/greenstatic/openspalib/response"
"github.com/satori/go.uuid"
log "github.com/sirupsen/logrus"
"net"
"github.com/greenstatic/openspa/internal/firewalltracker"
"strconv"
"time"
)
Expand Down Expand Up @@ -89,6 +89,24 @@ func (n *New) processPacket(data []byte) ([]byte, error) {
return nil, err
}

// Check the timestamp field is valid
if err = expiredPacket(packet); err != nil {
log.WithFields(log.Fields{
"clientDeviceId": packet.Payload.ClientDeviceID,
"created": packet.Payload.Timestamp.UTC().String(),
}).Warning("Received old packet or the client doesn't have their clock synchronized")
return nil, err
}

// Replay detection by hashing the packet
if err = n.Replay.Check(data); err != nil {
log.WithFields(log.Fields{
"clientDeviceId": packet.Payload.ClientDeviceID,
"created": packet.Payload.Timestamp.UTC().String(),
}).Warning("Replay detected - packet already received, discarding packet")
return nil, errors.New("replay detected")
}

clientID := packet.Payload.ClientDeviceID
log.WithField("clientDeviceId", clientID).
Debug("Getting the user's public key to verify packet")
Expand All @@ -100,7 +118,12 @@ func (n *New) processPacket(data []byte) ([]byte, error) {
return nil, errors.New("failed to get user's public key")
}

// TODO - if clientPubKey is null return with no packet data since they are not authorized
// If clientPubKey is null return with no packet data since they are not authorized
if clientPubKey == nil {
log.WithField("clientDeviceId", packet.Payload.ClientDeviceID).
Info("No client public key found, discarding packet")
return nil, errors.New("no client public key found")
}

// Verify signature
signatureValid := cryptography.RSA_SHA256_signature_verify(packet.ByteData, clientPubKey, packet.Signature)
Expand Down
54 changes: 54 additions & 0 deletions internal/server/replayDetection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package server

import (
"crypto/sha256"
"errors"
"github.com/greenstatic/openspalib/request"
"log"
"sync"
"time"
)

type ReplayDetect struct {
HashedPackets map[string]bool
mux sync.Mutex
}

// Discard packets that were generated more than 5 min ago - first line of
// defense against replay defense
func expiredPacket(packet request.Packet) error {
var dur time.Duration = 5 * time.Minute
if time.Now().Sub(packet.Payload.Timestamp) > dur {
return errors.New("packet expired")
}

return nil
}

func (rd *ReplayDetect) Setup() {
rd.HashedPackets = make(map[string]bool)
}

// Checks if the packet has already been sent by taking the SHA-256 hash of
// the packet and comparing it with all the received packets.
func (rd *ReplayDetect) Check(packet []byte) error {

if rd.HashedPackets == nil {
log.Fatal("ReplayDetect struct was not setup using the Setup() function")
}

// Take hash of the packet
sum := sha256.Sum256(packet)
sumStr := string(sum[:])

rd.mux.Lock()
defer rd.mux.Unlock()
_, found := rd.HashedPackets[sumStr]
if found {
return errors.New("hash of packet found")
}

rd.HashedPackets[sumStr] = true

return nil
}
5 changes: 3 additions & 2 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package server

import (
"crypto/rsa"
"github.com/greenstatic/openspalib/request"
"net"
"github.com/greenstatic/openspa/internal/extensionScripts"
"github.com/greenstatic/openspa/internal/firewalltracker"
"github.com/greenstatic/openspalib/request"
"net"
)

const (
Expand All @@ -19,4 +19,5 @@ type New struct {
PublicKey *rsa.PublicKey
ExtensionScripts extensionScripts.Scripts
FirewallState *firewalltracker.State
Replay *ReplayDetect
}
2 changes: 1 addition & 1 deletion internal/server/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import "fmt"

const VersionMajor = 0
const VersionMinor = 1
const VersionBugfix = 1
const VersionBugfix = 2

var Version = fmt.Sprintf("%d.%d.%d", VersionMajor, VersionMinor, VersionBugfix)

0 comments on commit 05217b6

Please sign in to comment.