---
 plugins/loopback.c |   70 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/plugins/loopback.c b/plugins/loopback.c
index 1800c49..cba923c 100644
--- a/plugins/loopback.c
+++ b/plugins/loopback.c
@@ -32,6 +32,7 @@
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <net/if.h>
+#include <ctype.h>
 
 #include <glib.h>
 
@@ -204,14 +205,70 @@ static const char *loopback_get_hostname(void)
        return system_hostname;
 }
 
+/* Check routine modified from ics-dhcp 4.2.3-P2 */
+static int check_name(const char *ptr, size_t len)
+{
+       const char *p;
+
+       /*
+        * Not empty or complete length not over 255 characters.
+        */
+       if ((len == 0) || (len > 256))
+               return -1;
+
+       /*
+        * Consists of [[:alnum:]-]+ labels separated by [.]
+        * a [_] is against RFC but seems to be "widely used"
+        */
+       for (p = ptr; (*p != 0) && (len-- > 0); p++) {
+
+               if ((*p == '-') || (*p == '_')) {
+                       /*
+                        * Not allowed at begin or end of a label.
+                        */
+                       if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
+                               return -1;
+
+               } else if (*p == '.') {
+                       /*
+                        * Each label has to be 1-63 characters;
+                        * we allow [.] at the end ('foo.bar.')
+                        */
+                       size_t d = p - ptr;
+
+                       if ((d <= 0) || (d >= 64))
+                               return -1;
+
+                       ptr = p + 1; /* Jump to the next label */
+
+               } else if (isalnum((unsigned char)*p) == 0) {
+                       /*
+                        * Also numbers at the begin are fine
+                        */
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 static int loopback_set_hostname(const char *hostname)
 {
-       int err;
+       const char *ptr;
+       int err, len;
 
        if (g_strcmp0(hostname, "<hostname>") == 0)
                return 0;
 
-       if (sethostname(hostname, strlen(hostname)) < 0) {
+       len = strlen(hostname);
+
+       if (check_name(hostname, len) != 0)
+               return -EINVAL;
+
+       if ((ptr = strstr(hostname, ".")) != NULL)
+               len = ptr - hostname;
+
+       if (sethostname(hostname, len) < 0) {
                err = -errno;
                connman_error("Failed to set hostname to %s", hostname);
                return err;
@@ -224,9 +281,14 @@ static int loopback_set_hostname(const char *hostname)
 
 static int loopback_set_domainname(const char *domainname)
 {
-       int err;
+       int err, len;
+
+       len = strlen(domainname);
+
+       if (check_name(domainname, len) != 0)
+               return -EINVAL;
 
-       if (setdomainname(domainname, strlen(domainname)) < 0) {
+       if (setdomainname(domainname, len) < 0) {
                err = -errno;
                connman_error("Failed to set domainname to %s", domainname);
                return err;
-- 
1.7.5.4

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to