Exemple #1
0
static void
AddConfigFileToList(int config, const TCHAR *filename, const TCHAR *config_dir)
{
    connection_t *c = &o.conn[config];
    int i;

    _tcsncpy(c->config_file, filename, _countof(c->config_file) - 1);
    _tcsncpy(c->config_dir, config_dir, _countof(c->config_dir) - 1);
    _tcsncpy(c->config_name, c->config_file, _countof(c->config_name) - 1);
    c->config_name[_tcslen(c->config_name) - _tcslen(o.ext_string) - 1] = _T('\0');
    _sntprintf_0(c->log_path, _T("%s\\%s.log"), o.log_dir, c->config_name);

    c->manage.sk = INVALID_SOCKET;
    c->manage.skaddr.sin_family = AF_INET;
    c->manage.skaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    c->manage.skaddr.sin_port = htons(25340 + config);

    /* Check if connection should be autostarted */
    for (i = 0; i < MAX_CONFIGS && o.auto_connect[i]; ++i)
    {
        if (_tcsicmp(c->config_file, o.auto_connect[i]) == 0)
        {
            c->auto_connect = true;
            break;
        }
    }
}
Exemple #2
0
void
RunDisconnectScript(connection_t *c, int run_as_service)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    TCHAR cmdline[256];
    DWORD exit_code;
    struct _stat st;
    int i;

    /* Cut off extention from config filename and add "_down.bat" */
    int len = _tcslen(c->config_file) - _tcslen(o.ext_string) - 1;
    _sntprintf_0(cmdline, _T("%s\\%.*s_down.bat"), c->config_dir, len, c->config_file);

    /* Return if no script exists */
    if (_tstat(cmdline, &st) == -1)
        return;

    if (!run_as_service)
        SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONN_SCRIPT));

    CLEAR(si);
    CLEAR(pi);

    /* fill in STARTUPINFO struct */
    GetStartupInfo(&si);
    si.cb = sizeof(si);
    si.dwFlags = 0;
    si.wShowWindow = SW_SHOWDEFAULT;
    si.hStdInput = NULL;
    si.hStdOutput = NULL;

    /* make an env array with confg specific env appended to the process's env */
    WCHAR *env = c->es ? merge_env_block(c->es) : NULL;
    DWORD flags = CREATE_UNICODE_ENVIRONMENT;

    if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE,
                       (o.show_script_window ? flags|CREATE_NEW_CONSOLE : flags|CREATE_NO_WINDOW),
                       NULL, c->config_dir, &si, &pi))
    {
        free(env);
        return;
    }

    for (i = 0; i <= (int) o.disconnectscript_timeout; i++)
    {
        if (!GetExitCodeProcess(pi.hProcess, &exit_code))
            goto out;

        if (exit_code != STILL_ACTIVE)
            goto out;

        Sleep(1000);
    }
out:
    free(env);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
}
Exemple #3
0
void
RunPreconnectScript(connection_t *c)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    TCHAR cmdline[256];
    DWORD exit_code;
    struct _stat st;
    int i;

    /* Cut off extention from config filename and add "_pre.bat" */
    int len = _tcslen(c->config_file) - _tcslen(o.ext_string) - 1;
    _sntprintf_0(cmdline, _T("%s\\%.*s_pre.bat"), c->config_dir, len, c->config_file);

    /* Return if no script exists */
    if (_tstat(cmdline, &st) == -1)
        return;

    CLEAR(si);
    CLEAR(pi);

    /* fill in STARTUPINFO struct */
    GetStartupInfo(&si);
    si.cb = sizeof(si);
    si.dwFlags = 0;
    si.wShowWindow = SW_SHOWDEFAULT;
    si.hStdInput = NULL;
    si.hStdOutput = NULL;

    /* Preconnect script is run too early for config env to be available
     * so we use the default process env here.
     */

    if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE,
                       (o.show_script_window ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW),
                       NULL, c->config_dir, &si, &pi))
        return;

    for (i = 0; i <= (int) o.preconnectscript_timeout; i++)
    {
        if (!GetExitCodeProcess(pi.hProcess, &exit_code))
            goto out;

        if (exit_code != STILL_ACTIVE)
            goto out;

        Sleep(1000);
    }
