Skip to content
This repository has been archived by the owner on Sep 2, 2024. It is now read-only.

Commit

Permalink
DBC Feeder TLS support
Browse files Browse the repository at this point in the history
  • Loading branch information
erikbosch committed Jun 22, 2023
1 parent e484416 commit e7147b3
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 22 deletions.
31 changes: 31 additions & 0 deletions dbc2val/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ A smaller excerpt from the above sample, with fewer signals.
| - | *KUKSA_ADDRESS* | *[general].ip* | `127.0.0.1` | IP address for Server/Databroker |
| - | *KUKSA_PORT* | *[general].port* | `55555` | Port for Server/Databroker |
| *--tls* | - | *[general].tls* | `False` | Shall tls be used for Server/Databroker connection? |
| | - | *[general].root_ca_path* | *Undefined* | Path to root CA: Only needed if using TLS |
| | - | *[general].tls_server_name* | *Undefined* | TLS server name, may be needed if addressing a server by IP-name |
| - | - | *[general].token* | *Undefined* | Token path. Only needed if Databroker/Server requires authentication |
| - | *VEHICLEDATABROKER_DAPR_APP_ID* | - | - | Add dapr-app-id metadata. Only relevant for KUKSA.val Databroker |
| *--dbc2val /--no-dbc2val* | *USE_DBC2VAL* / *NO_USE_DBC2VAL* | *[can].dbc2val* | dbc2val enabled | Specifies if sending data from CAN to KUKSA.val is enabled. Setting the environment variable to any value is equivalent to activating the switch on the command line.|
Expand All @@ -271,6 +273,35 @@ Configuration options have the following priority (highest at top).
3. configuration file
4. default value

### Using kuksa-client with a server requiring Authorization

The [default configuration file](config/dbc-feeder.ini) does not specify any token to use.
If the KUKSA.val Databroker or KUKSA.val Server requires authorization the `token` attribute in the config file
must be set. The default config file include (commented) values to use if using KUKSA.val example tokens.

*Note: Production deployments are strongly recommend to use Authorization but must NOT use the example tokens available in the KUKSA.val repository!*

### Using kuksa-client with a server requiring TLS

The [default configuration file](config/dbc-feeder.ini) does not specify that TLS shall be used.
If the KUKSA.val Databroker or KUKSA.val Server requires authentication the `tls` attribute in the config file
must be set to `True` and `root_ca_path` must be set.
The default config file include (commented) values to use if using KUKSA.val example certificates.

The feeder verifies that the Databroker/Server presents a certificate with a name matching the server.
The KUKSA.val default server certificate include `Server`, `localhost` and `127.0.0.1` as names, but due to a limitation
name validation does not work when using gRPC and a numeric IP-address, so for that combination you must as a work around
specify the `tls_server_name` to use in name validation, like in the example below.

```
ip = 127.0.0.1
tls = True
root_ca_path=../../kuksa.val/kuksa_certificates/CA.pem
tls_server_name=localhost
```

*Note: Production deployments are strongly recommend to use TLS but must NOT use the example certificates available in the KUKSA.val repository!*

## Using kuksa-val-server

