Skip to content

Commit 3c0b272

Browse files
marceloaqnomfalkvidd
authored andcommitted
Linux: Support keys in config file (#1093)
- Signing and encryption keys are set through the configuration file. - SoftEeprom update.
1 parent 4d90c00 commit 3c0b272

File tree

6 files changed

+230
-127
lines changed

6 files changed

+230
-127
lines changed

configure

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,20 @@ MySensors options:
113113
EOF
114114
}
115115

116+
# Colors
117+
GREEN='\033[0;32m'
118+
RED='\033[0;31m'
119+
YELLOW='\033[1;33m'
120+
LIGHT_BLUE='\033[1;34m'
121+
NO_COLOR='\033[0m'
122+
123+
OK="${GREEN}[OK]${NO_COLOR}"
124+
ERROR="${RED}[ERROR]${NO_COLOR}"
125+
FAILED="${YELLOW}[FAILED]${NO_COLOR}"
126+
SECTION="${LIGHT_BLUE}[SECTION]${NO_COLOR}"
127+
116128
function die {
117-
echo "[ERROR] $1"
129+
printf "${ERROR} $1 \n"
118130
exit $2
119131
}
120132

@@ -497,12 +509,12 @@ CC=${CC:-gcc}
497509
CXX=${CXX:-g++}
498510

499511
if [ -z "${SOC}" ]; then
500-
echo "[SECTION] Detecting target machine."
512+
printf "${SECTION} Detecting target machine.\n"
501513
info=($(detect_machine))
502514
SOC=${info[0]}
503515
TYPE=${info[1]}
504516
CPU=${info[2]}
505-
echo " [OK] machine detected: SoC=${SOC}, Type=${TYPE}, CPU=${CPU}."
517+
printf " ${OK} machine detected: SoC=${SOC}, Type=${TYPE}, CPU=${CPU}.\n"
506518
fi
507519

508520
if [ -z "${CPUFLAGS}" ]; then
@@ -512,23 +524,23 @@ fi
512524
if [[ $SOC == "BCM2835" || $SOC == "BCM2836" || $SOC == "BCM2837" ]]; then
513525
CPPFLAGS="-DLINUX_ARCH_RASPBERRYPI $CPPFLAGS"
514526
else
515-
echo "[SECTION] Checking GPIO Sysfs."
527+
printf "${SECTION} Checking GPIO Sysfs.\n"
516528
if [[ $(eval 'ls /sys/class/gpio/export 2>/dev/null') ]]; then
517-
echo " [OK] /sys/class/gpio/export found"
529+
printf " ${OK} /sys/class/gpio/export found.\n"
518530
else
519531
echo " [WARNING] /sys/class/gpio/export not found."
520532
fi
521533
fi
522534

523535
if [ -z "${SPI_DRIVER}" ]; then
524-
echo "[SECTION] Detecting SPI driver."
536+
printf "${SECTION} Detecting SPI driver.\n"
525537
if [[ $SOC == "BCM2835" || $SOC == "BCM2836" || $SOC == "BCM2837" ]]; then
526538
SPI_DRIVER=BCM
527539
elif [[ $(eval 'ls /dev/spidev* 2>/dev/null') ]]; then
528540
SPI_DRIVER=SPIDEV
529541
fi
530542
if [ -n "${SPI_DRIVER}" ]; then
531-
echo " [OK] SPI driver detected:${SPI_DRIVER}."
543+
printf " ${OK} SPI driver detected:${SPI_DRIVER}.\n"
532544
else
533545
echo " [WARNING] No supported SPI driver detected. Using SPIDEV."
534546
SPI_DRIVER=SPIDEV
@@ -551,6 +563,8 @@ if [ -n "${SPI_DRIVER}" ]; then
551563
esac
552564
fi
553565

566+
printf "${SECTION} Gateway configuration.\n"
567+
554568
if [[ ${debug} == "enable" ]]; then
555569
CPPFLAGS="-DMY_DEBUG $CPPFLAGS"
556570
fi
@@ -567,6 +581,7 @@ elif [[ ${gateway_type} == "mqtt" ]]; then
567581
else
568582
die "Invalid gateway type." 2
569583
fi
584+
printf " ${OK} Type: ${gateway_type}.\n"
570585