out:
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
}
void EditConfig(int config)
{
  TCHAR filename[200];

  STARTUPINFO start_info;
  PROCESS_INFORMATION proc_info;
  SECURITY_ATTRIBUTES sa;
  SECURITY_DESCRIPTOR sd;

  CLEAR (start_info);
  CLEAR (proc_info);
  CLEAR (sa);
  CLEAR (sd);

  _sntprintf_0(filename, _T("%s \"%s\\%s\""), o.editor, o.conn[config].config_dir, o.conn[config].config_file);

  /* fill in STARTUPINFO struct */
  GetStartupInfo(&start_info);
  start_info.cb = sizeof(start_info);
  start_info.dwFlags = 0;
  start_info.wShowWindow = SW_SHOWDEFAULT;
  start_info.hStdInput = NULL;
  start_info.hStdOutput = NULL;

  if (!CreateProcess(NULL,
		     filename, 	//commandline
		     NULL,
		     NULL,
		     TRUE,
		     CREATE_NEW_CONSOLE,
		     NULL,
		     o.conn[config].config_dir,	//start-up dir
		     &start_info,
		     &proc_info))
    {
        /* could not start editor */ 
	ShowLocalizedMsg(IDS_ERR_START_CONF_EDITOR, o.editor);
    }

  CloseHandle(proc_info.hThread);
  CloseHandle(proc_info.hProcess);
}
void ViewLog(int config)
{
  TCHAR filename[200];

  STARTUPINFO start_info;
  PROCESS_INFORMATION proc_info;
  SECURITY_ATTRIBUTES sa;
  SECURITY_DESCRIPTOR sd;

  CLEAR (start_info);
  CLEAR (proc_info);
  CLEAR (sa);
  CLEAR (sd);

  _sntprintf_0(filename, _T("%s \"%s\""), o.log_viewer, o.conn[config].log_path);

  /* fill in STARTUPINFO struct */
  GetStartupInfo(&start_info);
  start_info.cb = sizeof(start_info);
  start_info.dwFlags = 0;
  start_info.wShowWindow = SW_SHOWDEFAULT;
  start_info.hStdInput = NULL;
  start_info.hStdOutput = NULL;

  if (!CreateProcess(NULL,
		     filename, 	//commandline
		     NULL,
		     NULL,
		     TRUE,
		     CREATE_NEW_CONSOLE,
		     NULL,
		     o.log_dir,	//start-up dir
		     &start_info,
		     &proc_info))
    {
      /* could not start log viewer */
      ShowLocalizedMsg(IDS_ERR_START_LOG_VIEWER, o.log_viewer);
    }

}
void
RunConnectScript(connection_t *c, int run_as_service)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    TCHAR cmdline[256];
    DWORD exit_code;
    struct _stat st;
    int i;

    /* Cut off extention from config filename and add "_up.bat" */
    int len = _tcslen(c->config_file) - _tcslen(o.ext_string) - 1;
    _sntprintf_0(cmdline, _T("%s\\%.*s_up.bat"), c->config_dir, len, c->config_file);

    /* Return if no script exists */
    if (_tstat(cmdline, &st) == -1)
        return;

    if (!run_as_service)
        SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONN_SCRIPT));

    CLEAR(si);
    CLEAR(pi);

    /* fill in STARTUPINFO struct */
    GetStartupInfo(&si);
    si.cb = sizeof(si);
    si.dwFlags = 0;
    si.wShowWindow = SW_SHOWDEFAULT;
    si.hStdInput = NULL;
    si.hStdOutput = NULL;

    if (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE,
                       (o.show_script_window[0] == '1' ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW),
                       NULL, c->config_dir, &si, &pi))
    {
        ShowLocalizedMsg(IDS_ERR_RUN_CONN_SCRIPT, cmdline);
        return;
    }

    if (o.connectscript_timeout == 0)
        goto out;

    for (i = 0; i <= o.connectscript_timeout; i++)
    {
        if (!GetExitCodeProcess(pi.hProcess, &exit_code))
        {
            ShowLocalizedMsg(IDS_ERR_GET_EXIT_CODE, cmdline);
            goto out;
        }

        if (exit_code != STILL_ACTIVE)
        {
            if (exit_code != 0)
                ShowLocalizedMsg(IDS_ERR_CONN_SCRIPT_FAILED, exit_code);
            goto out;
        }

        Sleep(1000);
    }

    ShowLocalizedMsg(IDS_ERR_RUN_CONN_SCRIPT_TIMEOUT, o.connectscript_timeout);

