Home | History | Annotate | Download | only in launcher
      1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sandbox/win/src/restricted_token_utils.h"
      6 
      7 // launcher.exe is an application used to launch another application with a
      8 // restricted token. This is to be used for testing only.
      9 // The parameters are the level of security of the primary token, the
     10 // impersonation token and the job object along with the command line to
     11 // execute.
     12 // See the usage (launcher.exe without parameters) for the correct format.
     13 
     14 #define PARAM_IS(y) (argc > i) && (_wcsicmp(argv[i], y) == 0)
     15 
     16 void PrintUsage(const wchar_t *application_name) {
     17   wprintf(L"\n\nUsage: \n  %ls --main level --init level --job level cmd_line ",
     18           application_name);
     19   wprintf(L"\n\n  Levels : \n\tLOCKDOWN \n\tRESTRICTED "
     20       L"\n\tLIMITED_USER \n\tINTERACTIVE_USER \n\tNON_ADMIN \n\tUNPROTECTED");
     21   wprintf(L"\n\n  main: Security level of the main token");
     22   wprintf(L"\n  init: Security level of the impersonation token");
     23   wprintf(L"\n  job: Security level of the job object");
     24 }
     25 
     26 bool GetTokenLevelFromString(const wchar_t *param,
     27                              sandbox::TokenLevel* level) {
     28   if (_wcsicmp(param, L"LOCKDOWN") == 0) {
     29     *level = sandbox::USER_LOCKDOWN;
     30   } else if (_wcsicmp(param, L"RESTRICTED") == 0) {
     31     *level = sandbox::USER_RESTRICTED;
     32   } else if (_wcsicmp(param, L"LIMITED_USER") == 0) {
     33     *level = sandbox::USER_LIMITED;
     34   } else if (_wcsicmp(param, L"INTERACTIVE_USER") == 0) {
     35     *level = sandbox::USER_INTERACTIVE;
     36   } else if (_wcsicmp(param, L"NON_ADMIN") == 0) {
     37     *level = sandbox::USER_NON_ADMIN;
     38   } else if (_wcsicmp(param, L"USER_RESTRICTED_SAME_ACCESS") == 0) {
     39     *level = sandbox::USER_RESTRICTED_SAME_ACCESS;
     40   } else if (_wcsicmp(param, L"UNPROTECTED") == 0) {
     41     *level = sandbox::USER_UNPROTECTED;
     42   } else {
     43     return false;
     44   }
     45 
     46   return true;
     47 }
     48 
     49 bool GetJobLevelFromString(const wchar_t *param, sandbox::JobLevel* level) {
     50   if (_wcsicmp(param, L"LOCKDOWN") == 0) {
     51     *level = sandbox::JOB_LOCKDOWN;
     52   } else if (_wcsicmp(param, L"RESTRICTED") == 0) {
     53     *level = sandbox::JOB_RESTRICTED;
     54   } else if (_wcsicmp(param, L"LIMITED_USER") == 0) {
     55     *level = sandbox::JOB_LIMITED_USER;
     56   } else if (_wcsicmp(param, L"INTERACTIVE_USER") == 0) {
     57     *level = sandbox::JOB_INTERACTIVE;
     58   } else if (_wcsicmp(param, L"NON_ADMIN") == 0) {
     59     wprintf(L"\nNON_ADMIN is not a supported job type");
     60     return false;
     61   } else if (_wcsicmp(param, L"UNPROTECTED") == 0) {
     62     *level = sandbox::JOB_UNPROTECTED;
     63   } else {
     64     return false;
     65   }
     66 
     67   return true;
     68 }
     69 
     70 int wmain(int argc, wchar_t *argv[]) {
     71   // Extract the filename from the path.
     72   wchar_t *app_name = wcsrchr(argv[0], L'\\');
     73   if (!app_name) {
     74     app_name = argv[0];
     75   } else {
     76     app_name++;
     77   }
     78 
     79   // no argument
     80   if (argc == 1) {
     81     PrintUsage(app_name);
     82     return -1;
     83   }
     84 
     85   sandbox::TokenLevel primary_level = sandbox::USER_LOCKDOWN;
     86   sandbox::TokenLevel impersonation_level =
     87       sandbox::USER_RESTRICTED_SAME_ACCESS;
     88   sandbox::JobLevel job_level = sandbox::JOB_LOCKDOWN;
     89   ATL::CString command_line;
     90 
     91   // parse command line.
     92   for (int i = 1; i < argc; ++i) {
     93     if (PARAM_IS(L"--main")) {
     94       i++;
     95       if (argc > i) {
     96         if (!GetTokenLevelFromString(argv[i], &primary_level)) {
     97           wprintf(L"\nAbord, Unrecognized main token level \"%ls\"", argv[i]);
     98           PrintUsage(app_name);
     99           return -1;
    100         }
    101       }
    102     } else if (PARAM_IS(L"--init")) {
    103       i++;
    104       if (argc > i) {
    105         if (!GetTokenLevelFromString(argv[i], &impersonation_level)) {
    106           wprintf(L"\nAbord, Unrecognized init token level \"%ls\"", argv[i]);
    107           PrintUsage(app_name);
    108           return -1;
    109         }
    110       }
    111     } else if (PARAM_IS(L"--job")) {
    112       i++;
    113       if (argc > i) {
    114         if (!GetJobLevelFromString(argv[i], &job_level)) {
    115           wprintf(L"\nAbord, Unrecognized job security level \"%ls\"", argv[i]);
    116           PrintUsage(app_name);
    117           return -1;
    118         }
    119       }
    120     } else {
    121       if (command_line.GetLength()) {
    122         command_line += L' ';
    123       }
    124       command_line += argv[i];
    125     }
    126   }
    127 
    128   if (!command_line.GetLength()) {
    129     wprintf(L"\nAbord, No command line specified");
    130     PrintUsage(app_name);
    131     return -1;
    132   }
    133 
    134   wprintf(L"\nLaunching command line: \"%ls\"\n", command_line.GetBuffer());
    135 
    136   HANDLE job_handle;
    137   DWORD err_code = sandbox::StartRestrictedProcessInJob(
    138       command_line.GetBuffer(),
    139       primary_level,
    140       impersonation_level,
    141       job_level,
    142       &job_handle);
    143   if (ERROR_SUCCESS != err_code) {
    144     wprintf(L"\nAbord, Error %d while launching command line.", err_code);
    145     return -1;
    146   }
    147 
    148   wprintf(L"\nPress any key to continue.");
    149   while(!_kbhit()) {
    150     Sleep(100);
    151   }
    152 
    153   ::CloseHandle(job_handle);
    154 
    155   return 0;
    156 }
    157