Updates for V3.0

pull/476/head
sfeakes 2025-09-30 18:33:09 -05:00
parent 3c265d5d16
commit cc4ec9f2dd
13 changed files with 83 additions and 33 deletions

View File

@ -57,7 +57,7 @@ DBGFLAGS = -g -O0 -Wall -D AQ_DEBUG -D AQ_TM_DEBUG
# Mongoose 7.19 flags
#MGFLAGS = -D MG_TLS=2 #(2=MG_TLS_OPENSSL. 3=MG_TLS_BUILTIN) --or-- -DMG_TLS=MG_TLS_BUILTIN
MGFLAGS = -D MG_TLS=3
MGFLAGS = -D MG_TLS=3 -D MG_ENABLE_SSI=0
# Detect OS and set some specifics
ifeq ($(OS),Windows_NT)

View File

@ -148,6 +148,7 @@ NEED TO FIX FOR THIS RELEASE.
* Fixed bug with sensor UOM.
* UI code cleanup.
* Included program advance to AqualinkD programmable light mode. (lot quicker for lights that remember state)
* Changed caching of HTTP server. (Better for UI config updates)
* Need to finish off :-
* HAT serial optimizations broke some USB serial adapters

42
extras/generate-certs.sh Executable file
View File

@ -0,0 +1,42 @@
#/bin/sh
#
# Geneate self-signed ECC certificates
#cd `dirname $0`
# Create cnf for adding SAN DNS:aqualinkd.local
cat > cnf <<EOF
[SAN]
subjectAltName=DNS:aqualinkd.local
EOF
# Generate CA
# Important: CN names must be different for CA and client/server certs
openssl ecparam -noout -name prime256v1 -genkey -out ca.key
openssl req -x509 -new -key ca.key -days 3650 -subj /CN=AqualinkD -out ca.crt
# Generate server cert
openssl ecparam -noout -name prime256v1 -genkey -out server.key
openssl req -new -sha256 -key server.key -days 3650 -subj /CN=server -out server.csr
openssl x509 -req -sha256 -in server.csr -extensions SAN -extfile cnf \
-CAkey ca.key -CA ca.crt -CAcreateserial -days 3650 -out server.crt
# Generate client cert
openssl ecparam -noout -name prime256v1 -genkey -out client.key
openssl req -new -sha256 -key client.key -days 3650 -subj /CN=client -out client.csr
openssl x509 -req -sha256 -in client.csr -extensions SAN -extfile cnf \
-CAkey ca.key -CA ca.crt -CAcreateserial -days 3650 -out client.crt
# Verify
openssl verify -verbose -CAfile ca.crt server.crt
openssl verify -verbose -CAfile ca.crt client.crt
# Inspect
# openssl x509 -text -noout -ext subjectAltName -in server.crt
# Create links to valid file names we want for HTTPS server
ln -s ./server.crt ./crt.pem
ln -s ./server.key ./key.pem
# If we want 2 way auth, add the ca. ie server validates client and client validates server
#ln -s ./ca.crt ./ca.pem

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -438,12 +438,12 @@ int lock_port(int fd, const char* tty)
LOG(RSSD_LOG,LOG_ERR, "Can't put (%s) into exclusive mode (%d): %s\n", tty,errno, strerror( errno ));
return -1;
}
/*
if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
LOG(RSSD_LOG,LOG_ERR, "Can't lock (%s) (%d): %s\n", tty,errno, strerror( errno ));
return -1;
}
*/
return 0;
}
@ -453,12 +453,14 @@ int unlock_port(int fd)
LOG(RSSD_LOG,LOG_ERR, "Failed to remove into exclusive mode (%d): %s\n", errno, strerror( errno ));
}
/*
if (flock(fd, LOCK_UN) < 0) {
//if (!isAqualinkDStopping()) {
LOG(RSSD_LOG,LOG_ERR, "Can't unlock serial port (%d): %s\n",errno, strerror( errno ));
//}
return -1;
}
*/
return 0;
}

View File

