Add support for marking connections as persistent

Persistent connections have openvpn.exe daemon started
external to the GUI (e.g., by the automatic service).
This patch adds support for attaching to the management
i/f of such daemons from the GUI and control the connection.

The GUI never stops or starts the openvpn.exe process in this
case. Instead, connect and disconnect buttons signal the
management interface of a running openvpn.exe process to start
the tunnel by attaching to mgmt i/f and sending hold-release if
needed  or stop it and wait in management-hold state
(see DisconnectDaemon()).

When the GUI process exits, persistent connections are left in their
current state using DetachOpenVPN().

No connections are marked as persistent as yet. That is done
in a following commit.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
pull/519/head
Selva Nair 2022-07-03 16:30:31 -04:00
parent f8a1495667
commit 428ee29246
29 changed files with 224 additions and 12 deletions

24
main.c
View File

@ -351,10 +351,23 @@ StopAllOpenVPN()
{
int i;
/* Stop all connections started by us -- we leave persistent ones
* at their current state. Use the disconnect menu to put them into
* hold state before exit, if desired.
*/
for (i = 0; i < o.num_configs; i++)
{
if (o.conn[i].state != disconnected)
StopOpenVPN(&o.conn[i]);
{
if (o.conn[i].flags & FLAG_DAEMON_PERSISTENT)
{
DetachOpenVPN(&o.conn[i]);
}
else
{
StopOpenVPN(&o.conn[i]);
}
}
}
/* Wait for all connections to terminate (Max 5 sec) */
@ -756,14 +769,21 @@ CloseApplication(HWND hwnd)
&& ShowLocalizedMsgEx(MB_YESNO, NULL, _T("Exit OpenVPN"), IDS_NFO_SERVICE_ACTIVE_EXIT) == IDNO)
return;
/* Show a message if any non-persistent connections are active */
for (i = 0; i < o.num_configs; i++)
{
if (o.conn[i].state == disconnected)
if (o.conn[i].state == disconnected
|| o.conn[i].flags & FLAG_DAEMON_PERSISTENT)
{
continue;
}
/* Ask for confirmation if still connected */
if (ShowLocalizedMsgEx(MB_YESNO, NULL, _T("Exit OpenVPN"), IDS_NFO_ACTIVE_CONN_EXIT) == IDNO)
{
return;
}
break; /* show the above message box only once */
}
DestroyWindow(hwnd);

2
main.h
View File

@ -58,10 +58,12 @@
#define WM_OVPN_NOTIFY (WM_APP + 16)
#define WM_OVPN_EXIT (WM_APP + 17)
#define WM_OVPN_SILENT (WM_APP + 18)
#define WM_OVPN_RELEASE (WM_APP + 19)
#define WM_OVPN_IMPORT (WM_APP + 20)
#define WM_OVPN_RESCAN (WM_APP + 21)
#define WM_OVPN_ECHOMSG (WM_APP + 22)
#define WM_OVPN_STATE (WM_APP + 23)
#define WM_OVPN_DETACH (WM_APP + 24)
/* bool definitions */
#define bool int

View File

