summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--options.c4
-rw-r--r--socket.c39
-rw-r--r--socket.h1
3 files changed, 42 insertions, 2 deletions
diff --git a/options.c b/options.c
index ca9b9e1..ebccd7f 100644
--- a/options.c
+++ b/options.c
@@ -3436,11 +3436,11 @@ add_option (struct options *options,
else if (streq (p[0], "lladdr") && p[1])
{
VERIFY_PERMISSION (OPT_P_UP);
- if (ip_addr_dotted_quad_safe (p[1])) /* FQDN -- IP address only */
+ if (mac_addr_safe (p[1])) /* MAC address only */
options->lladdr = p[1];
else
{
- msg (msglevel, "lladdr parm '%s' must be an IP address", p[1]);
+ msg (msglevel, "lladdr parm '%s' must be a MAC address", p[1]);
goto err;
}
}
diff --git a/socket.c b/socket.c
index df922a9..fe58c3e 100644
--- a/socket.c
+++ b/socket.c
@@ -317,6 +317,45 @@ ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn)
return false;
}
+bool
+mac_addr_safe (const char *mac_addr)
+{
+ /* verify non-NULL */
+ if (!mac_addr)
+ return false;
+
+ /* verify length is within limits */
+ if (strlen (mac_addr) > 17)
+ return false;
+
+ /* verify that all chars are either alphanumeric or ':' and that no
+ alphanumeric substring is greater than 2 chars */
+ {
+ int nnum = 0;
+ const char *p = mac_addr;
+ int c;
+
+ while ((c = *p++))
+ {
+ if ( (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') )
+ {
+ ++nnum;
+ if (nnum > 2)
+ return false;
+ }
+ else if (c == ':')
+ {
+ nnum = 0;
+ }
+ else
+ return false;
+ }
+ }
+
+ /* error-checking is left to script invoked in lladdr.c */
+ return true;
+}
+
static void
update_remote (const char* host,
struct openvpn_sockaddr *addr,
diff --git a/socket.h b/socket.h
index f6ec570..980322d 100644
--- a/socket.h
+++ b/socket.h
@@ -400,6 +400,7 @@ int openvpn_inet_aton (const char *dotted_quad, struct in_addr *addr);
/* integrity validation on pulled options */
bool ip_addr_dotted_quad_safe (const char *dotted_quad);
bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn);
+bool mac_addr_safe (const char *mac_addr);
socket_descriptor_t create_socket_tcp (void);