@ -255,7 +255,8 @@ bool run_aqualinkd_upgrade(uint8_t type)
#if MG_TLS > 0
char* read_pem_file(const char* fmt, ...) {
// silentError is only silent if the file does not exist.
char* read_pem_file(bool silentError, const char* fmt, ...) {
char filepath[1024];
// Build file path from format + arguments
@ -266,7 +267,7 @@ char* read_pem_file(const char* fmt, ...) {
FILE* file = fopen(filepath, "rb");
if (!file) {
LOG(AQUA_LOG, LOG_ERR, "Failed to open file %s\n",filepath);
if (!silentError){LOG(AQUA_LOG, LOG_ERR, "Failed to open file %s\n",filepath);}
return NULL;
}

View File

@ -3,7 +3,7 @@
#if MG_TLS > 0
#define MAX_PEM_SIZE (64 * 1024) // 64KB limit
char* read_pem_file(const char* fmt, ...);
char* read_pem_file(bool silentError, const char* fmt, ...);
#endif
FILE *aq_open_file( char *filename, bool *ro_root, bool* created_file);

View File

@ -95,7 +95,7 @@ bool uri_strcmp(const char *uri, const char *string);
//static const char *s_http_port = "8080";
//static struct mg_serve_http_opts _http_server_opts;
static struct mg_http_serve_opts _http_server_opts;
static struct mg_http_serve_opts _http_server_opts_nocache;
static void net_signal_handler(int sig_num) {
intHandler(sig_num); // Force signal handler to aqualinkd.c
@ -1605,7 +1605,11 @@ void action_web_request(struct mg_connection *nc, struct mg_http_message *http_m
// If we have a get request, pass it
if (strncmp(http_msg->uri.buf, "/api", 4 ) != 0) {
DEBUG_TIMER_START(&tid);
mg_http_serve_dir(nc, http_msg, &_http_server_opts);
if ( FAST_SUFFIX_3_CI(http_msg->uri.buf, http_msg->uri.len, ".js") ) {
mg_http_serve_dir(nc, http_msg, &_http_server_opts_nocache);
} else {
mg_http_serve_dir(nc, http_msg, &_http_server_opts);
}
DEBUG_TIMER_STOP(tid, NET_LOG, "action_web_request() serve file took");
} else {
char buf[JSON_BUFFER_SIZE];
@ -1709,14 +1713,14 @@ void action_web_request(struct mg_connection *nc, struct mg_http_message *http_m
}
LOG(NET_LOG, LOG_DEBUG, "Downloading log of max %d lines\n",value>0?(int)value:DEFAULT_LOG_DOWNLOAD_LINES);
if (write_systemd_logmessages_2file("/dev/shm/aqualinkd.log", value>0?(int)value:DEFAULT_LOG_DOWNLOAD_LINES) ) {
mg_http_serve_file(nc, http_msg, "/dev/shm/aqualinkd.log", &_http_server_opts);
mg_http_serve_file(nc, http_msg, "/dev/shm/aqualinkd.log", &_http_server_opts_nocache);
remove("/dev/shm/aqualinkd.log");
}
break;
case uConfigDownload:
LOG(NET_LOG, LOG_DEBUG, "Downloading config\n");
mg_http_serve_file(nc, http_msg, _aqconfig_.config_file, &_http_server_opts);
mg_http_serve_file(nc, http_msg, _aqconfig_.config_file, &_http_server_opts_nocache);
break;
#endif
case uBad:
@ -1941,25 +1945,20 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
if (nc->is_tls) {
static char *crt;
static char *key;
static char *ca;
struct mg_tls_opts opts;
memset(&opts, 0, sizeof(opts));
if (crt == NULL || key == NULL) {
LOG(NET_LOG,LOG_NOTICE, "HTTPS: loading certs from : %s\n", _aqconfig_.cert_dir);
crt = read_pem_file("%s/crt.pem",_aqconfig_.cert_dir);
key = read_pem_file("%s/key.pem",_aqconfig_.cert_dir);
crt = read_pem_file(false, "%s/crt.pem",_aqconfig_.cert_dir);
key = read_pem_file(false, "%s/key.pem",_aqconfig_.cert_dir);
ca = read_pem_file(true, "%s/ca.pem",_aqconfig_.cert_dir); // If this doesn't exist we don't care. If it exists, 2 way auth
}
opts.ca = mg_str(ca); // Most cases this will be null, only get's set for 2 way auth (ie load cert and authority onto client)
opts.cert = mg_str(crt);
opts.key = mg_str(key);
#ifdef TLS_TWOWAY
static char *ca;
if (ca == NULL)
ca = read_pem_file("%s/ca.pem",_aqconfig_.cert_dir);
opts.ca = mg_str(ca);
#endif
opts.key = mg_str(key);
mg_tls_init(nc, &opts);
}
#endif
@ -1981,9 +1980,9 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
if (crt == NULL || key == NULL) {
LOG(NET_LOG,LOG_NOTICE, "MQTTS: loading certs from : %s\n", _aqconfig_.mqtt_cert_dir);
crt = read_pem_file("%s/crt.pem",_aqconfig_.cert_dir);
key = read_pem_file("%s/key.pem",_aqconfig_.cert_dir);
ca = read_pem_file("%s/ca.pem",_aqconfig_.cert_dir);
crt = read_pem_file(false, "%s/crt.pem",_aqconfig_.cert_dir);
key = read_pem_file(false, "%s/key.pem",_aqconfig_.cert_dir);
ca = read_pem_file(true, "%s/ca.pem",_aqconfig_.cert_dir);
}
opts.cert = mg_str(crt);
opts.key = mg_str(key);
@ -2186,11 +2185,13 @@ bool _start_net_services(struct mg_mgr *mgr, struct aqualinkdata *aqdata) {
}
// Set default web options
_http_server_opts.root_dir = _aqconfig_.web_directory; // Serve current directory
_http_server_opts.extra_headers = "Cache-Control: public, max-age=604800, immutable\r\n"; // 7 days
//_http_server_opts.extra_headers = "Cache-Control: public, max-age=31536000,immutable\r\n"; // 1 year. Let's be as agressive on browser caching.
// Need to disable directory_listing somehow
_http_server_opts.root_dir = _aqconfig_.web_directory;
_http_server_opts.extra_headers = CACHE;
_http_server_opts.ssi_pattern = NULL;
_http_server_opts_nocache.root_dir = _aqconfig_.web_directory;
_http_server_opts_nocache.extra_headers = NO_CACHE;
_http_server_opts_nocache.ssi_pattern = NULL;
// Start MQTT
start_mqtt(mgr);

View File

@ -11,9 +11,12 @@
//#define CONTENT_JS "Content-Type: text/javascript"
//#define CONTENT_TEXT "Content-Type: text/plain"
#define CONTENT_JSON "Content-Type: application/json\r\n"
#define CONTENT_JS "Content-Type: text/javascript\r\n"
#define CONTENT_TEXT "Content-Type: text/plain\r\n"
//#define CACHE "Cache-Control: public, max-age=31536000,immutable\r\n" // 1 year
#define CACHE "Cache-Control: public, max-age=604800, immutable\r\n" // 7 days
#define NO_CACHE "Cache-Control: no-cache, no-store, must-revalidate\r\nPragma: no-cache\r\nExpires: 0\r\n"
#define CONTENT_JSON NO_CACHE"Content-Type: application/json\r\n"
#define CONTENT_JS NO_CACHE"Content-Type: text/javascript\r\n"
#define CONTENT_TEXT NO_CACHE "Content-Type: text/plain\r\n"
//void main_server();

View File

@ -4,5 +4,5 @@
#define AQUALINKD_SHORT_NAME "AqualinkD"
// Use Magor . Minor . Patch
#define AQUALINKD_VERSION "3.0.0 (dev 4)"
#define AQUALINKD_VERSION "3.0.0 (dev r5)"