use managment interface

pull/1/head
Heiko Hund 2010-08-13 17:42:23 +02:00
parent 7c4bea3f7e
commit 4bcebba60f
32 changed files with 1873 additions and 2151 deletions

View File

@ -10,15 +10,14 @@ LIBS = @CRYPTO_LIBS@ @LIBS@
CFLAGS = @CRYPTO_CPPFLAGS@ @CFLAGS@ @CPPFLAGS@
CFLAGS += -W -Wall -Wno-unused-parameter -pedantic
OBJS = main.o tray.o openvpn.o openvpn_monitor_process.o viewlog.o \
service.o options.o passphrase.o proxy.o registry.o \
OBJS = main.o tray.o openvpn.o viewlog.o \
service.o options.o passphrase.o proxy.o registry.o manage.o \
openvpn_config.o scripts.o localization.o openvpn-gui-res.o
SOURCES = main.c main.h openvpn.c openvpn.h localization.c localization.h \
openvpn_monitor_process.c openvpn_monitor_process.h \
tray.c tray.h viewlog.c viewlog.h service.c service.h \
options.c options.h passphrase.c passphrase.h proxy.c proxy.h \
registry.c registry.h scripts.c scripts.h \
registry.c registry.h scripts.c scripts.h manage.c manage.h \
openvpn_config.c openvpn_config.h openvpn-gui.manifest \
chartable.h openvpn-gui-res.h openvpn-gui-res*.rc

10
TODO Normal file
View File

@ -0,0 +1,10 @@
TODOs for OpenVPN-GUI
* support usernames and passwords that contain a " character
* pass string length to IDS_NFO_CONNECTION_XXX
* move registry values below openvpn pregistry key
* convert boolean registry values from string to dword
* maybe parse config and use selected options in command line directly
* have some kind of error log instead of message boxes for low level errors
* user auth dlg box: enable OK button only if username contains something

View File