@ -204,8 +204,12 @@ OnManagement(SOCKET sk, LPARAM lParam)
case FD_CONNECT:
if (WSAGETSELECTERROR(lParam))
{
if (time(NULL) < c->manage.timeout)
/* keep trying for connections with persistent daemons */
if (c->flags & FLAG_DAEMON_PERSISTENT
|| time(NULL) < c->manage.timeout)
{
connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr));
}
else
{
/* Connection to MI timed out. */

View File

@ -248,6 +248,7 @@
#define IDS_NFO_CONFIG_AUTH_PENDING 1256
#define IDS_ERR_ADD_USER_TO_ADMIN_GROUP 1257
#define IDS_NFO_BYTECOUNT 1258
#define IDS_NFO_STATE_ONHOLD 1259
/* Program Startup Related */
#define IDS_ERR_OPEN_DEBUG_FILE 1301

164
openvpn.c
View File

@ -121,6 +121,9 @@ OnReady(connection_t *c, UNUSED char *msg)
ManagementCommand(c, "log on all", OnLogLine, combined);
ManagementCommand(c, "echo on all", OnEcho, combined);
ManagementCommand(c, "bytecount 5", NULL, regular);
/* ask for the current state, especially useful when the daemon was prestarted */
ManagementCommand(c, "state", OnStateChange, regular);
}
@ -130,6 +133,19 @@ OnReady(connection_t *c, UNUSED char *msg)
void
OnHold(connection_t *c, UNUSED char *msg)
{
EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), TRUE);
if ((c->flags & FLAG_DAEMON_PERSISTENT) && (c->state == disconnecting))
{
/* retain the hold state if we are here while disconnecting */
c->state = onhold;
SetMenuStatus(c, onhold);
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_ONHOLD));
SetStatusWinIcon(c->hwndStatus, ID_ICO_DISCONNECTED);
EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE);
CheckAndSetTrayIcon();
return;
}
EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), TRUE);
ManagementCommand(c, "hold off", NULL, regular);
ManagementCommand(c, "hold release", NULL, regular);
}
@ -296,8 +312,11 @@ OnStateChange(connection_t *c, char *data)
LoadLocalizedStringBuf(ip_txt, _countof(ip_txt), IDS_NFO_ASSIGN_IP, ip);
/* Run Connect Script */
if (c->state == connecting || c->state == resuming)
if (!(c->flags & FLAG_DAEMON_PERSISTENT)
&& (c->state == connecting || c->state == resuming))
{
RunConnectScript(c, false);
}
/* Show connection tray balloon */
if ((c->state == connecting && o.show_balloon != 0)
@ -1319,6 +1338,7 @@ OnStop(connection_t *c, UNUSED char *msg)
c->failed_auth_attempts = 0;
c->state = disconnected;
CheckAndSetTrayIcon();
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED));
SendMessage(c->hwndStatus, WM_CLOSE, 0, 0);
break;
@ -1753,6 +1773,44 @@ OnNeedStr (connection_t *c, UNUSED char *msg)
WriteStatusLog (c, L"GUI> ", L"Error: Received NEED-STR message -- not implemented", false);
}
/* Parse the management port and password of a
* a running daemon -- useful when the daemon is externally
* started (persistent) and we need to use the cached
* management interface address parameters to connect to it.
*/
static BOOL
ParseManagementAddress(connection_t *c)
{
/* Not implemented */
return false;
}
/* Stop the connection -- this sets the daemon to exit if
* started by us, else instructs the daemon to disconnect and
* and wait.
*/
static void
DisconnectDaemon(connection_t *c)
{
if (c->flags & FLAG_DAEMON_PERSISTENT)
{
if (c->manage.connected)
{
ManagementCommand(c, "hold on", NULL, regular);
ManagementCommand(c, "signal SIGHUP", NULL, regular);
}
else
{
OnStop(c, NULL);
}
}
else
{
SetEvent(c->exit_event);
SetTimer(c->hwndStatus, IDT_STOP_TIMER, 15000, NULL);
}
}
/*
* Close open handles
*/
@ -1889,7 +1947,6 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
return TRUE;
case ID_RESTART:
c->state = reconnecting;
SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG));
RestartOpenVPN(c);
return TRUE;
@ -1921,19 +1978,42 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
PostQuitMessage(0);
break;
case WM_OVPN_RELEASE:
c = (connection_t *) GetProp(hwndDlg, cfgProp);
c->state = reconnecting;
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING));
SetDlgItemTextW(c->hwndStatus, ID_TXT_IP, L"");
SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTING);
OnHold(c, "");
break;
case WM_OVPN_STOP:
c = (connection_t *) GetProp(hwndDlg, cfgProp);
/* external messages can trigger when we are not ready -- check the state */
if (!IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_DISCONNECT)))
if (!IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_DISCONNECT))
|| c->state == onhold)
{
break;
}
c->state = disconnecting;
RunDisconnectScript(c, false);
if (!(c->flags & FLAG_DAEMON_PERSISTENT))
{
RunDisconnectScript(c, false);
}
EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE);
SetMenuStatus(c, disconnecting);
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM));
SetEvent(c->exit_event);
SetTimer(hwndDlg, IDT_STOP_TIMER, 15000, NULL);
DisconnectDaemon(c);
break;
case WM_OVPN_DETACH:
c = (connection_t *) GetProp(hwndDlg, cfgProp);
/* just stop the thread keeping openvpn.exe running */
c->state = disconnecting;
EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE);
OnStop(c, NULL);
break;
case WM_OVPN_SUSPEND:
@ -1962,7 +2042,13 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
c = (connection_t *) GetProp(hwndDlg, cfgProp);
/* external messages can trigger when we are not ready -- check the state */
if (IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_RESTART)))
{
c->state = reconnecting;
ManagementCommand(c, "signal SIGHUP", NULL, regular);
SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING));
SetDlgItemTextW(c->hwndStatus, ID_TXT_IP, L"");
SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTING);
}
if (!o.silent_connection)
{
SetForegroundWindow(c->hwndStatus);
@ -2037,7 +2123,21 @@ ThreadOpenVPNStatus(void *p)
while (WM_QUIT != msg.message)
{
DWORD res;
if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
if (wait_event == NULL) /* for persistent connections there is no wait_event */
{
res = GetMessage(&msg, NULL, 0, 0);
if (res == (DWORD) -1) /* log the error and continue */
{
MsgToEventLog(EVENTLOG_WARNING_TYPE, L"GetMessage for <%ls> returned error (status=%lu)",
c->config_name, GetLastError());
continue;
}
else if (res == 0) /* WM_QUIT */
{
break;
}
}
else if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if ((res = MsgWaitForMultipleObjectsEx (1, &wait_event, INFINITE, QS_ALLINPUT,
MWMO_ALERTABLE)) == WAIT_OBJECT_0)
@ -2140,6 +2240,17 @@ out:
}
#endif
/* If state is on hold -- release */
void
ReleaseOpenVPN(connection_t *c)
{
if (c->state != onhold)
{
return;
}
PostMessage(c->hwndStatus, WM_OVPN_RELEASE, 0, 0);
}
/* Start a thread to monitor a connection and launch openvpn.exe if required */
BOOL
StartOpenVPN(connection_t *c)
@ -2148,6 +2259,11 @@ StartOpenVPN(connection_t *c)
if (c->hwndStatus)
{
if (c->state == onhold)
{
ReleaseOpenVPN(c);
return true;
}
PrintDebug(L"Connection request when already started -- ignored");
/* the tread can hang around after disconnect if user has not dismissed any popups */
if (c->state == disconnected)
@ -2175,8 +2291,16 @@ StartOpenVPN(connection_t *c)
return false;
}
if (c->flags & FLAG_DAEMON_PERSISTENT)
{
if (!ParseManagementAddress(c))
{
TerminateThread(hThread, 1);
return false;
}
}
/* Launch openvpn.exe using the service or directly */
if (!LaunchOpenVPN(c))
else if (!LaunchOpenVPN(c))
{
TerminateThread(hThread, 1);
return false;
@ -2388,6 +2512,20 @@ out:
}
/* Close the status thread without disconnecting the tunnel.
* Meant to be used only on persistent connections which can
* stay connected without the GUI tending to it.
*/
void
DetachOpenVPN(connection_t *c)
{
/* currently supported only for persistent connections */
if (c->flags & FLAG_DAEMON_PERSISTENT)
{
PostMessage(c->hwndStatus, WM_OVPN_DETACH, 0, 0);
}
}
void
StopOpenVPN(connection_t *c)
{
@ -2431,10 +2569,18 @@ SuspendOpenVPN(int config)
void
RestartOpenVPN(connection_t *c)
{
if (c->hwndStatus)
if (c->state == onhold)
{
ReleaseOpenVPN(c);
}
else if (c->hwndStatus)
{
PostMessage(c->hwndStatus, WM_OVPN_RESTART, 0, 0);
}
else /* Not started: treat this as a request to connect */
{
StartOpenVPN(c);
}
}
void

View File

@ -27,8 +27,10 @@
BOOL StartOpenVPN(connection_t *);
void StopOpenVPN(connection_t *);
void DetachOpenVPN(connection_t *);
void SuspendOpenVPN(int config);
void RestartOpenVPN(connection_t *);
void ReleaseOpenVPN(connection_t *);
BOOL CheckVersion();
void SetStatusWinIcon(HWND hwndDlg, int IconID);

View File

@ -65,6 +65,7 @@ typedef enum {
/* connection states */
typedef enum {
disconnected,
onhold,
connecting,
reconnecting,
connected,
@ -87,6 +88,7 @@ typedef struct {
#define FLAG_SAVE_AUTH_PASS (1<<5)
#define FLAG_DISABLE_SAVE_PASS (1<<6)
#define FLAG_DISABLE_ECHO_MSG (1<<7)
#define FLAG_DAEMON_PERSISTENT (1<<8)
#define CONFIG_VIEW_AUTO (0)
#define CONFIG_VIEW_FLAT (1)

View File

@ -359,6 +359,7 @@ Prosím dokončete předchozí autorizační dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread k zobrazení stavu selhal."
IDS_NFO_STATE_WAIT_TERM "Aktuální stav: Čekání, než se OpenVPN ukončí…"
IDS_NFO_STATE_CONNECTED "Aktuální stav: Připojeno"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls je nyní připojeno."
IDS_NFO_ASSIGN_IP "Přiřazená IP: %ls"
IDS_ERR_CERT_EXPIRED "Spojení nelze navázat, protože certifikát expiroval, nebo není správně nastaven systémový čas."

View File

@ -361,6 +361,7 @@ Bitte vervollständigen Sie den vorhergehenden Autorisierungsdialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread zum Anzeigen des Status-Fensters ist fehlgeschlagen."
IDS_NFO_STATE_WAIT_TERM "Aktueller Status: Wartet bis OpenVPN beendet ist…"
IDS_NFO_STATE_CONNECTED "Aktueller Status: Verbunden"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls ist nun verbunden."
IDS_NFO_ASSIGN_IP "Zugewiesene IP: %ls"
IDS_ERR_CERT_EXPIRED "Es konnte keine Verbindung hergestellt werden, weil Ihr Zertifikat abgelaufen ist oder die Systemzeit nicht korrekt eingestellt ist."

View File

@ -359,6 +359,7 @@ Please complete the previous authorization dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread for at vise statusvindue fejlramt."
IDS_NFO_STATE_WAIT_TERM "Status: Venter på OpenVPN afslutning…"
IDS_NFO_STATE_CONNECTED "Status: Forbundet"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls er forbundet."
IDS_NFO_ASSIGN_IP "tildelt IP: %ls"
IDS_ERR_CERT_EXPIRED "Kunne ikke forbinde, dit certifikat er for gammelt eller uret på din PC er forkert."

View File

@ -373,6 +373,7 @@ Please complete the previous authorization dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
IDS_NFO_STATE_WAIT_TERM "Current State: Waiting for OpenVPN to terminate…"
IDS_NFO_STATE_CONNECTED "Current State: Connected"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls is now connected."
IDS_NFO_ASSIGN_IP "Assigned IP: %ls"
IDS_ERR_CERT_EXPIRED "Unable to connect because your certificate has expired or the system time is incorrect."

View File

@ -357,6 +357,7 @@ Please complete the previous authorization dialog."
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_NFO_STATE_CONNECTED "Estado actual: Conectado."
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "Conectado a %ls."
IDS_NFO_ASSIGN_IP "IP asignada: %ls"
IDS_ERR_CERT_EXPIRED "Imposible conectar porque su certificado ha expirado o la hora del sistema no es correcta."

View File

@ -361,6 +361,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "ایجاد موضوع برای نمایش پنجره وضعیت ناموفق بود."
IDS_NFO_STATE_WAIT_TERM "وضعیت اخیر: منتظر OpenVPN برای پایان دادن…"
IDS_NFO_STATE_CONNECTED "وضعیت اخیر: متصل"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls متصل است."
IDS_NFO_ASSIGN_IP "ّIP اختصاص داده شده: %ls"
IDS_ERR_CERT_EXPIRED "اتصال امکان پذیر نیست زیرا گواهی شما منقضی شده است یا زمان سیستم نادرست است."

View File

@ -358,6 +358,7 @@ Ole hyvä ja suorita aiempi varmennus loppuun."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
IDS_NFO_STATE_WAIT_TERM "Tila: odotetaan OpenVPN:n sammumista…"
IDS_NFO_STATE_CONNECTED "Tila: yhdistetty"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls on nyt yhdistetty."
IDS_NFO_ASSIGN_IP "IP-osoite: %ls"
IDS_ERR_CERT_EXPIRED "Yhdistäminen epäonnistui, koska varmenne on vanhentunut tai tietokoneen kello on väärässä ajassa."

View File

@ -358,6 +358,7 @@ Veuillez compléter la boîte de dialogue d'autorisation précédente."
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_NFO_STATE_CONNECTED "Etat actuel: Connecté"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls est désormais connecté."
IDS_NFO_ASSIGN_IP "Adresse IP assignée: %ls"
IDS_ERR_CERT_EXPIRED "Connexion impossible car votre certificat a expiré ou la date de votre système est incorrecte."

View File

@ -358,6 +358,7 @@ Completa la richiesta di autorizzazione precedente."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread fallito per visualizzare lo stato."
IDS_NFO_STATE_WAIT_TERM "Stato corrente: In attesa che OpenVPN termini…"
IDS_NFO_STATE_CONNECTED "Stato corrente: Connesso"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls è ora connesso."
IDS_NFO_ASSIGN_IP "IP assegnato: %ls"
IDS_ERR_CERT_EXPIRED "Non riesco a connettermi perché il tuo certificato è scaduto o l'orologio di sistema non è corretto."

View File

@ -359,6 +359,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
IDS_NFO_STATE_WAIT_TERM "現在の状況: OpenVPNの終了を待機中..."
IDS_NFO_STATE_CONNECTED "現在の状況: 接続済み"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls に接続しました。"
IDS_NFO_ASSIGN_IP "割り当てられたIP: %ls"
IDS_ERR_CERT_EXPIRED "証明書の期限が切れているかシステム時刻が正しくないため、接続できません。"

View File

@ -357,6 +357,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
IDS_NFO_STATE_WAIT_TERM "현재 상태: OpenVPN 종료 대기 중…"
IDS_NFO_STATE_CONNECTED "현재 상태: 연결됨"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls 접속이 연결 되었습니다."
IDS_NFO_ASSIGN_IP "할당된 IP: %ls"
IDS_ERR_CERT_EXPIRED "인증서가 만료 되었거나, 시스템 시간이 잘못 설정 되어 연결할 수 없습니다."

View File

@ -359,6 +359,7 @@ Vul het voorgaande autorisatiescherm volledig in."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread om Statusvenster te tonen mislukt."
IDS_NFO_STATE_WAIT_TERM "Huidige status: Wachten tot OpenVPN gestopt is…"
IDS_NFO_STATE_CONNECTED "Huidige status: Verbonden"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls is nu verbonden."
IDS_NFO_ASSIGN_IP "Toegewezen IP: %ls"
IDS_ERR_CERT_EXPIRED "Kan geen verbinding maken, het certificaat is vervallen. Controleer eventueel de systeemtijd."

View File

@ -356,6 +356,7 @@ Please complete the previous authorization dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread for å vise statusvindu feilet."
IDS_NFO_STATE_WAIT_TERM "Status: Venter på at OpenVPN stopper…"
IDS_NFO_STATE_CONNECTED "Status: Tilkoblet"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls er tilkoblet."
IDS_NFO_ASSIGN_IP "Tildelt IP: %ls"
IDS_ERR_CERT_EXPIRED "Kunne ikke koble til. Sertifikatet er ikke lenger gyldig. Eventuelt kan klokken på datamaskinen din gå feil."

View File

@ -359,6 +359,7 @@ Proszę uzupełnić poprzednie okno autoryzacji."
IDS_ERR_CREATE_THREAD_STATUS "Utworzenie wątku dla okna statusu zakończone niepowodzeniem."
IDS_NFO_STATE_WAIT_TERM "Stan obecny: Oczekiwanie na zakończenie OpenVPN-a…"
IDS_NFO_STATE_CONNECTED "Stan obecny: Połączony"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls jest teraz połączony."
IDS_NFO_ASSIGN_IP "Przyznany IP: %ls"
IDS_ERR_CERT_EXPIRED "Połączenie nie jest możliwe z powodu wygaśnięcia certyfikatu lub błędnie ustawionego czasu systemowego."

View File

@ -357,6 +357,7 @@ Por favor, complete o diálogo de autorização anterior."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread falhou ao mostrar janela de status."
IDS_NFO_STATE_WAIT_TERM "Estado atual: Aguardando OpenVPN terminar…"
IDS_NFO_STATE_CONNECTED "Estado atual: Conectado"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls está conectado."
IDS_NFO_ASSIGN_IP "IP atribuído: %ls"
IDS_ERR_CERT_EXPIRED "Impossível conectar porque seu certificado expirou ou a data do sistema está incorreta."

View File

@ -360,6 +360,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "Ошибка выполнения CreateThread при отображении окна состояния."
IDS_NFO_STATE_WAIT_TERM "Текущее состояние: ожидание завершения работы OpenVPN…"
IDS_NFO_STATE_CONNECTED "Текущее состояние: подключено"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls сейчас подключено."
IDS_NFO_ASSIGN_IP "Назначенный IP: %ls"
IDS_ERR_CERT_EXPIRED "Невозможно подключиться, так как срок действия вашего сертификата истёк или системное время некорректно."

View File

@ -357,6 +357,7 @@ Please complete the previous authorization dialog."
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_NFO_STATE_CONNECTED "Status: Ansluten"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls är nu ansluten."
IDS_NFO_ASSIGN_IP "Tilldelad IP: %ls"
IDS_ERR_CERT_EXPIRED "Kunde inte ansluta för att ditt certifikat är för gammalt, eller för att klockan i din dator går fel."

View File

@ -359,6 +359,7 @@ Please complete the previous authorization dialog."
IDS_ERR_CREATE_THREAD_STATUS "CreateThread anında durum penceresi gösterilemedi hatası."
IDS_NFO_STATE_WAIT_TERM "Geçerli Durum: OpenVPN' in kapanması bekleniyor…"
IDS_NFO_STATE_CONNECTED "Geçerli Durum: Bağlandı"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls şu an bağlı."
IDS_NFO_ASSIGN_IP "Atanan IP: %ls"
IDS_ERR_CERT_EXPIRED "Sertifikanız veya sistem tarih/zaman ayarlarınız geçersiz olduğundan bağlantı sağlanamadı."

View File

@ -359,6 +359,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "Робоча помилка CreateThread, а саме у час відображення вікна статусу."
IDS_NFO_STATE_WAIT_TERM "У цей час статус: очікування зупинки роботи OpenVPN…"
IDS_NFO_STATE_CONNECTED "У цей час статус: підключено."
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "%ls зараз підключено."
IDS_NFO_ASSIGN_IP "Отримано IP: %ls"
IDS_ERR_CERT_EXPIRED "Неможливо з'єднатися, бо час дії вашого сертифікату минув або системний час некорректний."

View File

@ -361,6 +361,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "CreateThread 显示状态窗口时失败。"
IDS_NFO_STATE_WAIT_TERM "当前状态: 等待中止 OpenVPN…"
IDS_NFO_STATE_CONNECTED "当前状态: 已连接"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "已连接至 %ls。"
IDS_NFO_ASSIGN_IP "分配 IP: %ls"
IDS_ERR_CERT_EXPIRED "您的证书已过期,或是系统时间不正确,无法连接。"

View File

@ -361,6 +361,7 @@ BEGIN
IDS_ERR_CREATE_THREAD_STATUS "CreateThread 以顯示狀態視窗時失敗。"
IDS_NFO_STATE_WAIT_TERM "目前狀態: 等待中止 OpenVPN…"
IDS_NFO_STATE_CONNECTED "目前狀態: 已連線"
IDS_NFO_STATE_ONHOLD "Current State: On Hold (disconnected)"
IDS_NFO_NOW_CONNECTED "已連線至 %ls。"
IDS_NFO_ASSIGN_IP "配發 IP: %ls"
IDS_ERR_CERT_EXPIRED "您的憑證已過期,或是系統時間不正確,無法連線。"

14
tray.c
View File

@ -576,6 +576,13 @@ SetMenuStatusById(int i, conn_state_t state)
EnableMenuItem(hMenu, IDM_RECONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
}
else if (state == onhold)
{
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_RECONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
}
if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS))
EnableMenuItem(hMenu, IDM_CLEARPASSMENU, MF_ENABLED);
else
@ -635,6 +642,13 @@ SetMenuStatusById(int i, conn_state_t state)
EnableMenuItem(hMenuConn[i], IDM_RECONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenuConn[i], IDM_STATUSMENU, MF_ENABLED);
}
else if (state == onhold)
{
EnableMenuItem(hMenuConn[i], IDM_CONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenuConn[i], IDM_DISCONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenuConn[i], IDM_RECONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenuConn[i], IDM_STATUSMENU, MF_ENABLED);
}
if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS))
EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU, MF_ENABLED);
else