out:
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
}
Exemple #7
0
static void
BuildFileList0(const TCHAR *config_dir, bool warn_duplicates)
{
    WIN32_FIND_DATA find_obj;
    HANDLE find_handle;
    TCHAR find_string[MAX_PATH];
    TCHAR subdir_table[MAX_CONFIG_SUBDIRS][MAX_PATH];
    TCHAR fullpath[MAX_PATH];
    int subdirs = 0;
    int i;

    _sntprintf_0(find_string, _T("%s\\*"), config_dir);
    find_handle = FindFirstFile(find_string, &find_obj);
    if (find_handle == INVALID_HANDLE_VALUE)
        return;

    /* Loop over each config file in main config dir */
    do
    {
        if (o.num_configs >= MAX_CONFIGS)
        {
            ShowLocalizedMsg(IDS_ERR_MANY_CONFIGS, MAX_CONFIGS);
            break;
        }

        match_t match_type = match(&find_obj, o.ext_string);
        if (match_type == match_file)
        {
            _sntprintf_0(fullpath, _T("%s\\%s"), config_dir, find_obj.cFileName);

            if (ConfigAlreadyExists(find_obj.cFileName))
            {
                if (warn_duplicates)
                    ShowLocalizedMsg(IDS_ERR_CONFIG_EXIST, find_obj.cFileName);
                continue;
            }

            if (CheckReadAccess (fullpath))
                AddConfigFileToList(o.num_configs++, find_obj.cFileName, config_dir);
        }
        else if (match_type == match_dir)
        {
            if (_tcsncmp(find_obj.cFileName, _T("."), _tcslen(find_obj.cFileName)) != 0
            &&  _tcsncmp(find_obj.cFileName, _T(".."), _tcslen(find_obj.cFileName)) != 0
            &&  subdirs < MAX_CONFIG_SUBDIRS)
            {
                /* Add dir to dir_table */
                _sntprintf_0(subdir_table[subdirs], _T("%s\\%s"), config_dir, find_obj.cFileName);
                subdirs++;
            }
        }
    } while (FindNextFile(find_handle, &find_obj));

    FindClose(find_handle);

    /* Loop over each config file in every subdir */
    for (i = 0; i < subdirs; ++i)
    {
        _sntprintf_0(find_string, _T("%s\\*"), subdir_table[i]);

        find_handle = FindFirstFile (find_string, &find_obj);
        if (find_handle == INVALID_HANDLE_VALUE)
            continue;

        do
        {
            if (o.num_configs >= MAX_CONFIGS)
            {
                ShowLocalizedMsg(IDS_ERR_MANY_CONFIGS, MAX_CONFIGS);
                FindClose(find_handle);
                return;
            }

            /* does file have the correct type and extension? */
            if (match(&find_obj, o.ext_string) != match_file)
                continue;

            if (ConfigAlreadyExists(find_obj.cFileName))
            {
                if (warn_duplicates)
                    ShowLocalizedMsg(IDS_ERR_CONFIG_EXIST, find_obj.cFileName);
                continue;
            }

            AddConfigFileToList(o.num_configs++, find_obj.cFileName, subdir_table[i]);
        } while (FindNextFile(find_handle, &find_obj));

        FindClose(find_handle);
    }
}
Exemple #8
0
/*
 * Launch an OpenVPN process and the accompanying thread to monitor it
 */