@ -39,8 +39,12 @@ AX_ASSERT_LIB([wininet], [wininet.h],
[Make sure you have a recent w32api installed.])
AX_ASSERT_LIB([comctl32], [prsht.h],
[PROPSHEETHEADER psh; PropertySheet(&psh)],
[Make sure you have a recent w32api installed.], [#include <windows.h>])
[PROPSHEETHEADER psh; PropertySheet(&psh)],
[Make sure you have a recent w32api installed.], [#include <windows.h>])
AX_ASSERT_LIB([Ws2_32], [Winsock2.h],
[WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData)],
[Make sure you have a recent w32api installed.], [#include <windows.h>])
AX_SEARCH_LIB([crypto], [cryptoeay32 eay32 crypto], [-lgdi32],
[openssl/pkcs12.h], [EVP_PKEY *k = EVP_PKEY_new()])

89
main.c
View File

@ -20,6 +20,7 @@
*/
#define _WIN32_IE 0x0500
#include <windows.h>
#include <shlwapi.h>
#include <Pbt.h>
@ -37,6 +38,7 @@
#include "registry.h"
#include "openvpn-gui-res.h"
#include "localization.h"
#include "manage.h"
#ifndef DISABLE_CHANGE_PASSWORD
#include <openssl/evp.h>
@ -56,6 +58,36 @@ TCHAR szTitleText[ ] = _T("OpenVPN");
/* Options structure */
options_t o;
static int
VerifyAutoConnections()
{
int i;
BOOL match;
for (i = 0; o.auto_connect[i] != 0 && i < MAX_CONFIGS; i++)
{
int j;
match = FALSE;
for (j = 0; j < MAX_CONFIGS; j++)
{
if (_tcsicmp(o.conn[j].config_file, o.auto_connect[i]) == 0)
{
match = TRUE;
break;
}
}
if (match == FALSE)
{
/* autostart config not found */
ShowLocalizedMsg(IDS_ERR_AUTOSTART_CONF, o.auto_connect[i]);
return FALSE;
}
}
return TRUE;
}
int WINAPI WinMain (HINSTANCE hThisInstance,
UNUSED HINSTANCE hPrevInstance,
UNUSED LPSTR lpszArgument,
@ -66,6 +98,17 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
WNDCLASSEX wincl; /* Data structure for the windowclass */
DWORD shell32_version;
/* Initialize handlers for manangement interface notifications */
mgmt_rtmsg_handler handler[] = {
{ ready, OnReady },
{ hold, OnHold },
{ log, OnLogLine },
{ state, OnStateChange },
{ password, OnPassword },
{ stop, OnStop },
{ 0, NULL }
};
InitManagement(handler);
/* initialize options to default state */
InitOptions(&o);
@ -125,6 +168,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
if (!CheckVersion()) {
exit(1);
}
BuildFileList();
if (!VerifyAutoConnections()) {
exit(1);
@ -187,6 +231,41 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
}
static void
StopAllOpenVPN()
{
int i;
for (i = 0; i < o.num_configs; i++)
{
if (o.conn[i].state != disconnected)
StopOpenVPN(&o.conn[i]);
}
/* Wait for all connections to terminate (Max 5 sec) */
for (i = 0; i < 20; i++, Sleep(250))
{
if (CountConnState(disconnected) == o.num_configs)
break;
}
}
static int
AutoStartConnections()
{
int i;
for (i = 0; i < o.num_configs; i++)
{
if (o.conn[i].auto_connect)
StartOpenVPN(&o.conn[i]);
}
return TRUE;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
@ -221,13 +300,13 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
case WM_NOTIFYICONTRAY:
OnNotifyTray(lParam); // Manages message from tray
break;
case WM_COMMAND:
if ( (LOWORD(wParam) >= IDM_CONNECTMENU) && (LOWORD(wParam) < IDM_CONNECTMENU + MAX_CONFIGS) ) {
StartOpenVPN(LOWORD(wParam) - IDM_CONNECTMENU);
StartOpenVPN(&o.conn[LOWORD(wParam) - IDM_CONNECTMENU]);
}
if ( (LOWORD(wParam) >= IDM_DISCONNECTMENU) && (LOWORD(wParam) < IDM_DISCONNECTMENU + MAX_CONFIGS) ) {
StopOpenVPN(LOWORD(wParam) - IDM_DISCONNECTMENU);
StopOpenVPN(&o.conn[LOWORD(wParam) - IDM_DISCONNECTMENU]);
}
if ( (LOWORD(wParam) >= IDM_STATUSMENU) && (LOWORD(wParam) < IDM_STATUSMENU + MAX_CONFIGS) ) {
ShowWindow(o.conn[LOWORD(wParam) - IDM_STATUSMENU].hwndStatus, SW_SHOW);
@ -303,11 +382,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
{
/* Restart suspend connections */
if (o.conn[i].state == suspended)
StartOpenVPN(i);
StartOpenVPN(&o.conn[i]);
/* If some connection never reached SUSPENDED state */
if (o.conn[i].state == suspending)
StopOpenVPN(i);
StopOpenVPN(&o.conn[i]);
}
return FALSE;
}

1
main.h
View File

@ -39,6 +39,7 @@
/* Registry key for Global Settings */
#define GUI_REGKEY_HKLM _T("SOFTWARE\\OpenVPN-GUI")
#define MAX_LOG_LENGTH 1024/* Max number of characters per log line */
#define MAX_LOG_LINES 500 /* Max number of lines in LogWindow */
#define DEL_LOG_LINES 10 /* Number of lines to delete from LogWindow */

307
manage.c Normal file
View File

@ -0,0 +1,307 @@
/*
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
*
* Copyright (C) 2010 Heiko Hund <heikoh@users.sf.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <Winsock2.h>
#include "options.h"
#include "main.h"
#include "manage.h"
extern options_t o;
static mgmt_msg_func rtmsg_handler[mgmt_rtmsg_type_max];
/*
* Initialize the real-time notification handlers
*/
void
InitManagement(const mgmt_rtmsg_handler *handler)
{
int i;
for (i = 0; handler[i].handler; ++i)
{
rtmsg_handler[handler[i].type] = handler[i].handler;
}
}
/*
* Connect to the OpenVPN management interface and register
* asynchronous socket event notification for it
*/
BOOL
OpenManagement(connection_t *c, u_long addr, u_short port)
{
WSADATA wsaData;
SOCKADDR_IN skaddr = {
.sin_family = AF_INET,
.sin_addr.s_addr = addr,
.sin_port = htons(port)
};
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
return FALSE;
c->manage.sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (c->manage.sk == INVALID_SOCKET)
return FALSE;
if (WSAAsyncSelect(c->manage.sk, c->hwndStatus, WM_MANAGEMENT,
FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE) != 0)
return FALSE;
connect(c->manage.sk, (SOCKADDR *)&skaddr, sizeof(skaddr));
return TRUE;
}
/*
* Send a command to the OpenVPN management interface
*/
BOOL
ManagementCommand(connection_t *c, char *command, mgmt_msg_func handler, mgmt_cmd_type type)
{
int res = 0;
int size = strlen(command) + 1;
mgmt_cmd_t *cmd = calloc(1, sizeof(*cmd));
if (cmd == NULL)
return FALSE;
cmd->handler = handler;
cmd->type = type;
if (c->manage.cmd_queue)
{
cmd->next = c->manage.cmd_queue;
cmd->prev = c->manage.cmd_queue->prev;
cmd->next->prev = cmd->prev->next = cmd;
}
else
{
cmd->next = cmd->prev = cmd;
c->manage.cmd_queue = cmd;
}
if (c->manage.cmd_queue == cmd)
{
*(command + size - 1) = '\n';
res = send(c->manage.sk, command, size, 0);
*(command + size - 1) = '\0';
}
if (res != size)
{
if (res == SOCKET_ERROR)
res = 0;
size -= res;
cmd->command = malloc(size);
if (cmd->command == NULL)
{
free(cmd);
return FALSE;
}
memcpy(cmd->command, command + res, size);
*(cmd->command + size - 1) = '\n';
cmd->size = size;
}
return TRUE;
}
/*
* Try to send a queued management command to OpenVPN
*/
static void
SendCommand(connection_t *c)
{
int res;
mgmt_cmd_t *cmd = c->manage.cmd_queue;
if (cmd == NULL || cmd->size == 0)
return;
res = send(c->manage.sk, cmd->command, cmd->size, 0);
if (res < 1)
return;
if (res != cmd->size)
memmove(cmd->command, cmd->command + res, cmd->size - res);
cmd->size -= res;
}
/*
* Remove a command from a connection's command queue
*/
static BOOL
UnqueueCommand(connection_t *c)
{
mgmt_cmd_t *cmd = c->manage.cmd_queue;
if (!cmd)
return FALSE;
if (cmd->type == combined)
{
cmd->type = regular;
return TRUE;
}
if (cmd->next == cmd)
{
c->manage.cmd_queue = NULL;
}
else
{
cmd->prev->next = cmd->next;
cmd->next->prev = cmd->prev;
c->manage.cmd_queue = cmd->next;
SendCommand(c);
}
free(cmd->command);
free(cmd);
return TRUE;
}
/*
* Handle management socket events asynchronously
*/
void
OnManagement(SOCKET sk, LPARAM lParam)
{
int res;
char *pos = NULL;
char data[MAX_LOG_LENGTH];
connection_t *c = GetConnByManagement(sk);
if (c == NULL)
return;
switch (WSAGETSELECTEVENT(lParam))
{
case FD_CONNECT:
if (WSAGETSELECTERROR(lParam))
SendMessage(c->hwndStatus, WM_CLOSE, 0, 0);
break;
case FD_READ:
/* Check if there's a complete line to read */
res = recv(c->manage.sk, data, sizeof(data), MSG_PEEK);
if (res < 1)
return;
pos = memchr(data, (*c->manage.password ? ':' : '\n'), res);
if (!pos)
return;
/* There is data available: read it */
res = recv(c->manage.sk, data, pos - data + 1, 0);
if (res != pos - data + 1)
return;
/* Reply to a management password request */
if (*c->manage.password)
{
ManagementCommand(c, c->manage.password, NULL, regular);
*c->manage.password = '\0';
return;
}
/* Handle regular management interface output */
data[pos - data - 1] = '\0';
if (data[0] == '>')
{
/* Real time notifications */
pos = data + 1;
if (strncmp(pos, "LOG:", 4) == 0)
{
if (rtmsg_handler[log])
rtmsg_handler[log](c, pos + 4);
}
else if (strncmp(pos, "STATE:", 6) == 0)
{
if (rtmsg_handler[state])
rtmsg_handler[state](c, pos + 6);
}
else if (strncmp(pos, "HOLD:", 5) == 0)
{
if (rtmsg_handler[hold])
rtmsg_handler[hold](c, pos + 5);
}
else if (strncmp(pos, "PASSWORD:", 9) == 0)
{
if (rtmsg_handler[password])
rtmsg_handler[password](c, pos + 9);
}
else if (strncmp(pos, "INFO:", 5) == 0)
{
/* delay until management interface accepts input */
Sleep(100);
if (rtmsg_handler[ready])
rtmsg_handler[ready](c, pos + 5);
}
}
else if (c->manage.cmd_queue)
{
/* Response to commands */
mgmt_cmd_t *cmd = c->manage.cmd_queue;
if (strncmp(data, "SUCCESS:", 8) == 0)
{
if (cmd->handler)
cmd->handler(c, data + 9);
UnqueueCommand(c);
}
else if (strncmp(data, "ERROR:", 6) == 0)
{
if (cmd->handler)
cmd->handler(c, NULL);
UnqueueCommand(c);
}
else if (strcmp(data, "END") == 0)
{
UnqueueCommand(c);
}
else if (cmd->handler)
{
cmd->handler(c, data);
}
}
break;
case FD_WRITE:
SendCommand(c);
break;
case FD_CLOSE:
closesocket(c->manage.sk);
c->manage.sk = INVALID_SOCKET;
while (UnqueueCommand(c))
;
WSACleanup();
if (rtmsg_handler[stop])
rtmsg_handler[stop](c, "");
break;
}
}

69
manage.h Normal file
View File

@ -0,0 +1,69 @@
/*
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
*
* Copyright (C) 2010 Heiko Hund <heikoh@users.sf.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANAGE_H
#define MANAGE_H
#define WM_MANAGEMENT (WM_APP + 2)
typedef enum {
ready,
stop,
bytecount,
echo,
hold,
log,
password,
state,
needok,
needstr,
pkcs11_id_count,
mgmt_rtmsg_type_max
} mgmt_rtmsg_type;
typedef enum {
regular,
combined
} mgmt_cmd_type;
typedef void (*mgmt_msg_func)(connection_t *, char *);
typedef struct {
mgmt_rtmsg_type type;
mgmt_msg_func handler;
} mgmt_rtmsg_handler;
typedef struct mgmt_cmd {
struct mgmt_cmd *prev, *next;
char *command;
int size;
mgmt_msg_func handler;
mgmt_cmd_type type;
} mgmt_cmd_t;
void InitManagement(const mgmt_rtmsg_handler *handler);
BOOL OpenManagement(connection_t *, u_long, u_short);
BOOL ManagementCommand(connection_t *, char *, mgmt_msg_func, mgmt_cmd_type);
void OnManagement(SOCKET, LPARAM);
#endif

View File

@ -199,16 +199,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor fehlgeschlagen."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl fehlgeschlagen."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe an hOutputWrite fehlgeschlagen."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle an hErrorWrite fehlgeschlagen."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe an hInputRead fehlgeschlagen."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle an hOutputRead fehlgeschlagen."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle an hInputWrite fehlgeschlagen."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle an hOutputReadTmp/hInputWriteTmp fehlgeschlagen."
IDS_ERR_CREATE_PROCESS "CreateProcess fehlgeschlagen, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle fehlgeschlagen."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread, welcher das Statusfenster zeigt ist fehlgschlagen."
IDS_NFO_STATE_WAIT_TERM "Aktueller Status: Wartet bis OpenVPN beendet ist..."
IDS_ERR_OPEN_LOG_WRITE "Fehler beim Schreiben des Logfiles: %s. Sie haben vermutlich keine Administratorenrechte, welche nötig sind um OpenVPN zu starten."
IDS_NFO_STATE_CONNECTED "Aktueller Status: Verbunden"
IDS_NFO_NOW_CONNECTED "%s ist nun verbunden."
IDS_NFO_ASSIGN_IP "Zugewiesene IP: %s"
@ -229,7 +225,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe an hInputRead fehlgeschlagen."
IDS_NFO_STATE_CONNECTING "Aktueller Status: Verbinden"
IDS_NFO_CONNECTION_XXX "OpenVPN Verbindung (%s)"
IDS_ERR_THREAD_READ_STDOUT "CreateThread zum Lesen des OpenVPN Prozess stdout fehlgeschlagen."
IDS_NFO_STATE_CONN_SCRIPT "Aktueller Status: Verbindungsscript läuft"
IDS_NFO_STATE_DISCONN_SCRIPT "Aktueller Status: Verbindungstrennungsscript läuft"
IDS_ERR_RUN_CONN_SCRIPT "Fehler beim Ausführen des Verbindungsscript: %s"
@ -252,11 +247,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "Der OpenVPN Dienst ist gestartet und verbunden. " \
"Die Verbindung besteht solange bis Sie die OpenVPN GUI beenden.\n\n" \
"\n\nSind sie sicher, dass Sie das Programm beenden möchten?"
IDS_ERR_OPTION_LOG_IN_CONFIG "Sie haben ""log"" oder ""log-append"" in Ihrer OpenVPN Konfigurationsdatei. Diese Optionen " \
"sollten nicht mit der OpenVPN GUI verwendet werden, denn es verhindert, dass die Ausgaben " \
"von OpenVPN lesen kann, welche nötig ist, für den korrekten Betrieb des OpenVPN " \
"GUI. Die Ausgabe wird immer in ein Logfile geschrieben, wenn OpenVPN GUI verwendet wird. " \
"Deshalb sollten Sie diese Option entfernen.\n\nMöchten Sie dennoch mit dem Verbinden fortfahren? "
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Zeigt diese Information.\n" \

View File

@ -194,16 +194,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor failed."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl failed."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe on hOutputWrite failed."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle on hErrorWrite failed."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe on hInputRead failed."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle on hOutputRead failed."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle on hInputWrite failed."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle on hOutputReadTmp/hInputWriteTmp failed."
IDS_ERR_CREATE_PROCESS "CreateProcess failed, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle failed."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
IDS_NFO_STATE_WAIT_TERM "Current State: Waiting for OpenVPN to terminate..."
IDS_ERR_OPEN_LOG_WRITE "Error opening logfile for writing: %s. You probably don't have administrator privileges, which are necessary to run OpenVPN."
IDS_NFO_STATE_CONNECTED "Current State: Connected"
IDS_NFO_NOW_CONNECTED "%s is now connected."
IDS_NFO_ASSIGN_IP "Assigned IP: %s"
@ -224,7 +220,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe on hInputRead failed."
IDS_NFO_STATE_CONNECTING "Current State: Connecting"
IDS_NFO_CONNECTION_XXX "OpenVPN Connection (%s)"
IDS_ERR_THREAD_READ_STDOUT "CreateThread to read openvpn process stdout failed."
IDS_NFO_STATE_CONN_SCRIPT "Current State: Running Connect Script"
IDS_NFO_STATE_DISCONN_SCRIPT "Current State: Running Disconnect Script"
IDS_ERR_RUN_CONN_SCRIPT "Error running Connect Script: %s"
@ -246,12 +241,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "You are currently connected (the OpenVPN Service is running). " \
"You will stay connected even if you exit OpenVPN GUI.\n\n" \
"Do you want to proceed and exit OpenVPN GUI?"
IDS_ERR_OPTION_LOG_IN_CONFIG "You have ""log"" or ""log-append"" in your OpenVPN config file. These options " \
"should not be used with OpenVPN GUI as they prevents OpenVPN GUI from reading " \
"the log output of OpenVPN which is necessary for correct operation of OpenVPN " \
"GUI. The log is always written to a logfile when OpenVPN GUI is beeing used " \
"anyway, so you should remove this option.\n\nDo you want to proceed connecting " \
"anyway?"
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Show this message.\n" \

View File

@ -181,16 +181,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor fallido."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl fallido."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe on hOutputWrite fallido."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle on hErrorWrite fallido."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe on hInputRead fallido."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle on hOutputRead fallido."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle on hInputWrite fallido."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle on hOutputReadTmp/hInputWriteTmp fallido."
IDS_ERR_CREATE_PROCESS "CreateProcess fallido, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle fallido."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread para mostrar la Ventana de Estado fallido."
IDS_NFO_STATE_WAIT_TERM "Estado actual: Esperando que OpenVPN termine..."
IDS_ERR_OPEN_LOG_WRITE "Error al abrir el fichero de log para escritura: %s. Probablemente no tiene privilegios de administrador, que son necesarios para ejecutar OpenVPN."
IDS_NFO_STATE_CONNECTED "Estado actual: Conectado."
IDS_NFO_NOW_CONNECTED "Conectado a %s."
IDS_NFO_ASSIGN_IP "IP asignada: %s"
@ -211,7 +207,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe on hInputRead falló."
IDS_NFO_STATE_CONNECTING "Estado actual: Conectando"
IDS_NFO_CONNECTION_XXX "Conexión OpenVPN (%s)"
IDS_ERR_THREAD_READ_STDOUT "CreateThread para leer la salida del proceso de OpenVPN falló."
IDS_NFO_STATE_CONN_SCRIPT "Estado actual: Ejecutando el script de conexión"
IDS_NFO_STATE_DISCONN_SCRIPT "Estado actual: Ejecutando el script de desconexión"
IDS_ERR_RUN_CONN_SCRIPT "Error ejecutando el script de conexión: %s"
@ -233,12 +228,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "Ahora mismo está conectado (el servicio OpenVPN está corriendo). " \
"Seguriá conectado incluso si sale de OpenVPN GUI.\n\n" \
"¿Quiere proceder y salir de OpenVPN GUI?"
IDS_ERR_OPTION_LOG_IN_CONFIG "Tiene ""log"" ó ""log-append"" en el fichero de configuración de OpenVPN. Dichas opciones " \
"no deberían usarse con OpenVPN GUI pues impiden que OpenVPN GUI pueda leer " \
"el log de salida de OpenVPN que es necesario para el correcto funcionamiento de OpenVPN " \
"GUI. En todo caso, el log siempre se escribe en un fichero cuando OpenVPN GUI está en " \
"uso, asi que deberia quitar ésta opción.\n\n¿Quiere continuar con la conexión " \
"de todas formas?"
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Mostrar éste mensaje.\n" \

View File

@ -194,16 +194,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor failed."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl failed."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe on hOutputWrite failed."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle on hErrorWrite failed."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe on hInputRead failed."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle on hOutputRead failed."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle on hInputWrite failed."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle on hOutputReadTmp/hInputWriteTmp failed."
IDS_ERR_CREATE_PROCESS "CreateProcess failed, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle failed."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
IDS_NFO_STATE_WAIT_TERM "Tila: Odotetaan OpenVPN:n sammumista..."
IDS_ERR_OPEN_LOG_WRITE "Virhe kirjoitettaessa lokitiedostoon: %s. Varmista, että OpenVPN käynnistetään ylläpitäjän oikeuksin."
IDS_NFO_STATE_CONNECTED "Tila: Yhdistetty"
IDS_NFO_NOW_CONNECTED "%s on nyt yhdistetty."
IDS_NFO_ASSIGN_IP "IP-osoite: %s"
@ -224,7 +220,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe on hInputRead failed."
IDS_NFO_STATE_CONNECTING "Tila: Yhdistetään"
IDS_NFO_CONNECTION_XXX "OpenVPN-yhteys (%s)"
IDS_ERR_THREAD_READ_STDOUT "CreateThread to read openvpn process stdout failed."
IDS_NFO_STATE_CONN_SCRIPT "Tila: Suoritetaan yhteydenmuodostamisskripti"
IDS_NFO_STATE_DISCONN_SCRIPT "Tila: Suoritetaan yhteydenkatkaisemisskripti "
IDS_ERR_RUN_CONN_SCRIPT "Virhe suoritettaessa yhteydenmuodostamisskriptiä: %s"
@ -247,11 +242,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "Yhteys on muodostettu OpenVPN-palvelun avulla. " \
"Yhteydet eivät katkea, vaikka OpenVPN GUI suljettaisiinkin.\n\n" \
"Suljetaanko OpenVPN GUI?"
IDS_ERR_OPTION_LOG_IN_CONFIG "OpenVPN:n asetustiedostossa on käytössä ""log"" tai ""log-append"". " \
"Nämä asetukset estävät OpenVPN GUI:ta toimimasta oikein eikä niitä " \
"tulisi käyttää. Vaikka asetukset eivät olisikaan käytössä, OpenVPN " \
"GUI kirjoittaa silti lokia." \
"\n\nHaluatko varmasti jatkaa?"
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Näytä tämä viesti.\n" \

View File

@ -192,16 +192,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor échoué."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl échoué."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe sur hOutputWrite échoué."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle sur hErrorWrite échoué."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe sur hInputRead échoué."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle sur hOutputRead échoué."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle sur hInputWrite échoué."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle sur hOutputReadTmp/hInputWriteTmp échoué."
IDS_ERR_CREATE_PROCESS "CreateProcess échoué, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle échoué."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread échoué pour afficher la fenêtre de statut."
IDS_NFO_STATE_WAIT_TERM "Etat actuel: Attente que OpenVPN se termine..."
IDS_ERR_OPEN_LOG_WRITE "Erreur pour ouverture du fichier de log pour écriture: %s. Vous n'avez probablement pas les privilèges administrateur, nécessaires pour lancer OpenVPN."
IDS_NFO_STATE_CONNECTED "Etat actuel: Connecté"
IDS_NFO_NOW_CONNECTED "%s est désormais connecté."
IDS_NFO_ASSIGN_IP "Adresse IP assignée: %s"
@ -222,7 +218,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe sur hInputRead échoué."
IDS_NFO_STATE_CONNECTING "Etat actuel: En cours de connexion"
IDS_NFO_CONNECTION_XXX "Connexion OpenVPN (%s)"
IDS_ERR_THREAD_READ_STDOUT "CreateThread pour lecture de la procédure openvpn stdout échoué."
IDS_NFO_STATE_CONN_SCRIPT "Etat actuel: Exécution du script de connexion"
IDS_NFO_STATE_DISCONN_SCRIPT "Etat actuel: Exécution du script de déconnexion"
IDS_ERR_RUN_CONN_SCRIPT "Erreur d'exécution du script de connexion: %s"
@ -244,12 +239,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "Vous êtes actuellement connecté (Le service OpenVPN est actif). " \
"Vous restez connecté même si vous terminez l'OpenVPN GUI.\n\n" \
"Voulez-vous continuer et fermer l'OpenVPN GUI ?"
IDS_ERR_OPTION_LOG_IN_CONFIG "Vous avez ""log"" ou ""log-append"" dans votre fichier de configuration OpenVPN. Ces options " \
"ne doivent pas être utilisées avec OpenVPN GUI afin d'éviter la lecture en sortie " \
"d'OpenVPN ce qui est nécéssaire au fonctionnement correct OpenVPN GUI. " \
"Les actions sont toujours écrites dans le fichier de log lorsque OpenVPN GUI est utilisé " \
"donc, vous devez supprimer cette option.\n\nVoulez-vous malgré tout procéder à " \
"la connexion ?"
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Afficher ce message.\n" \

View File

@ -180,16 +180,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor fallito."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl fallito."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe on hOutputWrite fallito."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle on hErrorWrite fallito."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe on hInputRead fallito."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle on hOutputRead fallito."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle on hInputWrite fallito."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle on hOutputReadTmp/hInputWriteTmp fallito."
IDS_ERR_CREATE_PROCESS "CreateProcess fallito, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle fallito."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread fallito per visualizzare lo stato."
IDS_NFO_STATE_WAIT_TERM "Stato corrente: In attesa che OpenVPN termini..."
IDS_ERR_OPEN_LOG_WRITE "Errore apertura del file di log in scrittura: %s. Probabilmente non hai i privilegi di amministratore, che sono necessari a far funzionare OpenVPN."
IDS_NFO_STATE_CONNECTED "Stato corrente: Connesso"
IDS_NFO_NOW_CONNECTED "%s è ora connesso."
IDS_NFO_ASSIGN_IP "IP asseganto: %s"
@ -210,7 +206,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe on hInputRead falito."
IDS_NFO_STATE_CONNECTING "Stato corrente: Connessione in corso"
IDS_NFO_CONNECTION_XXX "Connessione OpenVPN (%s)"
IDS_ERR_THREAD_READ_STDOUT "CreateThread per leggere il process stdout di openvpn è fallito."
IDS_NFO_STATE_CONN_SCRIPT "Stato corrente: Avviato lo script di connessione"
IDS_NFO_STATE_DISCONN_SCRIPT "Stato corrente: Avviato lo script di disconnessione"
IDS_ERR_RUN_CONN_SCRIPT "Errore durante il funzionamento dello script di connessione: %s"
@ -232,11 +227,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "Al momento sei connesso (il servizio di OpenVPN è in funzione). " \
"Rimarrai connesso finché non uscirai da OpenVPN GUI.\n\n" \
"Vuoi continuare e uscire da OpenVPN GUI?"
IDS_ERR_OPTION_LOG_IN_CONFIG "Hai ""log"" o ""log-append"" nel tuo file di configurazione OpenVPN . Queste opzioni " \
"non devono essere usate con OpenVPN GUI in quanto impediscono a OpenVPN GUI la lettura " \
"del file di log di output di OpenVPN che è necessario per il corretto funzionamento di OpenVPN " \
"GUI. I log vengono sempre scritti in un file di log quando OpenVPN GUI è in uso, " \
"quindi devi rimuovere queste opzioni.\n\nVuoi continuare e conntterti comunque?"
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Visualizza questo messaggio.\n" \

View File

@ -180,16 +180,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor mislukt."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl mislukt."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe on hOutputWrite mislukt."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle on hErrorWrite mislukt."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe on hInputRead mislukt."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle on hOutputRead mislukt."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle on hInputWrite mislukt."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle on hOutputReadTmp/hInputWriteTmp mislukt."
IDS_ERR_CREATE_PROCESS "CreateProcess mislukt, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle mislukt."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread om om Status venster te tonen mislukt."
IDS_NFO_STATE_WAIT_TERM "Huidige Status: Wachten tot OpenVPN gestopt is..."
IDS_ERR_OPEN_LOG_WRITE "Fout tijdens schrijven naar log-bestand: %s. U heeft waarschijnlijk geen Administrator rechten, deze zijn noodzakelijk om OpenVPN te starten."
IDS_NFO_STATE_CONNECTED "Hudige status: Verbonden"
IDS_NFO_NOW_CONNECTED "%s is nu verbonden."
IDS_NFO_ASSIGN_IP "Toegewezen IP: %s"
@ -210,7 +206,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe tijdens hInputRead mislukt."
IDS_NFO_STATE_CONNECTING "Huidige Status: Verbinden"
IDS_NFO_CONNECTION_XXX "OpenVPN Verbinding (%s)"
IDS_ERR_THREAD_READ_STDOUT "CreateThread naar OpenVPN stdout lees-proces mislukt.."
IDS_NFO_STATE_CONN_SCRIPT "Huidige Status: Connect Script Uitvoeren"
IDS_NFO_STATE_DISCONN_SCRIPT "Hudige Status: Disconnect Script Uitvoeren"
IDS_ERR_RUN_CONN_SCRIPT "Fout tijdens uitvoeren Connect Script: %s"
@ -233,11 +228,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "Er is momenteel een active verbinding (OpenVPN services is gestart). " \
"De verbinding blijft actief ook als OpenVPN GUI afgesloten wordt.\n\n" \
"OpenVPN GUI afsluiten?"
IDS_ERR_OPTION_LOG_IN_CONFIG "Er is een ""log"" of ""log-append"" parameter in de OpenVPN configuratie. Deze parameters " \
"kunnen niet samen met OpenVPN GUI gebruikt worden. " \
"OpenVPN GUI moet via STDOUT toegang hebben tot de log gegevens om correcte te werken. " \
"OpenVPN GUI maakt automatisch een log bestand aan, ook als deze parameters niet ingesteld zijn. " \
"Toch verbinding maken? " \
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Toon dit bericht.\n" \

View File

@ -185,16 +185,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor feilet."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl feilet."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe på hOutputWrite feilet."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle på hErrorWrite feilet."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe på hInputRead feilet."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle på hOutputRead feilet."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle på hInputWrite feilet."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle på hOutputReadTmp/hInputWriteTmp feilet."
IDS_ERR_CREATE_PROCESS "CreateProcess feilet, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle feilet."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread for å vise statusvindu feilet."
IDS_NFO_STATE_WAIT_TERM "Status: Ventar på OpenVPN avslutning..."
IDS_ERR_OPEN_LOG_WRITE "Feil under åpning av loggfil for skrivning: %s. Du trenger sannsynligvis administrator-rettigheter for å kjøre OpenVPN."
IDS_NFO_STATE_CONNECTED "Status: Tilkoblet"
IDS_NFO_NOW_CONNECTED "%s er tilkoblet."
IDS_NFO_ASSIGN_IP "tildelt IP: %s"
@ -215,7 +211,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe på hInputRead feilet."
IDS_NFO_STATE_CONNECTING "Status: Kobler til"
IDS_NFO_CONNECTION_XXX "OpenVPN Tilkoblet (%s)"
IDS_ERR_THREAD_READ_STDOUT "En feil oppsto under opprettelse av tråd for å lytte til OpenVPN logg."
IDS_NFO_STATE_CONN_SCRIPT "Status: Kjører skript for tilkobling"
IDS_NFO_STATE_DISCONN_SCRIPT "Status: Kjører skript for frakobling"
IDS_ERR_RUN_CONN_SCRIPT "En feil oppsto under kjøring av skript: %s"
@ -236,10 +231,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "Du er tilkoblet med OpenVPN (OpenVPN tjenesten kjører). " \
"Aktive tilkoblinger vil forbli tilkoblet om du avslutter OpenVPN GUI.\n\n" \
"Vil du avslutte?"
IDS_ERR_OPTION_LOG_IN_CONFIG "Du har ""log"" eller ""log-append"" i din OpenVPN konfig fil. Du bør ikke benytte " \
"disse innstillingene ved bruk av OpenVPN GUI, ettersom GUI'et da ikke kan ""se"" " \
"logge meldingene fra OpenVPN. Dette er nødvendig for OpenVPN GUI's funksjon.\n\n" \
"Vil du allikevel koble til?"
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Vis dene meldingen.\n" \

View File

@ -181,16 +181,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor falhou."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl falhou."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe em hOutputWrite falhou."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle em hErrorWrite falhou."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe em hInputRead falhou."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle em hOutputRead falhou."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle em hInputWrite falhou."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle em hOutputReadTmp/hInputWriteTmp falhou."
IDS_ERR_CREATE_PROCESS "CreateProcess falhou, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle falhou."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread falhou ao mostrar janela de status."
IDS_NFO_STATE_WAIT_TERM "Estado atual: Aguardando OpenVPN terminar..."
IDS_ERR_OPEN_LOG_WRITE "Erro ao abrir arquivo de log para gravação: %s. Você provavelmente não tem permissão de administrador, que é necessária para rodar o OpenVPN."
IDS_NFO_STATE_CONNECTED "Estado atual: Conectado"
IDS_NFO_NOW_CONNECTED "%s está conectado."
IDS_NFO_ASSIGN_IP "IP atribuído: %s"
@ -211,7 +207,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe em hInputRead falhou."
IDS_NFO_STATE_CONNECTING "Estado atual: Conectando"
IDS_NFO_CONNECTION_XXX "Conexão OpenVPN (%s)"
IDS_ERR_THREAD_READ_STDOUT "CreateThread para ler processo de saída openvpn falhou."
IDS_NFO_STATE_CONN_SCRIPT "Estado atual: Rodando script de conexão"
IDS_NFO_STATE_DISCONN_SCRIPT "Estado atual: Running script de desconexão"
IDS_ERR_RUN_CONN_SCRIPT "Erro rodando script de conexão: %s"
@ -233,12 +228,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "Você está conectado atualmente (Serviço OpenVPN está rodando). " \
"Você irá ficar conectado mesmo que feche o OpenVPN GUI.\n\n" \
"Você deseja continuar e fechar o OpenVPN GUI?"
IDS_ERR_OPTION_LOG_IN_CONFIG "Você possui os parâmetros ""log"" ou ""log-append"" no seu arquivo de configuração do OpenVPN. Estas opções " \
"não devem ser usadas com o OpenVPN GUI, sendo que elas impedem o OpenVPN de ler. " \
"the log output of OpenVPN which is necessary for correct operation of OpenVPN " \
"O log é sempre gravado em um arquivo de log quando o OpenVPN GUI é usado," \
"de qualquer maneira você deve retirar esta opção.\n\nVocê deseja conectar " \
"mesmo assim?"
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Mostra esta mensagem.\n" \

View File

@ -186,16 +186,12 @@ BEGIN
IDS_ERR_INIT_SEC_DESC "InitializeSecurityDescriptor misslyckades."
IDS_ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl misslyckades."
IDS_ERR_CREATE_PIPE_OUTPUT "CreatePipe på hOutputWrite misslyckades."
IDS_ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle på hErrorWrite misslyckades."
IDS_ERR_CREATE_PIPE_INPUT "CreatePipe på hInputRead misslyckades."
IDS_ERR_DUP_HANDLE_OUT_READ "DuplicateHandle på hOutputRead misslyckades."
IDS_ERR_DUP_HANDLE_IN_WRITE "DuplicateHandle på hInputWrite misslyckades."
IDS_ERR_CLOSE_HANDLE_TMP "CloseHandle på hOutputReadTmp/hInputWriteTmp misslyckades."
IDS_ERR_CREATE_PROCESS "CreateProcess misslyckades, exe='%s' cmdline='%s' dir='%s'"
IDS_ERR_CLOSE_HANDLE "CloseHandle misslyckades."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread för att visa status fönstret misslyckades."
IDS_NFO_STATE_WAIT_TERM "Status: Väntar på att OpenVPN skall avslutas..."
IDS_ERR_OPEN_LOG_WRITE "Fel vid öppnande av logg fil för skrivning: %s. Du saknar förmodligen administratörs rättigheter vilket du behöver för att köra OpenVPN."
IDS_NFO_STATE_CONNECTED "Status: Ansluten"
IDS_NFO_NOW_CONNECTED "%s är nu ansluten."
IDS_NFO_ASSIGN_IP "Tilldelad IP: %s"
@ -216,7 +212,6 @@ BEGIN
IDS_ERR_CREATE_PIPE_IN_READ "CreatePipe på hInputRead misslyckades."
IDS_NFO_STATE_CONNECTING "Status: Ansluter"
IDS_NFO_CONNECTION_XXX "OpenVPN Anslutning (%s)"
IDS_ERR_THREAD_READ_STDOUT "Ett fel uppstod vid skapande av tråd för att lyssna på OpenVPNs logg."
IDS_NFO_STATE_CONN_SCRIPT "Status: Kör anslutnings-skript"
IDS_NFO_STATE_DISCONN_SCRIPT "Status: Kör frånkopplings-skript"
IDS_ERR_RUN_CONN_SCRIPT "Ett fel uppstod vid körning av följande skript: %s"
@ -237,10 +232,6 @@ BEGIN
IDS_NFO_SERVICE_ACTIVE_EXIT "Du är uppkopplad med OpenVPN (OpenVPN tjänsten är igång). " \
"Du kommer att förbli uppkopplad även om du avslutar OpenVPN GUI.\n\n" \
"Är du säker på att du vill avsluta OpenVPN GUI?"
IDS_ERR_OPTION_LOG_IN_CONFIG "Du har ""log"" eller ""log-append"" in din OpenVPN konfig fil. Du bör inte använda " \
"dessa inställningar när du använder OpenVPN GUI, eftersom GUI:t då inte kan ""se"" " \
"logg meddelandena från OpenVPN, vilka är nödvändiga för OpenVPN GUI's funktion.\n\n" \
"Vill du fortsätta och ansluta ändå?"
/* options - Resources */
IDS_NFO_USAGE "--help\t\t\t: Visa detta meddelande.\n" \

View File

@ -125,16 +125,12 @@
#define IDS_ERR_INIT_SEC_DESC 1209
#define IDS_ERR_SET_SEC_DESC_ACL 1210
#define IDS_ERR_CREATE_PIPE_OUTPUT 1211
#define IDS_ERR_DUP_HANDLE_ERR_WRITE 1212
#define IDS_ERR_CREATE_PIPE_INPUT 1213
#define IDS_ERR_DUP_HANDLE_OUT_READ 1214
#define IDS_ERR_DUP_HANDLE_IN_WRITE 1215
#define IDS_ERR_CLOSE_HANDLE_TMP 1216
#define IDS_ERR_CREATE_PROCESS 1217
#define IDS_ERR_CLOSE_HANDLE 1218
#define IDS_ERR_CREATE_THREAD_STATUS 1219
#define IDS_NFO_STATE_WAIT_TERM 1220
#define IDS_ERR_OPEN_LOG_WRITE 1221
#define IDS_NFO_STATE_CONNECTED 1222
#define IDS_NFO_NOW_CONNECTED 1223
#define IDS_NFO_ASSIGN_IP 1224
@ -155,14 +151,12 @@
#define IDS_ERR_CREATE_PIPE_IN_READ 1240
#define IDS_NFO_STATE_CONNECTING 1241
#define IDS_NFO_CONNECTION_XXX 1242
#define IDS_ERR_THREAD_READ_STDOUT 1243
#define IDS_NFO_STATE_CONN_SCRIPT 1244
#define IDS_NFO_STATE_DISCONN_SCRIPT 1245
#define IDS_ERR_RUN_CONN_SCRIPT 1246
#define IDS_ERR_GET_EXIT_CODE 1247
#define IDS_ERR_CONN_SCRIPT_FAILED 1248
#define IDS_ERR_RUN_CONN_SCRIPT_TIMEOUT 1249
#define IDS_ERR_OPTION_LOG_IN_CONFIG 1250
#define IDS_ERR_CONFIG_EXIST 1251
/* Program Startup Related */

1305
openvpn.c

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
*
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
* 2010 Heiko Hund <heikoh@users.sf.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,20 +20,20 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
struct process_info {
HANDLE hProcess;
int config;
};
#ifndef OEPNVPN_H
#define OPENVPN_H
int StartOpenVPN(int config);
void StopOpenVPN(int config);
BOOL StartOpenVPN(connection_t *);
void StopOpenVPN(connection_t *);
void SuspendOpenVPN(int config);
void StopAllOpenVPN();
int ReadLineFromStdOut(HANDLE hStdOut, int config, char line[1024]);
BOOL CALLBACK StatusDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
int AutoStartConnections();
int VerifyAutoConnections();
BOOL CheckVersion();
void CheckAndSetTrayIcon();
void SetStatusWinIcon(HWND hwndDlg, int IconID);
void ThreadOpenVPNStatus(int status) __attribute__ ((noreturn));
void OnReady(connection_t *, char *);
void OnHold(connection_t *, char *);
void OnLogLine(connection_t *, char *);
void OnStateChange(connection_t *, char *);
void OnPassword(connection_t *, char *);
void OnStop(connection_t *, char *);
#endif

View File

@ -83,6 +83,8 @@ AddConfigFileToList(int config, TCHAR *filename, TCHAR *config_dir)
_tcsncpy(conn->config_name, conn->config_file, _tsizeof(conn->config_name) - 1);
conn->config_name[_tcslen(conn->config_name) - _tcslen(o.ext_string) - 1] = _T('\0');
_sntprintf_0(conn->log_path, _T("%s\\%s.log"), o.log_dir, conn->config_name);
conn->manage.sk = INVALID_SOCKET;
conn->manage.port = 25340 + config;
/* Check if connection should be autostarted */
for (i = 0; i < MAX_CONFIGS && o.auto_connect[i]; ++i)

View File

@ -1,659 +0,0 @@
/*
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
*
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Parts of this sourcefile is taken from openvpnserv.c from the
* OpenVPN source, with approval from the author, James Yonan
* <jim@yonan.net>.
*/
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include "config.h"
#include "main.h"
#include "options.h"
#include "openvpn.h"
#include "scripts.h"
#include "openvpn-gui-res.h"
#include "passphrase.h"
#include "tray.h"
#include "localization.h"
extern options_t o;
static const char connect_string[] = "Initialization Sequence Completed";
/* Wait for a complete line (CR/LF) and return it.
* Return values:
* 1 - Successful. Line is available in *line.
* 0 - Broken Pipe during ReadFile.
* -1 - Other Error during ReadFile.
*
* I'm really unhappy with this code! If anyone knows of an easier
* way to convert the streaming data from ReadFile() into lines,
* please let me know!
*/
int ReadLineFromStdOut(HANDLE hStdOut, int config, char *line)
{
#define MAX_LINELEN 1024
CHAR lpBuffer[MAX_LINELEN];
static char lastline[MAX_CONFIGS][MAX_LINELEN];
static int charsleft[MAX_CONFIGS];
char tmpline[MAX_LINELEN];
DWORD nBytesRead;
char *p;
unsigned int len, i;
static int first_call = 1;
if (first_call)
{
for (i=0; i < MAX_CONFIGS; i++)
charsleft[i]=0;
first_call = 0;
}
while (true)
{
if (charsleft[config])
{
/* Check for Passphrase prompt */
CheckPrivateKeyPassphrasePrompt(lastline[config], config);
/* Check for Username/Password Auth prompt */
CheckAuthUsernamePrompt(lastline[config], config);
CheckAuthPasswordPrompt(lastline[config]);
p=strchr(lastline[config], '\n');
if (p == NULL)
{
if (!ReadFile(hStdOut,lpBuffer,sizeof(lpBuffer) - strlen(lastline[config]) - 1,
&nBytesRead,NULL) || !nBytesRead)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
return(0); // pipe done - normal exit path.
else
{
/* error reading from pipe */
ShowLocalizedMsg(IDS_ERR_READ_STDOUT_PIPE);
return(-1);
}
}
lpBuffer[nBytesRead] = '\0';
p=strchr(lpBuffer, '\n');
if (p == NULL)
{
strncat(lastline[config], lpBuffer, sizeof(lastline[config]) - strlen(lastline[config]) - 1);
if (strlen(lastline[config]) >= (MAX_LINELEN - 1))
{
strncpy(line, lastline[config], MAX_LINELEN);
charsleft[config]=0;
return(1);
}
}
else
{
p[0] = '\0';
strncpy(line, lastline[config], MAX_LINELEN - 1);
strncat(line, lpBuffer, MAX_LINELEN - strlen(line));
if (line[strlen(line) - 1] == '\r') line[strlen(line) - 1] = '\0';
if (nBytesRead > (strlen(lpBuffer) + 1))
{
strncpy(lastline[config], p+1, sizeof(lastline[config]) - 1);
charsleft[config]=1;
return(1);
}
charsleft[config]=0;
return(1);
}
}
else
{
len = strlen(lastline[config]);
p[0] = '\0';
strncpy(line, lastline[config], MAX_LINELEN - 1);
if (line[strlen(line) - 1] == '\r') line[strlen(line) - 1] = '\0';
if (len > (strlen(line) + 2))
{
strncpy(tmpline, p+1, sizeof(tmpline) - 1);
strncpy(lastline[config], tmpline, sizeof(lastline[config]) - 1);
charsleft[config]=1;
return(1);
}
charsleft[config]=0;
return(1);
}
}
else
{
if (!ReadFile(hStdOut,lpBuffer,sizeof(lpBuffer) - 1,
&nBytesRead,NULL) || !nBytesRead)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
return(0); // pipe done - normal exit path.
else
{
/* error reading from pipe */
ShowLocalizedMsg(IDS_ERR_READ_STDOUT_PIPE);
return(-1);
}
}
lpBuffer[nBytesRead] = '\0';
p=strchr(lpBuffer, '\n');
if (p == NULL)
{
if (nBytesRead >= (MAX_LINELEN - 1))
{
strncpy(line, lpBuffer, MAX_LINELEN);
charsleft[config]=0;
return(1);
}
else
{
strncpy(lastline[config], lpBuffer, sizeof(lastline[config]) - 1);
charsleft[config]=1;
}
}
else
{
p[0] = '\0';
strncpy(line, lpBuffer, MAX_LINELEN - 1);
if (line[strlen(line) - 1] == '\r') line[strlen(line) - 1] = '\0';
if (nBytesRead > strlen(line))
{
strncpy(lastline[config], p+1, sizeof(lastline[config]) - 1);
charsleft[config]=1;
return(1);
}
}
}
}
}
/*
* Monitor the openvpn log output while CONNECTING
*/
void monitor_openvpnlog_while_connecting(int config, char *line)
{
TCHAR msg[200];
unsigned int i;
char *linepos;
/* Check for Connected message */
if (strstr(line, connect_string) != NULL)
{
/* Run Connect Script */
RunConnectScript(config, false);
/* Save time when we got connected. */
o.conn[config].connected_since = time(NULL);
o.conn[config].state = connected;
SetMenuStatus(config, connected);
SetTrayIcon(connected);
/* Remove Proxy Auth file */
DeleteFile(o.proxy_authfile);
/* Zero psw attempt counter */
o.conn[config].failed_psw_attempts = 0;
/* UserInfo: Connected */
SetDlgItemText(o.conn[config].hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONNECTED));
SetStatusWinIcon(o.conn[config].hwndStatus, ID_ICO_CONNECTED);
/* Show Tray Balloon msg */
if (o.show_balloon[0] != '0')
{
LoadLocalizedStringBuf(msg, _tsizeof(msg), IDS_NFO_NOW_CONNECTED, o.conn[config].config_name);
if (_tcslen(o.conn[config].ip) > 0)
{
ShowTrayBalloon(msg, LoadLocalizedString(IDS_NFO_ASSIGN_IP, o.conn[config].ip));
}
else
{
ShowTrayBalloon(msg, _T(""));
}
}
/* Hide Status Window */
ShowWindow(o.conn[config].hwndStatus, SW_HIDE);
}
/* Check for failed passphrase log message */
if ((strstr(line, "TLS Error: Need PEM pass phrase for private key") != NULL) ||
(strstr(line, "EVP_DecryptFinal:bad decrypt") != NULL) ||
(strstr(line, "PKCS12_parse:mac verify failure") != NULL) ||
(strstr(line, "Received AUTH_FAILED control message") != NULL) ||
(strstr(line, "Auth username is empty") != NULL))
{
o.conn[config].failed_psw_attempts++;
o.conn[config].failed_psw=1;
o.conn[config].restart=true;
}
/* Check for "certificate has expired" message */
if ((strstr(line, "error=certificate has expired") != NULL))
{
StopOpenVPN(config);
/* Cert expired... */
ShowLocalizedMsg(IDS_ERR_CERT_EXPIRED);
}
/* Check for "certificate is not yet valid" message */
if ((strstr(line, "error=certificate is not yet valid") != NULL))
{
StopOpenVPN(config);
/* Cert not yet valid */
ShowLocalizedMsg(IDS_ERR_CERT_NOT_YET_VALID);
}
/* Check for "Notified TAP-Win32 driver to set a DHCP IP" message */
if (((linepos=strstr(line, "Notified TAP-Win32 driver to set a DHCP IP")) != NULL))
{
char ip_addr[40];
strncpy(ip_addr, linepos+54, sizeof(ip_addr)); /* Copy IP address */
for (i = 0; i < sizeof(ip_addr) - 1; ++i)
{
if (ip_addr[i] == '/' || ip_addr[i] == ' ')
break;
}
ip_addr[i] = '\0';
#ifdef _UNICODE
/* Convert the IP address to Unicode */
o.conn[config].ip[0] = _T('\0');
MultiByteToWideChar(CP_ACP, 0, ip_addr, -1, o.conn[config].ip, _tsizeof(o.conn[config].ip));
#else
strncpy(o.conn[config].ip, ip_addr, sizeof(o.conn[config].ip));
#endif
}
}
/*
* Monitor the openvpn log output while CONNECTED
*/
void monitor_openvpnlog_while_connected(int config, char *line)
{
/* Check for Ping-Restart message */
if (strstr(line, "process restarting") != NULL)
{
/* Set connect_status = ReConnecting */
o.conn[config].state = reconnecting;
CheckAndSetTrayIcon();
/* Set Status Window Controls "ReConnecting" */
SetDlgItemText(o.conn[config].hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING));
SetStatusWinIcon(o.conn[config].hwndStatus, ID_ICO_CONNECTING);
}
}
/*
* Monitor the openvpn log output while RECONNECTING
*/
void monitor_openvpnlog_while_reconnecting(int config, char *line)
{
TCHAR msg[200];
char *linepos;
size_t i;
/* Check for Connected message */
if (strstr(line, connect_string) != NULL)
{
o.conn[config].state = connected;
SetTrayIcon(connected);
/* Set Status Window Controls "Connected" */
SetDlgItemText(o.conn[config].hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONNECTED));
SetStatusWinIcon(o.conn[config].hwndStatus, ID_ICO_CONNECTED);
/* Show Tray Balloon msg */
if (o.show_balloon[0] == '2')
{
LoadLocalizedStringBuf(msg, _tsizeof(msg), IDS_NFO_NOW_CONNECTED, o.conn[config].config_name);
if (_tcslen(o.conn[config].ip) > 0)
{
ShowTrayBalloon(msg, LoadLocalizedString(IDS_NFO_ASSIGN_IP, o.conn[config].ip));
}
else
{
ShowTrayBalloon(msg, _T(""));
}
}
}
/* Check for failed passphrase log message */
if ((strstr(line, "TLS Error: Need PEM pass phrase for private key") != NULL) ||
(strstr(line, "EVP_DecryptFinal:bad decrypt") != NULL) ||
(strstr(line, "PKCS12_parse:mac verify failure") != NULL) ||
(strstr(line, "Received AUTH_FAILED control message") != NULL) ||
(strstr(line, "Auth username is empty") != NULL))
{
o.conn[config].failed_psw_attempts++;
o.conn[config].failed_psw=1;
o.conn[config].restart=true;
}
/* Check for "certificate has expired" message */
if ((strstr(line, "error=certificate has expired") != NULL))
{
/* Cert expired */
StopOpenVPN(config);
ShowLocalizedMsg(IDS_ERR_CERT_EXPIRED);
}
/* Check for "certificate is not yet valid" message */
if ((strstr(line, "error=certificate is not yet valid") != NULL))
{
StopOpenVPN(config);
/* Cert not yet valid */
ShowLocalizedMsg(IDS_ERR_CERT_NOT_YET_VALID);
}
/* Check for "Notified TAP-Win32 driver to set a DHCP IP" message */
if (((linepos=strstr(line, "Notified TAP-Win32 driver to set a DHCP IP")) != NULL))
{
char ip_addr[40];
strncpy(ip_addr, linepos+54, sizeof(ip_addr)); /* Copy IP address */
for (i = 0; i < sizeof(ip_addr) - 1; ++i)
{
if (ip_addr[i] == '/' || ip_addr[i] == ' ')
break;
}
ip_addr[i] = '\0';
#ifdef _UNICODE
/* Convert the IP address to Unicode */
o.conn[config].ip[0] = _T('\0');
MultiByteToWideChar(CP_ACP, 0, ip_addr, -1, o.conn[config].ip, _tsizeof(o.conn[config].ip));
#else
strncpy(o.conn[config].ip, ip_addr, sizeof(o.conn[config].ip));
#endif
}
}
/*
* Opens a log file and monitors the started OpenVPN process.
* All output from OpenVPN is written both to the logfile and
* to the status window.
*
* The output from OpenVPN is also watch for diffrent messages
* and appropriate actions are taken.
*/
void WatchOpenVPNProcess(int config)
{
char line[1024];
int ret;
TCHAR filemode[] = _T("w");
FILE *fd;
int LogLines = 0;
int logpos;
HWND LogWindow;
/* set log file append/truncate filemode */
if (o.append_string[0] == '1')
filemode[0] = _T('a');
/* Set Connect_Status = "Connecting" */
o.conn[config].state = connecting;
/* Set Tray Icon = "Connecting" if no other connections are running */
CheckAndSetTrayIcon();
/* Set MenuStatus = "Connecting" */
SetMenuStatus(config, connecting);
/* Clear failed_password flag */
o.conn[config].failed_psw = 0;
/* Open log file */
if ((fd=_tfopen(o.conn[config].log_path, filemode)) == NULL)
ShowLocalizedMsg(IDS_ERR_OPEN_LOG_WRITE, o.conn[config].log_path);
LogWindow = GetDlgItem(o.conn[config].hwndStatus, ID_EDT_LOG);
while(TRUE)
{
if ((ret=ReadLineFromStdOut(o.conn[config].hStdOut, config, line)) == 1)
{
/* Do nothing if line length = 0 */
if (strlen(line) == 0) continue;
/* Write line to Log file */
if (fd != NULL)
{
fputs (line, fd);
fputc ('\n', fd);
fflush (fd);
}
/* Remove lines from LogWindow if it is getting full */
LogLines++;
if (LogLines > MAX_LOG_LINES)
{
logpos = SendMessage(LogWindow, EM_LINEINDEX, DEL_LOG_LINES, 0);
SendMessage(LogWindow, EM_SETSEL, 0, logpos);
SendMessage(LogWindow, EM_REPLACESEL, FALSE, (LPARAM) _T(""));
LogLines -= DEL_LOG_LINES;
}
/* Write line to LogWindow */
strcat(line, "\r\n");
SendMessage(LogWindow, EM_SETSEL, (WPARAM) -1, (LPARAM) -1);
#ifdef _UNICODE
TCHAR wide_line[1024];
MultiByteToWideChar(CP_ACP, 0, line, -1, wide_line, _tsizeof(wide_line));
SendMessage(LogWindow, EM_REPLACESEL, FALSE, (LPARAM) wide_line);
#else
SendMessage(LogWindow, EM_REPLACESEL, FALSE, (LPARAM) line);
#endif
if (o.conn[config].state == connecting) /* Connecting state */
monitor_openvpnlog_while_connecting(config, line);
if (o.conn[config].state == connected) /* Connected state */
monitor_openvpnlog_while_connected(config, line);
if (o.conn[config].state == reconnecting) /* ReConnecting state */
monitor_openvpnlog_while_reconnecting(config, line);
}
else break;
}
/* OpenVPN has been shutdown */
/* Close logfile filedesc. */
if (fd != NULL) fclose(fd);
/* Close StdIn/StdOut handles */
CloseHandle(o.conn[config].hStdIn);
CloseHandle(o.conn[config].hStdOut);
/* Close exitevent handle */
CloseHandle(o.conn[config].exit_event);
o.conn[config].exit_event = NULL;
/* Enable/Disable menuitems for this connections */
SetMenuStatus(config, disconnecting);
/* Remove Proxy Auth file */
DeleteFile(o.proxy_authfile);
/* Process died outside our control */
if(o.conn[config].state == connected)
{
/* Zero psw attempt counter */
o.conn[config].failed_psw_attempts = 0;
/* Set connect_status = "Not Connected" */
o.conn[config].state=disconnected;
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
/* Show Status Window */
SetDlgItemText(o.conn[config].hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED));
SetStatusWinIcon(o.conn[config].hwndStatus, ID_ICO_DISCONNECTED);
EnableWindow(GetDlgItem(o.conn[config].hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(o.conn[config].hwndStatus, ID_RESTART), FALSE);
SetForegroundWindow(o.conn[config].hwndStatus);
ShowWindow(o.conn[config].hwndStatus, SW_SHOW);
ShowLocalizedMsg(IDS_NFO_CONN_TERMINATED, o.conn[config].config_name);
/* Close Status Window */
SendMessage(o.conn[config].hwndStatus, WM_CLOSE, 0, 0);
}
/* We have failed to connect */
else if(o.conn[config].state == connecting)
{
/* Set connect_status = "DisConnecting" */
o.conn[config].state=disconnecting;
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
if ((o.conn[config].failed_psw) &&
(o.conn[config].failed_psw_attempts < o.psw_attempts))
{
/* Restart OpenVPN to make another attempt to connect */
PostMessage(o.hWnd, WM_COMMAND, (WPARAM) IDM_CONNECTMENU + config, 0);
}
else
{
/* Show Status Window */
SetDlgItemText(o.conn[config].hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_FAILED));
SetStatusWinIcon(o.conn[config].hwndStatus, ID_ICO_DISCONNECTED);
EnableWindow(GetDlgItem(o.conn[config].hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(o.conn[config].hwndStatus, ID_RESTART), FALSE);
SetForegroundWindow(o.conn[config].hwndStatus);
ShowWindow(o.conn[config].hwndStatus, SW_SHOW);
/* Zero psw attempt counter */
o.conn[config].failed_psw_attempts = 0;
ShowLocalizedMsg(IDS_NFO_CONN_FAILED, o.conn[config].config_name);
/* Set connect_status = "Not Connected" */
o.conn[config].state=disconnected;
/* Close Status Window */
SendMessage(o.conn[config].hwndStatus, WM_CLOSE, 0, 0);
/* Reset restart flag */
o.conn[config].restart=false;
}
}
/* We have failed to reconnect */
else if(o.conn[config].state == reconnecting)
{
/* Set connect_status = "DisConnecting" */
o.conn[config].state=disconnecting;
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
if ((o.conn[config].failed_psw) &&
(o.conn[config].failed_psw_attempts < o.psw_attempts))
{
/* Restart OpenVPN to make another attempt to connect */
PostMessage(o.hWnd, WM_COMMAND, (WPARAM) IDM_CONNECTMENU + config, 0);
}
else
{
/* Show Status Window */
SetDlgItemText(o.conn[config].hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_FAILED_RECONN));
SetStatusWinIcon(o.conn[config].hwndStatus, ID_ICO_DISCONNECTED);
EnableWindow(GetDlgItem(o.conn[config].hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(o.conn[config].hwndStatus, ID_RESTART), FALSE);
SetForegroundWindow(o.conn[config].hwndStatus);
ShowWindow(o.conn[config].hwndStatus, SW_SHOW);
/* Zero psw attempt counter */
o.conn[config].failed_psw_attempts = 0;
ShowLocalizedMsg(IDS_NFO_RECONN_FAILED, o.conn[config].config_name);
/* Set connect_status = "Not Connected" */
o.conn[config].state=disconnected;
/* Close Status Window */
SendMessage(o.conn[config].hwndStatus, WM_CLOSE, 0, 0);
/* Reset restart flag */
o.conn[config].restart=false;
}
}
/* We have chosed to Disconnect */
else if(o.conn[config].state == disconnecting)
{
/* Zero psw attempt counter */
o.conn[config].failed_psw_attempts = 0;
/* Set connect_status = "Not Connected" */
o.conn[config].state=disconnected;
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
if (o.conn[config].restart)
{
/* Restart OpenVPN */
StartOpenVPN(config);
}
else
{
/* Close Status Window */
SendMessage(o.conn[config].hwndStatus, WM_CLOSE, 0, 0);
}
}
/* We have chosed to Suspend */
else if(o.conn[config].state == suspending)
{
/* Zero psw attempt counter */
o.conn[config].failed_psw_attempts = 0;
/* Set connect_status = "SUSPENDED" */
o.conn[config].state=suspended;
SetDlgItemText(o.conn[config].hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_SUSPENDED));
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
}
/* Enable/Disable menuitems for this connections */
SetMenuStatus(config, disconnected);
}

