------------------------------------------------------------ revno: 13498 revision-id: squid3@treenet.co.nz-20140714125803-t39gkx9wcfve8dm0 parent: squid3@treenet.co.nz-20140714094847-w3ojd24bzmv00tl3 committer: Amos Jeffries branch nick: trunk timestamp: Mon 2014-07-14 05:58:03 -0700 message: Validate -n service name parameter value 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. ------------------------------------------------------------ # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: squid3@treenet.co.nz-20140714125803-t39gkx9wcfve8dm0 # target_branch: http://bzr.squid-cache.org/bzr/squid3/trunk/ # testament_sha1: 389fc46836415ebea10fdab348856ec9417da5df # timestamp: 2014-07-14 13:54:02 +0000 # source_branch: http://bzr.squid-cache.org/bzr/squid3/trunk/ # base_revision_id: squid3@treenet.co.nz-20140714094847-\ # w3ojd24bzmv00tl3 # # Begin patch === modified file 'src/WinSvc.cc' --- src/WinSvc.cc 2014-01-24 01:57:15 +0000 +++ src/WinSvc.cc 2014-07-14 12:58:03 +0000 @@ -510,7 +510,7 @@ 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 @@ SC_HANDLE schService; SC_HANDLE schSCManager; - if (!service_name) - service_name = xstrdup(APP_SHORTNAME); - - strcat(REGKEY, service_name); - - keys[4] = service_name; + if (service_name.isEmpty()) + service_name = SBuf(APP_SHORTNAME); + + const char *service = service_name.c_str(); + strcat(REGKEY, service); + + keys[4] = service; schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */ NULL, /* database (NULL == default) */ @@ -686,7 +687,7 @@ 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 @@ 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 @@ void WIN32_SetServiceCommandLine() { - if (!service_name) - service_name = xstrdup(APP_SHORTNAME); - - strcat(REGKEY, service_name); - - keys[4] = service_name; + if (service_name.isEmpty()) + service_name = SBuf(APP_SHORTNAME); + + const char *service = servie_name.c_str(); + strcat(REGKEY, service); + + 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 @@ char szPath[512]; int lenpath; - if (!service_name) - service_name = xstrdup(APP_SHORTNAME); - - strcat(REGKEY, service_name); - - keys[4] = service_name; + if (service_name.isEmpty()) + service_name = SBuf(APP_SHORTNAME); + + const char *service = service_name.c_str(); + strcat(REGKEY, service); + + 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 @@ 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_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 @@ 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 @@ /* 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 @@ 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 @@ 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", === modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2014-07-14 09:48:47 +0000 +++ src/cache_cf.cc 2014-07-14 12:58:03 +0000 @@ -358,7 +358,7 @@ 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)); } === modified file 'src/globals.h' --- src/globals.h 2014-06-24 22:52:53 +0000 +++ src/globals.h 2014-07-14 12:58:03 +0000 @@ -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 *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[]; === modified file 'src/ipc/Port.cc' --- src/ipc/Port.cc 2014-06-05 14:57:58 +0000 +++ src/ipc/Port.cc 2014-07-14 12:58:03 +0000 @@ -46,7 +46,7 @@ { 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 @@ static String coordinatorAddr; if (!coordinatorAddr.size()) { coordinatorAddr= channelPathPfx; - coordinatorAddr.append(service_name); + coordinatorAddr.append(service_name.c_str()); coordinatorAddr.append(coordinatorAddrLabel); coordinatorAddr.append(".ipc"); } === modified file 'src/main.cc' --- src/main.cc 2014-06-02 07:19:35 +0000 +++ src/main.cc 2014-07-14 12:58:03 +0000 @@ -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 @@ /** \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 @@ /** \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); === modified file 'src/stat.cc' --- src/stat.cc 2014-03-30 12:00:34 +0000 +++ src/stat.cc 2014-07-14 12:58:03 +0000 @@ -625,13 +625,13 @@ #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",