Skip to content

Commit

Permalink
fix(plc4go): options should now correctly be applied
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl authored and splatch committed Feb 12, 2024
1 parent 725f1f5 commit 9f658e6
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 70 deletions.
10 changes: 10 additions & 0 deletions plc4go/internal/cbus/Configuration.go
Expand Up @@ -21,6 +21,8 @@ package cbus

import (
"github.com/rs/zerolog"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"reflect"
"strconv"

Expand All @@ -45,6 +47,7 @@ type Configuration struct {
}

func ParseFromOptions(log zerolog.Logger, options map[string][]string) (Configuration, error) {
titleOptions(options)
configuration := createDefaultConfiguration()
reflectConfiguration := reflect.ValueOf(&configuration).Elem()
for i := 0; i < reflectConfiguration.NumField(); i++ {
Expand Down Expand Up @@ -72,6 +75,13 @@ func ParseFromOptions(log zerolog.Logger, options map[string][]string) (Configur
return configuration, nil
}

func titleOptions(options map[string][]string) {
caser := cases.Title(language.AmericanEnglish)
for key, value := range options {
options[caser.String(key)] = value
}
}

func createDefaultConfiguration() Configuration {
return Configuration{
Exstat: true,
Expand Down
54 changes: 32 additions & 22 deletions plc4go/internal/opcua/Configuration.go
Expand Up @@ -29,32 +29,35 @@ import (

"github.com/pkg/errors"
"github.com/rs/zerolog"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)

//go:generate go run ../../tools/plc4xgenerator/gen.go -type=Configuration
type Configuration struct {
code string
host string
port string
endpoint string
transportEndpoint string
params string
isEncrypted bool
thumbprint readWriteModel.PascalByteString
senderCertificate []byte
discovery bool
username string
password string
securityPolicy string
keyStoreFile string
certDirectory string
keyStorePassword string
ckp *CertificateKeyPair
Code string
Host string
Port string
Endpoint string
TransportEndpoint string
Params string
IsEncrypted bool
Thumbprint readWriteModel.PascalByteString
SenderCertificate []byte
Discovery bool
Username string
Password string
SecurityPolicy string
KeyStoreFile string
CertDirectory string
KeyStorePassword string
Ckp *CertificateKeyPair

log zerolog.Logger `ignore:"true"`
}

func ParseFromOptions(log zerolog.Logger, options map[string][]string) (Configuration, error) {
titleOptions(options)
configuration := createDefaultConfiguration()
reflectConfiguration := reflect.ValueOf(&configuration).Elem()
for i := 0; i < reflectConfiguration.NumField(); i++ {
Expand Down Expand Up @@ -83,19 +86,26 @@ func ParseFromOptions(log zerolog.Logger, options map[string][]string) (Configur
return configuration, nil
}

func titleOptions(options map[string][]string) {
caser := cases.Title(language.AmericanEnglish)
for key, value := range options {
options[caser.String(key)] = value
}
}

func (c *Configuration) openKeyStore() error {
c.isEncrypted = true
securityTempDir := path.Join(c.certDirectory, "security")
c.IsEncrypted = true
securityTempDir := path.Join(c.CertDirectory, "security")
if _, err := os.Stat(securityTempDir); errors.Is(err, os.ErrNotExist) {
if err := os.Mkdir(securityTempDir, 700); err != nil {
return errors.New("Unable to create directory please confirm folder permissions on " + securityTempDir)
}
}

serverKeyStore := path.Join(securityTempDir, c.keyStoreFile)
serverKeyStore := path.Join(securityTempDir, c.KeyStoreFile)
if _, err := os.Stat(securityTempDir); errors.Is(err, os.ErrNotExist) {
var err error
c.ckp, err = generateCertificate()
c.Ckp, err = generateCertificate()
if err != nil {
return errors.Wrap(err, "error generating certificate")
}
Expand All @@ -117,7 +127,7 @@ func (c *Configuration) openKeyStore() error {

func createDefaultConfiguration() Configuration {
return Configuration{
securityPolicy: "None",
SecurityPolicy: "None",
}
}

Expand Down
38 changes: 19 additions & 19 deletions plc4go/internal/opcua/Configuration_plc4xgen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions plc4go/internal/opcua/Driver.go
Expand Up @@ -125,17 +125,17 @@ func (d *Driver) GetConnectionWithContext(ctx context.Context, transportUrl url.
if err != nil {
return d.reportError(errors.Wrap(err, "can't parse options"))
}
configuration.host = transportHost
configuration.port = transportPort
configuration.transportEndpoint = transportEndpoint
configuration.Host = transportHost
configuration.Port = transportPort
configuration.TransportEndpoint = transportEndpoint
portAddition := ""
if transportPort != "" {
portAddition += ":" + transportPort
}
configuration.endpoint = "opc." + transportCode + "://" + transportHost + portAddition + "" + transportEndpoint
d.log.Debug().Stringer("configuration", &configuration).Msg("working with configurartion")
configuration.Endpoint = "opc." + transportCode + "://" + transportHost + portAddition + "" + transportEndpoint
d.log.Debug().Stringer("configuration", &configuration).Msg("working with configuration")

if securityPolicy := configuration.securityPolicy; securityPolicy != "" && securityPolicy != "None" {
if securityPolicy := configuration.SecurityPolicy; securityPolicy != "" && securityPolicy != "None" {
d.log.Trace().Str("securityPolicy", securityPolicy).Msg("working with security policy")
if err := configuration.openKeyStore(); err != nil {
return d.reportError(errors.Wrap(err, "error opening key store"))
Expand Down
2 changes: 1 addition & 1 deletion plc4go/internal/opcua/DriverContext.go
Expand Up @@ -29,7 +29,7 @@ type DriverContext struct {

func NewDriverContext(configuration Configuration) DriverContext {
return DriverContext{
fireDiscoverEvent: configuration.isEncrypted,
fireDiscoverEvent: configuration.IsEncrypted,
awaitSetupComplete: true,
awaitDisconnectComplete: true,
awaitSessionDiscoverComplete: true,
Expand Down
44 changes: 22 additions & 22 deletions plc4go/internal/opcua/SecureChannel.go
Expand Up @@ -128,33 +128,33 @@ type SecureChannel struct {
func NewSecureChannel(log zerolog.Logger, ctx DriverContext, configuration Configuration) *SecureChannel {
s := &SecureChannel{
configuration: configuration,
endpoint: readWriteModel.NewPascalString(configuration.endpoint),
username: configuration.username,
password: configuration.password,
securityPolicy: "http://opcfoundation.org/UA/SecurityPolicy#" + configuration.securityPolicy,
endpoint: readWriteModel.NewPascalString(configuration.Endpoint),
username: configuration.Username,
password: configuration.Password,
securityPolicy: "http://opcfoundation.org/UA/SecurityPolicy#" + configuration.SecurityPolicy,
sessionName: "UaSession:" + APPLICATION_TEXT.GetStringValue() + ":" + uniuri.NewLen(20),
authenticationToken: readWriteModel.NewNodeIdTwoByte(0),
clientNonce: []byte(uniuri.NewLen(40)),
keyStoreFile: configuration.keyStoreFile,
keyStoreFile: configuration.KeyStoreFile,
channelTransactionManager: NewSecureChannelTransactionManager(log),
lifetime: DEFAULT_CONNECTION_LIFETIME,
log: log,
}
s.requestHandleGenerator.Store(1)
s.channelId.Store(1)
s.tokenId.Store(1)
ckp := configuration.ckp
if configuration.securityPolicy == "Basic256Sha256" {
ckp := configuration.Ckp
if configuration.SecurityPolicy == "Basic256Sha256" {
//Sender Certificate gets populated during the 'discover' phase when encryption is enabled.
s.senderCertificate = configuration.senderCertificate
s.encryptionHandler = NewEncryptionHandler(s.log, ckp, s.senderCertificate, configuration.securityPolicy)
s.senderCertificate = configuration.SenderCertificate
s.encryptionHandler = NewEncryptionHandler(s.log, ckp, s.senderCertificate, configuration.SecurityPolicy)
certificate := ckp.getCertificate()
s.publicCertificate = readWriteModel.NewPascalByteString(int32(len(certificate.Raw)), certificate.Raw)
s.isEncrypted = true

s.thumbprint = configuration.thumbprint
s.thumbprint = configuration.Thumbprint
} else {
s.encryptionHandler = NewEncryptionHandler(s.log, ckp, s.senderCertificate, configuration.securityPolicy)
s.encryptionHandler = NewEncryptionHandler(s.log, ckp, s.senderCertificate, configuration.SecurityPolicy)
s.publicCertificate = NULL_BYTE_STRING
s.thumbprint = NULL_BYTE_STRING
s.isEncrypted = false
Expand All @@ -163,7 +163,7 @@ func NewSecureChannel(log zerolog.Logger, ctx DriverContext, configuration Confi
// Generate a list of endpoints we can use.
{
var err error
address, err := url.Parse("none://" + configuration.host)
address, err := url.Parse("none://" + configuration.Host)
if err == nil {
if names, lookupErr := net.LookupHost(address.Host); lookupErr == nil {
s.endpoints = append(s.endpoints, names[rand.Intn(len(names))])
Expand Down Expand Up @@ -611,11 +611,11 @@ func (s *SecureChannel) onConnectActivateSessionRequest(ctx context.Context, con
s.encryptionHandler.setServerCertificate(certificate)
s.senderNonce = sessionResponse.GetServerNonce().GetStringValue()
endpoints := make([]string, 3)
if address, err := url.Parse(s.configuration.host); err != nil {
if address, err := url.Parse(s.configuration.Host); err != nil {
if names, err := net.LookupAddr(address.Host); err != nil {
endpoints[0] = "opc.tcp://" + names[rand.Intn(len(names))] + ":" + s.configuration.port + s.configuration.transportEndpoint
endpoints[0] = "opc.tcp://" + names[rand.Intn(len(names))] + ":" + s.configuration.Port + s.configuration.TransportEndpoint
}
endpoints[1] = "opc.tcp://" + address.Hostname() + ":" + s.configuration.port + s.configuration.transportEndpoint
endpoints[1] = "opc.tcp://" + address.Hostname() + ":" + s.configuration.Port + s.configuration.TransportEndpoint
//endpoints[2] = "opc.tcp://" + address.getCanonicalHostName() + ":" + s.configuration.getPort() + s.configuration.transportEndpoint// TODO: not sure how to get that in golang
}

Expand Down Expand Up @@ -1190,11 +1190,11 @@ func (s *SecureChannel) onDiscoverGetEndpointsRequest(ctx context.Context, codec
endpointDescription := endpoint.(readWriteModel.EndpointDescription)
if endpointDescription.GetEndpointUrl().GetStringValue() == (s.endpoint.GetStringValue()) && endpointDescription.GetSecurityPolicyUri().GetStringValue() == (s.securityPolicy) {
s.log.Info().Str("stringValue", s.endpoint.GetStringValue()).Msg("Found OPC UA endpoint")
s.configuration.senderCertificate = endpointDescription.GetServerCertificate().GetStringValue()
s.configuration.SenderCertificate = endpointDescription.GetServerCertificate().GetStringValue()
}
}

digest := sha1.Sum(s.configuration.senderCertificate)
digest := sha1.Sum(s.configuration.SenderCertificate)
s.thumbprint = readWriteModel.NewPascalByteString(int32(len(digest)), digest[:])

go s.onDiscoverCloseSecureChannel(ctx, codec, response)
Expand Down Expand Up @@ -1538,20 +1538,20 @@ func (s *SecureChannel) isEndpoint(endpoint readWriteModel.EndpointDescription)
Str("transportEndpoint", matches["transportEndpoint"]).
Msg("Using Endpoint")

if s.configuration.discovery && !slices.Contains(s.endpoints, matches["transportHost"]) {
if s.configuration.Discovery && !slices.Contains(s.endpoints, matches["transportHost"]) {
return false
}

if s.configuration.port != matches["transportPort"] {
if s.configuration.Port != matches["transportPort"] {
return false
}

if s.configuration.transportEndpoint != matches["transportEndpoint"] {
if s.configuration.TransportEndpoint != matches["transportEndpoint"] {
return false
}

if !s.configuration.discovery {
s.configuration.host = matches["transportHost"]
if !s.configuration.Discovery {
s.configuration.Host = matches["transportHost"]
}

return true
Expand Down

0 comments on commit 9f658e6

Please sign in to comment.