From 530eba133fd1fc3af91457bad73220cfcfbbe2cc Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Sat, 16 Jun 2018 09:45:00 -0700
Subject: [PATCH 1/8] as,rsrv: use real client IP instead of untrusted host
name
---
modules/database/src/ioc/rsrv/camessage.c | 8 +++++
modules/database/src/ioc/rsrv/caservertask.c | 14 +++++++++
modules/database/src/ioc/rsrv/server.h | 2 +-
modules/libcom/src/as/asLib.h | 5 +++
modules/libcom/src/as/asLibRoutines.c | 32 +++++++++++++++++---
modules/libcom/src/iocsh/libComRegister.c | 6 ++++
6 files changed, 61 insertions(+), 6 deletions(-)
diff --git a/modules/database/src/ioc/rsrv/camessage.c b/modules/database/src/ioc/rsrv/camessage.c
index 72a4b17a1..40448d018 100644
--- a/modules/database/src/ioc/rsrv/camessage.c
+++ b/modules/database/src/ioc/rsrv/camessage.c
@@ -861,6 +861,14 @@ static int host_name_action ( caHdrLargeArray *mp, void *pPayload,
return RSRV_ERROR;
}
+ /* after all validation */
+ if(asUseIP) {
+
+ DLOG (2, ( "CAS: host_name_action for \"%s\" ignores clist provided host name\n",
+ client->pHostName ) );
+ return RSRV_OK;
+ }
+
/*
* user name will not change if there isnt enough memory
*/
diff --git a/modules/database/src/ioc/rsrv/caservertask.c b/modules/database/src/ioc/rsrv/caservertask.c
index f377d837f..048487b20 100644
--- a/modules/database/src/ioc/rsrv/caservertask.c
+++ b/modules/database/src/ioc/rsrv/caservertask.c
@@ -1421,6 +1421,20 @@ struct client *create_tcp_client (SOCKET sock , const osiSockAddr *peerAddr)
}
client->addr = peerAddr->ia;
+ if(asUseIP) {
+ epicsUInt32 ip = ntohl(client->addr.sin_addr.s_addr);
+ client->pHostName = malloc(24);
+ if(!client->pHostName) {
+ destroy_client ( client );
+ return NULL;
+ }
+ epicsSnprintf(client->pHostName, 24,
+ "%u.%u.%u.%u",
+ (ip>>24)&0xff,
+ (ip>>16)&0xff,
+ (ip>>8)&0xff,
+ (ip>>0)&0xff);
+ }
/*
* see TCP(4P) this seems to make unsolicited single events much
diff --git a/modules/database/src/ioc/rsrv/server.h b/modules/database/src/ioc/rsrv/server.h
index 4d502f77f..6392c692b 100644
--- a/modules/database/src/ioc/rsrv/server.h
+++ b/modules/database/src/ioc/rsrv/server.h
@@ -86,7 +86,7 @@ typedef struct client {
ELLLIST chanList;
ELLLIST chanPendingUpdateARList;
ELLLIST putNotifyQue;
- struct sockaddr_in addr;
+ struct sockaddr_in addr; /* peer address, TCP only */
epicsTimeStamp time_at_last_send;
epicsTimeStamp time_at_last_recv;
void *evuser;
diff --git a/modules/libcom/src/as/asLib.h b/modules/libcom/src/as/asLib.h
index 261e5ed7d..b4e5139ce 100644
--- a/modules/libcom/src/as/asLib.h
+++ b/modules/libcom/src/as/asLib.h
@@ -21,6 +21,11 @@
extern "C" {
#endif
+/* 0 - Use (unverified) client provided host name string.
+ * 1 - Use actual client IP address. HAG() are resolved to IPs at ACF load time.
+ */
+epicsShareExtern int asUseIP;
+
typedef struct asgMember *ASMEMBERPVT;
typedef struct asgClient *ASCLIENTPVT;
typedef int (*ASINPUTFUNCPTR)(char *buf,int max_size);
diff --git a/modules/libcom/src/as/asLibRoutines.c b/modules/libcom/src/as/asLibRoutines.c
index 3f5713efc..ceade030e 100644
--- a/modules/libcom/src/as/asLibRoutines.c
+++ b/modules/libcom/src/as/asLibRoutines.c
@@ -15,6 +15,8 @@
#include
#define epicsExportSharedSymbols
+#include "osiSock.h"
+#include "epicsTypes.h"
#include "epicsStdio.h"
#include "dbDefs.h"
#include "epicsThread.h"
@@ -27,6 +29,8 @@
#include "postfix.h"
#include "asLib.h"
+int asUseIP;
+
static epicsMutexId asLock;
#define LOCK epicsMutexMustLock(asLock)
#define UNLOCK epicsMutexUnlock(asLock)
@@ -1206,11 +1210,29 @@ static long asHagAddHost(HAG *phag,const char *host)
int len, i;
if (!phag) return 0;
- len = strlen(host);
- phagname = asCalloc(1, sizeof(HAGNAME) + len + 1);
- phagname->host = (char *)(phagname + 1);
- for (i = 0; i < len; i++) {
- phagname->host[i] = (char)tolower((int)host[i]);
+ if(!asUseIP) {
+ len = strlen(host);
+ phagname = asCalloc(1, sizeof(HAGNAME) + len + 1);
+ phagname->host = (char *)(phagname + 1);
+ for (i = 0; i < len; i++) {
+ phagname->host[i] = (char)tolower((int)host[i]);
+ }
+ } else {
+ struct sockaddr_in addr;
+ epicsUInt32 ip;
+ if(aToIPAddr(host, 0, &addr)) {
+ errlogPrintf("Unable to resolve host '%s'\n", host);
+ return S_asLib_noHag;
+ }
+ ip = ntohl(addr.sin_addr.s_addr);
+ phagname = asCalloc(1, sizeof(HAGNAME) + 24);
+ phagname->host = (char *)(phagname + 1);
+ epicsSnprintf(phagname->host, 24,
+ "%u.%u.%u.%u",
+ (ip>>24)&0xff,
+ (ip>>16)&0xff,
+ (ip>>8)&0xff,
+ (ip>>0)&0xff);
}
ellAdd(&phag->list, &phagname->node);
return 0;
diff --git a/modules/libcom/src/iocsh/libComRegister.c b/modules/libcom/src/iocsh/libComRegister.c
index 0d8c5678c..2bbb09f3e 100644
--- a/modules/libcom/src/iocsh/libComRegister.c
+++ b/modules/libcom/src/iocsh/libComRegister.c
@@ -12,6 +12,7 @@
#define epicsExportSharedSymbols
#include "iocsh.h"
+#include "asLib.h"
#include "epicsStdioRedirect.h"
#include "epicsString.h"
#include "epicsTime.h"
@@ -392,6 +393,8 @@ static void installLastResortEventProviderCallFunc(const iocshArgBuf *args)
installLastResortEventProvider();
}
+static iocshVarDef asUseIPDef = {"asUseIP", iocshArgInt, 0};
+
void epicsShareAPI libComRegister(void)
{
iocshRegister(&dateFuncDef, dateCallFunc);
@@ -424,4 +427,7 @@ void epicsShareAPI libComRegister(void)
iocshRegister(&generalTimeReportFuncDef,generalTimeReportCallFunc);
iocshRegister(&installLastResortEventProviderFuncDef, installLastResortEventProviderCallFunc);
+
+ asUseIPDef.pval = &asUseIP;
+ iocshRegisterVariable(&asUseIPDef);
}
From dced29c4752a224cafd85e9dc5ca65dea7b50960 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Wed, 14 Nov 2018 14:41:45 -0800
Subject: [PATCH 2/8] asLib: test asUseIP
---
modules/libcom/test/aslibtest.c | 39 +++++++++++++++++++++++++++++++--
1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/modules/libcom/test/aslibtest.c b/modules/libcom/test/aslibtest.c
index 875aa56fd..367a12426 100644
--- a/modules/libcom/test/aslibtest.c
+++ b/modules/libcom/test/aslibtest.c
@@ -81,8 +81,8 @@ static const char hostname_config[] = ""
static void testHostNames(void)
{
-
testDiag("testHostNames()");
+ asUseIP = 0;
testOk1(asInitMem(hostname_config, NULL)==0);
@@ -109,11 +109,46 @@ static void testHostNames(void)
testAccess("ro", 0);
testAccess("rw", 0);
}
+
+static void testUseIP(void)
+{
+ testDiag("testUseIP()");
+ asUseIP = 1;
+
+ /* still host names in .acf */
+ testOk1(asInitMem(hostname_config, NULL)==0);
+ /* now resolved to IPs */
+
+ setUser("testing");
+ setHost("localhost"); /* will not match against resolved IP */
+ asAsl = 0;
+
+ testAccess("invalid", 0);
+ testAccess("DEFAULT", 0);
+ testAccess("ro", 0);
+ testAccess("rw", 0);
+
+ setHost("127.0.0.1");
+
+ testAccess("invalid", 0);
+ testAccess("DEFAULT", 0);
+ testAccess("ro", 1);
+ testAccess("rw", 3);
+
+ setHost("nosuchhost");
+
+ testAccess("invalid", 0);
+ testAccess("DEFAULT", 0);
+ testAccess("ro", 0);
+ testAccess("rw", 0);
+}
+
MAIN(aslibtest)
{
- testPlan(14);
+ testPlan(27);
testSyntaxErrors();
testHostNames();
+ testUseIP();
errlogFlush();
return testDone();
}
From 73cdea5517d625243ba149abf4a1368fbae8fe81 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Wed, 8 May 2019 19:02:13 -0700
Subject: [PATCH 3/8] as-hostname address review comments
---
documentation/RELEASE_NOTES.html | 22 ++++++++++++++++++++
modules/database/src/ioc/rsrv/camessage.c | 4 ++--
modules/database/src/ioc/rsrv/caservertask.c | 2 +-
modules/libcom/src/as/asLib.h | 2 +-
modules/libcom/src/as/asLibRoutines.c | 4 ++--
modules/libcom/src/iocsh/libComRegister.c | 6 +++---
modules/libcom/test/aslibtest.c | 8 +++----
7 files changed, 35 insertions(+), 13 deletions(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 63f8880a7..25f0eac62 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -26,6 +26,28 @@ release.
-->
+ACF Hostname from DNS
+
+ACF hostname has so far been a string provided by a CA client,
+which may or may not agree with DNS. An option is now available
+to cause IOCs to resolve hostnames, and compare against the actual
+client IP address.
+ This resolution is done at ACF file load time,
+which has two consequences.
+
+
+- Slow/unavailable DNS will cause problems during ACF file
+loading. eg. during IOC start.
+- Changes in host -> IP mapping will not be picked up until/unless
+the ACF file is reloaded.
+
+
+This may be enabled with:
+
+
+var("asCheckClientIP",1)
+
+
Launchpad Bugs
The list of tracked bugs fixed in this release can be found on the
diff --git a/modules/database/src/ioc/rsrv/camessage.c b/modules/database/src/ioc/rsrv/camessage.c
index 40448d018..f54bb4888 100644
--- a/modules/database/src/ioc/rsrv/camessage.c
+++ b/modules/database/src/ioc/rsrv/camessage.c
@@ -862,9 +862,9 @@ static int host_name_action ( caHdrLargeArray *mp, void *pPayload,
}
/* after all validation */
- if(asUseIP) {
+ if(asCheckClientIP) {
- DLOG (2, ( "CAS: host_name_action for \"%s\" ignores clist provided host name\n",
+ DLOG (2, ( "CAS: host_name_action for \"%s\" ignores client provided host name\n",
client->pHostName ) );
return RSRV_OK;
}
diff --git a/modules/database/src/ioc/rsrv/caservertask.c b/modules/database/src/ioc/rsrv/caservertask.c
index 048487b20..7a9ae63b3 100644
--- a/modules/database/src/ioc/rsrv/caservertask.c
+++ b/modules/database/src/ioc/rsrv/caservertask.c
@@ -1421,7 +1421,7 @@ struct client *create_tcp_client (SOCKET sock , const osiSockAddr *peerAddr)
}
client->addr = peerAddr->ia;
- if(asUseIP) {
+ if(asCheckClientIP) {
epicsUInt32 ip = ntohl(client->addr.sin_addr.s_addr);
client->pHostName = malloc(24);
if(!client->pHostName) {
diff --git a/modules/libcom/src/as/asLib.h b/modules/libcom/src/as/asLib.h
index b4e5139ce..a29cf3b65 100644
--- a/modules/libcom/src/as/asLib.h
+++ b/modules/libcom/src/as/asLib.h
@@ -24,7 +24,7 @@ extern "C" {
/* 0 - Use (unverified) client provided host name string.
* 1 - Use actual client IP address. HAG() are resolved to IPs at ACF load time.
*/
-epicsShareExtern int asUseIP;
+epicsShareExtern int asCheckClientIP;
typedef struct asgMember *ASMEMBERPVT;
typedef struct asgClient *ASCLIENTPVT;
diff --git a/modules/libcom/src/as/asLibRoutines.c b/modules/libcom/src/as/asLibRoutines.c
index ceade030e..e3105facd 100644
--- a/modules/libcom/src/as/asLibRoutines.c
+++ b/modules/libcom/src/as/asLibRoutines.c
@@ -29,7 +29,7 @@
#include "postfix.h"
#include "asLib.h"
-int asUseIP;
+int asCheckClientIP;
static epicsMutexId asLock;
#define LOCK epicsMutexMustLock(asLock)
@@ -1210,7 +1210,7 @@ static long asHagAddHost(HAG *phag,const char *host)
int len, i;
if (!phag) return 0;
- if(!asUseIP) {
+ if(!asCheckClientIP) {
len = strlen(host);
phagname = asCalloc(1, sizeof(HAGNAME) + len + 1);
phagname->host = (char *)(phagname + 1);
diff --git a/modules/libcom/src/iocsh/libComRegister.c b/modules/libcom/src/iocsh/libComRegister.c
index 2bbb09f3e..c842dce27 100644
--- a/modules/libcom/src/iocsh/libComRegister.c
+++ b/modules/libcom/src/iocsh/libComRegister.c
@@ -393,7 +393,7 @@ static void installLastResortEventProviderCallFunc(const iocshArgBuf *args)
installLastResortEventProvider();
}
-static iocshVarDef asUseIPDef = {"asUseIP", iocshArgInt, 0};
+static iocshVarDef asCheckClientIPDef = {"asCheckClientIP", iocshArgInt, 0};
void epicsShareAPI libComRegister(void)
{
@@ -428,6 +428,6 @@ void epicsShareAPI libComRegister(void)
iocshRegister(&generalTimeReportFuncDef,generalTimeReportCallFunc);
iocshRegister(&installLastResortEventProviderFuncDef, installLastResortEventProviderCallFunc);
- asUseIPDef.pval = &asUseIP;
- iocshRegisterVariable(&asUseIPDef);
+ asCheckClientIPDef.pval = &asCheckClientIP;
+ iocshRegisterVariable(&asCheckClientIPDef);
}
diff --git a/modules/libcom/test/aslibtest.c b/modules/libcom/test/aslibtest.c
index 367a12426..4237fafb1 100644
--- a/modules/libcom/test/aslibtest.c
+++ b/modules/libcom/test/aslibtest.c
@@ -82,7 +82,7 @@ static const char hostname_config[] = ""
static void testHostNames(void)
{
testDiag("testHostNames()");
- asUseIP = 0;
+ asCheckClientIP = 0;
testOk1(asInitMem(hostname_config, NULL)==0);
@@ -102,7 +102,7 @@ static void testHostNames(void)
testAccess("ro", 0);
testAccess("rw", 0);
- setHost("nosuchhost");
+ setHost("guaranteed.invalid.");
testAccess("invalid", 0);
testAccess("DEFAULT", 0);
@@ -113,7 +113,7 @@ static void testHostNames(void)
static void testUseIP(void)
{
testDiag("testUseIP()");
- asUseIP = 1;
+ asCheckClientIP = 1;
/* still host names in .acf */
testOk1(asInitMem(hostname_config, NULL)==0);
@@ -135,7 +135,7 @@ static void testUseIP(void)
testAccess("ro", 1);
testAccess("rw", 3);
- setHost("nosuchhost");
+ setHost("guaranteed.invalid.");
testAccess("invalid", 0);
testAccess("DEFAULT", 0);
From 6eb6cc0d805e3ccab87963895b9a94f1c4485035 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Mon, 13 May 2019 14:52:10 -0500
Subject: [PATCH 4/8] Expand Release Note entry for as-hostname changes.
---
documentation/RELEASE_NOTES.html | 46 ++++++++++++++++++++++----------
1 file changed, 32 insertions(+), 14 deletions(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 25f0eac62..376279fc9 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -26,28 +26,46 @@ release.
-->
-ACF Hostname from DNS
+Channel Access Security: Check Hostname Against DNS
-ACF hostname has so far been a string provided by a CA client,
-which may or may not agree with DNS. An option is now available
-to cause IOCs to resolve hostnames, and compare against the actual
-client IP address.
- This resolution is done at ACF file load time,
-which has two consequences.
+Host names given in a HAG entry of an IOC's Access Security
+Configuration File (ACF) have to date been compared against the hostname
+provided by the CA client at connection time, which may or may not be the actual
+name of that client. This allows rogue clients to pretend to be a different
+host, and the IOC would believe them.
-
-- Slow/unavailable DNS will cause problems during ACF file
-loading. eg. during IOC start.
-- Changes in host -> IP mapping will not be picked up until/unless
-the ACF file is reloaded.
-
+An option is now available to cause an IOC to ask its operating system to
+look up the IP address of any hostnames listed in its ACF (which will normally
+be done using the DNS or the /etc/hosts file). The IOC will then
+compare the resulting IP address against the client's actual IP address when
+checking access permissions at connection time. This name resolution gets done
+at ACF file load time, which has a few consequences:
-This may be enabled with:
+
+
+- If the DNS is slow when the names are resolved this will delay the process
+of loading the ACF file.
+
+- If a host name cannot be resolved the IOC will treat the ACF as invalid,
+which prevents any CA clients from connecting.
+
+- Any changes in the hostname to IP address mapping will not be picked up by
+the IOC unless and until the ACF file gets reloaded.
+
+
+
+This feature can be enabled before iocInit with
var("asCheckClientIP",1)
+or with the VxWorks target shell use
+
+
+asCheckClientIP = 1
+
+
Launchpad Bugs
The list of tracked bugs fixed in this release can be found on the
From 932e9f3b21375e03641f9c1316b123e041ee2fe7 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Tue, 4 Jun 2019 14:36:42 +0200
Subject: [PATCH 5/8] asLib: asUseIP name lookup soft-fail
---
modules/libcom/src/as/asLibRoutines.c | 34 +++++++++++++++++----------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/modules/libcom/src/as/asLibRoutines.c b/modules/libcom/src/as/asLibRoutines.c
index e3105facd..c29fff674 100644
--- a/modules/libcom/src/as/asLibRoutines.c
+++ b/modules/libcom/src/as/asLibRoutines.c
@@ -1207,32 +1207,40 @@ static HAG *asHagAdd(const char *hagName)
static long asHagAddHost(HAG *phag,const char *host)
{
HAGNAME *phagname;
- int len, i;
if (!phag) return 0;
if(!asCheckClientIP) {
- len = strlen(host);
+ size_t i, len = strlen(host);
phagname = asCalloc(1, sizeof(HAGNAME) + len + 1);
phagname->host = (char *)(phagname + 1);
for (i = 0; i < len; i++) {
phagname->host[i] = (char)tolower((int)host[i]);
}
+
} else {
struct sockaddr_in addr;
epicsUInt32 ip;
+
if(aToIPAddr(host, 0, &addr)) {
- errlogPrintf("Unable to resolve host '%s'\n", host);
- return S_asLib_noHag;
+ static const char unresolved[] = "unresolved:";
+
+ errlogPrintf("ACF: Unable to resolve host '%s'\n", host);
+
+ phagname = asCalloc(1, sizeof(HAGNAME) + sizeof(unresolved)-1+strlen(host));
+ strcpy(phagname->host, unresolved);
+ strcat(phagname->host, host);
+
+ } else {
+ ip = ntohl(addr.sin_addr.s_addr);
+ phagname = asCalloc(1, sizeof(HAGNAME) + 24);
+ phagname->host = (char *)(phagname + 1);
+ epicsSnprintf(phagname->host, 24,
+ "%u.%u.%u.%u",
+ (ip>>24)&0xff,
+ (ip>>16)&0xff,
+ (ip>>8)&0xff,
+ (ip>>0)&0xff);
}
- ip = ntohl(addr.sin_addr.s_addr);
- phagname = asCalloc(1, sizeof(HAGNAME) + 24);
- phagname->host = (char *)(phagname + 1);
- epicsSnprintf(phagname->host, 24,
- "%u.%u.%u.%u",
- (ip>>24)&0xff,
- (ip>>16)&0xff,
- (ip>>8)&0xff,
- (ip>>0)&0xff);
}
ellAdd(&phag->list, &phagname->node);
return 0;
From a83a85af7c730164e8e3b1c1260bd41187e81f99 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Tue, 4 Jun 2019 16:05:54 +0200
Subject: [PATCH 6/8] asLib one short
---
modules/libcom/src/as/asLibRoutines.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/libcom/src/as/asLibRoutines.c b/modules/libcom/src/as/asLibRoutines.c
index c29fff674..4ca1916bd 100644
--- a/modules/libcom/src/as/asLibRoutines.c
+++ b/modules/libcom/src/as/asLibRoutines.c
@@ -1226,7 +1226,7 @@ static long asHagAddHost(HAG *phag,const char *host)
errlogPrintf("ACF: Unable to resolve host '%s'\n", host);
- phagname = asCalloc(1, sizeof(HAGNAME) + sizeof(unresolved)-1+strlen(host));
+ phagname = asCalloc(1, sizeof(HAGNAME) + sizeof(unresolved)+strlen(host));
strcpy(phagname->host, unresolved);
strcat(phagname->host, host);
From 048975ccc708987afdda43712485ff9dc24b0b29 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Wed, 5 Jun 2019 11:40:50 +0200
Subject: [PATCH 7/8] asLib more string size...
---
modules/libcom/src/as/asLib.h | 4 ++--
modules/libcom/src/as/asLibRoutines.c | 6 ++----
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/modules/libcom/src/as/asLib.h b/modules/libcom/src/as/asLib.h
index a29cf3b65..528ce6ed9 100644
--- a/modules/libcom/src/as/asLib.h
+++ b/modules/libcom/src/as/asLib.h
@@ -170,8 +170,8 @@ typedef struct uag{
} UAG;
/*Defs for Host Access Groups*/
typedef struct{
- ELLNODE node;
- char *host;
+ ELLNODE node;
+ char host[1];
} HAGNAME;
typedef struct hag{
ELLNODE node;
diff --git a/modules/libcom/src/as/asLibRoutines.c b/modules/libcom/src/as/asLibRoutines.c
index 4ca1916bd..ab0bf5071 100644
--- a/modules/libcom/src/as/asLibRoutines.c
+++ b/modules/libcom/src/as/asLibRoutines.c
@@ -1211,8 +1211,7 @@ static long asHagAddHost(HAG *phag,const char *host)
if (!phag) return 0;
if(!asCheckClientIP) {
size_t i, len = strlen(host);
- phagname = asCalloc(1, sizeof(HAGNAME) + len + 1);
- phagname->host = (char *)(phagname + 1);
+ phagname = asCalloc(1, sizeof(HAGNAME) + len);
for (i = 0; i < len; i++) {
phagname->host[i] = (char)tolower((int)host[i]);
}
@@ -1226,14 +1225,13 @@ static long asHagAddHost(HAG *phag,const char *host)
errlogPrintf("ACF: Unable to resolve host '%s'\n", host);
- phagname = asCalloc(1, sizeof(HAGNAME) + sizeof(unresolved)+strlen(host));
+ phagname = asCalloc(1, sizeof(HAGNAME) + sizeof(unresolved)-1+strlen(host));
strcpy(phagname->host, unresolved);
strcat(phagname->host, host);
} else {
ip = ntohl(addr.sin_addr.s_addr);
phagname = asCalloc(1, sizeof(HAGNAME) + 24);
- phagname->host = (char *)(phagname + 1);
epicsSnprintf(phagname->host, 24,
"%u.%u.%u.%u",
(ip>>24)&0xff,
From 4dcd6f37c697b1517b5e36ae1b9d130abfcd7699 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
Date: Sun, 23 Jun 2019 16:18:43 -0700
Subject: [PATCH 8/8] update release notes
---
documentation/RELEASE_NOTES.html | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 376279fc9..1d93d2b3b 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -38,7 +38,7 @@ host, and the IOC would believe them.
look up the IP address of any hostnames listed in its ACF (which will normally
be done using the DNS or the /etc/hosts file). The IOC will then
compare the resulting IP address against the client's actual IP address when
-checking access permissions at connection time. This name resolution gets done
+checking access permissions at connection time. This name resolution is performed
at ACF file load time, which has a few consequences:
@@ -46,14 +46,17 @@ at ACF file load time, which has a few consequences:
- If the DNS is slow when the names are resolved this will delay the process
of loading the ACF file.
-- If a host name cannot be resolved the IOC will treat the ACF as invalid,
-which prevents any CA clients from connecting.
+- If a host name cannot be resolved the IOC will proceed, but this host name
+will never be matched.
- Any changes in the hostname to IP address mapping will not be picked up by
the IOC unless and until the ACF file gets reloaded.
+Optionally, IP addresses may be added instead of, or in addition to, host names
+in the ACF file.
+
This feature can be enabled before iocInit with