571586
if [[ ${transport_type} == "none" ]]; then
572587
# Transport disabled
@@ -582,20 +597,22 @@ elif [[ ${transport_type} == "rfm95" ]]; then
582597
else
583598
die "Invalid transport type." 3
584599
fi
600+
printf " ${OK} Transport: ${transport_type}.\n"
585601

586602
if [[ ${signing} == "none" ]]; then
587603
# Signing disabled
588-
:
604+
printf " ${OK} Signing: Disabled.\n"
589605
elif [[ ${signing} == "software" ]]; then
590606
CPPFLAGS="-DMY_SIGNING_SOFT $CPPFLAGS"
591607
if [[ ${signing_request_signatures} == true ]]; then
592608
CPPFLAGS="-DMY_SIGNING_REQUEST_SIGNATURES $CPPFLAGS"
593609
fi
610+
printf " ${OK} Signing: Enabled - Using key from config file.\n"
594611
elif [[ ${signing} == "password" ]]; then
595612
if [ -z "${security_password}" ]; then
596-
die "You need to set the password for signing with --my-security-password= option" 6
613+
die "You need to set the password for signing with --my-security-password option" 6
597614
fi
598-
echo "Simplified signing using password"
615+
printf " ${OK} Signing: Enabled - Simplified signing using password.\n"
599616
CPPFLAGS="-DMY_SIGNING_SIMPLE_PASSWD=\\\"${security_password}\\\" $CPPFLAGS"
600617
else
601618
die "Invalid signing type." 7
@@ -604,41 +621,44 @@ fi
604621
if [[ ${encryption} == true ]]; then
605622
# Encryption enabled on some transport
606623
if [ -z "${security_password}" ]; then
607-
echo "Encryption key from configuration"
624+
printf " ${OK} Encryption: Enabled - Using key from config file.\n"
608625
else
609-
echo "Simplified encryption using password"
626+
printf " ${OK} Encryption: Enabled - Simplified encryption using password.\n"
610627
CPPFLAGS="-DMY_ENCRYPTION_SIMPLE_PASSWD=\\\"${security_password}\\\" $CPPFLAGS"
611628
fi
629+
else
630+
printf " ${OK} Encryption: Disabled.\n"
612631
fi
613632

614633
LDFLAGS="-pthread $LDFLAGS"
615634
CPPFLAGS="$CPUFLAGS $CPPFLAGS"
616635

617-
echo "[SECTION] Detecting init system."
636+
printf "${SECTION} Detecting init system.\n"
618637
if [ "${NO_INIT}" ]; then
619-
echo " [OK] no init system chosen."
638+
printf " ${OK} No init system chosen.\n"
620639
elif [ -x /usr/bin/systemctl ] || [ -x /bin/systemctl ]; then
621640
INIT_SYSTEM=systemd
622-
echo " [OK] init system detected: systemd."
641+
printf " ${OK} Init system detected: systemd.\n"
623642
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
624643
INIT_SYSTEM=sysvinit
625-
echo " [OK] init system detected: sysvinit."
644+
printf " ${OK} Init system detected: sysvinit.\n"
626645
else
627-
echo " [FAILED] unknown init system."
646+
printf " ${FAILED} Unknown init system."
628647
fi
629648

630-
echo "[SECTION] Saving configuration."
649+
printf "${SECTION} Saving configuration.\n"
631650
echo -n "" > Makefile.inc
632651
for param in ${params}; do
633652
if [[ ${!param} ]]; then
634653
echo "${param}=${!param}" >> Makefile.inc
635654
fi
636655
done
656+
printf " ${OK} Saved.\n"
637657

638658
if [ -z "${NO_CLEAN}" ]; then
639-
echo "[SECTION] Cleaning previous builds."
659+
printf "${SECTION} Cleaning previous builds.\n"
640660
make clean >/dev/null
641661
fi
642662

643663

644-
echo "[OK] Finished."
664+
printf " ${OK} Finished.\n"