BOOL
StartOpenVPN(connection_t *c)
{
    TCHAR cmdline[1024];
    TCHAR *options = cmdline + 8;
    TCHAR exit_event_name[17];
    HANDLE hStdInRead = NULL, hStdInWrite = NULL;
    HANDLE hNul = NULL, hThread = NULL;
    DWORD written;
    BOOL retval = FALSE;

    CLEAR(c->ip);

    if (c->hwndStatus)
    {
        PrintDebug(L"Connection request when previous status window is still open -- ignored");
        WriteStatusLog(c, L"OpenVPN GUI> ",
                       L"Complete the pending dialog before starting a new connection", false);
        SetForegroundWindow(c->hwndStatus);
        return FALSE;
    }

    RunPreconnectScript(c);

    /* Create thread to show the connection's status dialog */
    hThread = CreateThread(NULL, 0, ThreadOpenVPNStatus, c, CREATE_SUSPENDED, &c->threadId);
    if (hThread == NULL)
    {
        ShowLocalizedMsg(IDS_ERR_CREATE_THREAD_STATUS);
        goto out;
    }

    /* Create an event object to signal OpenVPN to exit */
    _sntprintf_0(exit_event_name, _T("%x%08x"), GetCurrentProcessId(), c->threadId);
    c->exit_event = CreateEvent(NULL, TRUE, FALSE, exit_event_name);
    if (c->exit_event == NULL)
    {
        ShowLocalizedMsg(IDS_ERR_CREATE_EVENT, exit_event_name);
        goto out;
    }

    /* Create a management interface password */
    GetRandomPassword(c->manage.password, sizeof(c->manage.password) - 1);

    /* Construct command line -- put log first */
    _sntprintf_0(cmdline, _T("openvpn --log%s \"%s\" --config \"%s\" "
        "--setenv IV_GUI_VER \"%S\" --service %s 0 --auth-retry interact "
        "--management %S %hd stdin --management-query-passwords %s"
        "--management-hold"),
        (o.log_append ? _T("-append") : _T("")), c->log_path,
        c->config_file, PACKAGE_STRING, exit_event_name,
        inet_ntoa(c->manage.skaddr.sin_addr), ntohs(c->manage.skaddr.sin_port),
        (o.proxy_source != config ? _T("--management-query-proxy ") : _T("")));

    /* Try to open the service pipe */
    if (!IsUserAdmin() && InitServiceIO (&c->iserv))
    {
        DWORD size = _tcslen(c->config_dir) + _tcslen(options) + sizeof(c->manage.password) + 3;
        TCHAR startup_info[1024];

        if ( !AuthorizeConfig(c))
        {
            CloseHandle(c->exit_event);
            goto out;
        }

        c->hProcess = NULL;
        c->manage.password[sizeof(c->manage.password) - 1] = '\n';
        _sntprintf_0(startup_info, _T("%s%c%s%c%.*S"), c->config_dir, _T('\0'),
            options, _T('\0'), sizeof(c->manage.password), c->manage.password);
        c->manage.password[sizeof(c->manage.password) - 1] = '\0';

        if (!WritePipe(c->iserv.pipe, startup_info, size * sizeof (TCHAR)))
        {
            ShowLocalizedMsg (IDS_ERR_WRITE_SERVICE_PIPE);
            CloseHandle(c->exit_event);
            CloseServiceIO(&c->iserv);
            goto out;
        }
    }
    else
    {
        /* Start OpenVPN directly */
        DWORD priority;
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        SECURITY_DESCRIPTOR sd;

        /* Make I/O handles inheritable and accessible by all */
        SECURITY_ATTRIBUTES sa = {
            .nLength = sizeof(sa),
            .lpSecurityDescriptor = &sd,
            .bInheritHandle = TRUE
        };

        if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
        {
            ShowLocalizedMsg(IDS_ERR_INIT_SEC_DESC);
            CloseHandle(c->exit_event);
            return FALSE;
        }
        if (!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
        {
            ShowLocalizedMsg(IDS_ERR_SET_SEC_DESC_ACL);
            CloseHandle(c->exit_event);
            return FALSE;
        }

        /* Set process priority */
        if (!SetProcessPriority(&priority))
        {
            CloseHandle(c->exit_event);
            return FALSE;
        }

        /* Get a handle of the NUL device */
        hNul = CreateFile(_T("NUL"), GENERIC_WRITE, FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, NULL);
        if (hNul == INVALID_HANDLE_VALUE)
        {
            CloseHandle(c->exit_event);
            return FALSE;
        }

        /* Create the pipe for STDIN with only the read end inheritable */
        if (!CreatePipe(&hStdInRead, &hStdInWrite, &sa, 0))
        {
            ShowLocalizedMsg(IDS_ERR_CREATE_PIPE_IN_READ);
            CloseHandle(c->exit_event);
            goto out;
        }
        if (!SetHandleInformation(hStdInWrite, HANDLE_FLAG_INHERIT, 0))
        {
            ShowLocalizedMsg(IDS_ERR_DUP_HANDLE_IN_WRITE);
            CloseHandle(c->exit_event);
            goto out;
        }

        /* Fill in STARTUPINFO struct */
        GetStartupInfo(&si);
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESTDHANDLES;
        si.hStdInput = hStdInRead;
        si.hStdOutput = hNul;
        si.hStdError = hNul;

        /* Create an OpenVPN process for the connection */
        if (!CreateProcess(o.exe_path, cmdline, NULL, NULL, TRUE,
                        priority | CREATE_NO_WINDOW, NULL, c->config_dir, &si, &pi))
        {
            ShowLocalizedMsg(IDS_ERR_CREATE_PROCESS, o.exe_path, cmdline, c->config_dir);
            CloseHandle(c->exit_event);
            goto out;
        }

        /* Pass management password to OpenVPN process */
        c->manage.password[sizeof(c->manage.password) - 1] = '\n';
        WriteFile(hStdInWrite, c->manage.password, sizeof(c->manage.password), &written, NULL);
        c->manage.password[sizeof(c->manage.password) - 1] = '\0';

        c->hProcess = pi.hProcess; /* Will be closed in the event loop on exit */
        CloseHandle(pi.hThread);
    }

    /* Start the status dialog thread */
    ResumeThread(hThread);
    retval = TRUE;

out:
    if (hThread && hThread != INVALID_HANDLE_VALUE)
        CloseHandle(hThread);
    if (hStdInWrite && hStdInWrite != INVALID_HANDLE_VALUE)
        CloseHandle(hStdInWrite);
    if (hStdInRead && hStdInRead != INVALID_HANDLE_VALUE)
        CloseHandle(hStdInRead);
    if (hNul && hNul != INVALID_HANDLE_VALUE)
        CloseHandle(hNul);
    return retval;
}


void
StopOpenVPN(connection_t *c)
{
    PostMessage(c->hwndStatus, WM_OVPN_STOP, 0, 0);
}
Exemple #9
0
int
GetRegistryKeys()
{
  TCHAR windows_dir[MAX_PATH];
  TCHAR temp_path[MAX_PATH];
  TCHAR openvpn_path[MAX_PATH];
  TCHAR profile_dir[MAX_PATH];
  HKEY regkey;

  if (!GetWindowsDirectory(windows_dir, _countof(windows_dir))) {
    /* can't get windows dir */
    ShowLocalizedMsg(IDS_ERR_GET_WINDOWS_DIR);
    return(false);
  }

  if (SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, profile_dir) != S_OK) {
    ShowLocalizedMsg(IDS_ERR_GET_PROFILE_DIR);
    return(false);
  }

  /* Get path to OpenVPN installation. */
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\OpenVPN"), 0, KEY_READ, &regkey)
      != ERROR_SUCCESS) 
    {
      /* registry key not found */
      ShowLocalizedMsg(IDS_ERR_OPEN_REGISTRY);
      return(false);
    }
  if (!GetRegistryValue(regkey, _T(""), openvpn_path, _countof(openvpn_path)))
    {
      /* error reading registry value */
      ShowLocalizedMsg(IDS_ERR_READING_REGISTRY);
      RegCloseKey(regkey);
      return(false);
    }
  if (openvpn_path[_tcslen(openvpn_path) - 1] != _T('\\'))
    _tcscat(openvpn_path, _T("\\"));

  /* an admin-defined global config dir defined in HKLM\OpenVPN\config_dir */
  if (!GetRegistryValue(regkey, _T("config_dir"), o.global_config_dir, _countof(o.global_config_dir)))
    {
      /* use default = openvpnpath\config */
      _sntprintf_0(o.global_config_dir, _T("%sconfig"), openvpn_path);
    }
  if (!GetRegistryValue(regkey, _T("ovpn_admin_group"), o.ovpn_admin_group, _countof(o.ovpn_admin_group)))
    {
      _tcsncpy(o.ovpn_admin_group, OVPN_ADMIN_GROUP, _countof(o.ovpn_admin_group));
    }
  RegCloseKey(regkey);

  /* config_dir in user's profile by default */
  _sntprintf_0(temp_path, _T("%s\\OpenVPN\\config"), profile_dir);
  if (!GetRegKey(_T("config_dir"), o.config_dir, 
      temp_path, _countof(o.config_dir))) return(false);

  if (!GetRegKey(_T("config_ext"), o.ext_string, _T("ovpn"), _countof(o.ext_string))) return(false);

  _sntprintf_0(temp_path, _T("%sbin\\openvpn.exe"), openvpn_path);
  if (!GetRegKey(_T("exe_path"), o.exe_path, 
      temp_path, _countof(o.exe_path))) return(false);

  _sntprintf_0(temp_path, _T("%s\\OpenVPN\\log"), profile_dir);
  if (!GetRegKey(_T("log_dir"), o.log_dir, 
      temp_path, _countof(o.log_dir))) return(false);

  if (!GetRegKey(_T("log_append"), o.append_string, _T("0"), _countof(o.append_string))) return(false);

  if (!GetRegKey(_T("priority"), o.priority_string, 
      _T("NORMAL_PRIORITY_CLASS"), _countof(o.priority_string))) return(false);

  _sntprintf_0(temp_path, _T("%s\\system32\\notepad.exe"), windows_dir);
  if (!GetRegKey(_T("log_viewer"), o.log_viewer, 
      temp_path, _countof(o.log_viewer))) return(false);

  _sntprintf_0(temp_path, _T("%s\\system32\\notepad.exe"), windows_dir);
  if (!GetRegKey(_T("editor"), o.editor, 
      temp_path, _countof(o.editor))) return(false);

  if (!GetRegKey(_T("allow_edit"), o.allow_edit, _T("1"), _countof(o.allow_edit))) return(false);
  
  if (!GetRegKey(_T("allow_service"), o.allow_service, _T("0"), _countof(o.allow_service))) return(false);

  if (!GetRegKey(_T("allow_password"), o.allow_password, _T("1"), _countof(o.allow_password))) return(false);

  if (!GetRegKey(_T("allow_proxy"), o.allow_proxy, _T("1"), _countof(o.allow_proxy))) return(false);

  if (!GetRegKey(_T("service_only"), o.service_only, _T("0"), _countof(o.service_only))) return(false);

  if (!GetRegKey(_T("show_balloon"), o.show_balloon, _T("1"), _countof(o.show_balloon))) return(false);

  if (!GetRegKey(_T("silent_connection"), o.silent_connection, _T("0"), _countof(o.silent_connection))) return(false);

  if (!GetRegKey(_T("show_script_window"), o.show_script_window, _T("1"), _countof(o.show_script_window))) return(false);

  if (!GetRegKey(_T("disconnect_on_suspend"), o.disconnect_on_suspend, _T("0"),
      _countof(o.disconnect_on_suspend))) return(false);

  if (!GetRegKey(_T("passphrase_attempts"), o.psw_attempts_string, _T("3"), 
      _countof(o.psw_attempts_string))) return(false);
  o.psw_attempts = _ttoi(o.psw_attempts_string);
  if ((o.psw_attempts < 1) || (o.psw_attempts > 9))
    {
      /* 0 <= passphrase_attempts <= 9 */
      ShowLocalizedMsg(IDS_ERR_PASSPHRASE_ATTEMPTS);
      return(false);
    }

  if (!GetRegKey(_T("connectscript_timeout"), o.connectscript_timeout_string, _T("15"), 
      _countof(o.connectscript_timeout_string))) return(false);
  o.connectscript_timeout = _ttoi(o.connectscript_timeout_string);
  if ((o.connectscript_timeout < 0) || (o.connectscript_timeout > 99))
    {
      /* 0 <= connectscript_timeout <= 99 */
      ShowLocalizedMsg(IDS_ERR_CONN_SCRIPT_TIMEOUT);
      return(false);
    }

  if (!GetRegKey(_T("disconnectscript_timeout"), o.disconnectscript_timeout_string, _T("10"), 
      _countof(o.disconnectscript_timeout_string))) return(false);
  o.disconnectscript_timeout = _ttoi(o.disconnectscript_timeout_string);
  if ((o.disconnectscript_timeout <= 0) || (o.disconnectscript_timeout > 99))
    {
      /* 0 < disconnectscript_timeout <= 99 */
      ShowLocalizedMsg(IDS_ERR_DISCONN_SCRIPT_TIMEOUT);
      return(false);
    }

  if (!GetRegKey(_T("preconnectscript_timeout"), o.preconnectscript_timeout_string, _T("10"), 
      _countof(o.preconnectscript_timeout_string))) return(false);
  o.preconnectscript_timeout = _ttoi(o.preconnectscript_timeout_string);
  if ((o.preconnectscript_timeout <= 0) || (o.preconnectscript_timeout > 99))
    {
      /* 0 < disconnectscript_timeout <= 99 */
      ShowLocalizedMsg(IDS_ERR_PRECONN_SCRIPT_TIMEOUT);
      return(false);
    }

  return(true);
}