diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/rvi | 71 | ||||
-rw-r--r-- | scripts/rvi.service | 19 | ||||
-rw-r--r-- | scripts/rvi.service.tizen | 19 | ||||
-rw-r--r-- | scripts/rvi.service.yocto | 18 | ||||
-rwxr-xr-x | scripts/rvi.sh | 192 | ||||
-rwxr-xr-x | scripts/rvi_create_certificate_key.sh | 254 | ||||
-rwxr-xr-x | scripts/rvi_create_device_key.sh | 155 | ||||
-rw-r--r-- | scripts/rvi_ctl.template | 141 | ||||
-rwxr-xr-x | scripts/rvi_devrun | 99 | ||||
-rwxr-xr-x | scripts/rvi_install | 322 | ||||
-rwxr-xr-x | scripts/rvi_install.sh | 88 | ||||
-rwxr-xr-x | scripts/rvi_node.sh | 84 |
12 files changed, 562 insertions, 900 deletions
diff --git a/scripts/rvi b/scripts/rvi deleted file mode 100644 index 6683c52..0000000 --- a/scripts/rvi +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2014, Jaguar Land Rover -# -# This program is licensed under the terms and conditions of the -# Mozilla Public License, version 2.0. The full text of the -# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ -# - -# -# Setup a correct configuration and launch an RVI release node. -# If a UUID file has not been created, it will be done at this time. -# - -SELF_DIR=$(dirname $(readlink -f "$0")) -CONFIG_DIR=/etc/opt/rvi -BIN_DIR=/opt/rvi - -usage() { - echo "Usage: $0 -c config_file" - echo " -c config_file Specify the configuration " - echo "Configuration data is read from the configuration file." - exit 1 -} - -while getopts "c:" o; do - case "${o}" in - c) - CONFIG_FILE=${OPTARG} - ;; - *) - usage - ;; - esac -done - -if [ -z "${CONFIG_FILE}" ] ; then - echo "Missing -c flag" - usage -fi - -# Check if we have a uuid file. -if [ ! -f ${CONFIG_DIR}/device_id ] -then - echo "Creating device ID in ${CONFIG_DIR}/device_id" - cat /proc/sys/kernel/random/uuid > ${CONFIG_DIR}/device_id -fi - -# -# Generate a config file that will end up as -# /tmp/rvi/sys.config -# -( - cd /tmp/ - rm -rf rvi - export ERL_LIBS=${BIN_DIR}/setup:${BIN_DIR}/lib/ - ${BIN_DIR}/setup_gen rvi $CONFIG_FILE rvi -) - -# Did we succeed with config generation? -if [ "$?" != "0" ] -then - # Nope - exit "$?" -fi - -# Copy created config file to /etc/opt/rvi/sys.config, -# which is symlinked to by /opt/rvi/sys.config -cp /tmp/rvi/sys.config /etc/opt/rvi/sys.config - -exec /opt/rvi/bin/rvi start diff --git a/scripts/rvi.service b/scripts/rvi.service deleted file mode 100644 index 1220eb9..0000000 --- a/scripts/rvi.service +++ /dev/null @@ -1,19 +0,0 @@ -# systemd(8) setup usde by Tizen and others. -[Unit] -Description=Remote Vehicle Interaction Service -Wants=network-online.target - -[Service] -Environment="HOME=/opt/rvi-0.4.0" -Type=forking -StandardOutput=journal -StandardError=journal -ExecStartPre=/usr/bin/chsmack --access User /home/app/content/Documents/vin -ExecStartPre=/opt/rvi-0.4.0/erts-5.10.4/bin/epmd -daemon -ExecStart=/bin/sh /opt/rvi-0.4.0/bin/rvi start -ExecStop=/bin/sh /opt/rvi-0.4.0/bin/rvi stop -ExecStopPost=/opt/rvi-0.4.0/erts-5.10.4/bin/epmd -kill -GuessMainPID=yes - -[Install] -WantedBy=graphical.target multi-user.target diff --git a/scripts/rvi.service.tizen b/scripts/rvi.service.tizen deleted file mode 100644 index 1220eb9..0000000 --- a/scripts/rvi.service.tizen +++ /dev/null @@ -1,19 +0,0 @@ -# systemd(8) setup usde by Tizen and others. -[Unit] -Description=Remote Vehicle Interaction Service -Wants=network-online.target - -[Service] -Environment="HOME=/opt/rvi-0.4.0" -Type=forking -StandardOutput=journal -StandardError=journal -ExecStartPre=/usr/bin/chsmack --access User /home/app/content/Documents/vin -ExecStartPre=/opt/rvi-0.4.0/erts-5.10.4/bin/epmd -daemon -ExecStart=/bin/sh /opt/rvi-0.4.0/bin/rvi start -ExecStop=/bin/sh /opt/rvi-0.4.0/bin/rvi stop -ExecStopPost=/opt/rvi-0.4.0/erts-5.10.4/bin/epmd -kill -GuessMainPID=yes - -[Install] -WantedBy=graphical.target multi-user.target diff --git a/scripts/rvi.service.yocto b/scripts/rvi.service.yocto deleted file mode 100644 index 1ddae5d..0000000 --- a/scripts/rvi.service.yocto +++ /dev/null @@ -1,18 +0,0 @@ -# systemd(8) setup usde by Tizen and others. -[Unit] -Description=Remote Vehicle Interaction Service -Wants=network-online.target - -[Service] -Environment="HOME=/opt/rvi" -Type=forking -StandardOutput=journal -StandardError=journal -ExecStartPre=epmd -daemon -ExecStart=/bin/sh /opt/rvi/rvi.sh -d /etc/opt/rvi -c /etc/opt/rvi/rvi_yocto.config start -ExecStop=/bin/sh /opt/rvi/rvi stop -ExecStopPost=epmd -kill -GuessMainPID=yes - -[Install] -# WantedBy=graphical.target multi-user.target diff --git a/scripts/rvi.sh b/scripts/rvi.sh deleted file mode 100755 index 7b69d8d..0000000 --- a/scripts/rvi.sh +++ /dev/null @@ -1,192 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2014, Jaguar Land Rover -# -# Mozilla Public License, version 2.0. The full text of the -# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ -# -# -# Setup a correct configuration and launch an RVI release node. -# If a UUID file has not been created, it will be done at this time. -# Init.d script to start and stop an RVI system installed -# through an RPM. -# - -SELF_DIR=$(dirname $(readlink -f "$0")) - -ERL=${ERL:=erl} - -usage() { - echo "Usage: $0 -d config_dir -c config_file -l log_dir \\" - echo " start|stop|console|attach|ping" - echo - echo " -c config_file Configuration file to launch rvi node with. " - echo " If omitted the rvi_sample.config in the configuration " - echo " directory will be used." - echo - echo " -s short_name Erlang node short name. Defaults to 'rvi_core'" - echo - echo " -C cookie Erlang node cookie to use. Defaults to 'rvi_cookue'" - echo - echo " -d config_dir Directory to put generated uuid 'device_id' file and" - echo " processed config files." - echo " Defauts to the '/etc/opt/rvi'." - echo - echo " -l log_dir The directory to store log files in." - echo " Defaults to '/tmp/rvi/[config]/log' where [config]" - echo " is the base name of the configuration file." - echo - echo " console [defaut] Start an rvi in foreground mode." - echo - echo " start Start an rvi node with the given configuration file." - echo - echo " stop Stop an rvi node previously started with 'start'." - echo - echo " attach Attach to an rvi node previously started with 'start'." - echo - echo " ping Ping to check if an rvi node is up. Returns 0 if up." - exit 1 -} - -CONFIG_FILE="" - -SNAME=rvi_core -COOKIE=rvi_cookie -unset CONFIG_DIR -unset LOG_DIR -while getopts "c:d:l:s:C:" o; do - case "${o}" in - s) - SNAME=${OPTARG} - ;; - c) - CONFIG_FILE=${OPTARG} - ;; - C) - COOKIE=${OPTARG} - ;; - d) - CONFIG_DIR=${OPTARG} - ;; - l) - LOG_DIR=${OPTARG} - ;; - *) - usage - ;; - esac -done - -CONFIG_DIR=${CONFIG_DIR:=/etc/opt/rvi} - -shift $((${OPTIND}-1)) - -if [ "${#}" = "0" ] -then - CMD="console" -else - CMD=$1 -fi - -if [ "${CMD}" != "start" -a "${CMD}" != "attach" -a "${CMD}" != "stop" -a "${CMD}" != "console" -a "${CMD}" != "ping" ] -then - usage -fi - -export ERL_LIBS=${SELF_DIR}/rvi_core:${SELF_DIR}/rvi_core/deps:${SELF_DIR}/rvi_core/components - -# Convert config dir to abs path -if [ $(echo ${CONFIG_DIR} | cut -c 1,1) != "/" ] -then - CONFIG_DIR=${PWD}/${CONFIG_DIR} -fi - -# Check that we have a config dir -if [ ! -d ${CONFIG_DIR} ] -then - install -d --mode=0755 ${CONFIG_DIR} -fi - -# Check if we have a uuid file. -if [ ! -f ${CONFIG_DIR}/device_id ] -then - echo "Creating device ID in ${CONFIG_DIR}/device_id" - cat /proc/sys/kernel/random/uuid > ${CONFIG_DIR}/device_id -fi - -# -# See if we need to process a config file -# -if [ ${CMD} = "start" -o ${CMD} = "console" ] -then - # Default to rvi.config - CONFIG_FILE=${CONFIG_FILE:=${CONFIG_DIR}/rvi_sample.config} - # - # Check if we need to prepend current dir - # to relative config file path - # - if [ $(echo ${CONFIG_FILE} | cut -c 1,1) != "/" ] - then - CONFIG_FILE=${PWD}/${CONFIG_FILE} - fi - - # Check that config file can be read. - if [ ! -r "${CONFIG_FILE}" ] - then - echo "${CONFIG_FILE} cannot be opened for reading." - usage - fi - # - # Generate a config file that will end up as - # /tmp/rvi/sys.config - # - ( - cd ${CONFIG_DIR} - ${SELF_DIR}/scripts/setup_gen rvi ${CONFIG_FILE} rvi - ) - - # Did we succeed with config generation? - if [ "$?" != "0" ] - then - # Nope - echo "Failed to process configuration file." - exit "$?" - fi -fi - -TMP_DIR=/tmp/rvi/$(basename ${CONFIG_FILE} .config) -LOG_DIR=${LOG_DIR:=${TMP_DIR}/rvi/log} - -if [ $(echo ${LOG_DIR} | cut -c 1,1) != "/" ] -then - LOG_DIR=${PWD}/${LOG_DIR} -fi - -LAUNCH="${ERL} +A 128 -boot ${CONFIG_DIR}/rvi/start -sname ${SNAME} -config ${CONFIG_DIR}/rvi/sys -setcookie ${COOKIE}" - -case "${CMD}" in - start) - install -d --mode 0755 ${TMP_DIR} - install -d --mode 0755 ${LOG_DIR} - cd ${SELF_DIR} - exec run_erl -daemon ${TMP_DIR}/ ${LOG_DIR} "exec ${LAUNCH}" - ;; - - console) - cd ${SELF_DIR} - exec ${LAUNCH} - ;; - - stop) - exec ${SELF_DIR}/scripts/nodetool -sname ${SNAME} -setcookie ${COOKIE} stop - ;; - - ping) - exec ${SELF_DIR}/scripts/nodetool -sname ${SNAME} -setcookie ${COOKIE} ping - ;; - - attach) - exec to_erl ${TMP_DIR} - ;; - -esac diff --git a/scripts/rvi_create_certificate_key.sh b/scripts/rvi_create_certificate_key.sh deleted file mode 100755 index 6e09fdc..0000000 --- a/scripts/rvi_create_certificate_key.sh +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/python - -# -# Copyright (C) 2015, Jaguar Land Rover -# -# This program is licensed under the terms and conditions of the -# Mozilla Public License, version 2.0. T full text of the -# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ -# -# Create a certificate giving the sender the right to invoke and -# - -import getopt -import sys -from Crypto.PublicKey import RSA - -# apt-get install python-dev -# apt-get install libffi-dev -# pip install cryptography -# pip install PyJWT - -import jwt -import time -import json -import base64 -import struct - -def long2intarr(long_int): - _bytes = [] - while long_int: - long_int, r = divmod(long_int, 256) - _bytes.insert(0, r) - return _bytes - -# copied from https://github.com/rohe/pyjwkest -def long_to_base64(n): - bys = long2intarr(n) - data = struct.pack('%sB' % len(bys), *bys) - if not len(data): - data = '\x00' - s = base64.urlsafe_b64encode(data).rstrip(b'=') - return s - -def usage(): - print "Usage:", sys.argv[0], "--id=<id> --invoke='<services>' -register='<services>' \\" - print " --root_key=<file> --start='<date/time>' --stop='<date/time>' \\" - print " --out=<file>" - print - print " --id=<id> System-wide unique certificate ID" - print - print " --invoke='<services>' Right to invoke service. Space separate multiple services." - print - print " --register='<services>' Right to register service. Space separate multiple services." - print " At least one --invoke or --register must be given." - print - print " --root_key=<file> Private root key to sign certificate with" - print " Mandatory" - print - print " --device_key=<file> Public device key to include in certificate" - print " Mandatory" - print - print " --start='<YYYY-MM-DD HH:MM:SS>' Date and time when certificate is activated." - print " Default: current time." - print - print " --stop='<YYYY-MM-DD HH:MM:SS>' Date and time when certificate is deactivated." - print " Default: 365 days from current time" - print - print " --jwt_out=<file> File name to store JWT-encoded certificate in." - print " Default: stdout" - print - print " --cert_out=<file> File name to unencoded JSON certificate in." - print " Default: Do not store certificate" - print - print " --issuer=issuer Name of the issuer. Default: jaguarlandrover.com" - print - print "Root key file is generated by rvi_create_root_key.sh" - print - print "Device key is the '_pub.pem'-suffixed file created by rvi_create_device_key.py" - print - print "Certificate file specified by out should be placed in 'priv/certs'" - print - print - print "Example:" - print "./rvi_create_certificate.py --id=317624d8-2ccf-11e5-993c-7f3b5182c649 \\" - print " --device_key=device_key_pub.pem \\" - print " --start='2015-12-01 00:00:00' \\" - print " --stop='2015-12-31 23:59:59' \\" - print " --root_key=root_key_priv.pem \\" - print " --register='jlr.com/vin/abc/unlock jlr.com/vin/abc/lock' \\" - print " --invoke='jlr.com/backend/report jlr.com/backend/set_state' \\" - print " --jwt_out=lock_cert.jwt \\" - print " --cert_out=lock_cert.json" - sys.exit(255) - -try: - opts, args = getopt.getopt(sys.argv[1:], "", [ 'issuer=', 'invoke=', 'register=', - 'root_key=', 'start=', - 'stop=', 'cert_out=', 'id=', - 'jwt_out=', 'device_key=']) -except getopt.GetoptError as e: - print - print e - print - usage() - -start=int(time.time()) -stop=int(time.time()) + 86400 * 365 - -issuer='jaguarlandrover.com' -invoke=None -register=None -root_key=None -device_key=None -jwt_out_file=None -cert_out_file=None -id_string=None -for o, a in opts: - if o == "--start": - try: - start = int(time.mktime(time.strptime(a, "%Y-%m-%d %H:%M:%S"))) - except: - print - print "Incorrect start time: {}".format(a) - print - usage() - - elif o == '--root_key': - try: - root_key_fname = a - root_key_file = open(root_key_fname, "r") - root_key = RSA.importKey(root_key_file.read()) - root_key_file.close() - except IOError as e: - print "Coould read root cert from {0}: {1}".format(a, e.strerror) - sys.exit(255) - - elif o == '--device_key': - try: - device_key_file = open(a, "r") - device_key = RSA.importKey(device_key_file.read()) - device_key_file.close() - except IOError as e: - print "Coould read root cert from {0}: {1}".format(a, e.strerror) - sys.exit(255) - - elif o == "--stop": - try: - stop = int(time.mktime(time.strptime(a, "%Y-%m-%d %H:%M:%S"))) - except: - print - print "Incorrect stop time: {}".format(a) - print - usage() - - elif o == '--invoke': - invoke=a.split(' ') - - elif o == '--register': - register=a.split(' ') - - elif o == '--id': - id_string=a - - elif o == '--issuer': - issuer=a - - elif o == '--jwt_out': - try: - jwt_out_file = open(a, "w") - except IOError as e: - print "Coould write to JWT file {0}: {1}".format(a, e.strerror) - sys.exit(255) - - elif o == '--cert_out': - try: - cert_out_file = open(a, "w") - except IOError as e: - print "Coould write to certificate file {0}: {1}".format(a, e.strerror) - sys.exit(255) - - else: - print - print "Unknown command line argument: {}".format(o) - print - usage() - -if jwt_out_file == None: - jwt_out_file = sys.stdout - -if not invoke and not register: - print - print "At least one --invoke or --register service must be specified." - print - usage() - -if not root_key: - print - print "No --root_key=<root_key_file.pem> specified" - print - usage() - -if not device_key: - print - print "No --device_key=<device_public_key_file.pem> specified" - print - usage() - -if not id_string: - print - print "No --id=<id_string> specified" - print - usage() - - -# Create a JSON Web Key based off our public device key PEM file - - -cert = { - 'iss': issuer, - 'id': id_string, - 'sources': register, - 'destinations': invoke, - 'create_timestamp': int(time.time()), - 'keys': [{ - "kty": "RSA", - "alg": "RS256", - "use": "sig", - "e": long_to_base64(device_key.e), - "n": long_to_base64(device_key.n) - }], - 'validity': { - 'start': start, - 'stop': stop - } -} - - -encoded = jwt.encode(cert, root_key.exportKey("PEM"), algorithm='RS256') - -# Validate -try: - jwt.decode(encoded, root_key.publickey().exportKey("PEM")) -except: - print "FAILED: Could not verify signed JSON Web Token using public part of" - print " root key {}".format(root_key_fname) - - -jwt_out_file.write(encoded) -jwt_out_file.close() - -if cert_out_file: - cert_out_file.write(json.dumps(cert, sort_keys=True, indent=4, separators=(',', ': ')) + '\n') - cert_out_file.close() - diff --git a/scripts/rvi_create_device_key.sh b/scripts/rvi_create_device_key.sh deleted file mode 100755 index 060ea8b..0000000 --- a/scripts/rvi_create_device_key.sh +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/python - -# -# Copyright (C) 2015, Jaguar Land Rover -# -# This program is licensed under the terms and conditions of the -# Mozilla Public License, version 2.0. T full text of the -# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ -# -# -# 1. Generate a device key through openssl. -# 2. Sign the public key using the provided private root key. -# 3. Create a JWT version of the signed device key. -# - -import getopt -import sys -from Crypto.PublicKey import RSA -import json -import base64 -import os - -# apt-get install python-dev -# apt-get install libffi-dev -# pip install cryptography -# pip install PyJWT - -import jwt -import struct - -def long2intarr(long_int): - _bytes = [] - while long_int: - long_int, r = divmod(long_int, 256) - _bytes.insert(0, r) - return _bytes - -# copied from https://github.com/rohe/pyjwkest -def long_to_base64(n): - bys = long2intarr(n) - data = struct.pack('%sB' % len(bys), *bys) - if not len(data): - data = '\x00' - s = base64.urlsafe_b64encode(data).rstrip(b'=') - return s - -def usage(): - print "Usage:", sys.argv[0], "-p <priv_root_key> -o <prefix> -b <bits>" - print " -p <priv_root_key> Private root key file to sign public device key with." - print " -o <prefix> File name prefix for generated device keys." - print " -b <bits> Device key length. Default 2048." - sys.exit(255) - -opts, args= getopt.getopt(sys.argv[1:], "p:o:b:") - -priv_root_key_fname="" -fname_prefix="" -key_lenth=2048 -for o, a in opts: - if o == "-p": - priv_root_key_fname = a - elif o == "-b": - key_length = int(a) - elif o == "-o": - fname_prefix = a - else: - usage() - -if priv_root_key_fname == "" or fname_prefix == "": - usage() - - -# -# Generate the device RSA key pair -# -new_key = RSA.generate(bits=key_length) - - -# -# Create private key file, which also contains the public key. -# -priv_key_fname = "{}_priv.pem".format(fname_prefix) -priv_key_file = open(priv_key_fname, 'w') -priv_key = new_key.exportKey("PEM") -priv_key_file.write(priv_key) -priv_key_file.close() - - -# Read the root private key -priv_root_key_file = open(priv_root_key_fname, 'r') -priv_root_key = RSA.importKey(priv_root_key_file.read()) -priv_root_key_file.close() - - -# -# Extract the device public key that we are to sign with the private root key. -# Dump it in a file to be used by rvi_create_certificate.py -# -pub_key_fname = "{}_pub.pem".format(fname_prefix) -pub_key_file = open(pub_key_fname, 'w') -pub_key = new_key.publickey() -pub_key_pem = pub_key.exportKey("PEM") -pub_key_file.write(pub_key_pem) -pub_key_file.close() - -print "pub_key.e = ", pub_key.e -print "pub_key.n = ", pub_key.n - -key_obj = { - 'keys': [{ - "kty": "RSA", - "alg": "RS256", - "use": "sig", - "e": long_to_base64(pub_key.e), - "n": long_to_base64(pub_key.n) - }], -} - -# Generate a JWT signature based on the pub key and the private root key -signature = jwt.encode(key_obj, priv_root_key.exportKey('PEM'), algorithm='RS256') - - -# Verify that we can use the public root key to verify the key. -pub_root_key = priv_root_key.publickey().exportKey('PEM') - -try: - jwt.decode(signature, pub_root_key) -except: - print "FAILED VERIFICATION!" - print "The public portion of the generated device key, signed by the provided private root key," - print "could not be verified using the public root key." - os.remove(priv_key_fname) - sys.exit(0) - -# -# Create signed public JWT file -# -pub_sign_key_fname = "{}_pub_sign.jwt".format(fname_prefix) - -pub_sign_key_file = open(pub_sign_key_fname, 'w') -pub_sign_key_file.write(signature) -pub_sign_key_file.close() - -print "Device private/public key pair stored in: ", priv_key_fname -print "Device public-only key stored in: ", pub_key_fname -print "Device JWT-formatted public key signed by private " -print " root key, stored in: ", pub_sign_key_fname -print "Root key used to sign the device public key read from: ", priv_root_key_fname -print -print "Set rvi node's device_key_pair config parameter to point to: ", priv_root_key_fname -print "Set rvi node's authorize_jwt config parameter to point to: ", pub_sign_key_fname -print -print "use ./rvi_create_certificate.py ... --device_key={} to include".format(pub_key_fname) -print "device public key in a certificate." - diff --git a/scripts/rvi_ctl.template b/scripts/rvi_ctl.template new file mode 100644 index 0000000..dc8dd9e --- /dev/null +++ b/scripts/rvi_ctl.template @@ -0,0 +1,141 @@ +#!/bin/sh +# + +# +# Mozilla Public License, version 2.0. The full text of the +# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ +# +# +# Setup a correct configuration and launch an RVI release node. +# If a UUID file has not been created, it will be done at this time. +# Init.d script to start and stop an RVI system installed +# through an RPM. +# + +# Assignment of default values done by rvi_install.sh +echo ${RVI_BINDIR:="__RVI_BINDIR__"} > /dev/null +echo ${RVI_LOGDIR:="__RVI_LOGDIR__"} > /dev/null +echo ${ERL:=erl} > /dev/null + + + +usage() { + echo "Usage: $0 -d config_dir [-c config_file] -l log_dir \\" + echo " start|stop|console|attach|ping" + echo + echo " -c config_file Configuration file to launch rvi node with." + echo " Mandatory for start and console. Ignored for" + echo " all other commands." + echo + echo " start Start an rvi node with the given configuration file." + echo + echo " stop Stop an rvi node previously started with 'start'." + echo + echo " console Start an rvi in foreground mode." + echo + echo " attach Attach to an rvi node previously started with 'start'." + echo + echo "Environennt variables. Default value in paranthesis::" + echo "\$RVI_BINDIR ($RVI_BINDIR) Location of binary files." + echo "\$RVI_LOGDIR ($RVI_LOGDIR) Location of log files." + exit 1 +} + +CONFIG_FILE="" +SNAME=rvi +COOKIE=rvi_cookie +while getopts "c:" o; do + case "${o}" in + c) + CONFIG_FILE=${OPTARG} + ;; + *) + usage + ;; + esac +done + +shift $((${OPTIND}-1)) +CMD=$1 + + +if [ "${CMD}" != "start" -a "${CMD}" != "stop" -a "${CMD}" != "console" -a "${CMD}" != "ping" ] +then + usage +fi + +RUNDIR=${RVI_RUNDIR:-"/tmp/rvi_${$}"} + +export ERL_LIBS=${RVI_BINDIR}:${RVI_BINDIR}/deps:${RVI_BINDIR}/components + +# +# See if we need to process a config file +# +if [ ${CMD} = "start" -o ${CMD} = "console" ] +then + if [ -z "${CONFIG_FILE}" ] + then + echo "Missing -c <config_file> argument." + usage + fi + # + # Check if we need to prepend current dir + # to relative config file path + # + if [ $(echo ${CONFIG_FILE} | cut -c 1,1) != "/" ] + then + CONFIG_FILE=${PWD}/${CONFIG_FILE} + fi + + # Check that config file can be read. + if [ ! -r "${CONFIG_FILE}" ] + then + echo "${CONFIG_FILE} cannot be opened for reading." + usage + fi + # + # Generate a config file that will end up as + # /tmp/rvi/[cfg]/sys.config + # + ( + rm -rf ${RUNDIR} + install -d --mode=0755 ${RUNDIR} + cd ${RUNDIR} + ${RVI_BINDIR}/setup_gen rvi ${CONFIG_FILE} rvi + ) + + # Did we succeed with config generation? + if [ "$?" != "0" ] + then + # Nope + echo "Failed to process configuration file." + exit "$?" + fi +fi + +LAUNCH="${ERL} -boot ${RUNDIR}/rvi/start -sname ${SNAME} -config ${RUNDIR}/rvi/sys -setcookie ${COOKIE}" + +case "${CMD}" in + start) + install -D -d --mode 0755 ${RVI_LOGDIR} + exec run_erl -daemon ${RUNDIR}/ ${RVI_LOGDIR} "exec ${LAUNCH}" + ;; + + console) + exec ${LAUNCH} + ;; + + stop) + exec ${RVI_BINDIR}/nodetool -sname ${SNAME} -setcookie ${COOKIE} stop + ;; + + ping) + exec ${RBI_BINDIR}/nodetool -sname ${SNAME} -setcookie ${COOKIE} ping + ;; + + attach) + exec to_erl ${RUNDIR} + ;; + +esac + diff --git a/scripts/rvi_devrun b/scripts/rvi_devrun new file mode 100755 index 0000000..901b002 --- /dev/null +++ b/scripts/rvi_devrun @@ -0,0 +1,99 @@ +#!/bin/sh +# +# Copyright (C) 2014, Jaguar Land Rover +# +# This program is licensed under the terms and conditions of the +# Mozilla Public License, version 2.0. The full text of the +# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ +# + +# +# Launch an RVI node using the build directories +# For now this is a simple wrapper around the installer + +SELF_DIR=$(dirname $(readlink -f "$0")) +PRIV_DIR=$(dirname ${SELF_DIR})/priv +TARGET_DIR="" +ROOT_CERT="${PRIV_DIR}/certificates/insecure_root_cert.crt" +DEVICE_CERT="${PRIV_DIR}/certificates/insecure_device_cert.crt" +DEVICE_KEY="${PRIV_DIR}/keys/insecure_device_key.pem" +DEVICE_CRED="${PRIV_DIR}/credentials/insecure_credential.jwt" + +usage() { + cat <<EOF +Usage: +$0 [-r root_cert] [-d device_cert] [-c credentials] config_file + +Run a developer version of RVI + +-r root_cert - The certificate to validate received X509 device + certificates and credentials. + Default ${ROOT_CERT} + +-k device_key - The PEM file containing the device key pair used + to sign traff + Default ${DEVICE_KEY} + +-d device_cert - Certificate to use when authenticating self toward + remote nodes. + Default ${DEVICE_CERT} + +-c credentials - Credentials to present to remote nodes. Can be specified + multiple times + Default ${DEVICE_CRED} + +EOF + exit 1 +} + +while getopts "r:d:c:k:" o; do + case "${o}" in + r) + ROOT_CERT=${OPTARG} + ;; + + d) + DEVICE_CERT=${OPTARG} + ;; + + c) + DEVICE_CRED=${OPTARG} + ;; + + k) + DEVICE_KEY=${OPTARG} + ;; + *) + usage + ;; + esac +done + +shift $((${OPTIND}-1)) + +# Check that we have a target dir + +if [ "${#}" != "1" ] +then + echo "ERROR: Wrong number of arguments. Only specify config file" + usage +fi + +CONFIG_FILE=${1} + +./scripts/rvi_install \ + -k ${DEVICE_KEY} \ + -r ${ROOT_CERT} \ + -d ${DEVICE_CERT} \ + -c ${DEVICE_CRED} \ + /tmp/rvi_dev/rvi_core > /tmp/dev_install.log + +if [ "${?}" != "0" ] +then + echo "ERROR: Devevelop install failed:" + cat /tmp/dev_install.log + exit 255 +fi + +/tmp/rvi_dev/rvi_core/rvi_ctl -c ${CONFIG_FILE} console + diff --git a/scripts/rvi_install b/scripts/rvi_install new file mode 100755 index 0000000..ac128e5 --- /dev/null +++ b/scripts/rvi_install @@ -0,0 +1,322 @@ +#!/bin/sh +# +# Copyright (C) 2014, Jaguar Land Rover +# +# This program is licensed under the terms and conditions of the +# Mozilla Public License, version 2.0. The full text of the +# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ +# + +# +# Setup an RVI release +# +# + +SELF_DIR=$(dirname $(readlink -f "$0")) +SETUP_GEN=$SELF_DIR/setup_gen # Ulf's kitchen sink setup utility + +usage() { + cat <<EOF +Usage: +$0 -r root_cert -d device_cert -c credentials \\ + [-l log_dir ] [-s prefix_strip] target_dir + +Install a built RVI system into a target directory + +NOTE: The last component of 'taget_dir' must be named 'rvi_core' + Example: /opt/rvi_core + +-l log_dir - Log directory. Default: ${target_dir}/log. + +-s prefix_strip - See below. Default: nil. + +-r root_cert - The certificate to validate received X509 device + certificates and credentials. + +-k device_key - The PEM file containing the device key pair used + to sign traff + +-d device_cert - Certificate to use when authenticating self toward + remote nodes. + +-c credentials - Credentials to present to remote nodes. Can be specified + multiple times + +The created node can be started with: 'target'/rvi_ctl +The RVI installation will rely on a separate erlang install +to run. + +PREFIX STRIPPING + If '-s prefix_strip' is provided, that part of the directories above + will be stripped of the given prefix in all internlal references. + This is useful in debian and other build systems. + + If, for example, 'target_dir' is './build/root/usr/bin', and + 'prefix_strip' is './build/root', all internal paths will + reference '/usr/bin'. + +ROOT CERTIFICATE + The root certificate is used to validate remote TLS connections and + device certificates. It is normally generated once and shared across + all RVI nodes. An initial root certificate, and its corresponding + keys can be generated using the following command. + + # Create a root key pair + openssl genrsa -out root_key.pem 4096 + + # Create a self-signed root certificate using the key above. + openssl req -x509 -new -nodes -key root_key.pem \\ + -days 365 -out root_cert.crt + + The root key pair should be stored securely and not be distributed. + + Provide the generated root_cert.crt file as a '-r' argument to rvi_install. + +DEVICE KEY PAIR + The device key pair is used to sign outgoing message based traffic, and + to create a device certificate signing request (See DEVICE CERTIFICATE) + + Create the device key PEM file using the following command: + + # Create a certificate signing request + openssl req -new -key device_key.pem -out device_cert.csr + + Provide the generated device_key.pem file as a '-k' argument to rvi_install. + +DEVICE CERTIFICATE + The device certificate, signed by the root certificate, is sent over + to the remote RVI node to prove that self is an authentic node + provisioned by the owner of the root key and certificate. + + A device certificate can be created using the following commands + + # Create the device key pair. + openssl genrsa -out device_key.pem 4096 + + # Create a certificate signing request + openssl req -new -key device_key.pem -out device_cert.csr + + # Sign the signing request and create the device_cert.crt file + openssl x509 -req -days 365 -in device_cert.csr \\ + -CA root_cert.crt -CAkey root_key.pem \\ + -set_serial 01 -out device_cert.crt + + Provide the generated device_cert.crt file as a '-d' argument to rvi_install. + +CREDENTIALS + Credentials are provided as JSON Web Tokens (JWT) signed by the root + certificate. The JWT, which has the sender's device certificate + embedded into it, proves that the owner of the root key/certificate + has approved that the owner of the device certificate has the right + to send the credential-specified service calls to the remote node, + and receive the credential-specified service calls from the remote + node. + + Credentials can be created using the following command (given + credential.json as input): + + rvi_create_credential.py --cred_out="credential.json" \\ + --jwt_out='credential.jwt' \\ + --id="my_device_1234" \\ + --issuer="genivi.org" \\ + --root_key=root_key.pem \\ + --device_cert=device_cert.crt \\ + --invoke='genivi.org/' \\ + --register='genivi.org/' + + Provide the generated credential.jwt file as a '-c' argument to rvi_install. + +EXAMPLE INSTALLATION + + If you want to run an *INSECURE* installation sharing keys + certificates, and credentials across all nodes, you can run the + following command from the rvi_core root directory to use the + provided sample keys, certificates, and credentials: + + $0 -k priv/keys/insecure_device_key.pem \\ + -r priv/certificates/insecure_root_cert.crt \\ + -d priv/certificates/insecure_device_cert.crt \\ + -c priv/credentials/insecure_credential.jwt \\ + /opt/rvi_core + + + WARNING: This example installation will provide no protection + against unauthenticated nodes, unauthorized calls, or + eavesdropping. Do not use in any externally facing + environment. + +EOF + exit 1 +} + +if [ "${#}" = "0" ] +then + usage +fi + +TARGET_DIR="" +LOG_DIR="" +ROOT_CERT="" +DEVICE_CERT="" +DEVICE_KEY="" +DEVICE_CRED="" + +while getopts "r:d:c:k:s:l:" o; do + case "${o}" in + r) + ROOT_CERT=${OPTARG} + ;; + + d) + DEVICE_CERT=${OPTARG} + ;; + + c) + DEVICE_CRED="${DEVICE_CRED} ${OPTARG}" + ;; + + k) + DEVICE_KEY=${OPTARG} + ;; + + l) + LOG_DIR=${OPTARG} + ;; + + s) + PREFIX_STRIP=${OPTARG} + ;; + + *) + usage + ;; + esac +done + +shift $((${OPTIND}-1)) + +# Check that we have a target dir + +if [ "${#}" != "1" ] +then + echo "ERROR: Wrong number of arguments. Only specify target_dir" + usage +fi + +TARGET_DIR=${1} + +# Make sure that the last element of target dir is rvi_core +# This is an erlang runtime requirement. +if [ $(basename ${TARGET_DIR}) != "rvi_core" ] +then + echo "ERROR: Last component of 'target_dir' must be named rvi_core." + echo " Example: $(dirname ${TARGET_DIR})/rvi_core" + echo " Run ${0} with no arguments for usage." + exit 255 +fi + +# Check that we can read the root cert +if [ -z "${ROOT_CERT}" -o ! -r "${ROOT_CERT}" ] +then + echo "ERROR: Cannot read root certificate ${ROOT_CERT}." + echo " Run ${0} with no arguments for usage." + exit 255 +fi + +# Check that we can read the device key PEM file +if [ -z "${DEVICE_KEY}" -o ! -r ${DEVICE_KEY} ] +then + echo "ERROR: Cannot read device key ${DEVICE_KEY}." + echo " Run ${0} with no arguments for usage." + exit 255 +fi + +# Check that we can read the device cert +if [ -z "${DEVICE_CERT}" -o ! -r ${DEVICE_CERT} ] +then + echo "ERROR: Cannot read device certificate ${DEVICE_CERT}." + echo " Run ${0} with no arguments for usage." + exit 255 +fi + +# Check that we have at least one device credential +if [ -z "${DEVICE_CERT}" ] +then + echo "ERROR: No device credential specified" + echo " Run ${0} with no arguments for usage." + exit 255 +fi + +# Check that we can read each device credential +for CRED in ${DEVICE_CRED}; do + + if [ ! -r ${CRED} ] + then + echo "ERROR: Cannot read device certificate ${CRED}." + echo " Run ${0} with no arguments for usage." + exit 255 + fi +done + +# +# Use default log dir if not specified +# +if [ -z "${LOG_DIR}" ] +then + LOG_DIR=${TARGET_DIR}/log +fi + +# Wipe old target dir. +rm -rf ${TARGET_DIR} > /dev/null 2>&1 + +# Create log dirs +install -m 0755 -d ${TARGET_DIR} +install -m 0755 -d ${LOG_DIR} + +# Copy over the relevant files to the target +FILE_SET=$(find ebin components deps -name ebin -o -name priv) +tar cf - ${FILE_SET} | (cd ${TARGET_DIR} ; tar xf - ) + +# If we have a prefix strip (for build systems not using +# chroot), apply it to paths. +if [ -s "${PREFIX_STRIP}" ] +then + STRIP_TARGET_DIR=$(echo ${TARGET_DIR} | sed "s|^${PREFIX_STRIP}||") + STRIP_LOG_DIR=$(echo ${LOG_DIR} | sed "s|^${PREFIX_STRIP}||") +else + STRIP_TARGET_DIR=${TARGET_DIR} + STRIP_LOG_DIR=${LOG_DIR} +fi + +# Patch rvi_ctl.template to set its ERL_LIBS path correctly. +sed -e "s|__RVI_BINDIR__|${STRIP_TARGET_DIR}|g" \ + -e "s|__RVI_LOGDIR__|${STRIP_LOG_DIR}|g" < scripts/rvi_ctl.template > /tmp/rvi_ctl + +# Install all relevant scripts. +install -m 0755 -d ${TARGET_DIR}/priv/certificates +install -m 0755 -d ${TARGET_DIR}/priv/keys +install -m 0755 -d ${TARGET_DIR}/priv/credentials +install -m 0644 ${ROOT_CERT} ${TARGET_DIR}/priv/certificates/root_cert.crt +install -m 0644 ${DEVICE_CERT} ${TARGET_DIR}/priv/certificates/device_cert.crt +install -m 0644 ${DEVICE_KEY} ${TARGET_DIR}/priv/keys/device_key.pem +install -m 0644 ${DEVICE_CRED} ${TARGET_DIR}/priv/credentials +install -m 0755 /tmp/rvi_ctl ${TARGET_DIR} +rm /tmp/rvi_ctl +install -m 0755 scripts/setup_gen ${TARGET_DIR} +install -m 0755 rel/files/nodetool ${TARGET_DIR} +install -m 0755 python/rvi_service.py ${TARGET_DIR}/rvi_service +install -m 0755 python/rvi_call.py ${TARGET_DIR}/rvi_call +install -m 0644 python/rvilib.py ${TARGET_DIR} +install -m 0755 python/rvi_get_services.py ${TARGET_DIR}/rvi_get_services +install -m 0755 -D priv/config/rvi_common.config ${TARGET_DIR}/priv/config/rvi_common.config + +echo "RVI binary files installed under ${TARGET_DIR}" +echo "RVI will log to ${LOG_DIR}" +echo +echo "Start: ${TARGET_DIR}/rvi_ctl -c <config_file> start" +echo "Attach started RVI: ${TARGET_DIR}/rvi_ctl attach" +echo "Stop: ${TARGET_DIR}/rvi_ctl stop" +echo "Start console mode: ${TARGET_DIR}/rvi_ctl -c <config_file> console" +echo +exit 0 + diff --git a/scripts/rvi_install.sh b/scripts/rvi_install.sh deleted file mode 100755 index 7e949a1..0000000 --- a/scripts/rvi_install.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2014, Jaguar Land Rover -# -# This program is licensed under the terms and conditions of the -# Mozilla Public License, version 2.0. The full text of the -# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ -# - -# -# Setup an RVI release with a configuration file. -# -# This script will setup a directory with with the same name -# as the release name. The script uses Ulf Wiger's setup application -# (github.com/Feuerlabs/setup) to generate the release. -# -# With the -d argument, a developer release will be built with -# only -# -# Once setup, the RVI node can be started with ./rvi_node <release_na,e? -# -# Please note that the generated release will depend on the built -# -# In order to create a standalone release, use create_rvi_release.sh -# - -SELF_DIR=$(dirname $(readlink -f "$0")) -SETUP_GEN=$SELF_DIR/setup_gen # Ulf's kitchen sink setup utility - -usage() { - echo "Usage: $0 binary_dir" - echo - echo "RVI will be installed in 'target_dir'." - echo - echo "The created node can be started with: 'target_dir'/rvi.sh" - echo "RVI in 'target_dir' will rely on a native erlang to function" - exit 1 -} - - - -shift $((${OPTIND}-1)) - -if [ "${#}" != "1" ] -then - echo "Target directory not specifiied." - usage -fi - -TARGET_DIR=$1 - -# -# Prepend abs path if TARGET_DIR is relative -# -if [ $(echo ${TARGET_DIR} | cut -c 1,1) != "/" ] -then - TARGET_DIR=${PWD}/${TARGET_DIR} -fi - - -cd ${SELF_DIR}/..; - -rm -rf ${TARGET_DIR} > /dev/null 2>&1 - -install --mode=0755 -d ${TARGET_DIR}/rvi_core -install --mode=0755 -d ${TARGET_DIR}/scripts - -FILE_SET=$(find priv ebin components deps -name ebin -o -name priv) - -echo "Installing rvi at ${TARGET_DIR}." - -tar cf - ${FILE_SET} | (cd ${TARGET_DIR}/rvi_core ; tar xf - ) -install --mode=0755 scripts/rvi.sh ${TARGET_DIR} -install --mode=0755 scripts/setup_gen ${TARGET_DIR}/scripts -install --mode=0755 rel/files/nodetool ${TARGET_DIR}/scripts -install --mode=0755 scripts/rvi_create_root_key.sh ${TARGET_DIR}/scripts -install --mode=0755 scripts/rvi_create_device_key.sh ${TARGET_DIR}/scripts -install --mode=0755 scripts/rvi_create_certificate_key.sh ${TARGET_DIR}/scripts - - -echo "RVI installed under ${TARGET_DIR}" -echo "Start: ${TARGET_DIR}/rvi.sh -c <config_file> start" -echo "Attach started RVI: ${TARGET_DIR}/rvi.sh attach" -echo "Stop: ${TARGET_DIR}/rvi.sh stop" -echo "Start console mode: ${TARGET_DIR}/rvi.sh -c <config_file> console" - -exit 0 - diff --git a/scripts/rvi_node.sh b/scripts/rvi_node.sh deleted file mode 100755 index a7cd201..0000000 --- a/scripts/rvi_node.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh -# -# Copyright (C) 2014, Jaguar Land Rover -# -# This program is licensed under the terms and conditions of the -# Mozilla Public License, version 2.0. The full text of the -# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ -# - -# -# Launch an RVI node using the build direcotriuies. -# -# This script launches the erlang runtime system and executes the RVI -# code directly from its build directory. Use ./setup_rvi_node without -# the -d flag to create an installable release that can execute -# without the use of this script. -# -# This script can be executed after a setup_node.sh has been executed to -# create the necessary config files and erlang boot scripts. -# -alias realpath="python -c 'import os, sys; print os.path.realpath(sys.argv[1])'" -SELF_DIR=$(dirname $(realpath "$0")) - -usage() { - echo "Usage: $0 [-d] -n node_name" - echo " -n node_name Specify the name of the rvi node to launch" - echo " -d Daemon mode (using start_erl)" - echo "Configuration data is read from the configuration file" - echo "provided to the setup_rvi_node.sh script that created the node." - exit 1 -} - -mode=build -daemon=0 -while getopts ":n:dbrp:s:" o; do - case "${o}" in - n) - node_name=${OPTARG} - ;; - d) - daemon=1 - ;; - *) - usage - ;; - esac -done - -if [ -z "${node_name}" ] ; then - echo "Missing -n flag" - usage -fi - -# check man erl for extra arguments - -if [ "${mode}" = "build" ] -then - if [ ! -f ${node_name}/sys.config ] - then - echo "Node ${node_name} not setup. Please run: " - echo "$SELF_DIR/setup_rvi_node.sh -n ${node_name} -c <configuration_file>" - exit 2 - fi - xboot="-boot ${node_name}/start" - xname="-sname ${node_name}" - xcfg="-config ${node_name}/sys" - CMD="erl ${xboot} ${xname} ${xcfg} -setcookie rvi_core" - if [ ${daemon} = 1 ] - then - PIPE=/tmp/rvi_node/${node_name} - LOG=${node_name}/log - mkdir -p ${PIPE} - mkdir -p ${LOG} - echo "starting with run_erl" - exec run_erl -daemon ${PIPE} ${LOG} "exec ${CMD}" - else - exec ${CMD} - fi - -elif [ "${mode}" = "release" ] -then - echo "Not yet supported." - exit 0 -fi |