core/MySigning.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,10 @@
182182
* * To generate HMAC key @verbatim --gen-soft-hmac-key @endverbatim
183183
* * To generate %AES key @verbatim --gen-aes-key @endverbatim
184184
* * To generate a soft serial number @verbatim --gen-soft-serial @endverbatim
185-
* 2. Store keys/values to the gateway, execute @c mysgw with arguments
186-
* * To store HMAC key @verbatim --set-soft-hmac-key=<DATA> @endverbatim
187-
* * To store %AES key @verbatim --set-aes-key=<DATA> @endverbatim
188-
* * To store soft serial number @verbatim --set-soft-serial-key=<DATA> @endverbatim
185+
* 2. Update the gateway config file with the generated keys/valeus
186+
* * For HMAC key @verbatim soft_hmac_key=<DATA> @endverbatim
187+
* * For %AES key @verbatim aes_key=<DATA> @endverbatim
188+
* * For soft serial number @verbatim soft_serial_key=<DATA> @endverbatim
189189
*
190190
* You are now set and ready to use message signing in your network.
191191
* As of now, the following restrictions will be applied to your nodes:

drivers/Linux/SoftEeprom.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ int SoftEeprom::init(const char *fileName, size_t length)
6060

6161
_length = length;
6262
_values = new uint8_t[_length];
63-
for (size_t i = 0; i < _length; ++i) {
64-
_values[i] = 0xFF;
65-
}
6663

6764
if (stat(_fileName, &fileInfo) != 0) {
6865
//File does not exist. Create it.
@@ -72,11 +69,16 @@ int SoftEeprom::init(const char *fileName, size_t length)
7269
logError("Unable to create config file %s.\n", _fileName);
7370
return -1;
7471
}
72+
// Fill the eeprom with 1s
73+
for (size_t i = 0; i < _length; ++i) {
74+
_values[i] = 0xFF;
75+
}
7576
myFile.write((const char*)_values, _length);
7677
myFile.close();
7778
} else if (fileInfo.st_size < 0 || (size_t)fileInfo.st_size != _length) {
7879
logError("EEPROM file %s is not the correct size of %zu. Please remove the file and a new one will be created.\n",
7980
_fileName, _length);
81+
destroy();
8082
return -1;
8183
} else {
8284
//Read config into local memory.
@@ -100,27 +102,19 @@ void SoftEeprom::destroy()
100102
if (_fileName) {
101103
free(_fileName);
102104
}
105+
_length = 0;
103106
}
104107