View File

@ -1,22 +0,0 @@
/*
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
*
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
void WatchOpenVPNProcess(int config);

View File

@ -291,3 +291,14 @@ CountConnState(conn_state_t check)
return count;
}
connection_t*
GetConnByManagement(SOCKET sk)
{
int i;
for (i = 0; i < o.num_configs; ++i)
{
if (o.conn[i].manage.sk == sk)
return &o.conn[i];
}
return NULL;
}

View File

@ -24,9 +24,14 @@
#ifndef OPTIONS_H
#define OPTIONS_H
typedef struct connection connection_t;
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include "manage.h"
/*
* Maximum number of parameters associated with an option,
* including the option name itself.
@ -48,26 +53,29 @@ typedef enum {
} conn_state_t;
/* Connections parameters */
typedef struct {
struct connection {
TCHAR config_file[MAX_PATH]; /* Name of the config file */
TCHAR config_name[MAX_PATH]; /* Name of the connection */
TCHAR config_dir[MAX_PATH]; /* Path to this configs dir */
TCHAR log_path[MAX_PATH]; /* Path to Logfile */
TCHAR ip[16]; /* Assigned IP address for this connection */
TCHAR exit_event_name[50]; /* Exit Event name for this connection */
BOOL auto_connect; /* AutoConnect at startup id TRUE */
BOOL restart; /* Restart connection after termination if TRUE*/
BOOL failed_psw; /* TRUE if OpenVPN failed because of wrong psw */
conn_state_t state; /* State the connection currently is in */
int failed_psw_attempts; /* # of failed attempts made to enter psw */
int failed_psw_attempts; /* # of failed attempts entering password(s) */
time_t connected_since; /* Time when the connection was established */
HANDLE exit_event;
struct {
SOCKET sk;
u_short port;
char password[16];
mgmt_cmd_t *cmd_queue;
} manage;
HANDLE hProcess;
HANDLE hStdOut;
HANDLE hStdIn;
HANDLE exit_event;
DWORD threadId;
HWND hwndStatus;
} connection_t;
};
typedef enum {
@ -147,5 +155,5 @@ typedef struct {
void InitOptions(options_t *);
void ProcessCommandLine(options_t *, TCHAR *);
int CountConnState(conn_state_t);
connection_t* GetConnByManagement(SOCKET);
#endif

View File

@ -2,6 +2,7 @@
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
*
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
* 2010 Heiko Hund <heikoh@users.sf.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,7 +20,14 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DISABLE_CHANGE_PASSWORD
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>
#endif
#include <windows.h>
#include <wincrypt.h>
#include "config.h"
#include "main.h"
@ -30,16 +38,77 @@
#include "chartable.h"
#include "localization.h"
#ifndef DISABLE_CHANGE_PASSWORD
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>
#endif
WCHAR passphrase[256];
extern options_t o;
int ConvertUnicode2Ascii(WCHAR str_unicode[], char str_ascii[], unsigned int str_ascii_size)
/*
* Create a random password from the printable ASCII range
*/
BOOL
GetRandomPassword(char *buf, size_t len)
{
HCRYPTPROV cp;
BOOL retval = FALSE;
unsigned i;
if (!CryptAcquireContext(&cp, NULL, NULL, PROV_DSS, CRYPT_VERIFYCONTEXT))
return FALSE;
if (!CryptGenRandom(cp, len, (PBYTE) buf))
goto out;
/* Make sure all values are between 0x21 '!' and 0x7e '~' */
for (i = 0; i < len; ++i)
buf[i] = (buf[i] & 0x5d) + 0x21;
retval = TRUE;
out:
CryptReleaseContext(cp, 0);
return retval;
}
#ifndef DISABLE_CHANGE_PASSWORD
const int KEYFILE_FORMAT_PKCS12 = 1;
const int KEYFILE_FORMAT_PEM = 2;
const int MIN_PASSWORD_LEN = 8;
/*
* Return TRUE if new passwords match
*/
static int
ConfirmNewPassword(HWND hwndDlg)
{
TCHAR newpsw[50];
TCHAR newpsw2[50];
GetDlgItemText(hwndDlg, ID_EDT_PASS_NEW, newpsw, _tsizeof(newpsw) - 1);
GetDlgItemText(hwndDlg, ID_EDT_PASS_NEW2, newpsw2, _tsizeof(newpsw2) - 1);
if (_tcsncmp(newpsw, newpsw2, _tsizeof(newpsw)) == 0)
return true;
else
return false;
}
/*
* Return lengh of the new password
*/
static int
NewPasswordLengh(HWND hwndDlg)
{
TCHAR newpsw[50];
GetDlgItemText(hwndDlg, ID_EDT_PASS_NEW, newpsw, _tsizeof(newpsw) - 1);
return (_tcslen(newpsw));
}
static int
ConvertUnicode2Ascii(WCHAR str_unicode[], char str_ascii[], unsigned int str_ascii_size)
{
unsigned int i;
unsigned int j;
@ -66,306 +135,209 @@ int ConvertUnicode2Ascii(WCHAR str_unicode[], char str_ascii[], unsigned int str
return(true);
}
void CheckPrivateKeyPassphrasePrompt (char *line, int config)
/*
* ChangePasswordPEM() returns:
* -1 Wrong password
* 0 Changing password failed for unknown reason
* 1 Password changed successfully
*/
static int
ChangePasswordPEM(HWND hwndDlg)
{
DWORD nCharsWritten;
char passphrase_ascii[256];
TCHAR keyfile[MAX_PATH];
char oldpsw[50];
char newpsw[50];
WCHAR oldpsw_unicode[50];
WCHAR newpsw_unicode[50];
FILE *fp;
/* Check for Passphrase prompt */
if (strncmp(line, "Enter PEM pass phrase:", 22) == 0)
EVP_PKEY *privkey;
/* Get filename, old_psw and new_psw from Dialog */
GetDlgItemText(hwndDlg, ID_TXT_KEYFILE, keyfile, _tsizeof(keyfile) - 1);
GetDlgItemTextW(hwndDlg, ID_EDT_PASS_CUR, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1);
GetDlgItemTextW(hwndDlg, ID_EDT_PASS_NEW, newpsw_unicode, sizeof(newpsw_unicode)/2 - 1);
/* Convert Unicode to ASCII (CP850) */
ConvertUnicode2Ascii(oldpsw_unicode, oldpsw, sizeof(oldpsw));
if (!ConvertUnicode2Ascii(newpsw_unicode, newpsw, sizeof(newpsw)))
{
CLEAR(passphrase);
if (LocalizedDialogBox(ID_DLG_PASSPHRASE, PassphraseDialogFunc) == IDCANCEL)
{
StopOpenVPN(config);
}
if (wcslen(passphrase) > 0)
{
CLEAR(passphrase_ascii);
ConvertUnicode2Ascii(passphrase, passphrase_ascii, sizeof(passphrase_ascii));
if (!WriteFile(o.conn[config].hStdIn, passphrase_ascii,
strlen(passphrase_ascii), &nCharsWritten, NULL))
{
/* PassPhrase -> stdin failed */
ShowLocalizedMsg(IDS_ERR_PASSPHRASE2STDIN);
}
}
if (!WriteFile(o.conn[config].hStdIn, "\r\n",
2, &nCharsWritten, NULL))
{
/* CR -> stdin failed */
ShowLocalizedMsg(IDS_ERR_CR2STDIN);
}
/* Remove Passphrase prompt from lastline buffer */
line[0]='\0';
/* Clear passphrase buffer */
CLEAR(passphrase);
CLEAR(passphrase_ascii);
ShowLocalizedMsg(IDS_ERR_INVALID_CHARS_IN_PSW);
return(-1);
}
/* Check for new passphrase prompt introduced with OpenVPN 2.0-beta12. */
if (strncmp(line, "Enter Private Key Password:", 27) == 0)
privkey = EVP_PKEY_new();
/* Open old keyfile for reading */
if (! (fp = _tfopen (keyfile, _T("r"))))
{
CLEAR(passphrase);
if (LocalizedDialogBox(ID_DLG_PASSPHRASE, PassphraseDialogFunc) == IDCANCEL)
{
StopOpenVPN(config);
}
if (wcslen(passphrase) > 0)
{
CLEAR(passphrase_ascii);
ConvertUnicode2Ascii(passphrase, passphrase_ascii, sizeof(passphrase_ascii));
if (!WriteFile(o.conn[config].hStdIn, passphrase_ascii,
strlen(passphrase_ascii), &nCharsWritten, NULL))
{
/* PassPhrase -> stdin failed */
ShowLocalizedMsg(IDS_ERR_PASSPHRASE2STDIN);
}
}
else
{
if (!WriteFile(o.conn[config].hStdIn, "\n",
1, &nCharsWritten, NULL))
{
/* CR -> stdin failed */
ShowLocalizedMsg(IDS_ERR_CR2STDIN);
}
}
/* Remove Passphrase prompt from lastline buffer */
line[0]='\0';
/* Clear passphrase buffer */
CLEAR(passphrase);
CLEAR(passphrase_ascii);
/* can't open key file */
ShowLocalizedMsg(IDS_ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
return(0);
}
}
void CheckAuthUsernamePrompt (char *line, int config)
{
DWORD nCharsWritten;
struct user_auth user_auth;
/* Check for Passphrase prompt */
if (strncmp(line, "Enter Auth Username:", 20) == 0)
/* Import old key */
if (! (privkey = PEM_read_PrivateKey (fp, NULL, NULL, oldpsw)))
{
CLEAR(user_auth);
if (LocalizedDialogBoxParam(ID_DLG_AUTH, AuthPasswordDialogFunc,
(LPARAM)&user_auth) == IDCANCEL)
{
StopOpenVPN(config);
}
if (strlen(user_auth.username) > 0)
{
if (!WriteFile(o.conn[config].hStdIn, user_auth.username,
strlen(user_auth.username), &nCharsWritten, NULL))
{
ShowLocalizedMsg(IDS_ERR_AUTH_USERNAME2STDIN);
}
}
else
{
if (!WriteFile(o.conn[config].hStdIn, "\n",
1, &nCharsWritten, NULL))
{
ShowLocalizedMsg(IDS_ERR_CR2STDIN);
}
}
if (strlen(user_auth.password) > 0)
{
if (!WriteFile(o.conn[config].hStdIn, user_auth.password,
strlen(user_auth.password), &nCharsWritten, NULL))
{
ShowLocalizedMsg(IDS_ERR_AUTH_PASSWORD2STDIN);
}
}
else
{
if (!WriteFile(o.conn[config].hStdIn, "\n",
1, &nCharsWritten, NULL))
{
ShowLocalizedMsg(IDS_ERR_CR2STDIN);
}
}
/* Remove Username prompt from lastline buffer */
line[0]='\0';
/* Clear user_auth buffer */
CLEAR(user_auth);
/* wrong password */
ShowLocalizedMsg(IDS_ERR_OLD_PWD_INCORRECT);
fclose(fp);
return(-1);
}
}
fclose(fp);
void CheckAuthPasswordPrompt (char *line)
{
/* Check for Passphrase prompt */
if (strncmp(line, "Enter Auth Password:", 20) == 0)
/* Open keyfile for writing */
if (! (fp = _tfopen (keyfile, _T("w"))))
{
/* Remove Passphrase prompt from lastline buffer */
line[0]='\0';
}
}
BOOL CALLBACK PassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
{
static TCHAR empty_string[100];
switch (msg) {
case WM_INITDIALOG:
SetForegroundWindow(hwndDlg);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK: // button
GetDlgItemTextW(hwndDlg, ID_EDT_PASSPHRASE, passphrase, sizeof(passphrase)/2 - 1);
/* Clear buffer */
SetDlgItemText(hwndDlg, ID_EDT_PASSPHRASE, empty_string);
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
case IDCANCEL: // button
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
return FALSE;
}
BOOL CALLBACK AuthPasswordDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
static struct user_auth *user_auth;
static TCHAR empty_string[100];
WCHAR username_unicode[50];
WCHAR password_unicode[50];
switch (msg) {
case WM_INITDIALOG:
user_auth = (struct user_auth *) lParam;
SetForegroundWindow(hwndDlg);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK: // button
GetDlgItemTextW(hwndDlg, ID_EDT_AUTH_USER, username_unicode, sizeof(username_unicode)/2 - 1);
GetDlgItemTextW(hwndDlg, ID_EDT_AUTH_PASS, password_unicode, sizeof(password_unicode)/2 - 1);
/* Convert username/password from Unicode to Ascii (CP850) */
ConvertUnicode2Ascii(username_unicode, user_auth->username, sizeof(user_auth->username) - 1);
ConvertUnicode2Ascii(password_unicode, user_auth->password, sizeof(user_auth->password) - 1);
/* Clear buffers */
SetDlgItemText(hwndDlg, ID_EDT_AUTH_USER, empty_string);
SetDlgItemText(hwndDlg, ID_EDT_AUTH_PASS, empty_string);
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
case IDCANCEL: // button
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
return FALSE;
}
#ifndef DISABLE_CHANGE_PASSWORD
const int KEYFILE_FORMAT_PKCS12 = 1;
const int KEYFILE_FORMAT_PEM = 2;
void ShowChangePassphraseDialog(int config)
{
HANDLE hThread;
DWORD IDThread;
/* Start a new thread to have our own message-loop for this dialog */
hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) ChangePassphraseThread,
(int *) config, // pass config nr
0, &IDThread);
if (hThread == NULL)
{
/* error creating thread */
ShowLocalizedMsg(IDS_ERR_CREATE_PASS_THREAD);
return;
}
}
void ChangePassphraseThread(int config)
{
HWND hwndChangePSW;
MSG messages;
TCHAR conn_name[100];
TCHAR keyfilename[MAX_PATH];
int keyfile_format=0;
/* Cut of extention from config filename. */
_tcsncpy(conn_name, o.conn[config].config_file, _tsizeof(conn_name));
conn_name[_tcslen(conn_name) - (_tcslen(o.ext_string)+1)]=0;
/* Get Key filename from config file */
if (!GetKeyFilename(config, keyfilename, _tsizeof(keyfilename), &keyfile_format))
{
ExitThread(1);
/* can't open file rw */
ShowLocalizedMsg(IDS_ERR_OPEN_WRITE_KEY, keyfile);
EVP_PKEY_free(privkey);
return(0);
}
/* Show ChangePassphrase Dialog */
hwndChangePSW = CreateLocalizedDialog(ID_DLG_CHGPASS, ChangePassphraseDialogFunc);
if (!hwndChangePSW)
return;
SetDlgItemText(hwndChangePSW, ID_TXT_KEYFILE, keyfilename);
SetDlgItemInt(hwndChangePSW, ID_TXT_KEYFORMAT, (UINT) keyfile_format, FALSE);
SetWindowText(hwndChangePSW, LoadLocalizedString(IDS_NFO_CHANGE_PWD, conn_name));
ShowWindow(hwndChangePSW, SW_SHOW);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
/* Write new key to file */
if (strlen(newpsw) == 0)
{
if(!IsDialogMessage(hwndChangePSW, &messages))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
/* No passphrase */
if ( !(PEM_write_PrivateKey(fp, privkey, \
NULL, NULL, /* Use NO encryption */
0, 0, NULL)))
{
/* error writing new key */
ShowLocalizedMsg(IDS_ERR_WRITE_NEW_KEY, keyfile);
EVP_PKEY_free(privkey);
fclose(fp);
return(0);
}
}
else
{
/* Use passphrase */
if ( !(PEM_write_PrivateKey(fp, privkey, \
EVP_des_ede3_cbc(), /* Use 3DES encryption */
(UCHAR*) newpsw, (int) strlen(newpsw), 0, NULL)))
{
/* can't write new key */
ShowLocalizedMsg(IDS_ERR_WRITE_NEW_KEY, keyfile);
EVP_PKEY_free(privkey);
fclose(fp);
return(0);
}
}
ExitThread(0);
EVP_PKEY_free(privkey);
fclose(fp);
/* signal success to user */
ShowLocalizedMsg(IDS_NFO_PWD_CHANGED);
return(1);
}
BOOL CALLBACK ChangePassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
/*
* ChangePasswordPKCS12() returns:
* -1 Wrong password
* 0 Changing password failed for unknown reason
* 1 Password changed successfully
*/
static int
ChangePasswordPKCS12(HWND hwndDlg)
{
TCHAR keyfile[MAX_PATH];
char oldpsw[50];
char newpsw[50];
WCHAR oldpsw_unicode[50];
WCHAR newpsw_unicode[50];
FILE *fp;
EVP_PKEY *privkey;
X509 *cert;
STACK_OF(X509) *ca = NULL;
PKCS12 *p12;
char *alias;
/* Get filename, old_psw and new_psw from Dialog */
GetDlgItemText(hwndDlg, ID_TXT_KEYFILE, keyfile, _tsizeof(keyfile) - 1);
GetDlgItemTextW(hwndDlg, ID_EDT_PASS_CUR, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1);
GetDlgItemTextW(hwndDlg, ID_EDT_PASS_NEW, newpsw_unicode, sizeof(newpsw_unicode)/2 - 1);
/* Convert Unicode to ASCII (CP850) */
ConvertUnicode2Ascii(oldpsw_unicode, oldpsw, sizeof(oldpsw));
if (!ConvertUnicode2Ascii(newpsw_unicode, newpsw, sizeof(newpsw)))
{
ShowLocalizedMsg(IDS_ERR_INVALID_CHARS_IN_PSW);
return(-1);
}
/* Load the PKCS #12 file */
if (!(fp = _tfopen(keyfile, _T("rb"))))
{
/* error opening file */
ShowLocalizedMsg(IDS_ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
return(0);
}
p12 = d2i_PKCS12_fp(fp, NULL);
fclose (fp);
if (!p12)
{
/* error reading PKCS #12 */
ShowLocalizedMsg(IDS_ERR_READ_PKCS12, keyfile);
return(0);
}
/* Parse the PKCS #12 file */
if (!PKCS12_parse(p12, oldpsw, &privkey, &cert, &ca))
{
/* old password incorrect */
ShowLocalizedMsg(IDS_ERR_OLD_PWD_INCORRECT);
PKCS12_free(p12);
return(-1);
}
/* Free old PKCS12 object */
PKCS12_free(p12);
/* Get FriendlyName of old cert */
alias = (char*) X509_alias_get0(cert, NULL);
/* Create new PKCS12 object */
p12 = PKCS12_create(newpsw, alias, privkey, cert, ca, 0,0,0,0,0);
if (!p12)
{
/* create failed */
ShowLocalizedMsg(IDS_ERR_CREATE_PKCS12);
return(0);
}
/* Free old key, cert and ca */
EVP_PKEY_free(privkey);
X509_free(cert);
sk_X509_pop_free(ca, X509_free);
/* Open keyfile for writing */
if (!(fp = _tfopen(keyfile, _T("wb"))))
{
ShowLocalizedMsg(IDS_ERR_OPEN_WRITE_KEY, keyfile);
PKCS12_free(p12);
return(0);
}
/* Write new key to file */
i2d_PKCS12_fp(fp, p12);
PKCS12_free(p12);
fclose(fp);
/* signal success to user */
ShowLocalizedMsg(IDS_NFO_PWD_CHANGED);
return(1);
}
static BOOL CALLBACK
ChangePassphraseDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
{
HICON hIcon;
TCHAR keyfile[MAX_PATH];
@ -429,56 +401,45 @@ BOOL CALLBACK ChangePassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam,
ShowLocalizedMsg(IDS_ERR_UNKNOWN_KEYFILE_FORMAT);
}
DestroyWindow(hwndDlg);
DestroyWindow(hwndDlg);
break;
case IDCANCEL:
DestroyWindow(hwndDlg);
DestroyWindow(hwndDlg);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CLOSE:
DestroyWindow(hwndDlg);
DestroyWindow(hwndDlg);
return FALSE;
}
return FALSE;
}
/* Return TRUE if new passwords match */
int ConfirmNewPassword(HWND hwndDlg)
static int
LineBeginsWith(char *line, const char *keyword, const unsigned int len)
{
TCHAR newpsw[50];
TCHAR newpsw2[50];
if (strncmp(line, keyword, len) == 0)
{
if ((line[len] == '\t') || (line[len] == ' '))
return true;
}
GetDlgItemText(hwndDlg, ID_EDT_PASS_NEW, newpsw, _tsizeof(newpsw) - 1);
GetDlgItemText(hwndDlg, ID_EDT_PASS_NEW2, newpsw2, _tsizeof(newpsw2) - 1);
if (_tcsncmp(newpsw, newpsw2, _tsizeof(newpsw)) == 0)
return true;
else
return false;
return false;
}
/* Return lengh of the new password */
int NewPasswordLengh(HWND hwndDlg)
{
TCHAR newpsw[50];
GetDlgItemText(hwndDlg, ID_EDT_PASS_NEW, newpsw, _tsizeof(newpsw) - 1);
return (_tcslen(newpsw));
}
int ParseKeyFilenameLine(int config, TCHAR *keyfilename, size_t keyfilenamesize, char *line)
static int
ParseKeyFilenameLine(int config, TCHAR *keyfilename, size_t keyfilenamesize, char *line)
{
const int STATE_INITIAL = 0;
const int STATE_READING_QUOTED_PARM = 1;
@ -501,7 +462,7 @@ int ParseKeyFilenameLine(int config, TCHAR *keyfilename, size_t keyfilenamesize,
break;
else if ((line[i] == ';') || (line[i] == '#'))
break;
else if ((line[i] != ' ') && (line[i] != '\t'))
else if ((line[i] != ' ') && (line[i] != '\t'))
{
if (line[i] == '\\')
{
@ -523,7 +484,7 @@ int ParseKeyFilenameLine(int config, TCHAR *keyfilename, size_t keyfilenamesize,
state=STATE_READING_UNQUOTED_PARM;
}
}
}
}
else if (state == STATE_READING_QUOTED_PARM)
{
@ -597,7 +558,7 @@ int ParseKeyFilenameLine(int config, TCHAR *keyfilename, size_t keyfilenamesize,
_tcsncpy(temp_filename, o.conn[config].config_dir, _tsizeof(temp_filename));
if (temp_filename[_tcslen(temp_filename) - 1] != '\\')
_tcscat(temp_filename, _T("\\"));
_tcsncat(temp_filename, keyfilename,
_tcsncat(temp_filename, keyfilename,
_tsizeof(temp_filename) - _tcslen(temp_filename) - 1);
_tcsncpy(keyfilename, temp_filename, keyfilenamesize - 1);
}
@ -606,213 +567,8 @@ int ParseKeyFilenameLine(int config, TCHAR *keyfilename, size_t keyfilenamesize,
}
/* ChangePasswordPEM() returns:
* -1 Wrong password
* 0 Changing password failed for unknown reason
* 1 Password changed successfully
*/
int ChangePasswordPEM(HWND hwndDlg)
{
TCHAR keyfile[MAX_PATH];
char oldpsw[50];
char newpsw[50];
WCHAR oldpsw_unicode[50];
WCHAR newpsw_unicode[50];
FILE *fp;
EVP_PKEY *privkey;
/* Get filename, old_psw and new_psw from Dialog */
GetDlgItemText(hwndDlg, ID_TXT_KEYFILE, keyfile, _tsizeof(keyfile) - 1);
GetDlgItemTextW(hwndDlg, ID_EDT_PASS_CUR, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1);
GetDlgItemTextW(hwndDlg, ID_EDT_PASS_NEW, newpsw_unicode, sizeof(newpsw_unicode)/2 - 1);
/* Convert Unicode to ASCII (CP850) */
ConvertUnicode2Ascii(oldpsw_unicode, oldpsw, sizeof(oldpsw));
if (!ConvertUnicode2Ascii(newpsw_unicode, newpsw, sizeof(newpsw)))
{
ShowLocalizedMsg(IDS_ERR_INVALID_CHARS_IN_PSW);
return(-1);
}
privkey = EVP_PKEY_new();
/* Open old keyfile for reading */
if (! (fp = _tfopen (keyfile, _T("r"))))
{
/* can't open key file */
ShowLocalizedMsg(IDS_ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
return(0);
}
/* Import old key */
if (! (privkey = PEM_read_PrivateKey (fp, NULL, NULL, oldpsw)))
{
/* wrong password */
ShowLocalizedMsg(IDS_ERR_OLD_PWD_INCORRECT);
fclose(fp);
return(-1);
}
fclose(fp);
/* Open keyfile for writing */
if (! (fp = _tfopen (keyfile, _T("w"))))
{
/* can't open file rw */
ShowLocalizedMsg(IDS_ERR_OPEN_WRITE_KEY, keyfile);
EVP_PKEY_free(privkey);
return(0);
}
/* Write new key to file */
if (strlen(newpsw) == 0)
{
/* No passphrase */
if ( !(PEM_write_PrivateKey(fp, privkey, \
NULL, NULL, /* Use NO encryption */
0, 0, NULL)))
{
/* error writing new key */
ShowLocalizedMsg(IDS_ERR_WRITE_NEW_KEY, keyfile);
EVP_PKEY_free(privkey);
fclose(fp);
return(0);
}
}
else
{
/* Use passphrase */
if ( !(PEM_write_PrivateKey(fp, privkey, \
EVP_des_ede3_cbc(), /* Use 3DES encryption */
(UCHAR*) newpsw, (int) strlen(newpsw), 0, NULL)))
{
/* can't write new key */
ShowLocalizedMsg(IDS_ERR_WRITE_NEW_KEY, keyfile);
EVP_PKEY_free(privkey);
fclose(fp);
return(0);
}
}
EVP_PKEY_free(privkey);
fclose(fp);
/* signal success to user */
ShowLocalizedMsg(IDS_NFO_PWD_CHANGED);
return(1);
}
/* ChangePasswordPKCS12() returns:
* -1 Wrong password
* 0 Changing password failed for unknown reason
* 1 Password changed successfully
*/
int ChangePasswordPKCS12(HWND hwndDlg)
{
TCHAR keyfile[MAX_PATH];
char oldpsw[50];
char newpsw[50];
WCHAR oldpsw_unicode[50];
WCHAR newpsw_unicode[50];
FILE *fp;
EVP_PKEY *privkey;
X509 *cert;
STACK_OF(X509) *ca = NULL;
PKCS12 *p12;
char *alias;
/* Get filename, old_psw and new_psw from Dialog */
GetDlgItemText(hwndDlg, ID_TXT_KEYFILE, keyfile, _tsizeof(keyfile) - 1);
GetDlgItemTextW(hwndDlg, ID_EDT_PASS_CUR, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1);
GetDlgItemTextW(hwndDlg, ID_EDT_PASS_NEW, newpsw_unicode, sizeof(newpsw_unicode)/2 - 1);
/* Convert Unicode to ASCII (CP850) */
ConvertUnicode2Ascii(oldpsw_unicode, oldpsw, sizeof(oldpsw));
if (!ConvertUnicode2Ascii(newpsw_unicode, newpsw, sizeof(newpsw)))
{
ShowLocalizedMsg(IDS_ERR_INVALID_CHARS_IN_PSW);
return(-1);
}
/* Load the PKCS #12 file */
if (!(fp = _tfopen(keyfile, _T("rb"))))
{
/* error opening file */
ShowLocalizedMsg(IDS_ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
return(0);
}
p12 = d2i_PKCS12_fp(fp, NULL);
fclose (fp);
if (!p12)
{
/* error reading PKCS #12 */
ShowLocalizedMsg(IDS_ERR_READ_PKCS12, keyfile);
return(0);
}
/* Parse the PKCS #12 file */
if (!PKCS12_parse(p12, oldpsw, &privkey, &cert, &ca))
{
/* old password incorrect */
ShowLocalizedMsg(IDS_ERR_OLD_PWD_INCORRECT);
PKCS12_free(p12);
return(-1);
}
/* Free old PKCS12 object */
PKCS12_free(p12);
/* Get FriendlyName of old cert */
alias = (char*) X509_alias_get0(cert, NULL);
/* Create new PKCS12 object */
p12 = PKCS12_create(newpsw, alias, privkey, cert, ca, 0,0,0,0,0);
if (!p12)
{
/* create failed */
ShowLocalizedMsg(IDS_ERR_CREATE_PKCS12);
return(0);
}
/* Free old key, cert and ca */
EVP_PKEY_free(privkey);
X509_free(cert);
sk_X509_pop_free(ca, X509_free);
/* Open keyfile for writing */
if (!(fp = _tfopen(keyfile, _T("wb"))))
{
ShowLocalizedMsg(IDS_ERR_OPEN_WRITE_KEY, keyfile);
PKCS12_free(p12);
return(0);
}
/* Write new key to file */
i2d_PKCS12_fp(fp, p12);
PKCS12_free(p12);
fclose(fp);
/* signal success to user */
ShowLocalizedMsg(IDS_NFO_PWD_CHANGED);
return(1);
}
int LineBeginsWith(char *line, const char *keyword, const unsigned int len)
{
if (strncmp(line, keyword, len) == 0)
{
if ((line[len] == '\t') || (line[len] == ' '))
return true;
}
return false;
}
int GetKeyFilename(int config, TCHAR *keyfilename, size_t keyfilenamesize, int *keyfile_format)
static int
GetKeyFilename(int config, TCHAR *keyfilename, size_t keyfilenamesize, int *keyfile_format)
{
FILE *fp;
char line[256];
@ -872,7 +628,7 @@ int GetKeyFilename(int config, TCHAR *keyfilename, size_t keyfilenamesize, int *
*keyfile_format = KEYFILE_FORMAT_PKCS12;
if (!ParseKeyFilenameLine(config, keyfilename, keyfilenamesize, &line[7]))
return(0);
}
}
}
if ((!found_key) && (!found_pkcs12))
@ -886,4 +642,70 @@ int GetKeyFilename(int config, TCHAR *keyfilename, size_t keyfilenamesize, int *
}
static void
ChangePassphraseThread(int config)
{
HWND hwndChangePSW;
MSG messages;
TCHAR conn_name[100];
TCHAR keyfilename[MAX_PATH];
int keyfile_format=0;
/* Cut of extention from config filename. */
_tcsncpy(conn_name, o.conn[config].config_file, _tsizeof(conn_name));
conn_name[_tcslen(conn_name) - (_tcslen(o.ext_string)+1)]=0;
/* Get Key filename from config file */
if (!GetKeyFilename(config, keyfilename, _tsizeof(keyfilename), &keyfile_format))
{
ExitThread(1);
}
/* Show ChangePassphrase Dialog */
hwndChangePSW = CreateLocalizedDialog(ID_DLG_CHGPASS, ChangePassphraseDialogFunc);
if (!hwndChangePSW)
return;
SetDlgItemText(hwndChangePSW, ID_TXT_KEYFILE, keyfilename);
SetDlgItemInt(hwndChangePSW, ID_TXT_KEYFORMAT, (UINT) keyfile_format, FALSE);
SetWindowText(hwndChangePSW, LoadLocalizedString(IDS_NFO_CHANGE_PWD, conn_name));
ShowWindow(hwndChangePSW, SW_SHOW);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
if(!IsDialogMessage(hwndChangePSW, &messages))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}
ExitThread(0);
}
void
ShowChangePassphraseDialog(int config)
{
HANDLE hThread;
DWORD IDThread;
/* Start a new thread to have our own message-loop for this dialog */
hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) ChangePassphraseThread,
(int *) config, // pass config nr
0, &IDThread);
if (hThread == NULL)
{
/* error creating thread */
ShowLocalizedMsg(IDS_ERR_CREATE_PASS_THREAD);
return;
}
}
#endif

View File

@ -2,6 +2,7 @@
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
*
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
* 2010 Heiko Hund <heikoh@users.sf.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,25 +20,13 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define MIN_PASSWORD_LEN 8
#ifndef PASSPHRASE_H
#define PASSPHRASE_H
struct user_auth {
char username[50];
char password[50];
};
BOOL GetRandomPassword(char *, size_t);
void CheckPrivateKeyPassphrasePrompt (char *line, int config);
void CheckAuthUsernamePrompt (char *line, int config);
void CheckAuthPasswordPrompt (char *line);
BOOL CALLBACK PassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK AuthPasswordDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void ShowChangePassphraseDialog(int config);
BOOL CALLBACK ChangePassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void ChangePassphraseThread(int config);
int ConfirmNewPassword(HWND hwndDlg);
int NewPasswordLengh(HWND hwndDlg);
int ChangePasswordPEM(HWND hwndDlg);
int ChangePasswordPKCS12(HWND hwndDlg);
int GetKeyFilename(int config, TCHAR *keyfilename, size_t keyfilenamesize, int *keyfile_format);
#ifndef DISABLE_CHANGE_PASSWORD
void ShowChangePassphraseDialog(int);
#endif
#endif

362
scripts.c
View File

@ -2,6 +2,7 @@
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
*
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
* 2010 Heiko Hund <heikoh@users.sf.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,6 +23,9 @@
#include <windows.h>
#include <process.h>
#include <tchar.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "config.h"
#include "main.h"
@ -31,258 +35,174 @@
extern options_t o;
void RunConnectScript(int config, int run_as_service)
void
RunPreconnectScript(connection_t *c)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
TCHAR command_line[256];
TCHAR batch_file[100];
DWORD ExitCode;
int i, TimeOut;
STARTUPINFO si;
PROCESS_INFORMATION pi;
TCHAR cmdline[256];
DWORD exit_code;
struct _stat st;
int i;
/* Cut of extention from config filename and add "_up.bat". */
_tcsncpy(batch_file, o.conn[config].config_file, _tsizeof(batch_file));
batch_file[_tcslen(batch_file) - (_tcslen(o.ext_string)+1)]=0;
_tcsncat(batch_file, _T("_up.bat"), _tsizeof(batch_file) - _tcslen(batch_file) - 1);
_sntprintf_0(command_line, _T("%s\\%s"), o.conn[config].config_dir, batch_file);
/* Cut off extention from config filename and add "_pre.bat" */
int len = _tcslen(c->config_file) - _tcslen(o.ext_string);
_sntprintf_0(cmdline, _T("%s\\%.*s_pre.bat"), c->config_dir, len, c->config_file);
/* Return if no script exists */
hFind = FindFirstFile(command_line, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
/* Return if no script exists */
if (_tstat(cmdline, &st) == -1)
return;
FindClose(hFind);
CLEAR(si);
CLEAR(pi);
if (!run_as_service)
/* 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))
return;
for (i = 0; i <= o.preconnectscript_timeout; i++)
{
/* UserInfo: Connect Script running */
SetDlgItemText(o.conn[config].hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONN_SCRIPT));
if (!GetExitCodeProcess(pi.hProcess, &exit_code))
goto out;
if (exit_code != STILL_ACTIVE)
goto out;
Sleep(1000);
}
CLEAR (start_info);
CLEAR (proc_info);
CLEAR (sa);
CLEAR (sd);
/* 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,
command_line, //commandline
NULL,
NULL,
TRUE,
((o.show_script_window[0] == '1') ? (DWORD) CREATE_NEW_CONSOLE :
(DWORD) CREATE_NO_WINDOW),
NULL,
o.conn[config].config_dir, //start-up dir
&start_info,
&proc_info))
{
/* Running Script failed */
ShowLocalizedMsg(IDS_ERR_RUN_CONN_SCRIPT, command_line);
return;
}
TimeOut = o.connectscript_timeout;
if (TimeOut == 0)
{
/* Don't check exist status, just return */
return;
}
for (i=0; i <= TimeOut; i++)
{
if (!GetExitCodeProcess(proc_info.hProcess, &ExitCode))
{
/* failed to get ExitCode */
ShowLocalizedMsg(IDS_ERR_GET_EXIT_CODE, command_line);
return;
}
if (ExitCode != STILL_ACTIVE)
{
if (ExitCode != 0)
{
/* ConnectScript failed */
ShowLocalizedMsg(IDS_ERR_CONN_SCRIPT_FAILED, ExitCode);
return;
}
return;
}
Sleep(1000);
}
/* UserInfo: Timeout */
ShowLocalizedMsg(IDS_ERR_RUN_CONN_SCRIPT_TIMEOUT, TimeOut);
out:
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
void RunDisconnectScript(int config, int run_as_service)
void
RunConnectScript(connection_t *c, int run_as_service)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
TCHAR command_line[256];
TCHAR batch_file[100];
DWORD ExitCode;
int i, TimeOut;
STARTUPINFO si;
PROCESS_INFORMATION pi;
TCHAR cmdline[256];
DWORD exit_code;
struct _stat st;
int i;
/* Append "_down.bat" to config name. */
_tcsncpy(batch_file, o.conn[config].config_name, _tsizeof(batch_file));
_tcsncat(batch_file, _T("_down.bat"), _tsizeof(batch_file) - _tcslen(batch_file) - 1);
_sntprintf_0(command_line, _T("%s\\%s"), o.conn[config].config_dir, batch_file);
/* Cut off extention from config filename and add "_up.bat" */
int len = _tcslen(c->config_file) - _tcslen(o.ext_string);
_sntprintf_0(cmdline, _T("%s\\%.*s_up.bat"), c->config_dir, len, c->config_file);
/* Return if no script exists */
hFind = FindFirstFile(command_line, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
/* Return if no script exists */
if (_tstat(cmdline, &st) == -1)
return;
FindClose(hFind);
if (!run_as_service)
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONN_SCRIPT));
if (!run_as_service)
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))
{
/* UserInfo: Disconnect Script running */
SetDlgItemText(o.conn[config].hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONN_SCRIPT));
ShowLocalizedMsg(IDS_ERR_RUN_CONN_SCRIPT, cmdline);
return;
}
CLEAR (start_info);
CLEAR (proc_info);
CLEAR (sa);
CLEAR (sd);
if (o.connectscript_timeout == 0)
goto out;
/* 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,
command_line, //commandline
NULL,
NULL,
TRUE,
((o.show_script_window[0] == '1') ? (DWORD) CREATE_NEW_CONSOLE :
(DWORD) CREATE_NO_WINDOW),
NULL,
o.conn[config].config_dir, //start-up dir
&start_info,
&proc_info))
for (i = 0; i <= o.connectscript_timeout; i++)
{
return;
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);
}
TimeOut = o.disconnectscript_timeout;
ShowLocalizedMsg(IDS_ERR_RUN_CONN_SCRIPT_TIMEOUT, o.connectscript_timeout);
for (i=0; i <= TimeOut; i++)
{
if (!GetExitCodeProcess(proc_info.hProcess, &ExitCode))
{
return;
}
if (ExitCode != STILL_ACTIVE)
{
return;
}
Sleep(1000);
}
out:
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
void RunPreconnectScript(int config)
void
RunDisconnectScript(connection_t *c, int run_as_service)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
TCHAR command_line[256];
TCHAR batch_file[100];
DWORD ExitCode;
int i, TimeOut;
STARTUPINFO si;
PROCESS_INFORMATION pi;
TCHAR cmdline[256];
DWORD exit_code;
struct _stat st;
int i;
/* Append "_pre.bat" to config name. */
_tcsncpy(batch_file, o.conn[config].config_name, _tsizeof(batch_file));
_tcsncat(batch_file, _T("_pre.bat"), _tsizeof(batch_file) - _tcslen(batch_file) - 1);
_sntprintf_0(command_line, _T("%s\\%s"), o.conn[config].config_dir, batch_file);
/* Cut off extention from config filename and add "_down.bat" */
int len = _tcslen(c->config_file) - _tcslen(o.ext_string);
_sntprintf_0(cmdline, _T("%s\\%.*s_down.bat"), c->config_dir, len, c->config_file);
/* Return if no script exists */
hFind = FindFirstFile(command_line, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
/* Return if no script exists */
if (_tstat(cmdline, &st) == -1)
return;
FindClose(hFind);
if (!run_as_service)
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONN_SCRIPT));
CLEAR (start_info);
CLEAR (proc_info);
CLEAR (sa);
CLEAR (sd);
CLEAR(si);
CLEAR(pi);
/* 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;
/* 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,
command_line, //commandline
NULL,
NULL,
TRUE,
((o.show_script_window[0] == '1') ? (DWORD) CREATE_NEW_CONSOLE :
(DWORD) CREATE_NO_WINDOW),
NULL,
o.conn[config].config_dir, //start-up dir
&start_info,
&proc_info))
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))
return;
for (i = 0; i <= o.disconnectscript_timeout; i++)
{
return;
if (!GetExitCodeProcess(pi.hProcess, &exit_code))
goto out;
if (exit_code != STILL_ACTIVE)
goto out;
Sleep(1000);
}
TimeOut = o.preconnectscript_timeout;
for (i=0; i <= TimeOut; i++)
{
if (!GetExitCodeProcess(proc_info.hProcess, &ExitCode))
{
return;
}
if (ExitCode != STILL_ACTIVE)
{
return;
}
Sleep(1000);
}
out:
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}

View File

@ -2,6 +2,7 @@
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
*
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
* 2010 Heiko Hund <heikoh@users.sf.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,6 +20,11 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
void RunConnectScript(int config, int run_as_service);
void RunDisconnectScript(int config, int run_as_service);
void RunPreconnectScript(int config);
#ifndef SCRIPTS_H
#define SCRIPTS_H
void RunPreconnectScript(connection_t *);
void RunConnectScript(connection_t *, int run_as_service);
void RunDisconnectScript(connection_t *, int run_as_service);
#endif

View File

@ -74,8 +74,8 @@ int MyStartService()
}
/* Run Pre-connect script */
for (i=0; i<o.num_configs; i++)
RunPreconnectScript(i);
for (i=0; i<o.num_configs; i++)
RunPreconnectScript(&o.conn[i]);
if (!StartService(
schService, // handle to service
@ -154,7 +154,7 @@ int MyStartService()
/* Run Connect script */
for (i=0; i<o.num_configs; i++)
RunConnectScript(i, true);
RunConnectScript(&o.conn[i], true);
/* Set Service Status = Connected */
o.service_state = service_connected;
@ -208,7 +208,7 @@ int MyStopService()
/* Run DisConnect script */
for (i=0; i<o.num_configs; i++)
RunDisconnectScript(i, true);
RunDisconnectScript(&o.conn[i], true);
if (!ControlService(
schService, // handle to service

83
tray.c
View File

@ -94,7 +94,7 @@ CreatePopupMenus()
AppendMenu(hMenu, MF_STRING ,IDM_ABOUT, LoadLocalizedString(IDS_MENU_ABOUT));
AppendMenu(hMenu, MF_STRING ,IDM_CLOSE, LoadLocalizedString(IDS_MENU_CLOSE));
SetMenuStatus(0, disconnected);
SetMenuStatus(&o.conn[0], o.conn[i].state);
}
else {
/* Create Main menu with all connections */
@ -140,7 +140,7 @@ CreatePopupMenus()
AppendMenu(hMenuConn[i], MF_STRING, (UINT_PTR) IDM_PASSPHRASEMENU + i, LoadLocalizedString(IDS_MENU_PASSPHRASE));
#endif
SetMenuStatus(i, disconnected);
SetMenuStatus(&o.conn[i], o.conn[i].state);
}
}
@ -324,6 +324,30 @@ SetTrayIcon(conn_state_t state)
}
void
CheckAndSetTrayIcon()
{
if (o.service_state == service_connected)
{
SetTrayIcon(connected);
return;
}
if (CountConnState(connected) != 0)
{
SetTrayIcon(connected);
}
else
{
if (CountConnState(connecting) != 0 || CountConnState(reconnecting) != 0
|| o.service_state == service_connecting)
SetTrayIcon(connecting);
else
SetTrayIcon(disconnected);
}
}
void
ShowTrayBalloon(TCHAR *infotitle_msg, TCHAR *info_msg)
{
@ -341,43 +365,58 @@ ShowTrayBalloon(TCHAR *infotitle_msg, TCHAR *info_msg)
void
SetMenuStatus(int config, conn_state_t state)
SetMenuStatus(connection_t *c, conn_state_t state)
{
if (o.num_configs == 1) {
if (state == disconnected) {
if (o.num_configs == 1)
{
if (state == disconnected)
{
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_GRAYED);
}
else if (state == connecting || state == connected) {
else if (state == connecting || state == connected)
{
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
}
else if (state == disconnecting) {
else if (state == disconnecting)
{
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
}
}
else {
UINT iState = (state == connected || state == disconnecting) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(hMenu, (UINT) hMenuConn[config], iState);
else
{
int i;
for (i = 0; i < o.num_configs; ++i)
{
if (c == &o.conn[i])
break;
}
if (state == disconnected) {
EnableMenuItem(hMenuConn[config], (UINT_PTR) IDM_CONNECTMENU + config, MF_ENABLED);
EnableMenuItem(hMenuConn[config], (UINT_PTR) IDM_DISCONNECTMENU + config, MF_GRAYED);
EnableMenuItem(hMenuConn[config], (UINT_PTR) IDM_STATUSMENU + config, MF_GRAYED);
UINT iState = (state == connected || state == disconnecting) ? MF_CHECKED : MF_UNCHECKED;
CheckMenuItem(hMenu, (UINT) hMenuConn[i], iState);
if (state == disconnected)
{
EnableMenuItem(hMenuConn[i], IDM_CONNECTMENU + i, MF_ENABLED);
EnableMenuItem(hMenuConn[i], IDM_DISCONNECTMENU + i, MF_GRAYED);
EnableMenuItem(hMenuConn[i], IDM_STATUSMENU + i, MF_GRAYED);
}
else if (state == connecting || state == connected) {
EnableMenuItem(hMenuConn[config], (UINT_PTR) IDM_CONNECTMENU + config, MF_GRAYED);
EnableMenuItem(hMenuConn[config], (UINT_PTR) IDM_DISCONNECTMENU + config, MF_ENABLED);
EnableMenuItem(hMenuConn[config], (UINT_PTR) IDM_STATUSMENU + config, MF_ENABLED);
else if (state == connecting || state == connected)
{
EnableMenuItem(hMenuConn[i], IDM_CONNECTMENU + i, MF_GRAYED);
EnableMenuItem(hMenuConn[i], IDM_DISCONNECTMENU + i, MF_ENABLED);
EnableMenuItem(hMenuConn[i], IDM_STATUSMENU + i, MF_ENABLED);
}
else if (state == disconnecting) {
EnableMenuItem(hMenuConn[config], (UINT_PTR) IDM_CONNECTMENU + config, MF_GRAYED);
EnableMenuItem(hMenuConn[config], (UINT_PTR) IDM_DISCONNECTMENU + config, MF_GRAYED);
EnableMenuItem(hMenuConn[config], (UINT_PTR) IDM_STATUSMENU + config, MF_ENABLED);
else if (state == disconnecting)
{
EnableMenuItem(hMenuConn[i], IDM_CONNECTMENU + i, MF_GRAYED);
EnableMenuItem(hMenuConn[i], IDM_DISCONNECTMENU + i, MF_GRAYED);
EnableMenuItem(hMenuConn[i], IDM_STATUSMENU + i, MF_ENABLED);
}
}
}

3
tray.h
View File

@ -48,8 +48,9 @@ void OnNotifyTray(LPARAM);
void OnDestroyTray(void);
void ShowTrayIcon();
void SetTrayIcon(conn_state_t);
void SetMenuStatus(int, conn_state_t);
void SetMenuStatus(connection_t *, conn_state_t);
void SetServiceMenuStatus();
void ShowTrayBalloon(TCHAR *, TCHAR *);
void CheckAndSetTrayIcon();
#endif