1. To make the feeder communicate with this server, use the `--server-type kuksa_val_server` CLI option or refer to [Configuration](#configuration) for `server-type`.
Expand Down
10 changes: 9 additions & 1 deletion dbc2val/config/dbc_feeder.ini
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,20 @@ port = 55555
tls = False
# tls = True

# TLS-related settings
# Path to root CA, needed if using TLS
root_ca_path=../../kuksa.val/kuksa_certificates/CA.pem
# Server name, typically only needed if accessing server by IP address like 127.0.0.1
# and typically only if connection to KUKSA.val Databroker
# If using KUKSA.val example certificates the names "Server" or "localhost" can be used.
# tls_server_name=localhost

# Token file for authorization.
# Default behavior differ between servers
# For KUKSA.val Databroker the KUKSA.val default token not included in packages and containers
# If you run your Databroker so it require authentication you must specify token
# The example below works if you have cloned kuksa.val in parallel to kuksa.val.feeders
#token=../../kuksa.val/jwt/provide-all.token
# token=../../kuksa.val/jwt/provide-all.token
# For KUKSA.val Server the default behavior is to use the token provided as part of kuksa-client
# So you only need to specify a different token if you want to use a different token
# Possibly like below
Expand Down
13 changes: 13 additions & 0 deletions dbc2val/dbcfeeder.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,19 @@ def main(argv):
if "tls" in config["general"]:
client_wrapper.set_tls(config["general"].getboolean("tls"))

if "root_ca_path" in config["general"]:
path = config['general']['root_ca_path']
log.info(f"Given root CA path: {path}")
client_wrapper.set_root_ca_path(path)
elif client_wrapper.get_tls():
# We do not want to rely on kuksa-client default
log.error("Root CA must be given when using TLS")

if "tls_server_name" in config["general"]:
name = config['general']['tls_server_name']
log.info(f"Given TLS server name: {name}")
client_wrapper.set_tls_server_name(name)

if "token" in config["general"]:
log.info(f"Given token information: {config['general']['token']}")
client_wrapper.set_token_path(config["general"]["token"])
Expand Down
16 changes: 16 additions & 0 deletions dbc2val/dbcfeederlib/clientwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def __init__(self, ip: str, port: int, token_path: str, tls: bool = True):
self._token_path = token_path
self._tls = tls
self._registered = False
self._root_ca_path = None
self._tls_server_name = None

def set_ip(self, ip: str):
""" Set IP address to use """
Expand All @@ -52,6 +54,20 @@ def set_tls(self, tls: bool):
"""
self._tls = tls

def get_tls(self) -> bool:
"""
Return TLS setting
"""
return self._tls

def set_root_ca_path(self, path: str):
""" Set Path for Root CA (CA.pem) """
self._root_ca_path = path

def set_tls_server_name(self, name: str):
""" Set Path for Root CA (CA.pem) """
self._tls_server_name = name

def set_token_path(self, token_path: str):
self._token_path = token_path

Expand Down
12 changes: 11 additions & 1 deletion dbc2val/dbcfeederlib/databrokerclientwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import contextlib

import grpc.aio
from pathlib import Path

import kuksa_client.grpc
from kuksa_client.grpc import Datapoint
Expand Down Expand Up @@ -90,10 +91,19 @@ def start(self):
# The alternative approach would be to provide token in constructor
# with/without ensure_startup_connection and not actively call "authorize"
# The only practical difference is how progress and errors (if any) are reported!

# If there is a path VSSClient will request a secure connection
if self._tls and self._root_ca_path:
root_path = Path(self._root_ca_path)
else:
root_path = None

self._grpc_client = self._exit_stack.enter_context(kuksa_client.grpc.VSSClient(
host=self._ip,
port=self._port,
ensure_startup_connection=False
ensure_startup_connection=False,
root_certificates=root_path,
tls_server_name=self._tls_server_name
))
self._grpc_client.authorize(token=self._token, **self._rpc_kwargs)
self._grpc_client.channel.subscribe(
Expand Down
5 changes: 4 additions & 1 deletion dbc2val/dbcfeederlib/serverclientwrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ def start(self):
if self._token_path != "":
self._client_config["token"] = self._token_path

# TODO add data for root cert if using TLS and if given
if self._root_ca_path:
self._client_config['cacertificate'] = self._root_ca_path
if self._tls_server_name:
self._client_config['tls_server_name'] = self._tls_server_name

self._kuksa = KuksaClientThread(self._client_config)
self._kuksa.start()
Expand Down
36 changes: 17 additions & 19 deletions dbc2val/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#
# This file is autogenerated by pip-compile with Python 3.8
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# pip-compile requirements.in
# pip-compile --pre requirements.in
#
argparse-addons==0.12.0
# via cantools
Expand All @@ -22,47 +22,45 @@ crccheck==1.3.0
# via cantools
decorator==5.1.1
# via jsonpath-ng
diskcache==5.5.1
diskcache==5.6.1
# via cantools
exceptiongroup==1.1.1
# via pytest
grpcio==1.53.0
# via
# grpcio-tools
# kuksa-client
grpcio-tools==1.53.0
grpcio==1.56.0rc2
# via grpcio-tools
grpcio-tools==1.56.0rc2
# via kuksa-client
iniconfig==2.0.0
# via pytest
jsonpath-ng==1.5.3
# via kuksa-client
kuksa-client==0.4.0a1
kuksa-client==0.4.0a3
# via -r requirements.in
msgpack==1.0.5
# via python-can
numpy==1.24.2
numpy==1.25.0
# via can-j1939
packaging==23.1
# via
# pytest
# python-can
pluggy==1.0.0
pluggy==1.2.0
# via pytest
ply==3.11
# via jsonpath-ng
protobuf==4.22.3
protobuf==4.23.3
# via grpcio-tools
py-expression-eval==0.3.14
# via -r requirements.in
pygments==2.15.0
pygments==2.15.1
# via kuksa-client
pyperclip==1.8.2
# via cmd2
pyserial==3.5
# via -r requirements.in
pytest==7.3.1
pytest==7.3.2
# via can-j1939
python-can==4.1.0
python-can==4.2.2
# via
# -r requirements.in
# can-j1939
Expand All @@ -75,17 +73,17 @@ textparser==0.24.0
# via cantools
tomli==2.0.1
# via pytest
types-protobuf==4.22.0.2
types-protobuf==4.23.0.1
# via -r requirements.in
types-pyyaml==6.0.12.9
types-pyyaml==6.0.12.10
# via -r requirements.in
typing-extensions==4.5.0
typing-extensions==4.7.0rc1
# via
# cantools
# python-can
wcwidth==0.2.6
# via cmd2
websockets==11.0.1
websockets==11.0.3
# via kuksa-client
wrapt==1.15.0
# via python-can
Expand Down

0 comments on commit e7147b3

Please sign in to comment.