105108
void SoftEeprom::readBlock(void* buf, void* addr, size_t length)
106109
{
107-
static bool config_to_mem = false;
108110
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
109111

110-
if (!config_to_mem && length) {
111-
//Read config into local memory.
112-
std::ifstream myFile(_fileName, std::ios::in | std::ios::binary);
113-
if (!myFile) {
114-
logError("Unable to open config to file %s for reading.\n", _fileName);
115-
exit(1);
116-
}
117-
myFile.read((char*)_values, _length);
118-
myFile.close();
119-
120-
config_to_mem = true;
112+
if (!length) {
113+
logError("EEPROM being read without being initialized!\n");
114+
return;
121115
}
122116

123-
if (length && offs + length <= _length) {
117+
if (offs + length <= _length) {
124118
memcpy(buf, _values+offs, length);
125119
}
126120
}
@@ -129,7 +123,16 @@ void SoftEeprom::writeBlock(void* buf, void* addr, size_t length)
129123
{
130124
unsigned long int offs = reinterpret_cast<unsigned long int>(addr);
131125

132-
if (length && offs + length <= _length) {
126+
if (!length) {
127+
logError("EEPROM being written without being initialized!\n");
128+
return;
129+
}
130+
131+
if (offs + length <= _length) {
132+
if (memcmp(_values+offs, buf, length) == 0) {
133+
return;
134+
}
135+
133136
memcpy(_values+offs, buf, length);
134137

135138
std::ofstream myFile(_fileName, std::ios::out | std::ios::in | std::ios::binary);

drivers/Linux/config.c

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,15 @@ int config_parse(const char *config_file)
4949
return -1;
5050
}
5151

52-
conf.verbose = 4;
52+
conf.verbose = 7;
5353
conf.log_pipe = 0;
5454
conf.log_pipe_file = NULL;
5555
conf.syslog = 0;
5656
conf.eeprom_file = NULL;
57-
conf.eeprom_size = 1024;
57+
conf.eeprom_size = 0;
58+
conf.soft_hmac_key = NULL;
59+
conf.soft_serial_key = NULL;
60+
conf.aes_key = NULL;
5861

5962
while (fgets(buf, 1024, fptr)) {
6063
if (buf[0] != '#' && buf[0] != 10 && buf[0] != 13) {
@@ -145,6 +148,21 @@ int config_parse(const char *config_file)
145148
return -1;
146149
}
147150
}
151+
} else if (!strncmp(buf, "soft_hmac_key=", 14)) {
152+
if (_config_parse_string(&(buf[14]), "soft_hmac_key", &conf.soft_hmac_key)) {
153+
fclose(fptr);
154+
return -1;
155+
}
156+
} else if (!strncmp(buf, "soft_serial_key=", 16)) {
157+
if (_config_parse_string(&(buf[16]), "soft_serial_key", &conf.soft_serial_key)) {
158+
fclose(fptr);
159+
return -1;
160+
}
161+
} else if (!strncmp(buf, "aes_key=", 8)) {
162+
if (_config_parse_string(&(buf[8]), "aes_key", &conf.aes_key)) {
163+
fclose(fptr);
164+
return -1;
165+
}
148166
} else {
149167
logWarning("Unknown config option \"%s\".\n", buf);
150168
}
@@ -172,36 +190,73 @@ int config_parse(const char *config_file)
172190

173191
void config_cleanup(void)
174192
{
175-
if (conf.eeprom_file) {
176-
free(conf.eeprom_file);
193+
if (conf.log_filepath) {
194+
free(conf.log_filepath);
177195
}
178196
if (conf.log_pipe_file) {
179197
free(conf.log_pipe_file);
180198
}
199+
if (conf.eeprom_file) {
200+
free(conf.eeprom_file);
201+
}
202+
if (conf.soft_hmac_key) {
203+
free(conf.soft_hmac_key);
204+
}
205+
if (conf.soft_serial_key) {
206+
free(conf.soft_serial_key);
207+
}
208+
if (conf.aes_key) {
209+
free(conf.aes_key);
210+
}
181211
}
182212

183213
int _config_create(const char *config_file)
184214
{
185215
FILE *myFile;
186216
int ret;
187217

188-
const char default_conf[] = "# Logging verbosity: debug,info,notice,warn,err\n" \
218+
const char default_conf[] = "# Logging\n" \
219+
"# Verbosity: debug,info,notice,warn,err\n" \
189220
"verbose=debug\n" \
221+
"\n" \
190222
"# Enable logging to a file.\n" \
191223
"log_file=0\n" \
192224
"# Log file path.\n" \
193225
"log_filepath=/tmp/mysgw.log\n" \
226+
"\n" \
194227
"# Enable logging to a named pipe.\n" \
195228
"# Use this option to view your gateway's log messages\n" \
196229
"# from the log_pipe_file defined bellow.\n" \
197230
"# To do so, run the following command on another terminal:\n" \
198231
"# cat \"log_pipe_file\"\n" \
199232
"log_pipe=0\n" \
200233
"log_pipe_file=/tmp/mysgw.pipe\n" \
234+
"\n" \
201235
"# Enable logging to syslog.\n" \
202236
"syslog=0\n" \
237+
"\n" \
238+
"# EEPROM settings\n" \
203239
"eeprom_file=/etc/mysensors.eeprom\n" \
204-
"eeprom_size=1024\n";
240+
"eeprom_size=1024\n" \
241+
"\n" \
242+
"# Software signing settings\n" \
243+
"# Note: The gateway must have been built with signing\n" \
244+
"# support to use the options below.\n" \
245+
"#\n" \
246+
"# To generate a HMAC key run mysgw with: --gen-soft-hmac-key\n" \
247+
"# copy the new key in the line below and uncomment it.\n" \
248+
"#soft_hmac_key=\n" \
249+
"# To generate a serial key run mysgw with: --gen-soft-serial-key\n" \
250+
"# copy the new key in the line below and uncomment it.\n" \
251+
"#soft_serial_key=\n" \
252+
"\n" \
253+
"# Encryption settings\n" \
254+
"# Note: The gateway must have been built with encryption\n" \
255+
"# support to use the options below.\n" \
256+
"#\n" \
257+
"# To generate a AES key run mysgw with: --gen-aes-key\n" \
258+
"# copy the new key in the line below and uncomment it.\n" \
259+
"#aes_key=\n";
205260

206261
myFile = fopen(config_file, "w");
207262
if (!myFile) {

drivers/Linux/config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ struct config {
3333
int syslog;
3434
char *eeprom_file;
3535
int eeprom_size;
36+
char *soft_hmac_key;
37+
char *soft_serial_key;
38+
char *aes_key;
3639
} conf;
3740

3841
int config_parse(const char *config_file);

0 commit comments

Comments
 (0)