- The wait function optionally calls IsDialogMessage() if a dialog
handle is specified. For other customizations the caller can
install a WH_MSGFILTER hook. The hook will get called with
nCode = MSGF_OVPN_WAIT and lParam = &msg.
- Use this in place of Sleep in main.c, scripts.c and PLAP dll.
Fixes#576
Signed-off-by: Selva Nair <selva.nair@gmail.com>
For all dialogs in a thread, set its status window in the same
thread as the owner.
Also set the owner of message boxes appropriately instead of
using NULL. This has the side effect of some of the modal message
popups blocking access to the status Window until dismissed.
Next:
Replace Sleep by a wait that pumps messages.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- ShellExecute with runas is used to elevate
- This Option is hidden if PLAP dll is not found in the
install_path bin folder
- Depends on the presence of openvpn-plap-install.reg
and openvpn-plap-uninstall.reg in the install-path bin
folder.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- Parse the management interface address and password
from the config file
- Hide the status Window by default for persistent
connections --- their startup is automated and may
distract the user otherwise. The user can use the
menu to review status when required.
- Seed srand() using threadId instead of time. Although we
use rand() only for cosmetics, the latter is almost
never unique among threads when multiple connections can
get started in a succession with this patch set.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Bind a socket and then close to identify
a free port and use it when starting openvpn.exe.
Try port = offset + config-index is first, matching
the current usage, and fallback to a dynamic port if
the former fails.
Trac: #1051
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Escape the username string before passing to management
interface. For other dialogs this is already done.
Move string-escape to a function and process the username
through it.
Also escape space, single quote in addition to double quote
and backslash.
Reported by: Jakob Curdes <jc@info-systems.de>
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- Set env variables such as OPENSSL_CONF and OPENSSL_MODULES
- Replace deprecated initialization (since OpenSSL 1.1.0)
by OpenSSL_init_crypto()
Signed-off-by: Selva Nair <selva.nair@gmail.com>
The user is prompted with a message showing the config
name that will be imported. The user can accept or cancel
the operation.
If the user was already prompted for over-write permission
because a config with the same name exists, no further dialog
is shown.
Import using the menu (Import File...) is not affected.
Rationale:
We want to set "Import" as the default verb for the context
menu of .ovpn files. This will allow import of configs by
double-click. Also when .ovpn file is downloaded using a browser,
setting the default bowser action to "open" will result in an import.
In such cases a silent import action could be surprising, and a
prompt showing what is being imported could provide a better UX.
On the flip-side, the prompt/dialog will also be shown when import
is done from the context menu of .ovpn by "right click and
choose import" or when "openvpn-gui.exe --import foo"
or "openvpn-gui.exe --command import foo" is executed. As import
is an action that does not result in an immediately visible result
(unlike, say, edit or print), a prompt requiring user action is of
some value even in these cases. At worst it's a minor annoyance.
See also: https://github.com/OpenVPN/openvpn-build/pull/227
and discussions there-in
Signed-off-by: Selva Nair <selva.nair@gmail.com>
When clicking on tray icon, menu items are deleted and then recreated.
Deletion uses o.num_config:
for (i = 0; i < o.num_configs; i++)
DestroyMenu(hMenuConn[i]);
Commit 8e4183f9 ("Add '--command import' command line option")
added BuildFileList() call which modifies o.num_configs
but doesn't touch menus. When clicking on tray icon after import,
abovementioned code attemps to access invalid item in hMenuConn array
and crashes when this is the first imported profile and hMenuConn is NULL.
In other DestryMenu is called with invalid argument.
Fix by recreating popup menus instead of just rescan file list -
this will first delete menus with correct o.num_config value.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
If the http header "Content-Disposition:" is present take the
filename specified in there as the name of the imported profile,
falling back to scanning the file contents for metadata.
If both filename= and filename*= attributes are present, the
latter takes precedence provided the character set is utf-8.
(Extended attributes as defined in RFC 5987).
In case of import from AS, the behaviour is unchanaged.
Issue: #450.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Less intrusive than a message box that user has
to close. Also the imported filename stub is now
included in the message.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
%S --> %hs in wide format strings, %ls otherwise
%s --> %ls in wide format strings, unchanged otherwise
%c --> %lc in wide format strings
Resource files together have about 970 lines affected and
were edited by looping through all with
sed -i 's/%S/%hs/g' $file
sed -i 's/%s/%ls/g' $file
All other files were manually changed (about 85 lines).
Recent versions of mingw-w64 implicitly turns on __USE_MINGW_ANSI_STDIO
if _GNU_SOURCE, _XOPEN_SOURCE etc are defined (which we do usei).
This breaks non-standard spec such as %S. Anyway, we have been
gradually getting rid of those.
MSVC builds should not be affected.
v2: multiple occurrences in same line was missed in v1 (/g missing in
sed expression). Fixed.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Import a config file from command line as
`openvpn-gui.exe --command import <file-path>`
The command is send to a running instance if any.
Otherwise the GUI extecutable is started and
the import processed.
`openvpn-gui --import <file-path>`
is interpreted as the same command.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Currently we construct the destination path and check whether
it exists. This could miss a connection profile with same
name in another directory.
If a config with same name is found we set it as the destination,
and ask the user for permission to overwrite. However, if the duplicate
is in the global_config_dir, the behaviour is not changed -- that is,
the config is imported with no further prompts.
Also fix the use of same buffer as destination and source in
swprintf(). It seems to work, but is not 'legal'.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Use WinInet to download profile into memory buffer.
If there are certain certificate errors (invalid CN,
wrong date, unknown CA, revocation check failed),
ask if user wants to continue.
Extract profile name from content, sanitize name and
save profile in temp directory. Then import profile
using existing facilities.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Factor out importing part (everything except file open dialog)
into separate function, which can be used when importing
profile from URL.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
This adds support for crtext method of pending authentication,
used by Access Server 2.7 and newer.
When enabled on the server side and on the client side (IV_SSO=crtext),
server returns AUTH_PENDING with Info command like:
CR_TEXT:R,E:Enter Authenticator Code
Client prompts user for the response and sends base64-encoded response
to the server via management interface command:
cr-response SGFsbG8gV2VsdCE=
See https://github.com/OpenVPN/openvpn/blob/master/doc/management-notes.txt (crtext part)
for more information.
Signed-off-by: Lev Stipakov <lev@openvpn.net>
- Left clickng on http or https url will open it on the default browser
Several other URL schemes are detected and formatted as clickable
links, but we only support opening of http/https links.
Note on spaces in URLs: We unescape all %xx occurrences in the echo
message text so that %20 will be converted to space in plain text.
This means embedded spaces in URLs will not work even if written
as %20. An option is to use %2520 which will get conveted to %20
after the unescaping.
A better option is to enclose the URL in <>. If the
text inside <> starts with a valid scheme (http, https etc.),
the entire text including spaces is parsed as the URL.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Process four new echo commands to construct messages to be
displayed to the user:
echo msg message-text
echo msg-n message-text
echo msg-window message-title
echo msg-notify message-title
Note: All rules of push and echo processing apply and determine
what is received as echo commands by the GUI. In addition,
'url-encoded' characters (% followed by two hex digits) are
decoded and displayed.
The message is constructed in the GUI by concatenating the text
specified in one or more "echo msg text" or "echo msg-n text"
commands. In case of "echo msg text" text is appended with a new
line. An empty text in this case will
just add a new line.
The message ends and gets displayed when one of the following
are receieved:
echo msg-window title
echo msg-notify title
where "title" becomes the title of the message window. In case of
msg-window, a modeless window shows the message, in the latter case
a notification balloon is shown.
Example: when pushed from the server:
push "echo msg I say let the world go to hell%2C"
push "echo msg I must have my cup of tea."
push "echo msg-window Notes from the underground"
will display a modeless window with title
"Notes from the underground" and a two line body
--
I say let the world go to hell,
I must have my cup of tea.
--
Note that the message itself is not quoted in the above examples
and so it relies on the server's option-parser combining
individual words into a space separated string. Number of words
on a line is limited by the maximum number of parameters allowed
in openvpn commands (16). This limitation may be avoided by quoting
the text that follows so that the option parser sees it as one
parameter.
The comma character is not allowed in pushed strings, so
it has to be sent encoded as %2C as shown above.
Such encoding of arbitrary bytes is suppored. For example,
newlines may be embedded as %0A, though discouraged. Instead
use multiple "echo msg" commands to separate lines by new line.
An example with embedded spaces and multiple lines concatenated
without a new line in between (note use of single quotes):
push "echo msg-n I swear to you gentlemen%2C that to be"
push "echo msg-n ' overly conscious is a sickness%2C ' "
push "echo msg-n a real%2C thorough sickness."
push "echo msg-notify Quote of the Day"
will show up as a notification that displays for an
OS-dependent interval as:
--
Quote of the Day
I swear to you gentlemen, that to be overly conscious
is a sickness, a real, thorough sickness.
--
where the location of the line break is automatically determined
by the notification API and is OS version-dependent.
Commands like "echo msg ..." in the config file are also
processed the same way. It gets displayed when the GUI connects
to the management interface and receives all pending echo.
Pushed message(s) get displayed when the client daemon
processes push-reply and passes on echo directives to the
GUI.
TODO: The actual window that displays the messages is
implemented in the next commit.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Strings passed to the management interface should escape characters
such as " and \ that have special meaning for the parser.
But, static-challenge password and response are base64 encoded
before passing to the management interface and get literally
transported to the server in that form. Escape processing of
these strings could result in altering the password and/or response.
Reported by: macskas https://github.com/OpenVPN/openvpn-gui/issues/351
Signed-off-by: Selva Nair <selva.nair@gmail.com>
By default CryptBinaryToString used for base64 encoding
adds CRLF every 76 characters or so. As LF is used as
the message delimiter by the management interface, this breaks
handling of static challenge.
Fix by setting CRYPT_STRING_NOCRLF in the flags. With this
change, the trailing '\r\n' removal is no longer required.
Fixes Issue 317: https://github.com/OpenVPN/openvpn-gui/issues/317
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Parent keeping the handle to write end of child's stdout will
cause ERROR_BROKEN_PIPE not signalled if/when the child exits.
Also add a wrapper for CloseHandle()
Fixes the GUI process hanging in read from child
if the latter unexpectedly dies due to some error.
Trac #1203
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- In tray info do not skip the address when v4 ip is absent
- When combining two strings do not add the separator (comma)
if either is empty.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
When openvpn is run with --help option it pops up a help
message and exits when that window is closed. Such instances
cannot accept any commands and should not be treated as a
running instance.
Fix by
(i) When run with --help, promptly release the semaphore used
to restrict to a single running instance.
(ii) Wait for a short interval (200 msec) before timing out of
locking the semaphore. This helps avoid race conditions.
While at it also make sure the semaphore is released and closed
on exit.
Fixes issue: #237
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- Implement connection specific env variables. These are merged
with the process environment strings and passed to scripts.
- To set an env variable, use 'echo setenv name value' in the config
or push from the server. This will set "OPENVPN_name=value" in
the connections's env set. Note that "name" is mangled as
"OPENVPN_name" to avoid servers overwriting sensitive variables
such as PATH. Names are set in the order received and same name
overwrites any previously set value.
- Environment variable names are allowed to contain only alpha numeric
characters and underscore as in openvpn.exe. But, unlike openvpn.exe,
invalid names are ignored, not sanitized.
v2 changes (Dec 16, 2017):
- If value is missing, the directive is interpreted as a delete command
and the env var with matching name in the connection's env set is removed.
- Windows needs env block to be ordered:
While merging connection specific env vars with process env block, order
the entries 'alphabetically' (locale independent, case insensitive
unicode ordinal order). In case of duplicates, the value in connection
env set replaces the one in process env.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- New option --command <action> <params> to send commands to
a running instance of openvpn-gui.exe
Supported actions are
connect, disconnect, reconnect
each of which takes the name of the config (with or without the
extension .ovpn) as a parameter;
disconnect_all, exit
which take no parameter and
silent_connection
which takes an optional parameter = 0 or 1 (1 is the default)
Examples: with the gui running, start a new instance as
openvpn-gui.exe --command disconnect myvpn : ask running instance
to disconnect myvpn if connected
openvpn-gui.exe --command status myvpn : ask running instance
to show the status window for myvpn if available
openvpn-gui.exe --command disconnect_all : ask running instance
to disconnect all active connections
- The second instance exits after issuing a SendMessage to the
already running instance. If no action is specified, the running
instance is notified to show a balloon to alert the user
- These messages may also be sent from scripts as COPYDATA messages
with the wData element specifying the action to execute and lpData
a pointer to the parameter. The dwData param must be one of
WM_OVPN_xxx with xxx = START, STOP, RESTART, STOPALL, EXIT or
SILENT. See main.h for their values.
v2: Bug fixes based on test reports from larson0815
here: https://github.com/selvanair/openvpn-gui/issues/5
and cron410 here: https://github.com/OpenVPN/openvpn-gui/issues/104
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- Flag password and username input if these contain an invalid character
(currently only embedded '\n' is disallowed). Shows a popup when OK
is pressed so that the user can correct the input and resubmit.
- Add an error message to the log when the management i/f returns
ERROR for incorrectly parsed commands. Otherwise such errors go
unnoticed.
Note: IDS_ERR_INVALID_USERNAME/PASSWORD need translations.
Reported and tested by: Florian Beier (H4ndl3 on github)
Fixes Trac: #958
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- Add a base64 decode function using Windows CyptoAPI
- Move multibyte to widechar conversions to a function
- Add config name to caption of password dialogs to help user
identify the request
- Add new dialog template for generic password/PIN requests
and use it to handle dynamic challenge
Note 1: if dynamic challenge response verification fails, an auth-failed
message is returned by the server causing the GUI to clear any saved
password even if the user-auth dialog itself succeeeded.
Note 2: Dialog template ID_DLG_CHALLENGE_RESPONSE added to language
files may require translation.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- Replace allow_password by a runtime check that enables password
change menu only when the user has write-access to the key file.
- Read exe_path and priority from HKLM and do not duplicate in HKCU.
- Always allow the user to view the config: edit will succeed if user
has write access.
- Always include the proxy settings tab which is the default.
- Remove the unused power event handling and disconnect_on_suspend key.
- Remove password_attempts -- user can stop the password dilaog
by clicking cancel.
- Remove allow_service: implicitly enabled if service_only is used.
- Deprecate removed options in cmd-line parser
- Update README.rst
- Close config file before exit in GetKeyFileName
- Close thread and dialog handles in passphrase.c
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- Username and, optionally, password as well as the private
key passphrase are saved in config-specific registry keys
- All saved data are kept encrypted using DPAPI
- The passphrase dialog is skipped if a valid saved private
key password is available. However, the user-auth dialog
is always presented, prefilled with the saved username
and password.
Note: A text string "Save password" is added to three dialogs
in all language resource files. Additional text with ids
IDS_MENU_CLEARPASS and IDS_NFO_DELETE_PASS are added to the
STRINGTABLE only in the English language resource file.
All these need translations.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
- Encode empty string to empty string
- If Base64Encode returns null do not pass it to snprintf
- Use the actual length of encoded string
Signed-off-by: Selva Nair <selva.nair@gmail.com>
When a connection is attempted using a config in a location
that would fail, offer an option to add the user to the "OpenVPN
Administrators" group. This is done using shell-execute which will
show a UAC prompt for elevation. If it fails (due to user chooses
NO or the UAC dialog fails) the connection is not started.
v2 Changes
- Rebase to master
- Automaticlaly add the admin group if it doesn't exist
- Allow unicode strings in debug output
- Use domain\username to identify user
- Fix the PrintDebug macro
Minor changes based on user feedback
- Bring the window back to foreground after UAC prompt completion
- Show a message if another connection is tried during authorization
- Do not add user to ovpn_admin_group if it is same as the built-in admin group
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Connecting to a named pipe server while running with admin rights is not
secure in some windows versions. As the interactive service is not required
to set routes while running as admin, this looks like a safe compromise.
Fix based on feedback from Heiko Hund
- Move IsUserAdmin() check before opening the service pipe
Signed-off-by: Selva Nair <selva.nair@gmail.com>
[openvpn_config.c:194]: (style) The function 'ConfigFileOptionExist' is never used.
[localization.c:299]: (style) The function 'LocalizedDialogBox' is never used.
[main.c:549]: (style) The function 'PrintErrorDebug' is never used.
[main.c:583]: (style) The function 'init_security_attributes_allow_all' is never used.
[misc.c:180]: (style) The function 'wcseq' is never used.
Proxy settings are fetched from the users Internet Options
for the active connection. If WPAD or a PAC script is configured
they are preferred and used for automatic proxy detection.
Proxy bypass configuration is completely ignored.