try to get nicer exception messages when we fail fetching the checkip URL
[dyn-nsupdate.git] / nsupd-wrapper / dyn-nsupdate.cpp
index 27db031e118420adcb2f0ceccdfcd183db2fa5e1..2acf3c0b3bcb229bfb78efd988007905ab6461c3 100644 (file)
@@ -52,8 +52,15 @@ static void write(int fd, const char *str)
 int main(int argc, const char ** argv)
 {
     try {
 int main(int argc, const char ** argv)
 {
     try {
-        static const regex regex_ipv4("\\d{1,3}(\\.\\d{1,3}){3}|");
-        static const regex regex_ipv6("[a-fA-F0-9]{1,4}(:[a-fA-F0-9]{1,4}){7}|");
+        // These regular expressions are not supposed to be fully precise: nsupdate will check the addresses, too.
+        // However, they have to make sure that there can be no injection attacks.
+#define GROUP "[0-9]{1,3}"
+        static const regex regex_ipv4(GROUP "(\\." GROUP "){3}|");
+#undef GROUP
+#define GROUP "[a-fA-F0-9]{1,4}"
+        static const regex regex_ipv6("(" GROUP "(::?" GROUP "){0,6})?::?" GROUP "|");
+#undef GROUP
+        
         static const regex regex_password("[a-zA-Z0-9.:;,_-]+");
         static const regex regex_domain("[a-zA-Z0-9.]+");
         
         static const regex regex_password("[a-zA-Z0-9.:;,_-]+");
         static const regex regex_domain("[a-zA-Z0-9.]+");
         
@@ -102,7 +109,14 @@ int main(int argc, const char ** argv)
         pt::ini_parser::read_ini(CONFIG_FILE, config);
         std::string nsupdate = config.get<std::string>("nsupdate");
         unsigned server_port = config.get<unsigned>("port", 53);
         pt::ini_parser::read_ini(CONFIG_FILE, config);
         std::string nsupdate = config.get<std::string>("nsupdate");
         unsigned server_port = config.get<unsigned>("port", 53);
-        std::string key = config.get<std::string>("key","");
+        std::string keyfile = config.get<std::string>("keyfile", "");
+        std::string key = config.get<std::string>("key", "");
+        
+        /* check for some invalid configurations */
+        if (keyfile.size() > 0 && key.size() > 0) {
+            std::cerr << "You can only have either a keyfile or a key set. Please fix your configuration." << std::endl;
+            exit(1);
+        }
         
         /* Given the domain, check whether the password matches */
         optional<std::string> correct_password = config.get_optional<std::string>(pt::ptree::path_type(domain+"/password", '/'));
         
         /* Given the domain, check whether the password matches */
         optional<std::string> correct_password = config.get_optional<std::string>(pt::ptree::path_type(domain+"/password", '/'));
@@ -133,9 +147,13 @@ int main(int argc, const char ** argv)
                 exit(1);
             }
             /* exec nsupdate */
                 exit(1);
             }
             /* exec nsupdate */
-            if (key.size() > 0) {
+            if (keyfile.size() > 0) {
+                execl(nsupdate.c_str(), nsupdate.c_str(), "-k", keyfile.c_str(), "-p", std::to_string(server_port).c_str(), "-l", (char *)NULL);
+            }
+            else if (key.size() > 0) {
                 execl(nsupdate.c_str(), nsupdate.c_str(), "-y", key.c_str(), "-p", std::to_string(server_port).c_str(), "-l", (char *)NULL);
                 execl(nsupdate.c_str(), nsupdate.c_str(), "-y", key.c_str(), "-p", std::to_string(server_port).c_str(), "-l", (char *)NULL);
-            } else {
+            }
+            else {
                 execl(nsupdate.c_str(), nsupdate.c_str(), "-p", std::to_string(server_port).c_str(), "-l", (char *)NULL);
             }
             /* There was an error */
                 execl(nsupdate.c_str(), nsupdate.c_str(), "-p", std::to_string(server_port).c_str(), "-l", (char *)NULL);
             }
             /* There was an error */