From 25ec776ded48d0d298d59920ce0f4eeef1a5cbf5 Mon Sep 17 00:00:00 2001 From: yakovlevdmv Date: Wed, 4 Apr 2018 22:42:40 +0300 Subject: [PATCH] Some improvements at Device.go. Adding WS security --- Device.go | 30 ++++++++++++++++++++++ WS_Security.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 WS_Security.go diff --git a/Device.go b/Device.go index 626b5ad..4cc611b 100644 --- a/Device.go +++ b/Device.go @@ -15,8 +15,34 @@ import ( "github.com/yakovlevdmv/goonvif/Media" "github.com/yakovlevdmv/goonvif/PTZ" "errors" + "strconv" ) +type DeviceType int + +const ( + NVD DeviceType = iota + NVS + NVA + NVT +) + +func (devType DeviceType) String() string { + stringRepresentation := []string { + "NetworkVideoDisplay", + "NetworkVideoStorage", + "NetworkVideoAnalytics", + "NetworkVideoTransmitter", + } + i := uint8(devType) + switch { + case i <= uint8(NVT): + return stringRepresentation[i] + default: + return strconv.Itoa(int(i)) + } +} + //deviceInfo struct contains general information about ONVIF device type deviceInfo struct { Manufacturer string @@ -42,6 +68,10 @@ type device struct { } +func getAvailableDevicesAtEthernet(interfaceName string) { + +} + //NewDevice function construct a ONVIF Device entity func NewDevice() *device { return &device{} diff --git a/WS_Security.go b/WS_Security.go new file mode 100644 index 0000000..c2a19f1 --- /dev/null +++ b/WS_Security.go @@ -0,0 +1,69 @@ +package goonvif + +import ( + "encoding/xml" + "time" + "encoding/base64" + "crypto/sha1" + "github.com/elgs/gostrgen" +) + +/************************* + WS-Security types +*************************/ +const (passwordType = "https://www.oasis-open.org/committees/download.php/13392/wss-v1.1-spec-pr-UsernameTokenProfile-01.htm#PasswordDigest") + +type security struct { + XMLName xml.Name `xml:"wsse:Security"` + Auth wsAuth +} + +type password struct { + XMLName xml.Name `xml:"wsse:Password"` + Type string `xml:"Type,attr"` + Password string `xml:",chardata"` +} + +type wsAuth struct { + XMLName xml.Name `xml:"wsse:UsernameToken"` + Username string `xml:"wsse:Username"` + Password password `xml:"wsse:Password"` + Nonce string `xml:"wsse:Nonce"` + Created string `xml:"wsse:Created"` +} + +func newSecurity(username, passwd string) security { + /** Generating Nonce sequence **/ + charsToGenerate := 16 + charSet := gostrgen.Lower | gostrgen.Digit + + nonce, _ := gostrgen.RandGen(charsToGenerate, charSet, "", "") + + auth := security{ + Auth:wsAuth{ + Username:username, + Password:password { + Type:passwordType, + Password:generateToken(username, nonce, time.Now(), passwd), + }, + Nonce: nonce, + Created: time.Now().Format(time.RFC3339), + }, + } + + return auth +} + +//Digest = B64ENCODE( SHA1( B64DECODE( Nonce ) + Date + Password ) ) +func generateToken(Username string, Nonce string, Created time.Time, Password string) string { + + sDec, _ := base64.StdEncoding.DecodeString(Nonce) + + + hasher := sha1.New() + //hasher.Write([]byte((base64.StdEncoding.EncodeToString([]byte(Nonce)) + Created.Format(time.RFC3339) + Password))) + hasher.Write([]byte(string(sDec) + Created.Format(time.RFC3339) + Password)) + + return base64.StdEncoding.EncodeToString(hasher.Sum(nil)) +} +