]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Validate -n service name parameter value
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 14 Jul 2014 12:58:03 +0000 (05:58 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 14 Jul 2014 12:58:03 +0000 (05:58 -0700)
Service name is used for path prefixes in SHM/UDS sockets, Windows
service name, Unix/Linux/BSD daemon names, and file path segments.

Restrict service names to a max 32 character alphanumeric value in order
to accommodate as widely portable names as possible in all these cases.

src/WinSvc.cc
src/cache_cf.cc
src/globals.h
src/ipc/Port.cc
src/main.cc
src/stat.cc

index 976ee9a8acb4c3282cb1873b5747619721332524..385f4d1e318b4bba499dc0ac7eb33fde4e6eb4b3 100644 (file)
@@ -510,7 +510,7 @@ int WIN32_Subsystem_Init(int * argc, char *** argv)
             return 1;
 
         /* Register the service Handler function */
-        svcHandle = RegisterServiceCtrlHandler(service_name, WIN32_svcHandler);
+        svcHandle = RegisterServiceCtrlHandler(service_name.c_str(), WIN32_svcHandler);
 
         if (svcHandle == 0)
             return 1;
@@ -671,12 +671,13 @@ WIN32_RemoveService()
     SC_HANDLE schService;
     SC_HANDLE schSCManager;
 
-    if (!service_name)
-        service_name = xstrdup(APP_SHORTNAME);
+    if (service_name.isEmpty())
+        service_name = SBuf(APP_SHORTNAME);
 
-    strcat(REGKEY, service_name);
+    const char *service =  service_name.c_str();
+    strcat(REGKEY, service);
 
-    keys[4] = service_name;
+    keys[4] = service;
 
     schSCManager = OpenSCManager(NULL, /* machine (NULL == local)    */
                                  NULL,                 /* database (NULL == default) */
@@ -686,7 +687,7 @@ WIN32_RemoveService()
     if (!schSCManager)
         fprintf(stderr, "OpenSCManager failed\n");
     else {
-        schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS);
+        schService = OpenService(schSCManager, service, SERVICE_ALL_ACCESS);
 
         if (schService == NULL)
             fprintf(stderr, "OpenService failed\n");
@@ -711,7 +712,7 @@ WIN32_RemoveService()
             if (DeleteService(schService) == 0)
                 fprintf(stderr, "DeleteService failed.\n");
             else
-                printf("Service %s deleted successfully.\n", service_name);
+                printf("Service " SQUIDSBUFPH " deleted successfully.\n", SQUIDSBUFPRINT(service_name));
 
             CloseServiceHandle(schService);
         }
@@ -723,12 +724,13 @@ WIN32_RemoveService()
 void
 WIN32_SetServiceCommandLine()
 {
-    if (!service_name)
-        service_name = xstrdup(APP_SHORTNAME);
+    if (service_name.isEmpty())
+        service_name = SBuf(APP_SHORTNAME);
 
-    strcat(REGKEY, service_name);
+    const char *service = servie_name.c_str();
+    strcat(REGKEY, service);
 
-    keys[4] = service_name;
+    keys[4] = service;
 
     /* Now store the Service Command Line in the registry */
     WIN32_StoreKey(COMMANDLINE, REG_SZ, (unsigned char *) WIN32_Command_Line, strlen(WIN32_Command_Line) + 1);
@@ -743,19 +745,20 @@ WIN32_InstallService()
     char szPath[512];
     int lenpath;
 
-    if (!service_name)
-        service_name = xstrdup(APP_SHORTNAME);
+    if (service_name.isEmpty())
+        service_name = SBuf(APP_SHORTNAME);
 
-    strcat(REGKEY, service_name);
+    const char *service = service_name.c_str();
+    strcat(REGKEY, service);
 
-    keys[4] = service_name;
+    keys[4] = service;
 
     if ((lenpath = GetModuleFileName(NULL, ServicePath, 512)) == 0) {
         fprintf(stderr, "Can't get executable path\n");
         exit(1);
     }
 
-    snprintf(szPath, sizeof(szPath), "%s %s:%s", ServicePath, _WIN_SQUID_SERVICE_OPTION, service_name);
+    snprintf(szPath, sizeof(szPath), "%s %s:" SQUIDSBUFPH, ServicePath, _WIN_SQUID_SERVICE_OPTION, SQUIDSBUFPRINT(service_name));
     schSCManager = OpenSCManager(NULL, /* machine (NULL == local)    */
                                  NULL,                 /* database (NULL == default) */
                                  SC_MANAGER_ALL_ACCESS /* access required            */
@@ -766,8 +769,8 @@ WIN32_InstallService()
         exit(1);
     } else {
         schService = CreateService(schSCManager,    /* SCManager database     */
-                                   service_name,                           /* name of service        */
-                                   service_name,                           /* name to display        */
+                                   service,                        /* name of service        */
+                                   service,                        /* name to display        */
                                    SERVICE_ALL_ACCESS,                     /* desired access         */
                                    SERVICE_WIN32_OWN_PROCESS,              /* service type           */
                                    SERVICE_AUTO_START,                     /* start type             */
@@ -801,7 +804,7 @@ WIN32_InstallService()
             WIN32_StoreKey(CONFIGFILE, REG_SZ, (unsigned char *) ConfigFile, strlen(ConfigFile) + 1);
 
             printf("Squid Cache version %s for %s\n", version_string, CONFIG_HOST_TYPE);
-            printf("installed successfully as %s Windows System Service.\n", service_name);
+            printf("installed successfully as " SQUIDSBUFPH " Windows System Service.\n", SQUIDSBUFPRINT(service_name));
             printf("To run, start it from the Services Applet of Control Panel.\n");
             printf("Don't forget to edit squid.conf before starting it.\n\n");
         } else {
@@ -821,8 +824,8 @@ WIN32_sendSignal(int WIN32_signal)
     SC_HANDLE schService;
     SC_HANDLE schSCManager;
 
-    if (!service_name)
-        service_name = xstrdup(APP_SHORTNAME);
+    if (service_name.isEmpty())
+        service_name = SBuf(APP_SHORTNAME);
 
     schSCManager = OpenSCManager(NULL, /* machine (NULL == local)    */
                                  NULL,                 /* database (NULL == default) */
@@ -875,11 +878,11 @@ WIN32_sendSignal(int WIN32_signal)
 
     /* Open a handle to the service. */
     schService = OpenService(schSCManager,     /* SCManager database */
-                             service_name,     /* name of service    */
+                             service_name.c_str(),     /* name of service    */
                              fdwAccess);               /* specify access     */
 
     if (schService == NULL) {
-        fprintf(stderr, "%s: ERROR: Could not open Service %s\n", APP_SHORTNAME, service_name);
+        fprintf(stderr, "%s: ERROR: Could not open Service " SQUIDSBUFPH "\n", APP_SHORTNAME, SQUIDSBUFPRINT(service_name));
         exit(1);
     } else {
         /* Send a control value to the service. */
@@ -887,12 +890,12 @@ WIN32_sendSignal(int WIN32_signal)
         if (!ControlService(schService,        /* handle of service      */
                             fdwControl,        /* control value to send  */
                             &ssStatus)) {      /* address of status info */
-            fprintf(stderr, "%s: ERROR: Could not Control Service %s\n",
-                    APP_SHORTNAME, service_name);
+            fprintf(stderr, "%s: ERROR: Could not Control Service " SQUIDSBUFPH "\n",
+                    APP_SHORTNAME, SQUIDSBUFPRINT(service_name));
             exit(1);
         } else {
             /* Print the service status. */
-            printf("\nStatus of %s Service:\n", service_name);
+            printf("\nStatus of " SQUIDSBUFPH " Service:\n", SQUIDSBUFPRINT(service_name));
             printf("  Service Type: 0x%lx\n", ssStatus.dwServiceType);
             printf("  Current State: 0x%lx\n", ssStatus.dwCurrentState);
             printf("  Controls Accepted: 0x%lx\n", ssStatus.dwControlsAccepted);
@@ -931,10 +934,11 @@ int main(int argc, char **argv)
             return 1;
         }
 
-        service_name = xstrdup(c+1);
-        DispatchTable[0].lpServiceName=service_name;
-        strcat(REGKEY, service_name);
-        keys[4] = service_name;
+        service_name = SBuf(c+1);
+        const char *service = service_name.c_str();
+        DispatchTable[0].lpServiceName=service;
+        strcat(REGKEY, service);
+        keys[4] = service;
 
         if (!StartServiceCtrlDispatcher(DispatchTable)) {
             fprintf(stderr, "StartServiceCtrlDispatcher error = %ld\n",
index 8ac2e8468bb08f343ae113c14ca4a870bfc782a5..413379339f1dde0a69564755bb16b1b75cb6417f 100644 (file)
@@ -358,7 +358,7 @@ SubstituteMacro(char*& line, int& len, const char* macroName, const char* substS
 static void
 ProcessMacros(char*& line, int& len)
 {
-    SubstituteMacro(line, len, "${service_name}", service_name);
+    SubstituteMacro(line, len, "${service_name}", service_name.c_str());
     SubstituteMacro(line, len, "${process_name}", TheKidName);
     SubstituteMacro(line, len, "${process_number}", xitoa(KidIdentifier));
 }
index 0305e47d1b1f38718fa5cbbf745a3f72c4d8d4f1..e90bb92efb0bb2f682325d15d19255719be6c611 100644 (file)
@@ -36,6 +36,7 @@
 #include "hash.h"
 #include "IoStats.h"
 #include "rfc2181.h"
+#include "SBuf.h"
 
 extern char *ConfigFile;       /* NULL */
 extern char *IcpOpcodeStr[];
@@ -52,7 +53,7 @@ extern const char *null_string;       /* "" */
 extern const char *version_string;     /* VERSION */
 extern const char *appname_string;     /* PACKAGE */
 extern char const *visible_appname_string; /* NULL */
-extern char *service_name;        /* xstrdup(APP_SHORTNAME) */
+extern SBuf service_name;        /* SBuf(APP_SHORTNAME) */
 extern const char *fdTypeStr[];
 extern const char *hier_strings[];
 extern const char *memStatusStr[];
index 1d8029cc2fc0273cd011a3b8978f3af29b56b4fb..409b1d97f6e989a548f91c3d76aaa9ad2adf052f 100644 (file)
@@ -46,7 +46,7 @@ String Ipc::Port::MakeAddr(const char* processLabel, int id)
 {
     assert(id >= 0);
     String addr = channelPathPfx;
-    addr.append(service_name);
+    addr.append(service_name.c_str());
     addr.append(processLabel);
     addr.append('-');
     addr.append(xitoa(id));
@@ -60,7 +60,7 @@ Ipc::Port::CoordinatorAddr()
     static String coordinatorAddr;
     if (!coordinatorAddr.size()) {
         coordinatorAddr= channelPathPfx;
-        coordinatorAddr.append(service_name);
+        coordinatorAddr.append(service_name.c_str());
         coordinatorAddr.append(coordinatorAddrLabel);
         coordinatorAddr.append(".ipc");
     }
index f388a8fa51f0760c583ac466ec41a3899dbd834d..e07028552dbd442acde655fb0968f0c0d6b9d997 100644 (file)
@@ -73,6 +73,7 @@
 #include "MemPool.h"
 #include "mime.h"
 #include "neighbors.h"
+#include "parser/Tokenizer.h"
 #include "pconn.h"
 #include "peer_sourcehash.h"
 #include "peer_userhash.h"
@@ -506,10 +507,18 @@ mainParseOptions(int argc, char *argv[])
             /** \par n
              * Set global option opt_signal_service (to true).
              * Stores the additional parameter given in global service_name */
-            // XXX: verify that the new name has ONLY alphanumeric characters
-            xfree(service_name);
-            service_name = xstrdup(optarg);
-            opt_signal_service = true;
+            if (optarg || *optarg == '\0') {
+                const SBuf t(optarg);
+                ::Parser::Tokenizer tok(t);
+                const CharacterSet chr = CharacterSet::ALPHA+CharacterSet::DIGIT;
+                if (!tok.prefix(service_name, chr) || !tok.atEnd())
+                    fatalf("Expected alphanumeric service name for the -n option but got: " SQUIDSBUFPH, SQUIDSBUFPRINT(service_name));
+                if (service_name.length() > 32)
+                    fatalf("Service name (-n option) must be limited to 32 characters but got %u", service_name.length());
+                opt_signal_service = true;
+            } else {
+                fatal("A service name is required for the -n option");
+            }
             break;
 
 #if USE_WIN32_SERVICE
@@ -561,7 +570,7 @@ mainParseOptions(int argc, char *argv[])
             /** \par v
              * Display squid version and build information. Then exit. */
             printf("Squid Cache: Version %s\n" ,version_string);
-            printf("Service Name: %s\n", service_name);
+            printf("Service Name: " SQUIDSBUFPH "\n", SQUIDSBUFPRINT(service_name));
             if (strlen(SQUID_BUILD_INFO))
                 printf("%s\n",SQUID_BUILD_INFO);
             printf( "configure options: %s\n", SQUID_CONFIGURE_OPTIONS);
index 0e66be8fd45de7b85bc418acc17adb2b2f6f81e6..8eba5d91f42f0afef92a16540b8d4934e52114ea 100644 (file)
@@ -625,13 +625,13 @@ DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry)
 
 #if _SQUID_WINDOWS_
     if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
-        storeAppendPrintf(sentry,"\nRunning as %s Windows System Service on %s\n",
-                          Service_name, WIN32_OS_string);
+        storeAppendPrintf(sentry,"\nRunning as " SQUIDSBUFPH " Windows System Service on %s\n",
+                          SQUIDBUFPRINT(service_name), WIN32_OS_string);
         storeAppendPrintf(sentry,"Service command line is: %s\n", WIN32_Service_Command_Line);
     } else
         storeAppendPrintf(sentry,"Running on %s\n",WIN32_OS_string);
 #else
-    storeAppendPrintf(sentry,"Service Name: %s\n", service_name);
+    storeAppendPrintf(sentry,"Service Name: " SQUIDSBUFPH "\n", SQUIDSBUFPRINT(service_name));
 #endif
 
     storeAppendPrintf(sentry, "Start Time:\t%s\n",