import of openvpn-gui-1.0.3.zip

git-svn-id: https://openvpn-gui.svn.sourceforge.net/svnroot/openvpn-gui/trunk@2 43a1345a-9c20-4331-951f-9845fc178312
pull/1/head
Heiko Hund 2008-12-18 11:08:35 +00:00
parent a0e7f98401
commit fd9e4ae6db
40 changed files with 8970 additions and 0 deletions

14
COPYING Normal file
View File

@ -0,0 +1,14 @@
OpenVPN GUI -- A Windows GUI for OpenVPN
Copyright (C) 2004-2005 by Mathias Sundman <info@openvpn.se>
OpenVPN GUI is distributed under GPL license.
(see COPYRIGHT.GPL)
Parts of the source code for OpenVPN GUI is taken from
openvpnserv.c included with the OpenVPN [1] distribution.
[1] OpenVPN is copyrighted by OpenVPN Solutions LLC <info@openvpn.net>,
and distributed under GPL license.

340
COPYRIGHT.GPL Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

44
Makefile Normal file
View File

@ -0,0 +1,44 @@
# This makefile builds OpenVPN-GUI using the mingw environment.
OPENSSL = /c/OpenSSL
RES_LANG = en
GUI_VERSION = 1.0.3
EXE = openvpn-gui-$(GUI_VERSION)-$(RES_LANG).exe
HEADERS = main.h openvpn.h openvpn_monitor_process.h tray.h viewlog.h \
service.h options.h passphrase.h openvpn-gui-res.h proxy.h \
ieproxy.h registry.h openvpn_config.h chartable.h scripts.h
OBJS = main.o tray.o openvpn.o openvpn_monitor_process.o viewlog.o \
service.o options.o passphrase.o proxy.o ieproxy.o registry.o \
openvpn_config.o scripts.o openvpn-gui-$(RES_LANG).res
INCLUDE_DIRS = -I. -I${OPENSSL}/include
LIB_DIRS = -L${OPENSSL}/lib/MinGW
WARNS = -W -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast \
-Wcast-align -Wwrite-strings -Wconversion -Wsign-compare \
-Waggregate-return -Wmissing-noreturn -Wmissing-format-attribute \
-Wredundant-decls -Winline -Wdisabled-optimization \
-Wno-unused-function -Wno-unused-variable
CC = gcc
CFLAGS = -g -O2 ${WARNS} -mno-cygwin
LDFLAGS = -mwindows -s
#LDFLAGS = -mwindows
WINDRES = windres.exe
all : ${OBJS}
${CC} -o ${EXE} ${OBJS} ${LIB_DIRS} -leay32 -lWinInet ${LDFLAGS}
# ${CC} -o ${EXE} ${OBJS} ${LIB_DIRS} -lWinInet ${LDFLAGS}
clean :
rm -f *.o *.exe *.res
%.o : %.c ${HEADERS}
${CC} ${CFLAGS} ${INCLUDE_DIRS} -c $< -o $@
openvpn-gui-$(RES_LANG).res : openvpn-gui-$(RES_LANG).rc openvpn-gui-res.h
$(WINDRES) -i openvpn-gui-$(RES_LANG).rc -I rc -o openvpn-gui-$(RES_LANG).res -O coff

231
OpenVPN GUI ReadMe.txt Normal file
View File

@ -0,0 +1,231 @@
Installation Instructions for OpenVPN GUI for Windows
-----------------------------------------------------
You can either get my installation package for OpenVPN 2.0.X where I've
bundled the gui in the installation package, or you can use the original
installation package from OpenVPN, and then manually install OpenVPN GUI.
Installation using the bundled OpenVPN package with OpenVPN GUI included
------------------------------------------------------------------------
* Download openvpn-2.0.X-gui-1.0.X-install.exe from
http://openvpn.se
* If you have a previous version of OpenVPN GUI installed, shut it down.
Make sure it's closed by ALL logged on users.
* Run the install program. During the installation you can choose if the GUI
should be started automatically at system startup. The default is yes.
* Create a xxxx.ovpn config-file with your favorite texteditor and save it in:
C:\Program files\OpenVPN\config\. You should NOT use the "log" or "log-append"
options as OpenVPN GUI redirect the normal output to a log file itself.
There is a sample config files in the "sample-config" folder. Please
refer to the OpenVPN project homepage for more information regarding
creating the configuration file. http://openvpn.net/
Manual installation of OpenVPN GUI
----------------------------------
* Download and install OpenVPN from http://openvpn.net/
* Download openvpn-gui-1.0.X.exe and save it in OpenVPN's bin folder.
Default is "C:\Program Files\OpenVPN\bin\". You must put it in this folder
because OpenVPN GUI depends on the OpenSSL DLLs installed in this folder by
OpenVPN.
* Create a xxxx.ovpn config-file with your favorite texteditor and save it in:
C:\Program files\OpenVPN\config\. You should NOT use the "log" or "log-append"
options as OpenVPN GUI redirect the normal output to a log file itself.
There is a sample config files in the "sample-config" folder. Please
refer to the OpenVPN project homepage for more information regarding
creating the configuration file. http://openvpn.net/
* Put a short-cut to openvpn-gui-1.0-X.exe in your
"Start->All Program->StartUp" folder if you want the gui started automatically
when you logon to Windows.
* Start the GUI by double-clicking the openvpn-gui-1.0.X.exe file.
*** You need to be Administrator the first time you run OpenVPN GUI for it to
create its registry keys. After that you don't have to be administrator
just to run the GUI, however OpenVPN requires the user to be
administrator to run! ***
Using OpenVPN GUI
-----------------
When OpenVPN GUI is started your config folder (C:\Program Files\OpenVPN\config)
will be scanned for .ovpn files, and an icon will be displayed in the taskbar's
status area.
If you do not have any openvpn connection running, the config dir will be
re-scanned for new config files every time you open the OpenVPN GUI menu by
right-clicking the icon.
When you choose to connect to a site OpenVPN GUI will launch openvpn with
the specified config file. If you use a passphrase protected key you will be
prompted for the passphrase.
If you want OpenVPN GUI to start a connection automatically when it's started,
you can use the --connect cmd-line option. You have to include the extention
for the config file. Example:
openvpn-gui --connect office.ovpn
Run OpenVPN GUI as a Non-Admin user
-----------------------------------
OpenVPN currently does not work as a normal (non-admin) user. OpenVPN GUI
2.0 will solve this by using an enhanced version of the OpenVPN service
to start and stop openvpn processes.
In the mean time, it is possible to use OpenVPN GUI to control the current
OpenVPN Service to start and stop a connection.
To use OpenVPN GUI to control the OpenVPN service, set the registry value
"service_only" to '1'. See the section about registry values below.
Limitations with this way:
There is no way for OpenVPN GUI ta hand over a password to the service
wrapper, so you can't use passphrase protected private keys or
username/password authentication.
If you have multiple openvpn configurations, all will be started and
stopped at the same time.
OpenVPN GUI is not able to retrieve any status info about the connections
from OpenVPN, so it will report connected as soon as the service is
started regarless of if OpenVPN has really succeded to connect or not.
You cannot see the OpenVPN log in real-time.
Run Connect/Disconnect/Preconnect Scripts
-----------------------------------------
There are three diffrent scripts that OpenVPN GUI can execute to help
with diffrent tasks like mapping network drives.
Preconnect If a file named "xxx_pre.bat" exist in the config folder
where xxx is the same as your OpenVPN config file name,
this will be executed BEFORE the OpenVPN tunnel is established.
Connect If a file named "xxx_up.bat" exist in the config folder
where xxx is the same as your OpenVPN config file name,
this will be executed AFTER the OpenVPN tunnel is established.
Disconnect If a file named "xxx_down.bat" exist in the config folder
where xxx is the same as your OpenVPN config file name,
this will be executed BEFORE the OpenVPN tunnel is closed.
Registry Values affecting the OpenVPN GUI operation
---------------------------------------------------
All OpenVPN GUI reg-values are located below the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI\
The follow keys are used to control the OpenVPN GUI
config_dir
configuration file directory, defaults to "C:\Program Files\OpenVPN\config"
config_ext
file extension on configuration files, defaults to "ovpn"
connectscript_timeout
Time in seconds to wait for the connect script to finish. If set to 0
the exitcode of the script is not checked.
disconnectscript_timeout
Time in seconds to wait for the disconnect script to finish. Must be a
value between 1-99.
preconnectscript_timeout
Time in seconds to wait for the preconnect script to finish. Must be a
value between 1-99.
exe_path
path to openvpn.exe, defaults to "C:\Program Files\OpenVPN\bin\openvpn.exe"
log_dir
log file directory, defaults to "C:\Program Files\OpenVPN\log"
log_append
if set to "0", the log file will be truncated every time you start a
connection. If set to "1", the log will be appended to the log file.
priority
the windows priority class for each instantiated OpenVPN process,
can be one of:
* "IDLE_PRIORITY_CLASS"
* "BELOW_NORMAL_PRIORITY_CLASS"
* "NORMAL_PRIORITY_CLASS" (default)
* "ABOVE_NORMAL_PRIORITY_CLASS"
* "HIGH_PRIORITY_CLASS"
allow_edit
If set to "1", the Edit config menu will be showed.
allow_password
If set to "1", the Change Password menu will be showed.
allow_proxy
If set to "1", the Proxy Settings menu will be showed.
allow_service
If set to "1", the Service control menu will be showed.
silent_connection
If set to "1", the status window with the OpenVPN log output will
not be showed while connecting.
service_only
If set to "1", OpenVPN GUI's normal "Connect" and "Disconnect"
actions are changed so they start/stop the OpenVPN service instead
of launching openvpn.exe directly.
show_balloon
If set to "0" - Never show any connected balloon.
"1" - Show balloon after initial connection is established.
"2" - Show balloon even after re-connects.
log_viewer
The program used to view your log files, defaults to
"C:\windows\notepad.exe"
editor
The program used to edit your config files, defaults to
"C:\windows\notepad.exe"
passphrase_attempts
Number of attempts to enter the passphrase to allow.
All these registry options is also available as cmd-line options.
Use "openvpn-gui --help" for more info about cmd-line options.
If you have any problem getting OpenVPN GUI to work you can reach me via
email at mathias@nilings.se.
Building OpenVPN GUI from source
--------------------------------
* Download and install MinGW and MSYS from http://www.mingw.org/
I'm using MinGW-3.2.0-rc-3 and MSYS-1.0.10.
* Download and install the binary distribution of OpenSSL from
http://www.slproweb.com/products/Win32OpenSSL.html
* Download and extract the OpenVPN GUI source archive.
* Start a bash shell by running msys.bat.
* Run "make" from the OpenVPN GUI source directory.

635
changes.txt Normal file
View File

@ -0,0 +1,635 @@
[1.0.3 2005-08-18]
Bug Fixes:
There was a bug in the code that expands variables in
registry values. If the expanded string was longer than
the original string it got incorrectly truncated.
[1.0.2 2005-07-27]
Pass paths read in OpenVPN GUI's registry values through
ExpandEnvironmentStrings(). This allows the use of Windows
variables like %HOMEPATH% or %PROGRAMFILES%. This allows
multiple users on the same system to have their own set
of config files and keys in their home dir.
[1.0.1 2005-06-10]
Bug Fixes:
The Change Password feature did not work correctly when TABs
were used in the config file between the key/pkcs12 keyword and
the accual path to the key file.
[1.0 2005-04-21]
No changes
[1.0-rc5 2005-03-29]
Bug Fixes:
[Pre/Dis]Connect scripts were not executed when starting or stopping
the OpenVPN Service, or using "Service Only" mode.
[1.0-rc4 2005-02-17]
Increased the width of buttons and space between text labels and edit
controls on dialogs to ease localization of OpenVPN GUI.
Bug Fixes:
Some fixed text strings was introduced in the code in 1.0-rc3. These
are moved to the resource file now to allow localization.
If starting the OpenVPN service failed, OpenVPN GUI would get
stuck with a yellow icon.
[1.0-rc3 2005-02-14]
New Features:
New registry value (show_balloon) to control whether to show the
"Connected Balloon" or not. show_ballon can have the following values
0=Never show any balloon.
1=Show balloon when the connection establishes (default).
2=Show balloon every time OpenVPN has reconnected (old behavior).
Show "Connected since: XXX" and "Assigned IP: X.X.X.X" in the tray
icon tip msg.
If a batch file named xxx_pre.bat exists in the config folder, where
xxx is the same name as an OpenVPN config file, this will be executed
before OpenVPN is launced.
If a batch file named xxx_down.bat exists in the config folder, where
xxx is the same name as an OpenVPN config file, this will be executed
on disconnect, but before the OpenVPN tunnel is closed.
Registry value "show_script_window" controls whether _up, _down and
_pre scripts should execute in the background or in a visible cmd-line
window.
Registry value "[pre/dis]connectscript_timeout" controls how long to
wait for each script to finish.
Updated information on the about dialog.
Bug Fixes:
Removed unused code that tried to determine the path to "Program
Files". This code caused an error in some rare occasions.
[1.0-rc2 2005-01-12]
New Features:
Support for one level of subdirectories below the config directory.
This means that if you have multiple connections, you can now put
them in a seperate subdirectory together with their keys and certs.
"Service Only" mode. This is a mode that makes OpenVPN GUI more
friendly to use for non-admin users to control the OpenVPN Service.
Enable this mode by setting the registry value "service_only" to "1".
In this mode the following happends:
* The normal "Connect", "Disconnect" and "Show Status" is removed.
* The Service menu items "Start", "Stop" and "Restart" is replaced
by "Connect", "Disconnect" and "Reconnect" directly on the main
menu. These now control the OpenVPN Service instead.
* Dubbleclicking the icon starts the OpenVPN Service.
* Dubbleclicking the icon when the service is running brings up a
dialog asking if you want to disconnect.
* The Proxy Settings menu item is removed as it can't control the service anyway.
The "OpenVPN Service started" dialog msg is replaced with a
balloon msg.
Ask the user if he really wants to exit OpenVPN GUI if the OpenVPN
Service is running.
Bug Fixes:
Full rights were required to control the OpenVPN Service. Now only
Start/Stop permissions are required, which allows a normal user to
control the OpenVPN Service if these rights are granted to the user.
(Can be done with subinacl.exe from the resource kit)
When passwords were retrieved from a user, OpenVPN GUI received them
in the default windows codepage (ISO 8859-1 on english XP), and this
was passed on untouched to OpenVPN. When OpenVPN is run from command-
line on the other hand, the old DOS CP850 codepage is used. This
caused passwords containing non-ASCII (7-bit) chars that worked from
cmd-line not to work from OpenVPN GUI. This is now solved by
retrieving passwords in unicode and translate them to CP850 before
supplying them to OpenVPN.
Re-scan the config dir for new files when dubble-clicking the tray
icon.
[1.0-rc1 2005-01-06]
New Features:
Show a warning message if "log" or "log-append" is found in the config
file.
Bug Fixed:
Added a bunch of compiler warnings which revealed a lot of minor
programming errors. Mostly cast conversion errors between signed and
unsigned intergers. All fixed now.
Set focus on the log window when the status window is re-opened to make
sure the log is scrolled automatically.
Set focus on the log window when clicking disconnect to allow the log
to continue scrolling automatically until OpenVPN is terminated.
[1.0-beta26 2004-12-04]
New Features:
Show "Connecting to: xxx" msg in tray icon tip message in addition to
the previously displayed "Connected to:" msg.
Bug Fixes:
Don't ask if you are sure you want to change your password to an EMPTY
password if you're not allowed to use passwords shorter than 8 chars.
Clear password buffers after use to avoid having passwords in memory.
[1.0-beta25 2004-12-01]
Changed button labels on the status dialog from DisConnect and ReConnect
to Disconnect and Reconnect.
Don't show "Assigned IP:" at all in the connected balloon if no IP
address is known, as when a real remote DHCP server is used.
Stripped out the last hardcoded strings to the resource file.
Raised maximum number of configs from 20 to 50.
Bug Fixes:
If OpenVPN printed a line longer that 1024 chars, OpenVPN GUI would crash.
This could happend when using "verb 5" or higher as OpenVPN then prints
an "r" or "w" for every packet without any line breaks. A new line will
now be inserted when 1024 chars is reached.
Ask if you want to close active connections when WM_CLOSE is received.
Handle WM_QUERYENDSESSION and WM_ENDSESSION correctly by closing any
active connections and then terminate.
[1.0-beta24 2004-11-15]
Bug Fixes:
Some openssl #includes were not #ifdef:ed when building a nochangepsw
version causing the build to fail if the openssl headers were not
available.
When using OpenVPN 1.5/1.6 and entering a false private key passphrase,
OpenVPN GUI would falsely think that the user attempted to start another
connection.
[1.0-beta23 2004-11-08]
Bug Fixes:
Passphrase protected keys stored in MS Certificate Store did not work
due to the way the openvpn console window was hidden.
[1.0-beta22 2004-11-05]
Bug Fixes:
OpenVPN GUI did not pass a CR/LF correctly after supplying OpenVPN
with the private key passphrase! OpenVPN 2.0-beta12 and higher which
uses a new prompt worked, but not earlier versions of OpenVPN.
If the Shell (explorer.exe) is restarted, OpenVPN GUI did not
re-register the tray icon.
[1.0-beta21 2004-10-29]
New Features:
Added support for username/password based authentication.
Support for Localization. Language have to chosen at build time.
Available are english, german, czech and swedish.
Bug Fixes:
Fixed crash after displaying that too many connections exist.
Removed duplicate length-check on setting new password.
Fixed error dialog which had the error message shown in window caption.
Status windows did not change to yellow icon while ReConnecting.
DisConnect and ReConnect button was not disabled after a termination.
This bug was introduced with beta20.
The Change Password feature did not parse the key/pkcs12 line in the
config file correctly if there was TABs after the filename.
The Change Password feature did not work if a relative path with
subdirectories was used.
[1.0-beta20 2004-10-18]
New Features:
Accept the new passphrase prompt introduced with OpenVPN 2.0-beta12.
When the machine is about to enter suspend mode the connection is
closed. When the machine is powered up again, the connection is
re-established.
Registry option "disconnect_on_suspend". Set to zero to disable the
above feature.
ReConnect button on the status dialog.
Registry option "allow_proxy" to hide the Proxy Settings menu item.
Registry option "silent_connection" that suppresses the status
dialog from being showed while connecting.
Command-line option to set the time to wait for the connect script
to finish.
Icon color now reflects the status of the OpenVPN Service.
Bug Fixes:
Included shellapi.h with the sourcecode, as the one distributed with
the current stable version of MinGW miss some definitions.
When closing OpenVPN GUI it waits for all connections to close before
exiting (Max 5 sec).
Made the password dialog always be on top of other windows.
Fixed a bug that occured if opening the log file for writing failed.
(which happends if you try to run OpenVPN GUI without admin rights)
The menuitems on the OpenVPN Service menu was incorrectly enabled/
disabled. This bug was introduced with beta19 as a result of the
dynamic rescanning for configs on every menu opening.
Starting OpenVPN GUI with OpenVPN 1.5/1.6 installed and OpenVPN
Service running failed with previous versions. (CreateEvent() error)
The installation package did not remove the OpenVPN-GUI registry key
on uninstall.
Removed dependency on libeay32.dll for the no change password build.
[1.0-beta19 2004-09-22]
New Features:
The menu is restructured. Previous versions had all "actions" on the
main menu, and a submenu with all configs for every action. This version
lists all configs on the main menu, and have a submenu with actions.
If only one config exist, the actions are placed on the main menu.
If no connection is running, the config dir is re-scanned for configs
every time the menu is opened.
If a file exists in the config folder named xxxx_up.bat, where xxxx
is the same name as an existing config file, this batch file will be
executed after a connection has been establish. If the batch file
fails (return an exitcode other than 0), an error message is displayed.
Auto-hide status window after a connection is established and show
a systray info balloon instead.
Show assigned IP address in connected balloon.
Don't allow starting multiple instances of OpenVPN GUI.
Added a cancel button to the Ask Password dialog.
Bug Fixes:
Removed [nopass] parameter on --connect option as the password prompt
is only showed if the private key really is passphrase protected.
Show an error msg if --connect refers to a non existing config file.
Ignore case of config file extension.
[1.0-beta18 2004-09-13]
New Features:
New Icons! Supplied by Radek Hladik.
If only one config file exists, dubble-clicking the systray icon will
start that connection.
Bug Fixes:
A bug in the GetRegKey() function caused OpenVPN GUI sometimes to
fail starting with the following error msg:
Error creating exit_event when checking openvpn version.
[1.0-beta17 2004-09-02]
New Features:
A dialog to configure Proxy Settings. You can now set http-proxy or
socks-proxy address and port from the GUI. You can also make the GUI
ask for proxy username and password, which will then be supplied to
OpenVPN via an auth file.
Use Internet Explorer Proxy Settings (Ewan Bhamrah Harley)
A "Hide" button on the status dialog.
Show an error message if the client certificate has expired or is not
yet valid.
Bug Fixes:
If OpenVPN was installed in a non default folder, OpenVPN GUI would try
to locate openvpn.exe, log-dir and conf-dir in the default openvpn
folder anyway. Fixed in this version.
OpenVPN GUI tried to check the status of the OpenVPN Service even
if the service menu was disabled in the registry, which caused an
error message to be showed if the service was not installed properly.
Wait for two seconds when exiting OpenVPN GUI, so running openvpn
processes can exit cleanly.
Disable Disconnect menu item while waiting for an openvpn process
to terminate.
[1.0-beta16 2004-08-25]
Bug Fixes:
When only a filename (no full path) was specified in the config file
for --key or --pkcs12, OpenVPN GUI did not look for the file in the
config dir when changing password. Fixed in this version.
[1.0-beta15 2004-08-25]
When changing password, require new password to be at least 8 chars.
[v1.0-beta14 2004-08-24]
New Features:
Change password of the private key. Both PEM and PKCS #12 files
are supported.
[v1.0-beta13 2004-08-19]
New Features:
Shows which connections are connected in the TrayIcon tip msg
Bug Fixes:
The "Enter Passphrase" dialog was a bit miss-designed. The textlabel
and the editbox was overlapping a few pixels which made it look a
little strange in some occasions.
[v1.0-beta12 2004-08-16]
New Features:
Show a Status Window while connecting that shows the output from
OpenVPN in real-time.
A new menuitem to show the real-time status window.
If only one connection is running, dubbleclicking the trayicon will
show the status window for the running connection.
Show a yellow TrayIcon while connecting.
Detect "restarting process" message, and shows "Connecting" status
until a new connected msg is received.
[v1.0-beta11a 2004-08-15]
Bug Fix:
The exit_event handle was not closed after checking the openvpn version
which made it impossible to restart connections with OpenVPN versions
lower than 2.0-beta6. You received the following msg when trying to
connect a second time:
"I seem to be running as a service, but my exit event object is telling
me to exit immediately"
This bug was introduced with OpenVPN GUI v1.0-beta10.
[v1.0-beta11 2004-08-09]
New Features:
This version is bundled with a patched version of openvpn that will
output a log message AFTER routes have been added to the system. This
allows the GUI to report "Connected" after this msg. This patch will
be included in next official release of OpenVPN 2.0-beta, so the GUI
will continue to work with future official releases of openvpn. Older
versions of openvpn will still work with this version of OpenVPN GUI,
but "Connected" will then be reported before routes are added as it
did with OpenVPN GUI 1.0-beta10.
If wrong passphrase is entered, openvpn will automatically be restarted
a specified nr of times (default 3), which allows the user to re-enter
his passphrase.
Number of passphase attempts to allow can be specified with reg-key
"passphrase_attempts" or cmd-line option with the same name.
Bug Fixes:
An empty line was printed in the log when prompting for passphrase.
[v1.0-beta10 2004-08-08]
Default registry setting for showing the "Edit Config" menuitem is
changed to "1" (Show it). If a previous version of OpenVPN GUI has
been used, the registry key will of cource not change without manually
changing it.
New Features:
Check version of openvpn.exe, so it can support all versions of OpenVPN
without a special build of OpenVPN GUI. Tested with 1.5.0, 1.6.0,
2.0-beta4, 2.0-beta7 and 2.0-beta10. Older versions than 2.0-beta6 still
only support one simultaneous connection though.
Redirect StdIn/StdOut/StdErr through OpenVPN GUI, so we can pass the
private key passphrase to openvpn without requiring a patched version
of OpenVPN. This also allows OpenVPN GUI to prompt for a passphrase only
when it's needed.
If connecting fails, ask the user if he wants to view the log.
Show a dialog while connecting to allow the user to abort the connection.
Bug Fixes:
Disable both "Connect" and "DisConnect" while connecting.
[v1.0-beta9 2004-07-23]
The passphrase support added in v1.5-beta1 has been merched into the v1.0
source so v1.5 does not exist any longer!
New Features:
Cmd-line options:
--connect cnn [nopass]: Autoconnect to "cnn" at startup. If "nopass"
is used, no passphrase will be asked for.
--help : Show list of cmd-line options.
And all registry settings is now available as cmd-line options:
--exe_path : Path to openvpn.exe.\n"
--config_dir : Path to dir to search for config files in.\n"
--ext_string : Extension on config files.\n"
--log_dir : Path to dir where log files will be saved.\n"
--priority_string : Priority string (See install.txt for more info).\n"
--append_string : 1=Append to log file. 0=Truncate logfile.\n"
--log_viewer : Path to log viewer.\n"
--editor : Path to config editor.\n"
--allow_edit : 1=Show Edit Config menu\n"
--allow_service : 1=Show Service control menu\n"
Bug Fixes:
If the GUI was started from a cmd prompt and no passphrase was given
openvpn.exe would query the user for the passphrase from the console
(which is not showed), so the openvpn process got stuck there.
[v1.5-beta1 2004-07-16]
This version is based on v1.0-beta8.
v1.5 is just a temporary version in wait for the management interface
to OpenVPN. When this is available features added in v1.5 will be
rewritten to use this interface instead in v2.0 of OpenVPN-GUI.
New Features:
Support for passphrase protected private keys. OpenVPN-GUI will now
always query the user for a passphrase before connecting. The
passphrase is then supplied to OpenVPN via the --passphrase option.
This requires a patched version of OpenVPN that supports the
--passphrase option. A patched version that supports this is included
in the OpenVPN-GUI v1.5-betaX installation package.
The user will always be asked for a passphrase even if the private
key is not encrypted. This is because the GUI does not know in advance
if the key is encrypted or not. This will be fixed in v2.0 when we
have the management interface ready.
[v1.0-beta8 2004-07-16]
New Features:
Tray Icon now shows red/green if any connection is established.
Bug Fixes:
If something failed before starting openvpn.exe, exit_event and
log_handle was not closed correctly which could make it impossible
to make any more connections without restarting OpenVPN-GUI.
[v1.0-beta7 2004-07-08]
New Features:
A seperate build version supporting OpenVPN v1.5, v1.6 and the
2.0 series before beta6. This version only supports having one
connection running at the same time.
Added an About box.
If there are active connections when "Exit OpenVPN-GUI" is selected,
a "Are you sure you want to exit?" box is displayed.
Bug Fixes
It was not possible to have cmd-line options on the reg-keys
"log_viewer" or "editor". This is now possible.
[v1.0-beta6 2004-07-05]
Bug Fixes:
The default values for paths created by beta3, beta4 and beta5 used
hardcoded values for "C:\windows..." and "C:\program files...", which
did not work on some localized Windows versions that is not using
these folders. This is fixed now by getting those pathnames from the
system.
*** If you have installed beta3-beta5 you need to manualy delete the
whole HKEY_LM\SOFTWARE\OpenVPN-GUI key in the registry. The correct
reg-keys will then be recreated when OpenVPN-GUI is started. ***
[v1.0-beta5 2004-07-04]
New Features:
Menu-commands to Start/Stop/Restart the OpenVPN Service. Enable this
feature by setting the following reg-key to 1:
HKEY_LM\SOFTWARE\OpenVPN-GUI\allow_service
Bug Fixes:
v1.0-beta4 always opened the registry with write-access, which made
it imposible to start it without administator rights.
[v1.0-beta4 2004-07-04]
New Features:
Menu-command to open a config-file for editing. Enable this feature
by setting the following reg-key to 1:
HKEY_LM\SOFTWARE\OpenVPN-GUI\allow_edit
[v1.0-beta3 2004-07-04]
New Features:
Log Viewer. As default OpenVPN-GUI launches Notepad to view the log.
The program used to view the log can be changed with this reg-key:
HKEY_LM\SOFTWARE\OpenVPN-GUI\log-viewer
OpenVPN-GUI now uses its own registry-keys, instead of the same as
the service wrapper uses. It now stores its values under this key:
HKEY_LM\SOFTWARE\OpenVPN-GUI\
If this key does not exist, OpenVPN-GUI will create it with the same
default values as the service-wrapper uses, so if you want to use the
service-wrapper on config-files indepentent of the GUI you should
change the "config-dir" key to another folder.
[v1.0-beta2 2004-07-03]
New Features:
Connect/Disconnect now shows a sub-menu so each connection can be
brought up/down individually.
Upon connect OpenVPN-GUI will wait for 3 seconds and then check if
the openvpn process is still alive and report "Connection successful"
only if this is the case.
OpenVPN-GUI monitors the openvpn processes it has started, and if a
process is terminated before the user has chosen to take it down, this
will be reported to the user.
If no config files is found when OpenVPN-GUI is started, it will
notify the user of this and terminate.
[v1.0-beta1 2004-07-02] Initial release
Features:
Adds itself as a system tray icon.
Menuitem "Connect" - Starts openvpn for all config-files it has found.

280
chartable.h Normal file
View File

@ -0,0 +1,280 @@
/*
* 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
*/
WCHAR unicode_to_ascii[256] = {
0x0000,
0x0001,
0x0002,
0x0003,
0x0004,
0x0005,
0x0006,
0x0007,
0x0008,
0x0009,
0x000a,
0x000b,
0x000c,
0x000d,
0x000e,
0x000f,
0x0010,
0x0011,
0x0012,
0x0013,
0x0014,
0x0015,
0x0016,
0x0017,
0x0018,
0x0019,
0x001a,
0x001b,
0x001c,
0x001d,
0x001e,
0x001f,
0x0020,
0x0021,
0x0022,
0x0023,
0x0024,
0x0025,
0x0026,
0x0027,
0x0028,
0x0029,
0x002a,
0x002b,
0x002c,
0x002d,
0x002e,
0x002f,
0x0030,
0x0031,
0x0032,
0x0033,
0x0034,
0x0035,
0x0036,
0x0037,
0x0038,
0x0039,
0x003a,
0x003b,
0x003c,
0x003d,
0x003e,
0x003f,
0x0040,
0x0041,
0x0042,
0x0043,
0x0044,
0x0045,
0x0046,
0x0047,
0x0048,
0x0049,
0x004a,
0x004b,
0x004c,
0x004d,
0x004e,
0x004f,
0x0050,
0x0051,
0x0052,
0x0053,
0x0054,
0x0055,
0x0056,
0x0057,
0x0058,
0x0059,
0x005a,
0x005b,
0x005c,
0x005d,
0x005e,
0x005f,
0x0060,
0x0061,
0x0062,
0x0063,
0x0064,
0x0065,
0x0066,
0x0067,
0x0068,
0x0069,
0x006a,
0x006b,
0x006c,
0x006d,
0x006e,
0x006f,
0x0070,
0x0071,
0x0072,
0x0073,
0x0074,
0x0075,
0x0076,
0x0077,
0x0078,
0x0079,
0x007a,
0x007b,
0x007c,
0x007d,
0x007e,
0x007f,
0x00c7,
0x00fc,
0x00e9,
0x00e2,
0x00e4,
0x00e0,
0x00e5,
0x00e7,
0x00ea,
0x00eb,
0x00e8,
0x00ef,
0x00ee,
0x00ec,
0x00c4,
0x00c5,
0x00c9,
0x00e6,
0x00c6,
0x00f4,
0x00f6,
0x00f2,
0x00fb,
0x00f9,
0x00ff,
0x00d6,
0x00dc,
0x00f8,
0x00a3,
0x00d8,
0x00d7,
0x0192,
0x00e1,
0x00ed,
0x00f3,
0x00fa,
0x00f1,
0x00d1,
0x00aa,
0x00ba,
0x00bf,
0x00ae,
0x00ac,
0x00bd,
0x00bc,
0x00a1,
0x00ab,
0x00bb,
0x2591,
0x2592,
0x2593,
0x2502,
0x2524,
0x00c1,
0x00c2,
0x00c0,
0x00a9,
0x2563,
0x2551,
0x2557,
0x255d,
0x00a2,
0x00a5,
0x2510,
0x2514,
0x2534,
0x252c,
0x251c,
0x2500,
0x253c,
0x00e3,
0x00c3,
0x255a,
0x2554,
0x2569,
0x2566,
0x2560,
0x2550,
0x256c,
0x00a4,
0x00f0,
0x00d0,
0x00ca,
0x00cb,
0x00c8,
0x0131,
0x00cd,
0x00ce,
0x00cf,
0x2518,
0x250c,
0x2588,
0x2584,
0x00a6,
0x00cc,
0x2580,
0x00d3,
0x00df,
0x00d4,
0x00d2,
0x00f5,
0x00d5,
0x00b5,
0x00fe,
0x00de,
0x00da,
0x00db,
0x00d9,
0x00fd,
0x00dd,
0x00af,
0x00b4,
0x00ad,
0x00b1,
0x2017,
0x00be,
0x00b6,
0x00a7,
0x00f7,
0x00b8,
0x00b0,
0x00a8,
0x00b7,
0x00b9,
0x00b3,
0x00b2,
0x25a0,
0x00a0
};

BIN
connected.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
connecting.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
disconnected.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

137
ieproxy.c Normal file
View File

@ -0,0 +1,137 @@
/*
* Copyright (C) 2004 Ewan Bhamrah Harley <code@ewan.info>
*
* 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 <WinInet.h>
#include <malloc.h>
LPCTSTR getIeHttpProxyError=NULL;
/* getIeHttpProxy fetches the current IE proxy settings for http */
LPCTSTR getIeHttpProxy()
{
DWORD psize=0;
INTERNET_PROXY_INFO *pinfo;
LPTSTR proxyString;
LPTSTR p;
LPTSTR q;
unsigned int len;
/* first see how big a buffer we need for the IPO structure */
InternetQueryOption(NULL, INTERNET_OPTION_PROXY, NULL, &psize);
if(!psize)
{
getIeHttpProxyError="InternetQueryOption failed to return buffer size";
return(NULL);
}
/* allocate memory for IPO */
pinfo = malloc (psize*sizeof(TCHAR));
if (pinfo == NULL)
{
getIeHttpProxyError="malloc failed (1)";
return(NULL);
}
/* now run the real query */
if(!InternetQueryOption(NULL, INTERNET_OPTION_PROXY, (LPVOID) pinfo, &psize))
{
getIeHttpProxyError="InternetQueryOption() failed to find proxy info";
free(pinfo);
return(NULL);
}
/* see what sort of result we got */
if(pinfo->dwAccessType == INTERNET_OPEN_TYPE_DIRECT)
{
/* No proxy configured */
free(pinfo);
return("");
}
else if(pinfo->dwAccessType == INTERNET_OPEN_TYPE_PROXY)
{
/* we have a proxy - now parse result string */
/* if result string does NOT contain an '=' sign then */
/* there is a single proxy for all protocols */
for (p=(LPTSTR)pinfo->lpszProxy; *p && *p != '='; p++);
if(!*p)
{
/* single proxy */
/* allocate a new string to return */
len = 1+strlen(pinfo->lpszProxy);
proxyString = malloc (len*sizeof(TCHAR));
if (proxyString == NULL)
{
getIeHttpProxyError="malloc failed (2)";
free(pinfo);
return(NULL);
}
strncpy(proxyString, pinfo->lpszProxy,len);
proxyString[len]=0;
free(pinfo);
return(proxyString);
}
else
{
/* multiple space seperated proxies defined in the form */
/* protocol=proxyhost[:port] */
/* we want the one marked "http=", if any. */
p=(LPTSTR)pinfo->lpszProxy;
while(*p && strncmp(p, "http=", 5))
{
for(; *p && *p != ' '; p++);
if(*p) p++;
}
if(*p)
{
/* found the proxy */
p+=5;
for(q=p; *q && *q != ' '; q++);
/* allocate a buffer for the proxy information */
len=1+(q-p);
proxyString=malloc(len*sizeof(TCHAR));
if(proxyString==NULL)
{
getIeHttpProxyError="malloc failed (3)";
free(pinfo);
return(NULL);
}
strncpy(proxyString, p, len);
proxyString[len]=0;
free(pinfo);
return(proxyString);
}
else
{
/* No http proxy in list */
free(pinfo);
return("");
}
}
}
else
{
/* InternetQueryOption returned a proxy type we don't know about*/
getIeHttpProxyError="Unknown Proxy Type";
free(pinfo);
return(NULL);
}
}

24
ieproxy.h Normal file
View File

@ -0,0 +1,24 @@
/*
* Copyright (C) 2004 Ewan Bhamrah Harley <code@ewan.info>
*
* 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 __GETIEHTTPPROXY__
#define __GETIEHTTPPROXY__
extern LPTSTR getIeHttpProxyError;
LPCTSTR getIeHttpProxy();
#endif

500
main.c Normal file
View File

@ -0,0 +1,500 @@
/*
* 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
*/
#include <windows.h>
#include <shlwapi.h>
#include <Pbt.h>
#include "tray.h"
#include "openvpn.h"
#include "openvpn_config.h"
#include "viewlog.h"
#include "service.h"
#include "main.h"
#include "options.h"
#include "passphrase.h"
#include "proxy.h"
#include "registry.h"
#include "openvpn-gui-res.h"
#ifndef DISABLE_CHANGE_PASSWORD
#include <openssl/evp.h>
#include <openssl/err.h>
#endif
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK AboutDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void CloseApplication(HWND hwnd);
/* Class name and window title */
char szClassName[ ] = "OpenVPN-GUI";
char szTitleText[ ] = "OpenVPN";
/* Options structure */
struct options o;
int WINAPI WinMain (HINSTANCE hThisInstance,
UNUSED HINSTANCE hPrevInstance,
LPSTR lpszArgument,
UNUSED int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
HWND hwndAbout;
DWORD shell32_version;
/* initialize options to default state */
init_options (&o);
#ifdef DEBUG
/* Open debug file for output */
if (!(o.debug_fp = fopen(DEBUG_FILE, "w")))
{
/* can't open debug file */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_DEBUG_FILE, DEBUG_FILE);
exit(1);
}
PrintDebug("Starting OpenVPN GUI v%s", GUI_VERSION);
#endif
o.hInstance = hThisInstance;
if(!GetModuleHandle("RICHED20.DLL"))
{
LoadLibrary("RICHED20.DLL");
}
else
{
/* can't load riched20.dll */
ShowLocalizedMsg(GUI_NAME, ERR_LOAD_RICHED20, "");
exit(1);
}
/* Check version of shell32.dll */
shell32_version=GetDllVersion("shell32.dll");
if (shell32_version < PACKVERSION(5,0))
{
/* shell32.dll version to low */
ShowLocalizedMsg(GUI_NAME, ERR_SHELL_DLL_VERSION, shell32_version);
exit(1);
}
#ifdef DEBUG
PrintDebug("Shell32.dll version: 0x%lx", shell32_version);
#endif
/* Parse command-line options */
Createargcargv(&o, lpszArgument);
/* Check if a previous instance is already running. */
if ((FindWindow (szClassName, NULL)) != NULL)
{
/* GUI already running */
ShowLocalizedMsg(GUI_NAME, ERR_GUI_ALREADY_RUNNING, "");
exit(1);
}
if (!GetRegistryKeys()) {
exit(1);
}
if (!CheckVersion()) {
exit(1);
}
if (!BuildFileList()) {
exit(1);
}
if (!VerifyAutoConnections()) {
exit(1);
}
GetProxyRegistrySettings();
#ifndef DISABLE_CHANGE_PASSWORD
/* Initialize OpenSSL */
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
#endif
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (hThisInstance, MAKEINTRESOURCE(APP_ICON));
wincl.hIconSm = LoadIcon (hThisInstance, MAKEINTRESOURCE(APP_ICON));
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_3DSHADOW; //COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 1;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
szTitleText, /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
(int)CW_USEDEFAULT, /* Windows decides the position */
(int)CW_USEDEFAULT, /* where the window ends up on the screen */
230, /* The programs width */
200, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static UINT s_uTaskbarRestart;
int i;
switch (message) {
case WM_CREATE:
/* Save Window Handle */
o.hWnd = hwnd;
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
CreatePopupMenus(); /* Create popup menus */
LoadAppIcon(); /* Load App Icon */
ShowTrayIcon();
if (o.allow_service[0]=='1' || o.service_only[0]=='1')
CheckServiceStatus(); // Check if service is running or not
if (!AutoStartConnections()) {
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_NOTIFYICONTRAY:
OnNotifyTray(lParam); // Manages message from tray
return TRUE;
case WM_COMMAND:
if ( (LOWORD(wParam) >= IDM_CONNECTMENU) && (LOWORD(wParam) < IDM_CONNECTMENU + MAX_CONFIGS) ) {
StartOpenVPN(LOWORD(wParam) - IDM_CONNECTMENU);
}
if ( (LOWORD(wParam) >= IDM_DISCONNECTMENU) && (LOWORD(wParam) < IDM_DISCONNECTMENU + MAX_CONFIGS) ) {
StopOpenVPN(LOWORD(wParam) - IDM_DISCONNECTMENU);
}
if ( (LOWORD(wParam) >= IDM_STATUSMENU) && (LOWORD(wParam) < IDM_STATUSMENU + MAX_CONFIGS) ) {
ShowWindow(o.cnn[LOWORD(wParam) - IDM_STATUSMENU].hwndStatus, SW_SHOW);
}
if ( (LOWORD(wParam) >= IDM_VIEWLOGMENU) && (LOWORD(wParam) < IDM_VIEWLOGMENU + MAX_CONFIGS) ) {
ViewLog(LOWORD(wParam) - IDM_VIEWLOGMENU);
}
if ( (LOWORD(wParam) >= IDM_EDITMENU) && (LOWORD(wParam) < IDM_EDITMENU + MAX_CONFIGS) ) {
EditConfig(LOWORD(wParam) - IDM_EDITMENU);
}
#ifndef DISABLE_CHANGE_PASSWORD
if ( (LOWORD(wParam) >= IDM_PASSPHRASEMENU) && (LOWORD(wParam) < IDM_PASSPHRASEMENU + MAX_CONFIGS) ) {
ShowChangePassphraseDialog(LOWORD(wParam) - IDM_PASSPHRASEMENU);
}
#endif
if (LOWORD(wParam) == IDM_PROXY) {
ShowProxySettingsDialog();
}
if (LOWORD(wParam) == IDM_ABOUT) {
DialogBox(o.hInstance, (LPCTSTR)IDD_ABOUTDIALOG, NULL, (DLGPROC)AboutDialogFunc);
}
if (LOWORD(wParam) == IDM_CLOSE) {
CloseApplication(hwnd);
}
if (LOWORD(wParam) == IDM_SERVICE_START) {
MyStartService();
}
if (LOWORD(wParam) == IDM_SERVICE_STOP) {
MyStopService();
}
if (LOWORD(wParam) == IDM_SERVICE_RESTART) MyReStartService();
break;
case WM_CLOSE:
CloseApplication(hwnd);
break;
case WM_DESTROY:
StopAllOpenVPN();
OnDestroyTray(); /* Remove Tray Icon and destroy menus */
PostQuitMessage (0); /* Send a WM_QUIT to the message queue */
break;
case WM_QUERYENDSESSION:
return(TRUE);
case WM_ENDSESSION:
StopAllOpenVPN();
OnDestroyTray();
break;
case WM_POWERBROADCAST:
switch (wParam) {
case PBT_APMSUSPEND:
if (o.disconnect_on_suspend[0] == '1')
{
/* Suspend running connections */
for (i=0; i<o.num_configs; i++)
{
if (o.cnn[i].connect_status == CONNECTED)
SuspendOpenVPN(i);
}
/* Wait for all connections to suspend */
for (i=0; i<10; i++, Sleep(500))
if (CountConnectedState(SUSPENDING) == 0) break;
}
return FALSE;
case PBT_APMRESUMESUSPEND:
case PBT_APMRESUMECRITICAL:
for (i=0; i<o.num_configs; i++)
{
/* Restart suspend connections */
if (o.cnn[i].connect_status == SUSPENDED)
StartOpenVPN(i);
/* If some connection never reached SUSPENDED state */
if (o.cnn[i].connect_status == SUSPENDING)
StopOpenVPN(i);
}
return FALSE;
}
default: /* for messages that we don't deal with */
if (message == s_uTaskbarRestart)
{
/* Explorer has restarted, re-register the tray icon. */
ShowTrayIcon();
CheckAndSetTrayIcon();
break;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
BOOL CALLBACK AboutDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
{
HICON hIcon;
TCHAR buf[1000];
char buf2[1000];
switch (msg) {
case WM_INITDIALOG:
hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(APP_ICON),
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
if (hIcon) {
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon));
}
/* Show version string */
myLoadString(TEXT_ABOUT_OPENVPNGUI);
mysnprintf(buf2, buf, GUI_VERSION);
SetDlgItemText(hwndDlg, ID_TEXT_OPENVPNGUI, buf2);
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK: // button
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
return FALSE;
}
void CloseApplication(HWND hwnd)
{
int i, ask_exit=0;
TCHAR buf[1000];
if (o.service_running == SERVICE_CONNECTED)
{
myLoadString(INFO_SERVICE_ACTIVE_EXIT);
if (MessageBox(NULL, buf, "Exit OpenVPN", MB_YESNO) == IDNO)
{
return;
}
}
for (i=0; i < o.num_configs; i++) {
if (o.cnn[i].connect_status != 0) {
ask_exit=1;
break;
}
}
if (ask_exit) {
/* aks for confirmation */
myLoadString(INFO_ACTIVE_CONN_EXIT);
if (MessageBox(NULL, buf, "Exit OpenVPN", MB_YESNO) == IDNO)
{
return;
}
}
DestroyWindow(hwnd);
}
#ifdef DEBUG
void PrintDebugMsg(char *msg)
{
time_t log_time;
struct tm *time_struct;
char date[30];
log_time = time(NULL);
time_struct = localtime(&log_time);
snprintf(date, sizeof(date), "%d-%.2d-%.2d %.2d:%.2d:%.2d",
time_struct->tm_year + 1900,
time_struct->tm_mon + 1,
time_struct->tm_mday,
time_struct->tm_hour,
time_struct->tm_min,
time_struct->tm_sec);
fprintf(o.debug_fp, "%s %s\n", date, msg);
fflush(o.debug_fp);
}
void PrintErrorDebug(char *msg)
{
LPVOID lpMsgBuf;
char *buf;
/* Get last error message */
if (!FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL ))
{
/* FormatMessage failed! */
PrintDebug("FormatMessage() failed. %s ", msg);
return;
}
/* Cut of CR/LFs */
buf = (char *)lpMsgBuf;
buf[strlen(buf) - 3] = '\0';
PrintDebug("%s %s", msg, (LPCTSTR)lpMsgBuf);
}
#endif
bool
init_security_attributes_allow_all (struct security_attributes *obj)
{
CLEAR (*obj);
obj->sa.nLength = sizeof (SECURITY_ATTRIBUTES);
obj->sa.lpSecurityDescriptor = &obj->sd;
obj->sa.bInheritHandle = FALSE;
if (!InitializeSecurityDescriptor (&obj->sd, SECURITY_DESCRIPTOR_REVISION))
return false;
if (!SetSecurityDescriptorDacl (&obj->sd, TRUE, NULL, FALSE))
return false;
return true;
}
#define PACKVERSION(major,minor) MAKELONG(minor,major)
DWORD GetDllVersion(LPCTSTR lpszDllName)
{
HINSTANCE hinstDll;
DWORD dwVersion = 0;
/* For security purposes, LoadLibrary should be provided with a
fully-qualified path to the DLL. The lpszDllName variable should be
tested to ensure that it is a fully qualified path before it is used. */
hinstDll = LoadLibrary(lpszDllName);
if(hinstDll)
{
DLLGETVERSIONPROC pDllGetVersion;
pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll,
"DllGetVersion");
/* Because some DLLs might not implement this function, you
must test for it explicitly. Depending on the particular
DLL, the lack of a DllGetVersion function can be a useful
indicator of the version. */
if(pDllGetVersion)
{
DLLVERSIONINFO dvi;
HRESULT hr;
ZeroMemory(&dvi, sizeof(dvi));
dvi.cbSize = sizeof(dvi);
hr = (*pDllGetVersion)(&dvi);
if(SUCCEEDED(hr))
{
dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
}
}
FreeLibrary(hinstDll);
}
return dwVersion;
}

108
main.h Normal file
View File

@ -0,0 +1,108 @@
/*
* 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
*/
#include <stdio.h>
/* Define this to enable DEBUG build */
//#define DEBUG
#define DEBUG_FILE "c:\\openvpngui_debug.txt"
/* Define this to disable Change Password support */
//#define DISABLE_CHANGE_PASSWORD
#define GUI_NAME "OpenVPN GUI"
#define GUI_VERSION "1.0.3"
/* Registry key for User Settings */
#define GUI_REGKEY_HKCU "Software\\Nilings\\OpenVPN-GUI"
/* Registry key for Global Settings */
#define GUI_REGKEY_HKLM "SOFTWARE\\OpenVPN-GUI"
#define MAX_LOG_LINES 500 /* Max number of lines in LogWindow */
#define DEL_LOG_LINES 10 /* Number of lines to delete from LogWindow */
/* bool definitions */
#define bool int
#define true 1
#define false 0
/* GCC function attributes */
#define UNUSED __attribute__ ((unused))
#define NORETURN __attribute__ ((noreturn))
#define PACKVERSION(major,minor) MAKELONG(minor,major)
struct security_attributes
{
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
};
/* clear an object */
#define CLEAR(x) memset(&(x), 0, sizeof(x))
/* snprintf with guaranteed null termination */
#define mysnprintf(out, args...) \
{ \
snprintf (out, sizeof(out), args); \
out [sizeof (out) - 1] = '\0'; \
}
/* Show Message */
#define ShowMsg(caption, args...) \
{ \
char x_msg[256]; \
mysnprintf (x_msg, args); \
MessageBox(NULL, x_msg, caption, MB_OK | MB_SETFOREGROUND); \
}
#define ShowLocalizedMsg(caption, id, args...) \
{ \
char x_msg[256]; \
TCHAR x_buf[1000]; \
LoadString(o.hInstance, id, x_buf, sizeof(x_buf)/sizeof(TCHAR)); \
mysnprintf(x_msg, x_buf, args); \
MessageBox(NULL, x_msg, caption, MB_OK | MB_SETFOREGROUND); \
}
#define myLoadString(id) \
{ \
LoadString(o.hInstance, id, buf, sizeof(buf)/sizeof(TCHAR)); \
}
#ifdef DEBUG
/* Print Debug Message */
#define PrintDebug(args...) \
{ \
char x_msg[256]; \
mysnprintf (x_msg, args); \
PrintDebugMsg(x_msg); \
}
void PrintDebugMsg(char *msg);
void PrintErrorDebug(char *msg);
bool init_security_attributes_allow_all (struct security_attributes *obj);
#endif
DWORD GetDllVersion(LPCTSTR lpszDllName);

351
openvpn-gui-en.rc Normal file
View File

@ -0,0 +1,351 @@
/*
* 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
*/
#include "openvpn-gui-res.h"
#include <windows.h>
/* Application Icons */
APP_ICON ICON DISCARDABLE "openvpn-gui.ico"
APP_ICON_CONNECTED ICON DISCARDABLE "connected.ico"
APP_ICON_CONNECTING ICON DISCARDABLE "connecting.ico"
APP_ICON_DISCONNECTED ICON DISCARDABLE "disconnected.ico"
/* About Dialog - designed with lcc-win32 resource editor */
IDD_ABOUTDIALOG DIALOG 0, 0, 260, 135
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTER
CAPTION "About - OpenVPN GUI for Windows"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "OK", IDOK, 99, 115, 63, 14
ICON APP_ICON_CONNECTED, 204, 11, 8, 21, 20
LTEXT "", ID_TEXT_OPENVPNGUI, 40, 5, 215, 8
LTEXT "Copyright (C) 2004-2005 Mathias Sundman <info@openvpn.se>", 102, 40, 15, 215, 8
LTEXT "http://openvpn.se/", 103, 40, 25, 215, 8
LTEXT "OpenVPN - An application to securely tunnel IP networks " \
"over a single UDP port, with support for SSL/TLS-based " \
"session authentication and key exchange, packet " \
"encryption, packet authentication, and packet compression.",
104, 11, 51, 235, 34
LTEXT "Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>", 105, 11, 87, 235, 11
LTEXT "http://openvpn.net/", 106, 11, 98, 235, 10
END
/* Passphrase Dialog */
IDD_PASSPHRASE DIALOGEX 6, 18, 120, 51
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_CENTER | DS_SETFOREGROUND
EXSTYLE WS_EX_TOPMOST
CAPTION "OpenVPN"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Enter Password:", 201, 6, 6, 100, 10
EDITTEXT EDIT_PASSPHRASE, 6, 17, 107, 12, ES_PASSWORD | ES_AUTOHSCROLL
PUSHBUTTON "OK", IDOK, 6, 33, 50, 14
PUSHBUTTON "Cancel", IDCANCEL, 64, 33, 50, 14
END
/* Auth Username/Password Dialog */
IDD_AUTH_PASSWORD DIALOG 6, 18, 160, 62
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_CENTER | DS_SETFOREGROUND
CAPTION "OpenVPN - User Authentication"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Username:", 0, 6, 9, 50, 10
LTEXT "Password:", 0, 6, 26, 50, 10
EDITTEXT EDIT_AUTH_USERNAME, 60, 6, 94, 12, ES_AUTOHSCROLL
EDITTEXT EDIT_AUTH_PASSWORD, 60, 23, 94, 12, ES_PASSWORD | ES_AUTOHSCROLL
PUSHBUTTON "OK", IDOK, 20, 42, 50, 14
PUSHBUTTON "Cancel", IDCANCEL, 90, 42, 52, 14
END
/* Status Dialog */
IDD_STATUS DIALOG 6, 18, 380, 210
STYLE WS_SIZEBOX | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | DS_CENTER
CAPTION "OpenVPN"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Connecting...", TEXT_STATUS, 20, 5, 200, 10
PUSHBUTTON "Disconnect", ID_DISCONNECT, 50, 190, 50, 14
PUSHBUTTON "Reconnect", ID_RESTART, 150, 190, 50, 14
PUSHBUTTON "Hide", ID_HIDE, 100, 190, 50, 14
LTEXT "", TEXT_CONFIG, 0, 0, 0, 0
END
/* Change Passphrase Dialog */
IDD_CHANGEPSW DIALOG 6, 18, 193, 82
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER
CAPTION "OpenVPN - Change Passphrase"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Old Password:", 171, 6, 9, 85, 10
LTEXT "New Password:", 172, 6, 26, 85, 10
LTEXT "Confirm New Password:", 173, 6, 42, 85, 10
EDITTEXT EDIT_PSW_CURRENT, 95, 6, 90, 12, ES_PASSWORD | ES_AUTOHSCROLL
EDITTEXT EDIT_PSW_NEW, 95, 23, 90, 12, ES_PASSWORD | ES_AUTOHSCROLL
EDITTEXT EDIT_PSW_NEW2, 95, 39, 90, 12, ES_PASSWORD | ES_AUTOHSCROLL
PUSHBUTTON "OK", IDOK, 40, 59, 50, 14
PUSHBUTTON "Cancel", IDCANCEL, 103, 59, 50, 14
LTEXT "", TEXT_KEYFORMAT, 0, 0, 0, 0
LTEXT "", TEXT_KEYFILE, 0, 0, 0, 0
END
/* Proxy Settings Dialog */
IDD_PROXY DIALOG 6, 18, 269, 228
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER
CAPTION "OpenVPN - Proxy Settings"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "", 201, 13, 62, 243, 137
AUTORADIOBUTTON "Use OpenVPN Config-file Settings", RB_PROXY_USE_OPENVPN, \
20, 12, 200, 10, WS_GROUP | WS_TABSTOP
AUTORADIOBUTTON "Use Internet Explorer Settings (manually configured)", \
RB_PROXY_USE_IE, 20, 31, 200, 10
AUTORADIOBUTTON "Manual Configuration", RB_PROXY_USE_MANUAL, 20, 50, 200, 10
AUTORADIOBUTTON "HTTP Proxy", RB_PROXY_HTTP, 20, 74, 59, 10, WS_GROUP | WS_TABSTOP
AUTORADIOBUTTON "SOCKS Proxy", RB_PROXY_SOCKS, 20, 147, 67, 10
GROUPBOX "", 202, 20, 86, 225, 43
LTEXT "Address:", TEXT_PROXY_HTTP_ADDRESS, 27, 98, 41, 10
LTEXT "Port:", TEXT_PROXY_HTTP_PORT, 176, 98, 25, 10
EDITTEXT EDIT_PROXY_HTTP_ADDRESS, 70, 96, 92, 12, ES_AUTOHSCROLL
EDITTEXT EDIT_PROXY_HTTP_PORT, 206, 96, 30, 12, ES_AUTOHSCROLL
AUTOCHECKBOX "Prompt for username/password when connecting.", CHECKB_PROXY_AUTH, 27, 112, 183, 10
GROUPBOX "", 203, 20, 158, 225, 33
LTEXT "Address:", TEXT_PROXY_SOCKS_ADDRESS, 27, 172, 41, 10
LTEXT "Port:", TEXT_PROXY_SOCKS_PORT, 176, 172, 20, 10
EDITTEXT EDIT_PROXY_SOCKS_ADDRESS, 70, 170, 98, 12, ES_AUTOHSCROLL
EDITTEXT EDIT_PROXY_SOCKS_PORT, 206, 170, 30, 12, ES_AUTOHSCROLL
PUSHBUTTON "OK", IDOK, 63, 206, 50, 14
PUSHBUTTON "Cancel", IDCANCEL, 159, 206, 50, 14
END
/* Proxy Authentication Dialog */
IDD_PROXY_AUTH DIALOG 29, 23, 154, 65
STYLE DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_CENTER
CAPTION "OpenVPN - Proxy Authentication"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Username:", 201, 9, 8, 38, 10
EDITTEXT EDIT_PROXY_USERNAME, 49, 5, 94, 12, ES_AUTOHSCROLL
LTEXT "Password:", 202, 9, 26, 38, 10
EDITTEXT EDIT_PROXY_PASSWORD, 49, 23, 94, 12, ES_PASSWORD | ES_AUTOHSCROLL
PUSHBUTTON "OK", IDOK, 58, 43, 40, 14
END
STRINGTABLE
BEGIN
/* About Dialog */
TEXT_ABOUT_OPENVPNGUI "OpenVPN GUI v%s - A Windows GUI for OpenVPN"
/* Tray - Resources */
MSG_TIP "OpenVPN GUI "
MSG_TIP_CONNECTED "\nConnected to: "
MSG_TIP_CONNECTING "\nConnecting to: "
MSG_TIP_CONNECTED_SINCE "\nConnected since: "
MSG_TIP_ASSIGNED_IP "\nAssigned IP: %s"
IDM_TEXT_SERVICE "OpenVPN Service"
IDM_TEXT_PROXY "Proxy Settings"
IDM_TEXT_ABOUT "About"
IDM_TEXT_CLOSE "Exit"
IDM_TEXT_CONNECT "Connect"
IDM_TEXT_DISCONNECT "Disconnect"
IDM_TEXT_STATUS "Show Status"
IDM_TEXT_VIEWLOG "View Log"
IDM_TEXT_EDITCONFIG "Edit Config"
IDM_TEXT_PASSPHRASE "Change Password"
IDM_TEXT_SERVICE_START "Start"
IDM_TEXT_SERVICE_STOP "Stop"
IDM_TEXT_SERVICE_RESTART "Restart"
IDM_TEXT_SERVICEONLY_START "Connect"
IDM_TEXT_SERVICEONLY_STOP "Disconnect"
IDM_TEXT_SERVICEONLY_RESTART "Reconnect"
IDM_TEXT_ASK_STOP_SERVICE "Do you want to disconnect (Stop the OpenVPN Service)?"
/* Logviewer - Resources */
ERR_START_LOG_VIEWER "Error starting log-viewer: %s"
ERR_START_CONF_EDITOR "Error starting config-editor: %s"
/* OpenVPN */
ERR_TO_MANY_CONFIGS "OpenVPN GUI does not support more than %d configs. Please contact the author if you have the need for more."
ERR_CANNOT_CONSTRUCT_LOG "Cannot construct logfile name based on: %s"
ERR_ONLY_ONE_CONN_OLD_VERSION "You can only have one connection running at the same time when using an older version on OpenVPN than 2.0-beta6."
ERR_STOP_SERV_ON_OLD_VERSION "You cannot use OpenVPN GUI to start a connection while the OpenVPN Service is running (with OpenVPN 1.5/1.6). Stop OpenVPN Service first if you want to use OpenVPN GUI."
ERR_CREATE_EVENT "CreateEvent failed on exit event: %s"
ERR_UNKNOWN_PRIORITY "Unknown priority name: %s"
ERR_LOG_APPEND_BOOL "Log file append flag (given as '%s') must be '0' or '1'"
ERR_GET_IE_PROXY_SETTINGS "Unable to get IE proxy settings because:\n%s"
ERR_INIT_SEC_DESC "InitializeSecurityDescriptor failed."
ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl failed."
ERR_CREATE_PIPE_OUTPUT "CreatePipe on hOutputWrite failed."
ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle on hErrorWrite failed."
ERR_CREATE_PIPE_INPUT "CreatePipe on hInputRead failed."
ERR_DUP_HANDLE_OUTPUT_READ "DuplicateHandle on hOutputRead failed."
ERR_DUP_HANDLE_INPUT_WRITE "DuplicateHandle on hInputWrite failed."
ERR_CLOSE_HANDLE_TMP "CloseHandle on hOutputReadTmp/hInputWriteTmp failed."
ERR_CREATE_PROCESS "CreateProcess failed, exe='%s' cmdline='%s' dir='%s'"
ERR_CLOSE_HANDLE "CloseHandle failed."
ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
INFO_STATE_WAIT_TERM "Current State: Waiting for OpenVPN to terminate..."
ERR_OPEN_LOG_WRITE "Error opening logfile for writing: %s. You probably don't have administrator privileges, which are necessary to run OpenVPN."
INFO_STATE_CONNECTED "Current State: Connected"
INFO_NOW_CONNECTED "%s is now connected."
INFO_ASSIG_IP "Assigned IP: %s"
ERR_CERT_EXPIRED "Unable to connect because your certificate has expired or the system time is incorrect."
ERR_CERT_NOT_YET_VALID "Unable to connect because your certificate is not yet valid. Check that your system time is correct."
INFO_STATE_RECONNECTING "Current State: Reconnecting"
INFO_STATE_DISCONNECTED "Current State: Disconnected"
INFO_CONN_TERMINATED "Connection to %s was terminated."
INFO_STATE_FAILED "Current State: Failed to connect"
INFO_CONN_FAILED "Connecting to %s has failed."
INFO_STATE_FAILED_RECONN "Current State: Failed to reconnect"
INFO_RECONN_FAILED "ReConnecting to %s has failed."
INFO_STATE_SUSPENDED "Current State: Suspended"
ERR_READ_STDOUT_PIPE "Error reading from OpenVPN StdOut Pipe."
ERR_CREATE_RICHED_LOGWINDOW "Creating RichEdit LogWindow Failed!!"
ERR_SET_SIZE "Set Size failed!"
ERR_AUTOSTART_CONF_NOT_FOUND "Cannot find requested config to autostart: %s"
ERR_VERSION_CREATE_EVENT "CreateEvent() failed when checking openvpn version."
ERR_CREATE_PIPE_INPUT_READ "CreatePipe on hInputRead failed."
INFO_STATE_CONNECTING "Current State: Connecting"
INFO_CONNECTION_XXX "OpenVPN Connection (%s)"
ERR_CREATE_THREAD_READ_STDOUT "CreateThread to read openvpn process stdout failed."
INFO_STATE_CONN_SCRIPT "Current State: Running Connect Script"
INFO_STATE_DISCONN_SCRIPT "Current State: Running Disconnect Script"
ERR_RUN_CONN_SCRIPT "Error running Connect Script: %s"
ERR_GET_EXIT_CODE "Failed to get ExitCode of Connect Script (%s)"
ERR_CONN_SCRIPT_FAILED "Connect Script failed. (exitcode=%ld)"
ERR_RUN_CONN_SCRIPT_TIMEOUT "Connect Script failed. TimeOut after %d sec."
ERR_CONFIG_ALREADY_EXIST "There already exist a config file named '%s'. You cannot " \
"have multiple config files with the same name, even if " \
"they reside in diffrent folders."
/* main - Resources */
ERR_OPEN_DEBUG_FILE "Error opening debug file (%s) for output."
ERR_LOAD_RICHED20 "Could not load RICHED20.DLL."
ERR_SHELL_DLL_VERSION "Your shell32.dll version is to low (0x%lx). You need at least version 5.0."
ERR_GUI_ALREADY_RUNNING "OpenVPN GUI is already running."
INFO_SERVICE_STARTED "OpenVPN Service started."
INFO_SERVICE_STOPPED "OpenVPN Service stopped."
INFO_ACTIVE_CONN_EXIT "There are still active connections that will be closed if you exit OpenVPN GUI." \
"\n\nAre you sure you want to exit?"
INFO_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?"
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 */
INFO_USAGE "--help\t\t\t: Show this message.\n" \
"--connect cnn \t\t: Connect to ""cnn"" at startup. (extension must be included)\n" \
"\t\t\t Example: openvpn-gui --connect office.ovpn\n" \
"\n" \
"Options to override registry settings:\n" \
"--exe_path\t\t: Path to openvpn.exe.\n" \
"--config_dir\t\t: Path to dir to search for config files in.\n" \
"--ext_string\t\t: Extension on config files.\n" \
"--log_dir\t\t\t: Path to dir where log files will be saved.\n" \
"--priority_string\t\t: Priority string (See install.txt for more info).\n" \
"--append_string\t\t: 1=Append to log file. 0=Truncate logfile when connecting.\n" \
"--log_viewer\t\t: Path to log viewer.\n" \
"--editor\t\t\t: Path to config editor.\n" \
"--allow_edit\t\t: 1=Show Edit Config menu item.\n" \
"--allow_service\t\t: 1=Show Service control menu.\n" \
"--allow_password\t\t: 1=Show Change Password menu item.\n" \
"--allow_proxy\t\t: 1=Show Proxy Settings menu.\n" \
"--show_balloon\t\t: 0=Never, 1=At initial connect, 2=At every re-connect.\n" \
"--service_only\t\t: 1=Enable Service Only mode.\n" \
"--silent_connection\t\t: 1=Do not show the status dialog while connecting.\n" \
"--show_script_window\t: 0=Hide Script execution window, 1=Show it.\n" \
"--passphrase_attempts\t: Number of passphrase attempts to allow.\n" \
"--connectscript_timeout\t: Time to wait for connect script to finish.\n" \
"--disconnectscript_timeout\t: Time to wait for disconnect script to finish.\n" \
"--preconnectscript_timeout\t: Time to wait for preconnect script to finish.\n"
INFO_USAGECAPTION "OpenVPN GUI Usage"
ERR_BAD_PARAMETER "I'm trying to parse ""%s"" as an --option parameter " \
"but I don't see a leading '--'"
ERR_BAD_OPTION "Options error: Unrecognized option or missing parameter(s): --%s\n" \
"Use openvpn-gui --help for more info."
/* passphrase - Resources */
ERR_CREATE_PASS_THREAD "CreateThread to show ChangePassphrase dialog failed."
INFO_CHANGE_PWD "Change Password (%s)"
ERR_PWD_DONT_MATCH "The passwords you typed do not match. Try again."
ERR_PWD_TO_SHORT "Your new password must be at least %d characters long."
INFO_EMPTY_PWD "Are you sure you want to set an EMPTY password?"
ERR_UNKNOWN_KEYFILE_FORMAT "Unknown keyfile format."
ERR_OPEN_PRIVATE_KEY_FILE "Error opening private key file (%s)."
ERR_OLD_PWD_INCORRECT "The old password is incorrect."
ERR_OPEN_WRITE_KEY "Error opening private key file for writing (%s)."
ERR_WRITE_NEW_KEY "Error writing new private key file (%s)."
INFO_PWD_CHANGED "Your password has been changed."
ERR_READ_PKCS12 "Error reading PKCS #12 file (%s)."
ERR_CREATE_PKCS12 "Error creating new PKCS #12 object. Change Password has failed."
ERR_OPEN_CONFIG "Could not open config file for reading: (%s)"
ERR_ONLY_ONE_KEY_OPTION "You cannot have more than one ""key"" option in your config."
ERR_ONLY_KEY_OR_PKCS12 "You cannot have both ""key"" and ""pkcs12"" options in your config."
ERR_ONLY_ONE_PKCS12_OPTION "You cannot have more than one ""pkcs12"" option in your config."
ERR_MUST_HAVE_KEY_OR_PKCS12 "Your config file does not contain any ""key"" or ""pkcs12"" option."
ERR_KEY_FILENAME_TO_LONG "Your key filename in the config is too long!"
ERR_PASSPHRASE2STDIN "Error passing passphrase to stdin."
ERR_AUTH_USERNAME2STDIN "Error passing auth username to stdin."
ERR_AUTH_PASSWORD2STDIN "Error passing auth password to stdin."
ERR_CR2STDIN "Error passing CR to stdin."
ERR_INVALID_CHARS_IN_PSW "Your new password contains non-valid characters. " \
"Please choose another one."
/* proxy */
ERR_HTTP_PROXY_ADDRESS "You must specify a HTTP proxy address."
ERR_HTTP_PROXY_PORT "You must specify a HTTP proxy port."
ERR_HTTP_PROXY_PORT_RANGE "You must specify a HTTP proxy port between 1-65535"
ERR_SOCKS_PROXY_ADDRESS "You must specify a SOCKS proxy address."
ERR_SOCKS_PROXY_PORT "You must specify a SOCKS proxy port."
ERR_SOCKS_PROXY_PORT_RANGE "You must specify a SOCKS proxy port between 1-65535"
ERR_CREATE_REG_HKCU_KEY "Error creating ""HKEY_CURRENT_USER\\%s"" key."
ERR_GET_TEMP_PATH "Error determining TempPath with GetTempPath(). Using ""C:\\"" instead."
ERR_CREATE_AUTH_FILE "Error creating AUTH file. (%s)"
/* service */
ERR_OPEN_SCMGR_ADMIN "OpenSCManager failed. You need Administrator rights to start a service."
ERR_OPEN_VPN_SERVICE "Failed to open ""OpenVPNService"""
ERR_START_SERVICE "Failed to start ""OpenVPNService"""
ERR_QUERY_SERVICE "Failed to query service status."
ERR_SERVICE_START_FAILED "OpenVPN Service failed to start."
ERR_OPEN_SCMGR "OpenSCManager failed (%d)"
ERR_STOP_SERVICE "Failed to stop OpenVPN Service"
INFO_RESTARTED "OpenVPN Service Restarted."
/* registry */
ERR_GET_WINDOWS_DIR "Error getting Windows Directory."
ERR_GET_PROGRAM_DIR "Error getting ""Program"" folder name."
ERR_OPEN_REGISTRY "Error opening registry for reading (HKLM\\SOFTWARE\\OpenVPN).\n " \
"OpenVPN is probably not installed"
ERR_READING_REGISTRY "Error reading registry value (HKLM\\SOFTWARE\\OpenVPN)."
ERR_PASSPHRASE_ATTEMPTS "Registry value ""passphrase_attempts"" must be a number between 1 and 9."
ERR_CONN_SCRIPT_TIMEOUT "Registry value ""connectscript_timeout"" must be a number between 0 and 99."
ERR_DISCONN_SCRIPT_TIMEOUT "Registry value ""disconnectscript_timeout"" must be a number between 1 and 99."
ERR_PRECONN_SCRIPT_TIMEOUT "Registry value ""preconnectscript_timeout"" must be a number between 1 and 99."
ERR_CREATE_REG_KEY "Error creating HKLM\\SOFTWARE\\OpenVPN-GUI key."
ERR_OPEN_WRITE_REG "Failed to open the registry for writing. You need to run this application " \
"once as Administrator to update the registry."
ERR_READ_SET_KEY "Error reading and setting registry key ""%s""."
ERR_WRITE_REGVALUE "Error writing registry value ""HKEY_CURRENT_USER\\%s\\%s""."
END

243
openvpn-gui-res.h Normal file
View File

@ -0,0 +1,243 @@
/*
* 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
*/
/* Icons */
#define APP_ICON 90
#define APP_ICON_CONNECTED 91
#define APP_ICON_CONNECTING 92
#define APP_ICON_DISCONNECTED 93
/* About Dialog */
#define IDD_ABOUTDIALOG 100
#define ID_TEXT_OPENVPNGUI 101
#define TEXT_ABOUT_OPENVPNGUI 102
/* Ask for Passphrase Dialog */
#define IDD_PASSPHRASE 150
#define EDIT_PASSPHRASE 151
/* Status Dialog */
#define IDD_STATUS 160
#define TEXT_STATUS 161
#define EDIT_LOG 162
#define ID_DISCONNECT 163
#define ID_RESTART 164
#define ID_HIDE 165
/* A hidden textbox used to pass the config nr so dialog knows
* which connection to cancel. If anyone knows of another way
* to pass a variable to dialog, please let me know.
*/
#define TEXT_CONFIG 166
/* Change Passphrase Dialog */
#define IDD_CHANGEPSW 170
#define EDIT_PSW_CURRENT 174
#define EDIT_PSW_NEW 175
#define EDIT_PSW_NEW2 176
#define TEXT_KEYFILE 177
#define TEXT_KEYFORMAT 178
/* Auth Username/Password Dialog */
#define IDD_AUTH_PASSWORD 180
#define EDIT_AUTH_USERNAME 181
#define EDIT_AUTH_PASSWORD 182
/* Proxy Settings Dialog */
#define IDD_PROXY 200
#define RB_PROXY_USE_OPENVPN 210
#define RB_PROXY_USE_IE 211
#define RB_PROXY_USE_MANUAL 212
#define RB_PROXY_HTTP 213
#define EDIT_PROXY_HTTP_ADDRESS 214
#define EDIT_PROXY_HTTP_PORT 215
#define TEXT_PROXY_HTTP_ADDRESS 216
#define TEXT_PROXY_HTTP_PORT 217
#define CHECKB_PROXY_AUTH 218
#define RB_PROXY_SOCKS 219
#define EDIT_PROXY_SOCKS_ADDRESS 220
#define EDIT_PROXY_SOCKS_PORT 221
#define TEXT_PROXY_SOCKS_ADDRESS 222
#define TEXT_PROXY_SOCKS_PORT 223
/* Proxy Auth Dialog */
#define IDD_PROXY_AUTH 250
#define EDIT_PROXY_USERNAME 251
#define EDIT_PROXY_PASSWORD 252
/* Tray - Resources */
#define MSG_TIP 1001
#define MSG_TIP_CONNECTED 1002
#define MSG_TIP_CONNECTING 1003
#define MSG_TIP_CONNECTED_SINCE 1004
#define MSG_TIP_ASSIGNED_IP 1005
#define IDM_TEXT_SERVICE 1006
#define IDM_TEXT_PROXY 1007
#define IDM_TEXT_ABOUT 1008
#define IDM_TEXT_CLOSE 1009
#define IDM_TEXT_CONNECT 1010
#define IDM_TEXT_DISCONNECT 1011
#define IDM_TEXT_STATUS 1012
#define IDM_TEXT_VIEWLOG 1013
#define IDM_TEXT_EDITCONFIG 1014
#define IDM_TEXT_PASSPHRASE 1015
#define IDM_TEXT_SERVICE_START 1016
#define IDM_TEXT_SERVICE_STOP 1017
#define IDM_TEXT_SERVICE_RESTART 1018
#define IDM_TEXT_SERVICEONLY_START 1019
#define IDM_TEXT_SERVICEONLY_STOP 1020
#define IDM_TEXT_SERVICEONLY_RESTART 1021
#define IDM_TEXT_ASK_STOP_SERVICE 1022
/* LogViewer */
#define ERR_START_LOG_VIEWER 1101
#define ERR_START_CONF_EDITOR 1102
/* OpenVpn */
#define ERR_TO_MANY_CONFIGS 1201
#define ERR_CANNOT_CONSTRUCT_LOG 1202
#define ERR_ONLY_ONE_CONN_OLD_VERSION 1203
#define ERR_STOP_SERV_ON_OLD_VERSION 1204
#define ERR_CREATE_EVENT 1205
#define ERR_UNKNOWN_PRIORITY 1206
#define ERR_LOG_APPEND_BOOL 1207
#define ERR_GET_IE_PROXY_SETTINGS 1208
#define ERR_INIT_SEC_DESC 1209
#define ERR_SET_SEC_DESC_ACL 1210
#define ERR_CREATE_PIPE_OUTPUT 1211
#define ERR_DUP_HANDLE_ERR_WRITE 1212
#define ERR_CREATE_PIPE_INPUT 1213
#define ERR_DUP_HANDLE_OUTPUT_READ 1214
#define ERR_DUP_HANDLE_INPUT_WRITE 1215
#define ERR_CLOSE_HANDLE_TMP 1216
#define ERR_CREATE_PROCESS 1217
#define ERR_CLOSE_HANDLE 1218
#define ERR_CREATE_THREAD_STATUS 1219
#define INFO_STATE_WAIT_TERM 1220
#define ERR_OPEN_LOG_WRITE 1221
#define INFO_STATE_CONNECTED 1222
#define INFO_NOW_CONNECTED 1223
#define INFO_ASSIG_IP 1224
#define ERR_CERT_EXPIRED 1225
#define ERR_CERT_NOT_YET_VALID 1226
#define INFO_STATE_RECONNECTING 1227
#define INFO_STATE_DISCONNECTED 1228
#define INFO_CONN_TERMINATED 1229
#define INFO_STATE_FAILED 1230
#define INFO_CONN_FAILED 1231
#define INFO_STATE_FAILED_RECONN 1232
#define INFO_RECONN_FAILED 1233
#define INFO_STATE_SUSPENDED 1234
#define ERR_READ_STDOUT_PIPE 1235
#define ERR_CREATE_RICHED_LOGWINDOW 1236
#define ERR_SET_SIZE 1237
#define ERR_AUTOSTART_CONF_NOT_FOUND 1238
#define ERR_VERSION_CREATE_EVENT 1239
#define ERR_CREATE_PIPE_INPUT_READ 1240
#define INFO_STATE_CONNECTING 1241
#define INFO_CONNECTION_XXX 1242
#define ERR_CREATE_THREAD_READ_STDOUT 1243
#define INFO_STATE_CONN_SCRIPT 1244
#define INFO_STATE_DISCONN_SCRIPT 1245
#define ERR_RUN_CONN_SCRIPT 1246
#define ERR_GET_EXIT_CODE 1247
#define ERR_CONN_SCRIPT_FAILED 1248
#define ERR_RUN_CONN_SCRIPT_TIMEOUT 1249
#define ERR_OPTION_LOG_IN_CONFIG 1250
#define ERR_CONFIG_ALREADY_EXIST 1251
/* main */
#define ERR_OPEN_DEBUG_FILE 1301
#define ERR_LOAD_RICHED20 1302
#define ERR_SHELL_DLL_VERSION 1303
#define ERR_GUI_ALREADY_RUNNING 1304
#define INFO_SERVICE_STARTED 1305
#define INFO_SERVICE_STOPPED 1306
#define INFO_ACTIVE_CONN_EXIT 1307
#define INFO_SERVICE_ACTIVE_EXIT 1308
/* options */
#define INFO_USAGE 1401
#define INFO_USAGECAPTION 1402
#define ERR_BAD_PARAMETER 1403
#define ERR_BAD_OPTION 1404
/* passphrase */
#define ERR_CREATE_PASS_THREAD 1501
#define INFO_CHANGE_PWD 1502
#define ERR_PWD_DONT_MATCH 1503
#define ERR_PWD_TO_SHORT 1504
#define INFO_EMPTY_PWD 1505
#define ERR_UNKNOWN_KEYFILE_FORMAT 1506
#define ERR_OPEN_PRIVATE_KEY_FILE 1507
#define ERR_OLD_PWD_INCORRECT 1508
#define ERR_OPEN_WRITE_KEY 1509
#define ERR_WRITE_NEW_KEY 1510
#define INFO_PWD_CHANGED 1511
#define ERR_READ_PKCS12 1512
#define ERR_CREATE_PKCS12 1513
#define ERR_OPEN_CONFIG 1514
#define ERR_ONLY_ONE_KEY_OPTION 1515
#define ERR_ONLY_KEY_OR_PKCS12 1516
#define ERR_ONLY_ONE_PKCS12_OPTION 1517
#define ERR_MUST_HAVE_KEY_OR_PKCS12 1518
#define ERR_KEY_FILENAME_TO_LONG 1519
#define ERR_PASSPHRASE2STDIN 1520
#define ERR_CR2STDIN 1521
#define ERR_AUTH_USERNAME2STDIN 1522
#define ERR_AUTH_PASSWORD2STDIN 1523
#define ERR_INVALID_CHARS_IN_PSW 1524
/* proxy */
#define ERR_HTTP_PROXY_ADDRESS 1601
#define ERR_HTTP_PROXY_PORT 1602
#define ERR_HTTP_PROXY_PORT_RANGE 1603
#define ERR_SOCKS_PROXY_ADDRESS 1604
#define ERR_SOCKS_PROXY_PORT 1605
#define ERR_SOCKS_PROXY_PORT_RANGE 1606
#define ERR_CREATE_REG_HKCU_KEY 1607
#define ERR_GET_TEMP_PATH 1608
#define ERR_CREATE_AUTH_FILE 1609
/* service */
#define ERR_OPEN_SCMGR_ADMIN 1701
#define ERR_OPEN_VPN_SERVICE 1702
#define ERR_START_SERVICE 1703
#define ERR_QUERY_SERVICE 1704
#define ERR_SERVICE_START_FAILED 1705
#define ERR_OPEN_SCMGR 1706
#define ERR_STOP_SERVICE 1707
#define INFO_RESTARTED 1708
/* registry */
#define ERR_GET_WINDOWS_DIR 1801
#define ERR_GET_PROGRAM_DIR 1802
#define ERR_OPEN_REGISTRY 1803
#define ERR_READING_REGISTRY 1804
#define ERR_PASSPHRASE_ATTEMPTS 1805
#define ERR_CONN_SCRIPT_TIMEOUT 1806
#define ERR_DISCONN_SCRIPT_TIMEOUT 1807
#define ERR_PRECONN_SCRIPT_TIMEOUT 1808
#define ERR_CREATE_REG_KEY 1809
#define ERR_OPEN_WRITE_REG 1810
#define ERR_READ_SET_KEY 1811
#define ERR_WRITE_REGVALUE 1812

BIN
openvpn-gui.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

974
openvpn.c Normal file
View File

@ -0,0 +1,974 @@
/*
* 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 <stdlib.h>
#include <stdio.h>
#include <process.h>
#include "tray.h"
#include "main.h"
#include "openvpn.h"
#include "openvpn_monitor_process.h"
#include "openvpn-gui-res.h"
#include "options.h"
#include "scripts.h"
#include "viewlog.h"
#include "proxy.h"
#include "passphrase.h"
#include <richedit.h>
extern struct options o;
/*
* Creates a unique exit_event name based on the
* config file number.
*/
int CreateExitEvent(int config)
{
o.cnn[config].exit_event = NULL;
if (o.oldversion == 1)
{
mysnprintf(o.cnn[config].exit_event_name, "openvpn_exit");
o.cnn[config].exit_event = CreateEvent (NULL,
TRUE,
FALSE,
o.cnn[config].exit_event_name);
if (o.cnn[config].exit_event == NULL)
{
if (GetLastError() == ERROR_ACCESS_DENIED)
{
/* service mustn't be running, while using old version */
ShowLocalizedMsg(GUI_NAME, ERR_STOP_SERV_ON_OLD_VERSION, "");
}
else
{
/* error creating exit event */
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_EVENT, o.cnn[config].exit_event_name);
}
return(false);
}
}
else
{
mysnprintf(o.cnn[config].exit_event_name, "openvpngui_exit_event_%d",config);
o.cnn[config].exit_event = CreateEvent (NULL,
TRUE,
FALSE,
o.cnn[config].exit_event_name);
if (o.cnn[config].exit_event == NULL)
{
/* error creating exit event */
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_EVENT, o.cnn[config].exit_event_name);
return(false);
}
}
return(true);
}
/*
* Set priority based on the registry or cmd-line value
*/
int SetProcessPriority(DWORD *priority)
{
/* set process priority */
*priority = NORMAL_PRIORITY_CLASS;
if (!strcmp (o.priority_string, "IDLE_PRIORITY_CLASS"))
*priority = IDLE_PRIORITY_CLASS;
else if (!strcmp (o.priority_string, "BELOW_NORMAL_PRIORITY_CLASS"))
*priority = BELOW_NORMAL_PRIORITY_CLASS;
else if (!strcmp (o.priority_string, "NORMAL_PRIORITY_CLASS"))
*priority = NORMAL_PRIORITY_CLASS;
else if (!strcmp (o.priority_string, "ABOVE_NORMAL_PRIORITY_CLASS"))
*priority = ABOVE_NORMAL_PRIORITY_CLASS;
else if (!strcmp (o.priority_string, "HIGH_PRIORITY_CLASS"))
*priority = HIGH_PRIORITY_CLASS;
else
{
/* unknown priority */
ShowLocalizedMsg (GUI_NAME, ERR_UNKNOWN_PRIORITY, o.priority_string);
return (false);
}
return(true);
}
/*
* Launch an OpenVPN process
*/
int StartOpenVPN(int config)
{
HANDLE hOutputReadTmp = NULL;
HANDLE hOutputRead = NULL;
HANDLE hOutputWrite = NULL;
HANDLE hInputWriteTmp = NULL;
HANDLE hInputRead = NULL;
HANDLE hInputWrite = NULL;
HANDLE hErrorWrite = NULL;
HANDLE hThread;
DWORD IDThread;
DWORD priority;
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
char command_line[256];
char proxy_string[100];
char msg[200];
int i, is_connected=0;
extern HINSTANCE hInstance;
CLEAR (start_info);
CLEAR (proc_info);
CLEAR (sa);
CLEAR (sd);
/* If oldversion, allow only ONE connection */
if (o.oldversion == 1)
{
for (i=0; i < o.num_configs; i++)
{
if ((o.cnn[i].connect_status != DISCONNECTED) &&
(o.cnn[i].connect_status != DISCONNECTING))
{
is_connected=1;
break;
}
}
if (is_connected)
{
/* only one simultanious connection on old version */
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_ONE_CONN_OLD_VERSION, "");
return(false);
}
}
/* Warn if "log" or "log-append" option is found in config file */
if ((ConfigFileOptionExist(config, "log ")) ||
(ConfigFileOptionExist(config, "log-append ")))
{
TCHAR buf[1000];
myLoadString(ERR_OPTION_LOG_IN_CONFIG);
if (MessageBox(NULL, buf, GUI_NAME, MB_YESNO | MB_DEFBUTTON2 | MB_ICONWARNING) != IDYES)
return(false);
}
/* Clear connection unique vars */
o.cnn[config].failed_psw = 0;
CLEAR (o.cnn[config].ip);
/* Create our exit event */
if (!CreateExitEvent(config))
return(false);
/* set process priority */
if (!SetProcessPriority(&priority))
goto failed;
/* Check that log append flag has a valid value */
if ((o.append_string[0] != '0') && (o.append_string[0] != '1'))
{
/* append_log must be 0 or 1 */
ShowLocalizedMsg (GUI_NAME, ERR_LOG_APPEND_BOOL, o.append_string);
goto failed;
}
/* construct proxy string to append to command line */
ConstructProxyCmdLine(proxy_string, sizeof(proxy_string));
/* construct command line */
if (o.oldversion == 1)
{
mysnprintf (command_line, "openvpn --config \"%s\" %s",
o.cnn[config].config_file, proxy_string);
}
else
{
mysnprintf (command_line, "openvpn --service %s 0 --config \"%s\" %s",
o.cnn[config].exit_event_name,
o.cnn[config].config_file,
proxy_string);
}
/* Make security attributes struct for logfile handle so it can
be inherited. */
sa.nLength = sizeof (sa);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = TRUE;
if (!InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION))
{
/* Init Sec. Desc. failed */
ShowLocalizedMsg (GUI_NAME, ERR_INIT_SEC_DESC, "");
goto failed;
}
if (!SetSecurityDescriptorDacl (&sd, TRUE, NULL, FALSE))
{
/* set Dacl failed */
ShowLocalizedMsg (GUI_NAME, ERR_SET_SEC_DESC_ACL, "");
goto failed;
}
/* Create the child output pipe. */
if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
{
/* CreatePipe failed. */
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PIPE_OUTPUT, "");
goto failed;
}
// Create a duplicate of the output write handle for the std error
// write handle. This is necessary in case the child application
// closes one of its std output handles.
if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
GetCurrentProcess(),&hErrorWrite,0,
TRUE,DUPLICATE_SAME_ACCESS))
{
/* DuplicateHandle failed. */
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_ERR_WRITE, "");
goto failed;
}
// Create the child input pipe.
if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
{
/* CreatePipe failed. */
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PIPE_INPUT, "");
goto failed;
}
// Create new output read handle and the input write handles. Set
// the Properties to FALSE. Otherwise, the child inherits the
// properties and, as a result, non-closeable handles to the pipes
// are created.
if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
GetCurrentProcess(),
&hOutputRead, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
{
/* Duplicate Handle failed. */
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_OUTPUT_READ, "");
goto failed;
}
if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
GetCurrentProcess(),
&hInputWrite, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
{
/* DuplicateHandle failed */
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_INPUT_WRITE, "");
goto failed;
}
/* Close inheritable copies of the handles */
if (!CloseHandle(hOutputReadTmp) || !CloseHandle(hInputWriteTmp))
{
/* Close Handle failed */
ShowLocalizedMsg(GUI_NAME, ERR_CLOSE_HANDLE_TMP, "");
CloseHandle (o.cnn[config].exit_event);
return(0);
}
hOutputReadTmp=NULL;
hInputWriteTmp=NULL;
/* fill in STARTUPINFO struct */
GetStartupInfo(&start_info);
start_info.cb = sizeof(start_info);
start_info.dwFlags = STARTF_USESTDHANDLES;
start_info.hStdInput = hInputRead;
start_info.hStdOutput = hOutputWrite;
start_info.hStdError = hErrorWrite;
/* Run Pre-connect script */
RunPreconnectScript(config);
/* create an OpenVPN process for one config file */
if (!CreateProcess(o.exe_path,
command_line,
NULL,
NULL,
TRUE,
priority | CREATE_NO_WINDOW,
NULL,
o.cnn[config].config_dir,
&start_info,
&proc_info))
{
/* CreateProcess failed */
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_PROCESS,
o.exe_path,
command_line,
o.cnn[config].config_dir);
goto failed;
}
/* close unneeded handles */
Sleep (250); /* try to prevent race if we close logfile
handle before child process DUPs it */
if(!CloseHandle (proc_info.hThread) ||
!CloseHandle (hOutputWrite) ||
!CloseHandle (hInputRead) ||
!CloseHandle (hErrorWrite))
{
/* CloseHandle failed */
ShowLocalizedMsg (GUI_NAME, ERR_CLOSE_HANDLE, "");
CloseHandle (o.cnn[config].exit_event);
return(false);
}
hOutputWrite = NULL;
hInputRead = NULL;
hErrorWrite = NULL;
/* Save StdIn and StdOut handles in our options struct */
o.cnn[config].hStdIn = hInputWrite;
o.cnn[config].hStdOut = hOutputRead;
/* Save Process Handle */
o.cnn[config].hProcess=proc_info.hProcess;
/* Start Thread to show Status Dialog */
hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) ThreadOpenVPNStatus,
(int *) config, // pass config nr
0, &IDThread);
if (hThread == NULL)
{
/* CreateThread failed */
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_THREAD_STATUS, "");
goto failed;
}
return(true);
failed:
if (o.cnn[config].exit_event) CloseHandle (o.cnn[config].exit_event);
if (hOutputWrite) CloseHandle (hOutputWrite);
if (hOutputRead) CloseHandle (hOutputRead);
if (hInputWrite) CloseHandle (hInputWrite);
if (hInputRead) CloseHandle (hInputRead);
if (hErrorWrite) CloseHandle (hOutputWrite);
return(false);
}
void StopOpenVPN(int config)
{
int i;
TCHAR buf[1000];
o.cnn[config].connect_status = DISCONNECTING;
if (o.cnn[config].exit_event) {
/* Run Disconnect script */
RunDisconnectScript(config, false);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
SetMenuStatus(config, DISCONNECTING);
myLoadString(INFO_STATE_WAIT_TERM);
/* UserInfo: waiting for OpenVPN termination... */
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
SetEvent(o.cnn[config].exit_event);
}
}
void SuspendOpenVPN(int config)
{
int i;
TCHAR buf[1000];
o.cnn[config].connect_status = SUSPENDING;
o.cnn[config].restart = true;
if (o.cnn[config].exit_event) {
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
SetMenuStatus(config, DISCONNECTING);
myLoadString(INFO_STATE_WAIT_TERM);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
SetEvent(o.cnn[config].exit_event);
}
}
void StopAllOpenVPN()
{
int i;
for(i=0; i < o.num_configs; i++) {
if(o.cnn[i].connect_status != DISCONNECTED)
StopOpenVPN(i);
}
/* Wait for all connections to terminate (Max 5 sec) */
for (i=0; i<20; i++, Sleep(250))
if (CountConnectedState(DISCONNECTED) == o.num_configs) break;
}
BOOL CALLBACK StatusDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
BOOL Translated;
HWND hwndLogWindow;
RECT rect;
CHARFORMAT charformat;
HICON hIcon;
int config;
switch (msg) {
case WM_INITDIALOG:
/* Set Window Icon "DisConnected" */
SetStatusWinIcon(hwndDlg, APP_ICON_CONNECTING);
/* Create LogWindow */
hwndLogWindow = CreateWindowEx (0, RICHEDIT_CLASS, NULL,
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | \
ES_SUNKEN | ES_LEFT | ES_MULTILINE | \
ES_READONLY | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
20, 25, 350, 160, // Posision and Size
hwndDlg, // Parent window handle
(HMENU) EDIT_LOG, // hMenu
o.hInstance, // hInstance
NULL); // WM_CREATE lpParam
if (!hwndLogWindow)
{
/* Create RichEd LogWindow Failed */
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_RICHED_LOGWINDOW, "");
return FALSE;
}
/* Set font and fontsize of the LogWindow */
charformat.cbSize = sizeof(CHARFORMAT);
charformat.dwMask = CFM_SIZE | CFM_FACE | CFM_BOLD | CFM_ITALIC | \
CFM_UNDERLINE | CFM_STRIKEOUT | CFM_PROTECTED;
charformat.dwEffects = 0;
charformat.yHeight = 100;
strcpy(charformat.szFaceName, "MS Sans Serif");
if ((SendMessage(hwndLogWindow, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &charformat) && CFM_SIZE) == 0) {
/* set size failed */
ShowLocalizedMsg(GUI_NAME, ERR_SET_SIZE, "");
}
/* Set Size and Posision of controls */
GetClientRect(hwndDlg, &rect);
MoveWindow (hwndLogWindow, 20, 25, rect.right - 40, rect.bottom - 70, TRUE);
MoveWindow (GetDlgItem(hwndDlg, TEXT_STATUS), 20, 5, rect.right - 25, 15, TRUE);
MoveWindow (GetDlgItem(hwndDlg, ID_DISCONNECT), 20, rect.bottom - 30, 90, 23, TRUE);
MoveWindow (GetDlgItem(hwndDlg, ID_RESTART), 125, rect.bottom - 30, 90, 23, TRUE);
MoveWindow (GetDlgItem(hwndDlg, ID_HIDE), rect.right - 110, rect.bottom - 30, 90, 23, TRUE);
/* Set focus on the LogWindow so it scrolls automatically */
SetFocus(hwndLogWindow);
return FALSE;
case WM_SIZE:
MoveWindow (GetDlgItem(hwndDlg, EDIT_LOG), 20, 25, LOWORD (lParam) - 40,
HIWORD (lParam) - 70, TRUE);
MoveWindow (GetDlgItem(hwndDlg, ID_DISCONNECT), 20,
HIWORD (lParam) - 30, 90, 23, TRUE);
MoveWindow (GetDlgItem(hwndDlg, ID_RESTART), 125,
HIWORD (lParam) - 30, 90, 23, TRUE);
MoveWindow (GetDlgItem(hwndDlg, ID_HIDE), LOWORD (lParam) - 110,
HIWORD (lParam) - 30, 90, 23, TRUE);
MoveWindow (GetDlgItem(hwndDlg, TEXT_STATUS), 20, 5, LOWORD (lParam) - 25, 15, TRUE);
InvalidateRect(hwndDlg, NULL, TRUE);
return TRUE;
case WM_COMMAND:
config=GetDlgItemInt(hwndDlg, TEXT_CONFIG, &Translated, FALSE);
switch (LOWORD(wParam)) {
case ID_DISCONNECT:
SetFocus(GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG));
StopOpenVPN(config);
return TRUE;
case ID_HIDE:
if (o.cnn[GetDlgItemInt(hwndDlg, TEXT_CONFIG, &Translated, FALSE)].connect_status != DISCONNECTED)
{
ShowWindow(hwndDlg, SW_HIDE);
}
else
{
DestroyWindow(hwndDlg);
}
return TRUE;
case ID_RESTART:
SetFocus(GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG));
o.cnn[config].restart = true;
StopOpenVPN(config);
return TRUE;
}
break;
case WM_SHOWWINDOW:
if (wParam == TRUE)
{
config=GetDlgItemInt(hwndDlg, TEXT_CONFIG, &Translated, FALSE);
if (o.cnn[config].hwndStatus)
SetFocus(GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG));
}
return FALSE;
case WM_CLOSE:
if (o.cnn[GetDlgItemInt(hwndDlg, TEXT_CONFIG, &Translated, FALSE)].connect_status != DISCONNECTED)
{
ShowWindow(hwndDlg, SW_HIDE);
}
else
{
DestroyWindow(hwndDlg);
}
return TRUE;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return FALSE;
}
void SetStatusWinIcon(HWND hwndDlg, int IconID)
{
HICON hIcon;
/* Set Window Icon */
hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IconID),
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
if (hIcon) {
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon));
}
}
int AutoStartConnections()
{
int i;
for (i=0; i < o.num_configs; i++)
{
if (o.cnn[i].auto_connect)
StartOpenVPN(i);
}
return(true);
}
int VerifyAutoConnections()
{
int i,j;
BOOL match;
for (i=0; (o.auto_connect[i] != 0) && (i < MAX_CONFIGS); i++)
{
match = false;
for (j=0; j < MAX_CONFIGS; j++)
{
if (strcasecmp(o.cnn[j].config_file, o.auto_connect[i]) == 0)
{
match=true;
break;
}
}
if (match == false)
{
/* autostart config not found */
ShowLocalizedMsg(GUI_NAME, ERR_AUTOSTART_CONF_NOT_FOUND, o.auto_connect[i]);
return false;
}
}
return true;
}
int CheckVersion()
{
HANDLE hOutputReadTmp = NULL;
HANDLE hOutputRead = NULL;
HANDLE hOutputWrite = NULL;
HANDLE hInputWriteTmp = NULL;
HANDLE hInputRead = NULL;
HANDLE hInputWrite = NULL;
HANDLE exit_event;
HANDLE debug_event;
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
char command_line[256];
char line[1024];
char bin_path[MAX_PATH];
char *p;
int oldversion, i;
CLEAR (start_info);
CLEAR (proc_info);
CLEAR (sa);
CLEAR (sd);
exit_event = CreateEvent (NULL, TRUE, FALSE, "openvpn_exit");
if (exit_event == NULL)
{
#ifdef DEBUG
PrintErrorDebug("CreateEvent(openvpn_exit) failed.");
#endif
if (GetLastError() == ERROR_ACCESS_DENIED)
{
/* Assume we're running OpenVPN 1.5/1.6 and the service is started. */
o.oldversion=1;
strncpy(o.connect_string, "Successful ARP Flush", sizeof(o.connect_string));
return(true);
}
else
{
/* CreateEvent failed */
ShowLocalizedMsg(GUI_NAME, ERR_VERSION_CREATE_EVENT, "");
return(false);
}
}
#ifdef DEBUG
PrintErrorDebug("CreateEvent(openvpn_exit) succeded.");
#endif
/* construct command line */
mysnprintf (command_line, "openvpn --version");
/* construct bin path */
strncpy(bin_path, o.exe_path, sizeof(bin_path));
for (i=strlen(bin_path) - 1; i > 0; i--)
if (bin_path[i] == '\\') break;
bin_path[i] = '\0';
/* Make security attributes struct for logfile handle so it can
be inherited. */
sa.nLength = sizeof (sa);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = TRUE;
if (!InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION))
{
/* Init Sec. Desc. failed */
ShowLocalizedMsg (GUI_NAME, ERR_INIT_SEC_DESC, "");
return(0);
}
if (!SetSecurityDescriptorDacl (&sd, TRUE, NULL, FALSE))
{
/* Set Dacl failed */
ShowLocalizedMsg (GUI_NAME, ERR_SET_SEC_DESC_ACL, "");
return(0);
}
/* Create the child input pipe. */
if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
{
/* create pipe failed */
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PIPE_INPUT_READ, "");
return(0);
}
/* Create the child output pipe. */
if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
{
/* CreatePipe failed */
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PIPE_OUTPUT, "");
return(0);
}
if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
GetCurrentProcess(),
&hOutputRead, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
{
/* DuplicateHandle failed */
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_OUTPUT_READ, "");
return(0);
}
if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
GetCurrentProcess(),
&hInputWrite, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
{
/* DuplicateHandle failed */
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_INPUT_WRITE, "");
return(0);
}
/* Close inheritable copies of the handles */
if (!CloseHandle(hOutputReadTmp) || !CloseHandle(hInputWriteTmp))
{
/* CloseHandle failed */
ShowLocalizedMsg(GUI_NAME, ERR_CLOSE_HANDLE_TMP, "");
return(0);
}
/* fill in STARTUPINFO struct */
GetStartupInfo(&start_info);
start_info.cb = sizeof(start_info);
start_info.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
start_info.wShowWindow = SW_HIDE;
start_info.hStdInput = hInputRead;
start_info.hStdOutput = hOutputWrite;
start_info.hStdError = hOutputWrite;
/* Start OpenVPN to check version */
if (!CreateProcess(o.exe_path,
command_line,
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
bin_path,
&start_info,
&proc_info))
{
/* CreateProcess failed */
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_PROCESS,
o.exe_path,
command_line,
bin_path);
return(0);
}
/* Default value for oldversion */
oldversion=0;
/* Default string to look for to report "Connected". */
strncpy(o.connect_string, "Successful ARP Flush", sizeof(o.connect_string));
if (ReadLineFromStdOut(hOutputRead, 0, line) == 1)
{
#ifdef DEBUG
PrintDebug("VersionString: %s", line);
#endif
if (line[8] == '2') /* Majorversion = 2 */
{
if (line[10] == '0') /* Minorversion = 0 */
{
p=strstr(line, "beta");
if (p != NULL)
{
if (p[5] == ' ') /* 2.0-beta1 - 2.0-beta9 */
{
if (p[4] >= '6') /* 2.0-beta6 - 2.0-beta9 */
{
oldversion=0;
}
else /* < 2.0-beta6 */
{
oldversion=1;
}
}
else /* >= 2.0-beta10 */
{
if (strncmp(&p[6], "ms", 2) == 0) /* 2.0-betaXXms */
strncpy(o.connect_string, "Initialization Sequence Completed",
sizeof(o.connect_string));
if ( !((p[4] == 1) && (p[5] == 0)) ) /* >= 2.0-beta11 */
strncpy(o.connect_string, "Initialization Sequence Completed",
sizeof(o.connect_string));
oldversion=0;
}
}
else /* 2.0 non-beta */
{
strncpy(o.connect_string, "Initialization Sequence Completed",
sizeof(o.connect_string));
oldversion=0;
}
}
else /* > 2.0 */
{
strncpy(o.connect_string, "Initialization Sequence Completed",
sizeof(o.connect_string));
oldversion=0;
}
}
else
{
if (line[8] == '1') /* Majorversion = 1 */
{
oldversion=1;
}
else /* Majorversion != (1 || 2) */
{
oldversion=0;
}
}
}
else return(0);
o.oldversion = oldversion;
if(!CloseHandle (proc_info.hThread) || !CloseHandle (hOutputWrite)
|| !CloseHandle (hInputRead) || !CloseHandle(exit_event))
{
/* CloseHandle failed */
ShowLocalizedMsg (GUI_NAME, ERR_CLOSE_HANDLE, "");
return(0);
}
return(1);
}
/* Return num of connections with Status = CheckVal */
int CountConnectedState(int CheckVal)
{
int i;
int count=0;
for (i=0; i < o.num_configs; i++)
{
if (o.cnn[i].connect_status == CheckVal)
count++;
}
return (count);
}
void CheckAndSetTrayIcon()
{
/* Show green icon if service is running */
if (o.service_running == SERVICE_CONNECTED)
{
SetTrayIcon(CONNECTED);
return;
}
/* Change tray icon if no more connections is running */
if (CountConnectedState(CONNECTED) != 0)
SetTrayIcon(CONNECTED);
else
{
if ((CountConnectedState(CONNECTING) != 0) ||
(CountConnectedState(RECONNECTING) != 0) ||
(o.service_running == SERVICE_CONNECTING))
SetTrayIcon(CONNECTING);
else
SetTrayIcon(DISCONNECTED);
}
}
void ThreadOpenVPNStatus(int config)
{
char conn_name[200];
HANDLE hThread;
DWORD IDThread;
char msg[200];
MSG messages;
/* Cut of extention from config filename. */
strncpy(conn_name, o.cnn[config].config_file, sizeof(conn_name));
conn_name[strlen(conn_name) - (strlen(o.ext_string)+1)]=0;
if (o.cnn[config].restart)
{
/* UserInfo: Connecting */
TCHAR buf[1000];
myLoadString(INFO_STATE_CONNECTING);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_CONNECTING);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), TRUE);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), TRUE);
SetFocus(GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG));
o.cnn[config].restart = false;
}
else
{
/* Create and Show Status Dialog */
TCHAR buf[1000];
if (!(o.cnn[config].hwndStatus = CreateDialog (o.hInstance,
MAKEINTRESOURCE (IDD_STATUS),
NULL, (DLGPROC) StatusDialogFunc)))
ExitThread(1);
/* UserInfo: Connecting */
myLoadString(INFO_STATE_CONNECTING);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, (LPCTSTR)buf);
SetDlgItemInt(o.cnn[config].hwndStatus, TEXT_CONFIG, (UINT)config, FALSE);
myLoadString(INFO_CONNECTION_XXX);
mysnprintf(msg, buf, conn_name);
SetWindowText(o.cnn[config].hwndStatus, msg);
if (o.silent_connection[0]=='0')
ShowWindow(o.cnn[config].hwndStatus, SW_SHOW);
}
/* Start Thread to monitor our OpenVPN process */
hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE) WatchOpenVPNProcess,
(int *) config, // pass config nr
0, &IDThread);
if (hThread == NULL)
{
/* CreateThread failed */
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_THREAD_READ_STDOUT, "");
ExitThread(0);
}
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
if(!IsDialogMessage(o.cnn[config].hwndStatus, &messages))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
}
ExitThread(0);
}

39
openvpn.h Normal file
View File

@ -0,0 +1,39 @@
/*
* 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
*/
struct process_info {
HANDLE hProcess;
int config;
};
int StartOpenVPN(int config);
void StopOpenVPN(int config);
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();
int CheckVersion();
int CountConnectedState(int CheckVal);
void CheckAndSetTrayIcon();
void SetStatusWinIcon(HWND hwndDlg, int IconID);
void ThreadOpenVPNStatus(int status) __attribute__ ((noreturn));

252
openvpn_config.c Normal file
View File

@ -0,0 +1,252 @@
/*
* 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
*/
#include <windows.h>
#include "main.h"
#include "openvpn-gui-res.h"
#include "options.h"
#define MATCH_FALSE 0
#define MATCH_FILE 1
#define MATCH_DIR 2
extern struct options o;
static int
match (const WIN32_FIND_DATA *find, const char *ext)
{
int i;
if (find->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
return MATCH_DIR;
if (!strlen (ext))
return MATCH_FILE;
i = strlen (find->cFileName) - strlen (ext) - 1;
if (i < 1)
return MATCH_FALSE;
if (find->cFileName[i] == '.' && !strcasecmp (find->cFileName + i + 1, ext))
return MATCH_FILE;
else
return MATCH_FALSE;
}
/*
* Modify the extension on a filename.
*/
static bool
modext (char *dest, unsigned int size, const char *src, const char *newext)
{
int i;
if (size > 0 && (strlen (src) + 1) <= size)
{
strcpy (dest, src);
dest [size - 1] = '\0';
i = strlen (dest);
while (--i >= 0)
{
if (dest[i] == '\\')
break;
if (dest[i] == '.')
{
dest[i] = '\0';
break;
}
}
if (strlen (dest) + strlen(newext) + 2 <= size)
{
strcat (dest, ".");
strcat (dest, newext);
return true;
}
dest [0] = '\0';
}
return false;
}
int ConfigAlreadyExists(char newconfig[])
{
int i;
for (i=0; i<o.num_configs; i++)
{
if (strcasecmp(o.cnn[i].config_file, newconfig) == 0)
return true;
}
return false;
}
int AddConfigFileToList(int config, char filename[], char config_dir[])
{
char log_file[MAX_PATH];
int i;
/* Save config file name */
strncpy(o.cnn[config].config_file, filename, sizeof(o.cnn[config].config_file));
/* Save config dir */
strncpy(o.cnn[config].config_dir, config_dir, sizeof(o.cnn[config].config_dir));
/* Save connection name (config_name - extension) */
strncpy(o.cnn[config].config_name, o.cnn[config].config_file,
sizeof(o.cnn[config].config_name));
o.cnn[config].config_name[strlen(o.cnn[config].config_name) -
(strlen(o.ext_string)+1)]=0;
/* get log file pathname */
if (!modext (log_file, sizeof (log_file), o.cnn[config].config_file, "log"))
{
/* cannot construct logfile-name */
ShowLocalizedMsg (GUI_NAME, ERR_CANNOT_CONSTRUCT_LOG, o.cnn[config].config_file);
return(false);
}
mysnprintf (o.cnn[config].log_path, "%s\\%s", o.log_dir, log_file);
/* Check if connection should be autostarted */
for (i=0; (i < MAX_CONFIGS) && o.auto_connect[i]; i++)
{
if (strcasecmp(o.cnn[config].config_file, o.auto_connect[i]) == 0)
{
o.cnn[config].auto_connect = true;
break;
}
}
return(true);
}
int
BuildFileList()
{
WIN32_FIND_DATA find_obj;
HANDLE find_handle;
BOOL more_files;
char find_string[MAX_PATH];
int i;
char subdir_table[MAX_CONFIG_SUBDIRS][MAX_PATH];
int subdir=0;
int subdir_counter=0;
/* Reset config counter */
o.num_configs=0;
mysnprintf (find_string, "%s\\*", o.config_dir);
find_handle = FindFirstFile (find_string, &find_obj);
if (find_handle == INVALID_HANDLE_VALUE)
{
return(true);
}
/*
* Loop over each config file in main config dir
*/
do
{
if (o.num_configs >= MAX_CONFIGS)
{
/* too many configs */
ShowLocalizedMsg(GUI_NAME, ERR_TO_MANY_CONFIGS, MAX_CONFIGS);
break;
}
/* does file have the correct type and extension? */
if (match (&find_obj, o.ext_string) == MATCH_FILE)
{
/* Add config file to list */
AddConfigFileToList(o.num_configs, find_obj.cFileName, o.config_dir);
o.num_configs++;
}
if (match (&find_obj, o.ext_string) == MATCH_DIR)
{
if ((strncmp(find_obj.cFileName, ".", strlen(find_obj.cFileName)) != 0) &&
(strncmp(find_obj.cFileName, "..", strlen(find_obj.cFileName)) != 0) &&
(subdir < MAX_CONFIG_SUBDIRS))
{
/* Add dir to dir_table */
mysnprintf(subdir_table[subdir], "%s\\%s", o.config_dir, find_obj.cFileName);
subdir++;
}
}
/* more files to process? */
more_files = FindNextFile (find_handle, &find_obj);
} while (more_files);
FindClose (find_handle);
/*
* Loop over each config file in every subdir
*/
for (subdir_counter=0; subdir_counter < subdir; subdir_counter++)
{
mysnprintf (find_string, "%s\\*", subdir_table[subdir_counter]);
find_handle = FindFirstFile (find_string, &find_obj);
if (find_handle == INVALID_HANDLE_VALUE)
continue;
do
{
if (o.num_configs >= MAX_CONFIGS)
{
/* too many configs */
ShowLocalizedMsg(GUI_NAME, ERR_TO_MANY_CONFIGS, MAX_CONFIGS);
FindClose (find_handle);
return(true);
}
/* does file have the correct type and extension? */
if (match (&find_obj, o.ext_string) == MATCH_FILE)
{
if (!ConfigAlreadyExists(find_obj.cFileName))
{
/* Add config file to list */
AddConfigFileToList(o.num_configs, find_obj.cFileName, subdir_table[subdir_counter]);
o.num_configs++;
}
else
{
/* Config filename already exists */
ShowLocalizedMsg(GUI_NAME, ERR_CONFIG_ALREADY_EXIST, find_obj.cFileName);
}
}
/* more files to process? */
more_files = FindNextFile (find_handle, &find_obj);
} while (more_files);
FindClose (find_handle);
}
return (true);
}

22
openvpn_config.h Normal file
View File

@ -0,0 +1,22 @@
/*
* 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
*/
int BuildFileList();

649
openvpn_monitor_process.c Normal file
View File

@ -0,0 +1,649 @@
/*
* 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 "main.h"
#include "options.h"
#include "openvpn.h"
#include "scripts.h"
#include "openvpn-gui-res.h"
#include "passphrase.h"
#include "tray.h"
extern struct options o;
/* 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;
DWORD nCharsWritten;
char *p;
unsigned int len, i;
static int first_call = 1;
extern HINSTANCE hInstance;
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(GUI_NAME, 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(GUI_NAME, 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 buf[1000];
char msg[200];
char msg2[200];
unsigned int i;
char *linepos;
/* Check for Connected message */
if (strstr(line, o.connect_string) != NULL)
{
/* Run Connect Script */
RunConnectScript(config, false);
/* Save time when we got connected. */
o.cnn[config].connected_since = time(NULL);
o.cnn[config].connect_status = CONNECTED;
SetMenuStatus(config, CONNECTED);
SetTrayIcon(CONNECTED);
/* Remove Proxy Auth file */
DeleteFile(o.proxy_authfile);
/* Zero psw attempt counter */
o.cnn[config].failed_psw_attempts = 0;
/* UserInfo: Connected */
myLoadString(INFO_STATE_CONNECTED);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_CONNECTED);
/* Show Tray Balloon msg */
if (o.show_balloon[0] != '0')
{
myLoadString(INFO_NOW_CONNECTED);
mysnprintf(msg, buf, o.cnn[config].config_name);
if (strlen(o.cnn[config].ip) > 0)
{
myLoadString(INFO_ASSIG_IP);
mysnprintf(msg2, buf, o.cnn[config].ip);
}
else
{
mysnprintf(msg2," ");
}
ShowTrayBalloon(msg, msg2);
}
/* Hide Status Window */
ShowWindow(o.cnn[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.cnn[config].failed_psw_attempts++;
o.cnn[config].failed_psw=1;
o.cnn[config].restart=true;
}
/* Check for "certificate has expired" message */
if ((strstr(line, "error=certificate has expired") != NULL))
{
StopOpenVPN(config);
/* Cert expired... */
ShowLocalizedMsg(GUI_NAME, 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(GUI_NAME, 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))
{
strncpy(o.cnn[config].ip, linepos+54, 15); /* Copy IP address */
for (i=0; i < strlen(o.cnn[config].ip); i++)
if (o.cnn[config].ip[i] == '/' || o.cnn[config].ip[i] == ' ') break;
o.cnn[config].ip[i] = '\0';
}
}
/*
* Monitor the openvpn log output while CONNECTED
*/
void monitor_openvpnlog_while_connected(int config, char *line)
{
TCHAR buf[1000];
/* Check for Ping-Restart message */
if (strstr(line, "process restarting") != NULL)
{
/* Set connect_status = ReConnecting */
o.cnn[config].connect_status = RECONNECTING;
CheckAndSetTrayIcon();
/* Set Status Window Controls "ReConnecting" */
myLoadString(INFO_STATE_RECONNECTING);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_CONNECTING);
}
}
/*
* Monitor the openvpn log output while RECONNECTING
*/
void monitor_openvpnlog_while_reconnecting(int config, char *line)
{
TCHAR buf[1000];
char msg[200];
char msg2[200];
unsigned int i;
char *linepos;
/* Check for Connected message */
if (strstr(line, o.connect_string) != NULL)
{
o.cnn[config].connect_status = CONNECTED;
SetTrayIcon(CONNECTED);
/* Set Status Window Controls "Connected" */
myLoadString(INFO_STATE_CONNECTED);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_CONNECTED);
/* Show Tray Balloon msg */
if (o.show_balloon[0] == '2')
{
myLoadString(INFO_NOW_CONNECTED);
mysnprintf(msg, buf, o.cnn[config].config_name);
if (strlen(o.cnn[config].ip) > 0)
{
myLoadString(INFO_ASSIG_IP);
mysnprintf(msg2, buf, o.cnn[config].ip);
}
else
{
mysnprintf(msg2," ");
}
ShowTrayBalloon(msg, msg2);
}
}
/* 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.cnn[config].failed_psw_attempts++;
o.cnn[config].failed_psw=1;
o.cnn[config].restart=true;
}
/* Check for "certificate has expired" message */
if ((strstr(line, "error=certificate has expired") != NULL))
{
/* Cert expired */
StopOpenVPN(config);
ShowLocalizedMsg(GUI_NAME, 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(GUI_NAME, 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))
{
strncpy(o.cnn[config].ip, linepos+54, 15); /* Copy IP address */
for (i=0; i < strlen(o.cnn[config].ip); i++)
if (o.cnn[config].ip[i] == '/' || o.cnn[config].ip[i] == ' ') break;
o.cnn[config].ip[i] = '\0';
}
}
/*
* 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;
char filemode[2] = "w\0";
FILE *fd;
char msg[200];
char msg2[200];
int i;
int iLineCount;
int LogLines = 0;
int logpos;
char *linepos;
HWND LogWindow;
TCHAR buf[1000];
/* set log file append/truncate filemode */
if (o.append_string[0] == '1')
filemode[0] = 'a';
/* Set Connect_Status = "Connecting" */
o.cnn[config].connect_status = CONNECTING;
/* Set Tray Icon = "Connecting" if no other connections are running */
CheckAndSetTrayIcon();
/* Set MenuStatus = "Connecting" */
SetMenuStatus(config, CONNECTING);
/* Clear failed_password flag */
o.cnn[config].failed_psw = 0;
/* Open log file */
if ((fd=fopen(o.cnn[config].log_path, filemode)) == NULL)
ShowLocalizedMsg (GUI_NAME, ERR_OPEN_LOG_WRITE, o.cnn[config].log_path);
LogWindow = GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG);
while(TRUE)
{
if ((ret=ReadLineFromStdOut(o.cnn[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) "");
LogLines -= DEL_LOG_LINES;
}
/* Write line to LogWindow */
strcat(line, "\r\n");
SendMessage(LogWindow, EM_SETSEL, (WPARAM) -1, (LPARAM) -1);
SendMessage(LogWindow, EM_REPLACESEL, FALSE, (LPARAM) line);
if (o.cnn[config].connect_status == CONNECTING) /* Connecting state */
monitor_openvpnlog_while_connecting(config, line);
if (o.cnn[config].connect_status == CONNECTED) /* Connected state */
monitor_openvpnlog_while_connected(config, line);
if (o.cnn[config].connect_status == 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.cnn[config].hStdIn);
CloseHandle(o.cnn[config].hStdOut);
/* Close exitevent handle */
CloseHandle(o.cnn[config].exit_event);
o.cnn[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.cnn[config].connect_status == CONNECTED)
{
/* Zero psw attempt counter */
o.cnn[config].failed_psw_attempts = 0;
/* Set connect_status = "Not Connected" */
o.cnn[config].connect_status=DISCONNECTED;
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
/* Show Status Window */
myLoadString(INFO_STATE_DISCONNECTED);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_DISCONNECTED);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
SetForegroundWindow(o.cnn[config].hwndStatus);
ShowWindow(o.cnn[config].hwndStatus, SW_SHOW);
ShowLocalizedMsg(GUI_NAME, INFO_CONN_TERMINATED, o.cnn[config].config_name);
/* Close Status Window */
SendMessage(o.cnn[config].hwndStatus, WM_CLOSE, 0, 0);
}
/* We have failed to connect */
else if(o.cnn[config].connect_status == CONNECTING)
{
/* Set connect_status = "DisConnecting" */
o.cnn[config].connect_status=DISCONNECTING;
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
if ((o.cnn[config].failed_psw) &&
(o.cnn[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 */
myLoadString(INFO_STATE_FAILED);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_DISCONNECTED);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
SetForegroundWindow(o.cnn[config].hwndStatus);
ShowWindow(o.cnn[config].hwndStatus, SW_SHOW);
/* Zero psw attempt counter */
o.cnn[config].failed_psw_attempts = 0;
ShowLocalizedMsg(GUI_NAME, INFO_CONN_FAILED, o.cnn[config].config_name);
/* Set connect_status = "Not Connected" */
o.cnn[config].connect_status=DISCONNECTED;
/* Close Status Window */
SendMessage(o.cnn[config].hwndStatus, WM_CLOSE, 0, 0);
/* Reset restart flag */
o.cnn[config].restart=false;
}
}
/* We have failed to reconnect */
else if(o.cnn[config].connect_status == RECONNECTING)
{
/* Set connect_status = "DisConnecting" */
o.cnn[config].connect_status=DISCONNECTING;
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
if ((o.cnn[config].failed_psw) &&
(o.cnn[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 */
myLoadString(INFO_STATE_FAILED_RECONN);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_DISCONNECTED);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
SetForegroundWindow(o.cnn[config].hwndStatus);
ShowWindow(o.cnn[config].hwndStatus, SW_SHOW);
/* Zero psw attempt counter */
o.cnn[config].failed_psw_attempts = 0;
ShowLocalizedMsg(GUI_NAME, INFO_RECONN_FAILED, o.cnn[config].config_name);
/* Set connect_status = "Not Connected" */
o.cnn[config].connect_status=DISCONNECTED;
/* Close Status Window */
SendMessage(o.cnn[config].hwndStatus, WM_CLOSE, 0, 0);
/* Reset restart flag */
o.cnn[config].restart=false;
}
}
/* We have chosed to Disconnect */
else if(o.cnn[config].connect_status == DISCONNECTING)
{
/* Zero psw attempt counter */
o.cnn[config].failed_psw_attempts = 0;
/* Set connect_status = "Not Connected" */
o.cnn[config].connect_status=DISCONNECTED;
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
if (o.cnn[config].restart)
{
/* Restart OpenVPN */
StartOpenVPN(config);
}
else
{
/* Close Status Window */
SendMessage(o.cnn[config].hwndStatus, WM_CLOSE, 0, 0);
}
}
/* We have chosed to Suspend */
else if(o.cnn[config].connect_status == SUSPENDING)
{
/* Zero psw attempt counter */
o.cnn[config].failed_psw_attempts = 0;
/* Set connect_status = "SUSPENDED" */
o.cnn[config].connect_status=SUSPENDED;
myLoadString(INFO_STATE_SUSPENDED);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
/* Change tray icon if no more connections is running */
CheckAndSetTrayIcon();
}
/* Enable/Disable menuitems for this connections */
SetMenuStatus(config, DISCONNECTED);
}

22
openvpn_monitor_process.h Normal file
View File

@ -0,0 +1,22 @@
/*
* 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);

352
options.c Normal file
View File

@ -0,0 +1,352 @@
/*
* 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
*
*/
#include "options.h"
#include "main.h"
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <windows.h>
#include "openvpn-gui-res.h"
extern struct options o;
void
init_options (struct options *opt)
{
CLEAR (*opt);
}
int Createargcargv(struct options* options, char* command_line)
{
int argc;
char** argv;
char* arg;
int myindex;
int result;
int i;
// count the arguments
argc = 1;
arg = command_line;
while (arg[0] != 0) {
while (arg[0] != 0 && arg[0] == ' ') {
arg++;
}
if (arg[0] != 0) {
argc++;
if (arg[0] == '\"') {
arg++;
while (arg[0] != 0 && arg[0] != '\"') {
arg++;
}
}
while (arg[0] != 0 && arg[0] != ' ') {
arg++;
}
}
}
// tokenize the arguments
argv = (char**)malloc(argc * sizeof(char*));
arg = command_line;
myindex = 1;
while (arg[0] != 0) {
while (arg[0] != 0 && arg[0] == ' ') {
arg++;
}
if (arg[0] != 0) {
if (arg[0] == '\"') {
arg++;
argv[myindex] = arg;
myindex++;
while (arg[0] != 0 && arg[0] != '\"') {
arg++;
}
if (arg[0] != 0) {
arg[0] = 0;
arg++;
}
while (arg[0] != 0 && arg[0] != ' ') {
arg++;
}
}
else {
argv[myindex] = arg;
myindex++;
while (arg[0] != 0 && arg[0] != ' ') {
arg++;
}
if (arg[0] != 0) {
arg[0] = 0;
arg++;
}
}
}
}
// put the program name into argv[0]
char filename[_MAX_PATH];
GetModuleFileName(NULL, filename, _MAX_PATH);
argv[0] = filename;
parse_argv(options, argc, argv);
free(argv);
return(0);
}
void
parse_argv (struct options* options,
int argc,
char *argv[])
{
int i, j;
/* parse command line */
for (i = 1; i < argc; ++i)
{
char *p[MAX_PARMS];
CLEAR (p);
p[0] = argv[i];
if (strncmp(p[0], "--", 2))
{
/* Missing -- before option. */
ShowLocalizedMsg(GUI_NAME, ERR_BAD_PARAMETER, p[0]);
exit(0);
}
else
p[0] += 2;
for (j = 1; j < MAX_PARMS; ++j)
{
if (i + j < argc)
{
char *arg = argv[i + j];
if (strncmp (arg, "--", 2))
p[j] = arg;
else
break;
}
}
i = add_option (options, i, p);
}
}
static int
add_option (struct options *options,
int i,
char *p[])
{
if (streq (p[0], "help"))
{
TCHAR usagetext[5000];
TCHAR usagecaption[200];
LoadString(o.hInstance, INFO_USAGE, usagetext, sizeof(usagetext) / sizeof(TCHAR));
LoadString(o.hInstance, INFO_USAGECAPTION, usagecaption, sizeof(usagetext) / sizeof(TCHAR));
MessageBox(NULL, usagetext, usagecaption, MB_OK);
exit(0);
}
else if (streq (p[0], "connect") && p[1])
{
++i;
static int auto_connect_nr=0;
if (auto_connect_nr == MAX_CONFIGS)
{
/* Too many configs */
ShowLocalizedMsg(GUI_NAME, ERR_TO_MANY_CONFIGS, MAX_CONFIGS);
exit(1);
}
options->auto_connect[auto_connect_nr] = p[1];
auto_connect_nr++;
}
else if (streq (p[0], "exe_path") && p[1])
{
++i;
strncpy(options->exe_path, p[1], sizeof(options->exe_path) - 1);
}
else if (streq (p[0], "config_dir") && p[1])
{
++i;
strncpy(options->config_dir, p[1], sizeof(options->config_dir) - 1);
}
else if (streq (p[0], "ext_string") && p[1])
{
++i;
strncpy(options->ext_string, p[1], sizeof(options->ext_string) - 1);
}
else if (streq (p[0], "log_dir") && p[1])
{
++i;
strncpy(options->log_dir, p[1], sizeof(options->log_dir) - 1);
}
else if (streq (p[0], "priority_string") && p[1])
{
++i;
strncpy(options->priority_string, p[1], sizeof(options->priority_string) - 1);
}
else if (streq (p[0], "append_string") && p[1])
{
++i;
strncpy(options->append_string, p[1], sizeof(options->append_string) - 1);
}
else if (streq (p[0], "log_viewer") && p[1])
{
++i;
strncpy(options->log_viewer, p[1], sizeof(options->log_viewer) - 1);
}
else if (streq (p[0], "editor") && p[1])
{
++i;
strncpy(options->editor, p[1], sizeof(options->editor) - 1);
}
else if (streq (p[0], "allow_edit") && p[1])
{
++i;
strncpy(options->allow_edit, p[1], sizeof(options->allow_edit) - 1);
}
else if (streq (p[0], "allow_service") && p[1])
{
++i;
strncpy(options->allow_service, p[1], sizeof(options->allow_service) - 1);
}
else if (streq (p[0], "allow_password") && p[1])
{
++i;
strncpy(options->allow_password, p[1], sizeof(options->allow_password) - 1);
}
else if (streq (p[0], "allow_proxy") && p[1])
{
++i;
strncpy(options->allow_proxy, p[1], sizeof(options->allow_proxy) - 1);
}
else if (streq (p[0], "show_balloon") && p[1])
{
++i;
strncpy(options->show_balloon, p[1], sizeof(options->show_balloon) - 1);
}
else if (streq (p[0], "service_only") && p[1])
{
++i;
strncpy(options->service_only, p[1], sizeof(options->service_only) - 1);
}
else if (streq (p[0], "show_script_window") && p[1])
{
++i;
strncpy(options->show_script_window, p[1], sizeof(options->show_script_window) - 1);
}
else if (streq (p[0], "silent_connection") && p[1])
{
++i;
strncpy(options->silent_connection, p[1], sizeof(options->silent_connection) - 1);
}
else if (streq (p[0], "passphrase_attempts") && p[1])
{
++i;
strncpy(options->psw_attempts_string, p[1], sizeof(options->psw_attempts_string) - 1);
}
else if (streq (p[0], "connectscript_timeout") && p[1])
{
++i;
strncpy(options->connectscript_timeout_string, p[1], sizeof(options->connectscript_timeout_string) - 1);
}
else if (streq (p[0], "disconnectscript_timeout") && p[1])
{
++i;
strncpy(options->disconnectscript_timeout_string, p[1],
sizeof(options->disconnectscript_timeout_string) - 1);
}
else if (streq (p[0], "preconnectscript_timeout") && p[1])
{
++i;
strncpy(options->preconnectscript_timeout_string, p[1],
sizeof(options->preconnectscript_timeout_string) - 1);
}
else
{
/* Unrecognized option or missing parameter */
ShowLocalizedMsg(GUI_NAME, ERR_BAD_OPTION, p[0]);
exit(1);
}
return i;
}
/*
* Returns TRUE if option exist in config file.
*/
int ConfigFileOptionExist(int config, const char *option)
{
FILE *fp;
char line[256];
int found_key=0;
int found_pkcs12=0;
char configfile_path[MAX_PATH];
strncpy(configfile_path, o.cnn[config].config_dir, sizeof(configfile_path));
if (!(configfile_path[strlen(configfile_path)-1] == '\\'))
strcat(configfile_path, "\\");
strncat(configfile_path, o.cnn[config].config_file,
sizeof(configfile_path) - strlen(configfile_path) - 1);
if (!(fp=fopen(configfile_path, "r")))
{
/* can't open config file */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_CONFIG, configfile_path);
return(0);
}
while (fgets(line, sizeof (line), fp))
{
if ((strncmp(line, option, sizeof(option)) == 0))
{
fclose(fp);
return(1);
}
}
fclose(fp);
return(0);
}

137
options.h Normal file
View File

@ -0,0 +1,137 @@
/*
* 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
*
*/
#include <windows.h>
#include <time.h>
/*
* Maximum number of parameters associated with an option,
* including the option name itself.
*/
#define MAX_PARMS 5
#define MAX_CONFIGS 50 /* Max number of config-files to read. */
#define MAX_CONFIG_SUBDIRS 50 /* Max number of subdirs to scan */
/* connect_status STATES */
#define DISCONNECTED 0
#define CONNECTING 1
#define CONNECTED 2
#define RECONNECTING 3
#define DISCONNECTING 4
#define SUSPENDING 5
#define SUSPENDED 6
/* OpenVPN Service STATES */
#define SERVICE_NOACCESS -1
#define SERVICE_DISCONNECTED 0
#define SERVICE_CONNECTING 1
#define SERVICE_CONNECTED 2
/* Connections parameters */
struct connections
{
char config_file[MAX_PATH]; /* Name of the config file */
char config_name[MAX_PATH]; /* Name of the connection */
char config_dir[MAX_PATH]; /* Path to this configs dir */
char log_path[MAX_PATH]; /* Path to Logfile */
char ip[16]; /* Assigned IP address for this connection */
char exit_event_name[50]; /* Exit Event name for this connection */
int connect_status; /* 0=Not Connected 1=Connecting
2=Connected 3=Reconnecting 4=Disconnecting */
int auto_connect; /* true=AutoConnect at startup */
int failed_psw; /* 1=OpenVPN failed because of wrong psw */
int failed_psw_attempts; /* # of failed attempts maid to enter psw */
int restart; /* true=Restart connection after termination */
time_t connected_since; /* Time when the connection was established */
HANDLE exit_event;
HANDLE hProcess;
HANDLE hStdOut;
HANDLE hStdIn;
HWND hwndStatus; /* Handle to Status Dialog Window */
};
/* All options used within OpenVPN GUI */
struct options
{
/* Array of configs to autostart */
const char *auto_connect[MAX_CONFIGS];
/* Connection parameters */
struct connections cnn[MAX_CONFIGS]; /* Connection structure */
int num_configs; /* Number of configs */
int oldversion; /* 1=OpenVPN version below 2.0-beta6 */
char connect_string[100]; /* String to look for to report connected */
int psw_attempts; /* Number of psw attemps to allow */
int connectscript_timeout; /* Connect Script execution timeout (sec) */
int disconnectscript_timeout; /* Disconnect Script execution timeout (sec) */
int preconnectscript_timeout; /* Preconnect Script execution timeout (sec) */
int service_running; /* true if OpenVPN Service is started */
HWND hWnd; /* Main Window Handle */
HINSTANCE hInstance;
/* Registry values */
char exe_path[MAX_PATH];
char config_dir[MAX_PATH];
char ext_string[16];
char log_dir[MAX_PATH];
char priority_string[64];
char append_string[2];
char log_viewer[MAX_PATH];
char editor[MAX_PATH];
char allow_edit[2];
char allow_service[2];
char allow_password[2];
char allow_proxy[2];
char silent_connection[2];
char service_only[2];
char show_balloon[2];
char show_script_window[2];
char psw_attempts_string[2];
char disconnect_on_suspend[2];
char connectscript_timeout_string[4];
char disconnectscript_timeout_string[4];
char preconnectscript_timeout_string[4];
/* Proxy Settings */
int proxy_source; /* 0=OpenVPN config, 1=IE, 2=Manual */
int proxy_type; /* 0=HTTP, 1=SOCKS */
int proxy_http_auth; /* 0=Auth Disabled, 1=Auth Enabled */
char proxy_http_address[100]; /* HTTP Proxy Address */
char proxy_http_port[6]; /* HTTP Proxy Port */
char proxy_socks_address[100]; /* SOCKS Proxy Address */
char proxy_socks_port[6]; /* SOCKS Proxy Address */
char proxy_authfile[100]; /* Path to proxy auth file */
/* Debug file pointer */
#ifdef DEBUG
FILE *debug_fp;
#endif
};
#define streq(x, y) (!strcmp((x), (y)))
void init_options (struct options *o);
int Createargcargv(struct options* options, char* command_line);
void parse_argv (struct options* options, int argc, char *argv[]);
static int add_option (struct options *options, int i, char *p[]);
int ConfigFileOptionExist(int config, const char *option);

902
passphrase.c Normal file
View File

@ -0,0 +1,902 @@
/*
* 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
*/
#include <windows.h>
#include "main.h"
#include "options.h"
#include "passphrase.h"
#include "openvpn.h"
#include "openvpn-gui-res.h"
#include "chartable.h"
#ifndef DISABLE_CHANGE_PASSWORD
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>
#endif
WCHAR passphrase[256];
extern struct options o;
int ConvertUnicode2Ascii(WCHAR str_unicode[], char str_ascii[], unsigned int str_ascii_size)
{
unsigned int i;
unsigned int j;
int illegal_chars = false;
char *str_unicode_ptr = (char *) str_unicode;
for (i=0; (i < wcslen(str_unicode)) && (i < (str_ascii_size - 1)); i++)
{
for (j=0; j <= 256; j++)
{
if (j == 256)
{
illegal_chars = true;
j = 0x2e;
break;
}
if (str_unicode[i] == unicode_to_ascii[j]) break;
}
str_ascii[i] = (char) j;
}
str_ascii[i] = '\0';
if (illegal_chars)
return(false);
else
return(true);
}
void CheckPrivateKeyPassphrasePrompt (char *line, int config)
{
DWORD nCharsWritten;
char passphrase_ascii[256];
/* Check for Passphrase prompt */
if (strncmp(line, "Enter PEM pass phrase:", 22) == 0)
{
CLEAR(passphrase);
if (DialogBox(o.hInstance, (LPCTSTR)IDD_PASSPHRASE, NULL,
(DLGPROC)PassphraseDialogFunc) == IDCANCEL)
{
StopOpenVPN(config);
}
if (wcslen(passphrase) > 0)
{
CLEAR(passphrase_ascii);
ConvertUnicode2Ascii(passphrase, passphrase_ascii, sizeof(passphrase_ascii));
if (!WriteFile(o.cnn[config].hStdIn, passphrase_ascii,
strlen(passphrase_ascii), &nCharsWritten, NULL))
{
/* PassPhrase -> stdin failed */
ShowLocalizedMsg(GUI_NAME, ERR_PASSPHRASE2STDIN, "");
}
}
if (!WriteFile(o.cnn[config].hStdIn, "\r\n",
2, &nCharsWritten, NULL))
{
/* CR -> stdin failed */
ShowLocalizedMsg(GUI_NAME, ERR_CR2STDIN, "");
}
/* Remove Passphrase prompt from lastline buffer */
line[0]='\0';
/* Clear passphrase buffer */
CLEAR(passphrase);
CLEAR(passphrase_ascii);
}
/* Check for new passphrase prompt introduced with OpenVPN 2.0-beta12. */
if (strncmp(line, "Enter Private Key Password:", 27) == 0)
{
CLEAR(passphrase);
if (DialogBox(o.hInstance, (LPCTSTR)IDD_PASSPHRASE, NULL,
(DLGPROC)PassphraseDialogFunc) == IDCANCEL)
{
StopOpenVPN(config);
}
if (wcslen(passphrase) > 0)
{
CLEAR(passphrase_ascii);
ConvertUnicode2Ascii(passphrase, passphrase_ascii, sizeof(passphrase_ascii));
if (!WriteFile(o.cnn[config].hStdIn, passphrase_ascii,
strlen(passphrase_ascii), &nCharsWritten, NULL))
{
/* PassPhrase -> stdin failed */
ShowLocalizedMsg(GUI_NAME, ERR_PASSPHRASE2STDIN, "");
}
}
else
{
if (!WriteFile(o.cnn[config].hStdIn, "\n",
1, &nCharsWritten, NULL))
{
/* CR -> stdin failed */
ShowLocalizedMsg(GUI_NAME, ERR_CR2STDIN, "");
}
}
/* Remove Passphrase prompt from lastline buffer */
line[0]='\0';
/* Clear passphrase buffer */
CLEAR(passphrase);
CLEAR(passphrase_ascii);
}
}
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)
{
CLEAR(user_auth);
if (DialogBoxParam(o.hInstance,
(LPCTSTR)IDD_AUTH_PASSWORD,
NULL,
(DLGPROC)AuthPasswordDialogFunc,
(LPARAM)&user_auth) == IDCANCEL)
{
StopOpenVPN(config);
}
if (strlen(user_auth.username) > 0)
{
if (!WriteFile(o.cnn[config].hStdIn, user_auth.username,
strlen(user_auth.username), &nCharsWritten, NULL))
{
ShowLocalizedMsg(GUI_NAME, ERR_AUTH_USERNAME2STDIN, "");
}
}
else
{
if (!WriteFile(o.cnn[config].hStdIn, "\n",
1, &nCharsWritten, NULL))
{
ShowLocalizedMsg(GUI_NAME, ERR_CR2STDIN, "");
}
}
if (strlen(user_auth.password) > 0)
{
if (!WriteFile(o.cnn[config].hStdIn, user_auth.password,
strlen(user_auth.password), &nCharsWritten, NULL))
{
ShowLocalizedMsg(GUI_NAME, ERR_AUTH_PASSWORD2STDIN, "");
}
}
else
{
if (!WriteFile(o.cnn[config].hStdIn, "\n",
1, &nCharsWritten, NULL))
{
ShowLocalizedMsg(GUI_NAME, ERR_CR2STDIN, "");
}
}
/* Remove Username prompt from lastline buffer */
line[0]='\0';
/* Clear user_auth buffer */
CLEAR(user_auth);
}
}
void CheckAuthPasswordPrompt (char *line)
{
/* Check for Passphrase prompt */
if (strncmp(line, "Enter Auth Password:", 20) == 0)
{
/* Remove Passphrase prompt from lastline buffer */
line[0]='\0';
}
}
BOOL CALLBACK PassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
{
static char empty_string[100];
switch (msg) {
case WM_INITDIALOG:
SetForegroundWindow(hwndDlg);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK: // button
GetDlgItemTextW(hwndDlg, EDIT_PASSPHRASE, passphrase, sizeof(passphrase)/2 - 1);
/* Clear buffer */
SetDlgItemText(hwndDlg, EDIT_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 char 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, EDIT_AUTH_USERNAME, username_unicode, sizeof(username_unicode)/2 - 1);
GetDlgItemTextW(hwndDlg, EDIT_AUTH_PASSWORD, 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, EDIT_AUTH_USERNAME, empty_string);
SetDlgItemText(hwndDlg, EDIT_AUTH_PASSWORD, 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 (GUI_NAME, ERR_CREATE_PASS_THREAD, "");
return;
}
}
void ChangePassphraseThread(int config)
{
HWND hwndChangePSW;
MSG messages;
char conn_name[100];
char msg[100];
char keyfilename[MAX_PATH];
int keyfile_format=0;
TCHAR buf[1000];
/* Cut of extention from config filename. */
strncpy(conn_name, o.cnn[config].config_file, sizeof(conn_name));
conn_name[strlen(conn_name) - (strlen(o.ext_string)+1)]=0;
/* Get Key filename from config file */
if (!GetKeyFilename(config, keyfilename, sizeof(keyfilename), &keyfile_format))
{
ExitThread(1);
}
/* Show ChangePassphrase Dialog */
if (!(hwndChangePSW = CreateDialog (o.hInstance,
MAKEINTRESOURCE (IDD_CHANGEPSW),
NULL, (DLGPROC) ChangePassphraseDialogFunc)))
return;
SetDlgItemText(hwndChangePSW, TEXT_KEYFILE, keyfilename);
SetDlgItemInt(hwndChangePSW, TEXT_KEYFORMAT, (UINT) keyfile_format, FALSE);
myLoadString(INFO_CHANGE_PWD);
mysnprintf(msg, buf, conn_name);
SetWindowText(hwndChangePSW, msg);
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);
}
BOOL CALLBACK ChangePassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
{
HICON hIcon;
char keyfile[MAX_PATH];
int keyfile_format;
BOOL Translated;
TCHAR buf[1000];
switch (msg) {
case WM_INITDIALOG:
hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(APP_ICON),
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
if (hIcon) {
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon));
}
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
/* Check if the type new passwords match. */
if (!ConfirmNewPassword (hwndDlg))
{
/* passwords don't match */
ShowLocalizedMsg(GUI_NAME, ERR_PWD_DONT_MATCH, "");
break;
}
/* Check minimum length of password */
if (NewPasswordLengh(hwndDlg) < MIN_PASSWORD_LEN)
{
ShowLocalizedMsg(GUI_NAME, ERR_PWD_TO_SHORT, MIN_PASSWORD_LEN);
break;
}
/* Check if the new password is empty. */
if (NewPasswordLengh(hwndDlg) == 0)
{
myLoadString(INFO_EMPTY_PWD);
if (MessageBox(NULL, buf, GUI_NAME, MB_YESNO) != IDYES)
break;
}
GetDlgItemText(hwndDlg, TEXT_KEYFILE, keyfile, sizeof(keyfile) - 1);
keyfile_format=GetDlgItemInt(hwndDlg, TEXT_KEYFORMAT, &Translated, FALSE);
if (keyfile_format == KEYFILE_FORMAT_PEM)
{
/* Change password of a PEM file */
if (ChangePasswordPEM(hwndDlg) == -1) /* Wrong password */
break;
}
else if (keyfile_format == KEYFILE_FORMAT_PKCS12)
{
/* Change password of a .P12 file */
if (ChangePasswordPKCS12(hwndDlg) == -1) /* Wrong password */
break;
}
else
{
/* Unknown key format */
ShowLocalizedMsg (GUI_NAME, ERR_UNKNOWN_KEYFILE_FORMAT, "");
}
DestroyWindow(hwndDlg);
break;
case IDCANCEL:
DestroyWindow(hwndDlg);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CLOSE:
DestroyWindow(hwndDlg);
return FALSE;
}
return FALSE;
}
/* Return TRUE if new passwords match */
int ConfirmNewPassword(HWND hwndDlg)
{
char newpsw[50];
char newpsw2[50];
GetDlgItemText(hwndDlg, EDIT_PSW_NEW, newpsw, sizeof(newpsw) - 1);
GetDlgItemText(hwndDlg, EDIT_PSW_NEW2, newpsw2, sizeof(newpsw2) - 1);
if (strncmp(newpsw, newpsw2, sizeof(newpsw)) == 0)
return true;
else
return false;
}
/* Return lengh of the new password */
int NewPasswordLengh(HWND hwndDlg)
{
char newpsw[50];
GetDlgItemText(hwndDlg, EDIT_PSW_NEW, newpsw, sizeof(newpsw) - 1);
return (strlen(newpsw));
}
int ParseKeyFilenameLine(int config, char *keyfilename, unsigned int keyfilenamesize, char *line)
{
const int STATE_INITIAL = 0;
const int STATE_READING_QUOTED_PARM = 1;
const int STATE_READING_UNQUOTED_PARM = 2;
int i=0;
unsigned int j=0;
int state = STATE_INITIAL;
int backslash=0;
char temp_filename[MAX_PATH];
while(line[i] != '\0')
{
if (state == STATE_INITIAL)
{
if (line[i] == '\"')
{
state=STATE_READING_QUOTED_PARM;
}
else if ((line[i] == 0x0A) || (line[i] == 0x0D))
break;
else if ((line[i] == ';') || (line[i] == '#'))
break;
else if ((line[i] != ' ') && (line[i] != '\t'))
{
if (line[i] == '\\')
{
if(!backslash)
{
keyfilename[j++]=line[i];
state=STATE_READING_UNQUOTED_PARM;
backslash=1;
}
else
{
backslash=0;
}
}
else
{
if (backslash) backslash=0;
keyfilename[j++]=line[i];
state=STATE_READING_UNQUOTED_PARM;
}
}
}
else if (state == STATE_READING_QUOTED_PARM)
{
if (line[i] == '\"')
break;
if ((line[i] == 0x0A) || (line[i] == 0x0D))
break;
if (line[i] == '\\')
{
if (!backslash)
{
keyfilename[j++]=line[i];
backslash=1;
}
else
{
backslash=0;
}
}
else
{
if (backslash) backslash=0;
keyfilename[j++]=line[i];
}
}
else if (state == STATE_READING_UNQUOTED_PARM)
{
if (line[i] == '\"')
break;
if ((line[i] == 0x0A) || (line[i] == 0x0D))
break;
if ((line[i] == ';') || (line[i] == '#'))
break;
if (line[i] == ' ')
break;
if (line[i] == '\t')
break;
if (line[i] == '\\')
{
if (!backslash)
{
keyfilename[j++]=line[i];
backslash=1;
}
else
{
backslash=0;
}
}
else
{
if (backslash) backslash=0;
keyfilename[j++]=line[i];
}
}
if (j >= (keyfilenamesize - 1))
{
/* key filename to long */
ShowLocalizedMsg(GUI_NAME, ERR_KEY_FILENAME_TO_LONG, "");
return(0);
}
i++;
}
keyfilename[j]='\0';
/* Prepend filename with configdir path if needed */
if ((keyfilename[0] != '\\') && (keyfilename[0] != '/') && (keyfilename[1] != ':'))
{
strncpy(temp_filename, o.cnn[config].config_dir, sizeof(temp_filename));
if (temp_filename[strlen(temp_filename) - 1] != '\\')
strcat(temp_filename, "\\");
strncat(temp_filename, keyfilename,
sizeof(temp_filename) - strlen(temp_filename) - 1);
strncpy(keyfilename, temp_filename, keyfilenamesize - 1);
}
return(1);
}
/* ChangePasswordPEM() returns:
* -1 Wrong password
* 0 Changing password failed for unknown reason
* 1 Password changed successfully
*/
int ChangePasswordPEM(HWND hwndDlg)
{
char 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, TEXT_KEYFILE, keyfile, sizeof(keyfile) - 1);
GetDlgItemTextW(hwndDlg, EDIT_PSW_CURRENT, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1);
GetDlgItemTextW(hwndDlg, EDIT_PSW_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(GUI_NAME, ERR_INVALID_CHARS_IN_PSW, "");
return(-1);
}
privkey = EVP_PKEY_new();
/* Open old keyfile for reading */
if (! (fp = fopen (keyfile, "r")))
{
/* can't open key file */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
return(0);
}
/* Import old key */
if (! (privkey = PEM_read_PrivateKey (fp, NULL, NULL, oldpsw)))
{
/* wrong password */
ShowLocalizedMsg(GUI_NAME, ERR_OLD_PWD_INCORRECT, "");
fclose(fp);
return(-1);
}
fclose(fp);
/* Open keyfile for writing */
if (! (fp = fopen (keyfile, "w")))
{
/* can't open file rw */
ShowLocalizedMsg(GUI_NAME, 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(GUI_NAME, 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 */
newpsw, (int) strlen(newpsw), 0, NULL)))
{
/* can't write new key */
ShowLocalizedMsg(GUI_NAME, ERR_WRITE_NEW_KEY, keyfile);
EVP_PKEY_free(privkey);
fclose(fp);
return(0);
}
}
EVP_PKEY_free(privkey);
fclose(fp);
/* signal success to user */
ShowLocalizedMsg(GUI_NAME, INFO_PWD_CHANGED, "");
return(1);
}
/* ChangePasswordPKCS12() returns:
* -1 Wrong password
* 0 Changing password failed for unknown reason
* 1 Password changed successfully
*/
int ChangePasswordPKCS12(HWND hwndDlg)
{
char 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;
PKCS12 *new_p12;
char *alias;
/* Get filename, old_psw and new_psw from Dialog */
GetDlgItemText(hwndDlg, TEXT_KEYFILE, keyfile, sizeof(keyfile) - 1);
GetDlgItemTextW(hwndDlg, EDIT_PSW_CURRENT, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1);
GetDlgItemTextW(hwndDlg, EDIT_PSW_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(GUI_NAME, ERR_INVALID_CHARS_IN_PSW, "");
return(-1);
}
/* Load the PKCS #12 file */
if (!(fp = fopen(keyfile, "rb")))
{
/* error opening file */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
return(0);
}
p12 = d2i_PKCS12_fp(fp, NULL);
fclose (fp);
if (!p12)
{
/* error reading PKCS #12 */
ShowLocalizedMsg(GUI_NAME, ERR_READ_PKCS12, keyfile);
return(0);
}
/* Parse the PKCS #12 file */
if (!PKCS12_parse(p12, oldpsw, &privkey, &cert, &ca))
{
/* old password incorrect */
ShowLocalizedMsg(GUI_NAME, ERR_OLD_PWD_INCORRECT, "");
PKCS12_free(p12);
return(-1);
}
/* Free old PKCS12 object */
PKCS12_free(p12);
/* Get FriendlyName of old cert */
alias = 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 */
//ShowMsg(GUI_NAME, ERR_error_string(ERR_peek_last_error(), NULL));
ShowLocalizedMsg(GUI_NAME, 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 = fopen(keyfile, "wb")))
{
ShowLocalizedMsg(GUI_NAME, 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(GUI_NAME, INFO_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, char *keyfilename, unsigned int keyfilenamesize, int *keyfile_format)
{
FILE *fp;
char line[256];
int found_key=0;
int found_pkcs12=0;
char configfile_path[MAX_PATH];
strncpy(configfile_path, o.cnn[config].config_dir, sizeof(configfile_path));
if (!(configfile_path[strlen(configfile_path)-1] == '\\'))
strcat(configfile_path, "\\");
strncat(configfile_path, o.cnn[config].config_file,
sizeof(configfile_path) - strlen(configfile_path) - 1);
if (!(fp=fopen(configfile_path, "r")))
{
/* can't open config file */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_CONFIG, configfile_path);
return(0);
}
while (fgets(line, sizeof (line), fp))
{
if (LineBeginsWith(line, "key", 3))
{
if (found_key)
{
/* only one key option */
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_ONE_KEY_OPTION, "");
return(0);
}
if (found_pkcs12)
{
/* key XOR pkcs12 */
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_KEY_OR_PKCS12, "");
return(0);
}
found_key=1;
*keyfile_format = KEYFILE_FORMAT_PEM;
if (!ParseKeyFilenameLine(config, keyfilename, keyfilenamesize, &line[4]))
return(0);
}
if (LineBeginsWith(line, "pkcs12", 6))
{
if (found_pkcs12)
{
/* only one pkcs12 option */
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_ONE_PKCS12_OPTION, "");
return(0);
}
if (found_key)
{
/* only key XOR pkcs12 */
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_KEY_OR_PKCS12, "");
return(0);
}
found_pkcs12=1;
*keyfile_format = KEYFILE_FORMAT_PKCS12;
if (!ParseKeyFilenameLine(config, keyfilename, keyfilenamesize, &line[7]))
return(0);
}
}
if ((!found_key) && (!found_pkcs12))
{
/* must have key or pkcs12 option */
ShowLocalizedMsg(GUI_NAME, ERR_MUST_HAVE_KEY_OR_PKCS12, "");
return(0);
}
return(1);
}
#endif

43
passphrase.h Normal file
View File

@ -0,0 +1,43 @@
/*
* 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
*/
#define MIN_PASSWORD_LEN 8
struct user_auth {
char username[50];
char password[50];
};
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, char *keyfilename, unsigned int keyfilenamesize, int *keyfile_format);

569
proxy.c Normal file
View File

@ -0,0 +1,569 @@
/*
* 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
*/
#include <windows.h>
#include "main.h"
#include "options.h"
#include "registry.h"
#include "proxy.h"
#include "ieproxy.h"
#include "openvpn-gui-res.h"
extern struct options o;
void ShowProxySettingsDialog()
{
DialogBox(o.hInstance, (LPCTSTR)IDD_PROXY, NULL, (DLGPROC)ProxySettingsDialogFunc);
}
BOOL CALLBACK ProxySettingsDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
{
HICON hIcon;
switch (msg) {
case WM_INITDIALOG:
hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(APP_ICON),
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
if (hIcon) {
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon));
}
/* Limit Port editboxs to 5 chars. */
SendMessage(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), EM_SETLIMITTEXT, 5, 0);
SendMessage(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), EM_SETLIMITTEXT, 5, 0);
LoadProxySettings(hwndDlg);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
if (CheckProxySettings(hwndDlg))
{
SaveProxySettings(hwndDlg);
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
return FALSE;
case IDCANCEL:
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
case RB_PROXY_USE_OPENVPN:
if (HIWORD(wParam) == BN_CLICKED)
{
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_HTTP), FALSE);
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_SOCKS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), FALSE);
break;
}
case RB_PROXY_USE_IE:
if (HIWORD(wParam) == BN_CLICKED)
{
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_HTTP), FALSE);
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_SOCKS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), TRUE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), FALSE);
break;
}
case RB_PROXY_USE_MANUAL:
if (HIWORD(wParam) == BN_CLICKED)
{
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_HTTP), TRUE);
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_SOCKS), TRUE);
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_HTTP) == BST_CHECKED)
{
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), TRUE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), TRUE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), TRUE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), FALSE);
}
else
{
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), TRUE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), TRUE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), TRUE);
}
break;
}
case RB_PROXY_HTTP:
if (HIWORD(wParam) == BN_CLICKED)
{
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), TRUE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), TRUE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), TRUE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), FALSE);
break;
}
case RB_PROXY_SOCKS:
if (HIWORD(wParam) == BN_CLICKED)
{
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), FALSE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), FALSE);
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), FALSE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), TRUE);
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), TRUE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), TRUE);
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), TRUE);
break;
}
}
break;
case WM_CLOSE:
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
return FALSE;
}
/* Check that proxy settings are valid */
int CheckProxySettings(HWND hwndDlg)
{
char text[100];
long port;
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_USE_MANUAL) == BST_CHECKED)
{
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_HTTP) == BST_CHECKED)
{
GetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_ADDRESS, text, sizeof(text));
if (strlen(text) == 0)
{
/* http_proxy_access not specified */
ShowLocalizedMsg(GUI_NAME, ERR_HTTP_PROXY_ADDRESS, "");
return(0);
}
GetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_PORT, text, sizeof(text));
if (strlen(text) == 0)
{
/* http_proxy_port not specified */
ShowLocalizedMsg(GUI_NAME, ERR_HTTP_PROXY_PORT, "");
return(0);
}
else
{
port=strtol(text, NULL, 10);
if ((port < 1) || (port > 65535))
{
/* http_proxy_port range error */
ShowLocalizedMsg(GUI_NAME, ERR_HTTP_PROXY_PORT_RANGE, "");
return(0);
}
}
}
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_SOCKS) == BST_CHECKED)
{
GetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS, text, sizeof(text));
if (strlen(text) == 0)
{
/* socks_proxy_address not specified */
ShowLocalizedMsg(GUI_NAME, ERR_SOCKS_PROXY_ADDRESS, "");
return(0);
}
GetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_PORT, text, sizeof(text));
if (strlen(text) == 0)
{
/* socks_proxy_port not specified */
ShowLocalizedMsg(GUI_NAME, ERR_SOCKS_PROXY_PORT, "");
return(0);
}
else
{
port=strtol(text, NULL, 10);
if ((port < 1) || (port > 65535))
{
/* socks_proxy_port range error */
ShowLocalizedMsg(GUI_NAME, ERR_SOCKS_PROXY_PORT_RANGE, "");
return(0);
}
}
}
}
return(1);
}
void LoadProxySettings(HWND hwndDlg)
{
/* Disable IE Settings untill this is implemented */
// EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_USE_IE), FALSE);
/* Set Proxy Type */
if (o.proxy_type == 0) /* HTTP Proxy */
{
CheckRadioButton(hwndDlg,
RB_PROXY_HTTP, /* First button in group */
RB_PROXY_SOCKS, /* Last button in group */
RB_PROXY_HTTP); /* Select this button */
}
else /* SOCKS Proxy */
{
CheckRadioButton(hwndDlg,
RB_PROXY_HTTP, /* First button in group */
RB_PROXY_SOCKS, /* Last button in group */
RB_PROXY_SOCKS); /* Select this button */
}
/* Set Proxy Settings Source */
if (o.proxy_source == 0)
SendMessage(GetDlgItem(hwndDlg, RB_PROXY_USE_OPENVPN), BM_CLICK, 0, 0);
if (o.proxy_source == 1)
SendMessage(GetDlgItem(hwndDlg, RB_PROXY_USE_IE), BM_CLICK, 0, 0);
if (o.proxy_source == 2)
SendMessage(GetDlgItem(hwndDlg, RB_PROXY_USE_MANUAL), BM_CLICK, 0, 0);
/* Set Proxy addresses and ports */
SetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_ADDRESS, o.proxy_http_address);
SetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_PORT, o.proxy_http_port);
SetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS, o.proxy_socks_address);
SetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_PORT, o.proxy_socks_port);
if (o.proxy_http_auth) CheckDlgButton(hwndDlg, CHECKB_PROXY_AUTH, BST_CHECKED);
}
void SaveProxySettings(HWND hwndDlg)
{
LONG status;
HKEY regkey;
DWORD dwDispos;
char proxy_source_string[2]="0";
char proxy_type_string[2]="0";
char proxy_http_auth_string[2]="0";
/* Save Proxy Settings Source */
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_USE_OPENVPN) == BST_CHECKED)
{
o.proxy_source = 0;
proxy_source_string[0] = '0';
}
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_USE_IE) == BST_CHECKED)
{
o.proxy_source = 1;
proxy_source_string[0] = '1';
}
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_USE_MANUAL) == BST_CHECKED)
{
o.proxy_source = 2;
proxy_source_string[0] = '2';
}
/* Save Proxy addresses and ports */
GetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_ADDRESS, o.proxy_http_address,
sizeof(o.proxy_http_address));
GetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_PORT, o.proxy_http_port,
sizeof(o.proxy_http_port));
GetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS, o.proxy_socks_address,
sizeof(o.proxy_http_address));
GetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_PORT, o.proxy_socks_port,
sizeof(o.proxy_socks_port));
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_HTTP) == BST_CHECKED)
{
o.proxy_type = 0;
proxy_type_string[0] = '0';
}
else
{
o.proxy_type = 1;
proxy_type_string[0] = '1';
}
if (IsDlgButtonChecked(hwndDlg, CHECKB_PROXY_AUTH) == BST_CHECKED)
{
o.proxy_http_auth = 1;
proxy_http_auth_string[0] = '1';
}
else
{
o.proxy_http_auth = 0;
proxy_http_auth_string[0] = '0';
}
/* Open Registry for writing */
if (RegCreateKeyEx(HKEY_CURRENT_USER,
GUI_REGKEY_HKCU,
0,
(LPTSTR) "",
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
NULL,
&regkey,
&dwDispos) != ERROR_SUCCESS)
{
/* error creating Registry-Key */
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU);
return;
}
/* Save Settings to registry */
SetRegistryValue(regkey, "proxy_source", proxy_source_string);
SetRegistryValue(regkey, "proxy_type", proxy_type_string);
SetRegistryValue(regkey, "proxy_http_auth", proxy_http_auth_string);
SetRegistryValue(regkey, "proxy_http_address", o.proxy_http_address);
SetRegistryValue(regkey, "proxy_http_port", o.proxy_http_port);
SetRegistryValue(regkey, "proxy_socks_address", o.proxy_socks_address);
SetRegistryValue(regkey, "proxy_socks_port", o.proxy_socks_port);
RegCloseKey(regkey);
}
void GetProxyRegistrySettings()
{
LONG status;
HKEY regkey;
char proxy_source_string[2]="0";
char proxy_type_string[2]="0";
char proxy_http_auth_string[2]="0";
char temp_path[100];
/* Construct Authfile path */
if (!GetTempPath(sizeof(temp_path) - 1, temp_path))
{
/* Error getting TempPath - using C:\ */
ShowLocalizedMsg(GUI_NAME, ERR_GET_TEMP_PATH, "");
strcpy(temp_path, "C:\\");
}
strncat(temp_path, "openvpn_authfile.txt",
sizeof(temp_path) - strlen(temp_path) - 1);
strncpy(o.proxy_authfile, temp_path, sizeof(o.proxy_authfile));
/* Open Registry for reading */
status = RegOpenKeyEx(HKEY_CURRENT_USER,
GUI_REGKEY_HKCU,
0,
KEY_READ,
&regkey);
/* Return if can't open the registry key */
if (status != ERROR_SUCCESS) return;
/* get registry settings */
GetRegistryValue(regkey, "proxy_http_address", o.proxy_http_address,
sizeof(o.proxy_http_address));
GetRegistryValue(regkey, "proxy_http_port", o.proxy_http_port,
sizeof(o.proxy_http_port));
GetRegistryValue(regkey, "proxy_socks_address", o.proxy_socks_address,
sizeof(o.proxy_socks_address));
GetRegistryValue(regkey, "proxy_socks_port", o.proxy_socks_port,
sizeof(o.proxy_socks_port));
GetRegistryValue(regkey, "proxy_source", proxy_source_string,
sizeof(proxy_source_string));
GetRegistryValue(regkey, "proxy_type", proxy_type_string,
sizeof(proxy_type_string));
GetRegistryValue(regkey, "proxy_http_auth", proxy_http_auth_string,
sizeof(proxy_http_auth_string));
if (proxy_source_string[0] == '1')
o.proxy_source=1;
if (proxy_source_string[0] == '2')
o.proxy_source=2;
if (proxy_source_string[0] == '3')
o.proxy_source=3;
if (proxy_type_string[0] == '1')
o.proxy_type=1;
if (proxy_http_auth_string[0] == '1')
o.proxy_http_auth=1;
RegCloseKey(regkey);
return;
}
BOOL CALLBACK ProxyAuthDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
{
char username[50];
char password[50];
FILE *fp;
switch (msg) {
case WM_INITDIALOG:
//SetForegroundWindow(hwndDlg);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
GetDlgItemText(hwndDlg, EDIT_PROXY_USERNAME, username, sizeof(username) - 1);
GetDlgItemText(hwndDlg, EDIT_PROXY_PASSWORD, password, sizeof(password) - 1);
if (!(fp = fopen(o.proxy_authfile, "w")))
{
/* error creating AUTH file */
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_AUTH_FILE, o.proxy_authfile);
EndDialog(hwndDlg, LOWORD(wParam));
}
fputs(username, fp);
fputs("\n", fp);
fputs(password, fp);
fputs("\n", fp);
fclose(fp);
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hwndDlg, LOWORD(wParam));
return TRUE;
}
return FALSE;
}
/*
* Construct the proxy options to append to the cmd-line.
*/
void ConstructProxyCmdLine(char *proxy_string_ptr, unsigned int size)
{
char proxy_string[100];
CLEAR(proxy_string);
if (o.proxy_source == PROXY_SOURCE_MANUAL)
{
if (o.proxy_type == PROXY_TYPE_HTTP)
{
if (o.proxy_http_auth == PROXY_HTTP_ASK_AUTH)
{
/* Ask for Proxy username/password */
DialogBox(o.hInstance, (LPCTSTR)IDD_PROXY_AUTH, NULL, (DLGPROC)ProxyAuthDialogFunc);
mysnprintf(proxy_string, "--http-proxy %s %s %s",
o.proxy_http_address,
o.proxy_http_port,
o.proxy_authfile);
}
else
{
mysnprintf(proxy_string, "--http-proxy %s %s",
o.proxy_http_address,
o.proxy_http_port);
}
}
if (o.proxy_type == PROXY_TYPE_SOCKS)
{
mysnprintf(proxy_string, "--socks-proxy %s %s",
o.proxy_socks_address,
o.proxy_socks_port);
}
}
if (o.proxy_source == PROXY_SOURCE_IE)
{
LPCTSTR ieproxy;
char *pos;
ieproxy = getIeHttpProxy();
if (!ieproxy)
{
/* can't get ie proxy settings */
ShowLocalizedMsg(GUI_NAME, ERR_GET_IE_PROXY_SETTINGS, getIeHttpProxyError);
}
else
{
/* Don't use a proxy if IE proxy string is empty */
if (strlen(ieproxy) > 1)
{
/* Parse the port number from the IE proxy string */
if ((pos = strchr(ieproxy, ':')))
{
*pos = '\0';
if (o.proxy_http_auth == PROXY_HTTP_ASK_AUTH)
{
/* Ask for Proxy username/password */
DialogBox(o.hInstance, (LPCTSTR)IDD_PROXY_AUTH, NULL, (DLGPROC)ProxyAuthDialogFunc);
mysnprintf(proxy_string, "--http-proxy %s %s %s",
ieproxy, pos+1, o.proxy_authfile)
}
else
{
mysnprintf(proxy_string, "--http-proxy %s %s", ieproxy, pos+1)
}
}
/* No port is specified, use 80 as default port */
else
{
if (o.proxy_http_auth == PROXY_HTTP_ASK_AUTH)
{
/* Ask for Proxy username/password */
DialogBox(o.hInstance, (LPCTSTR)IDD_PROXY_AUTH, NULL, (DLGPROC)ProxyAuthDialogFunc);
mysnprintf(proxy_string, "--http-proxy %s 80 %s",
ieproxy, o.proxy_authfile)
}
else
{
mysnprintf(proxy_string, "--http-proxy %s 80", ieproxy)
}
}
}
//free (ieproxy);
}
}
strncpy(proxy_string_ptr, proxy_string, size);
}

37
proxy.h Normal file
View File

@ -0,0 +1,37 @@
/*
* 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
*/
#define PROXY_SOURCE_OPENVPN 0
#define PROXY_SOURCE_IE 1
#define PROXY_SOURCE_MANUAL 2
#define PROXY_TYPE_HTTP 0
#define PROXY_TYPE_SOCKS 1
#define PROXY_HTTP_NO_AUTH 0
#define PROXY_HTTP_ASK_AUTH 1
void ShowProxySettingsDialog();
BOOL CALLBACK ProxySettingsDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
int CheckProxySettings(HWND hwndDlg);
void LoadProxySettings(HWND hwndDlg);
void SaveProxySettings(HWND hwndDlg);
void GetProxyRegistrySettings();
BOOL CALLBACK ProxyAuthDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void ConstructProxyCmdLine(char *proxy_string_ptr, unsigned int size);

BIN
reconnecting.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

272
registry.c Normal file
View File

@ -0,0 +1,272 @@
/*
* 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
*
*/
#include <windows.h>
#include <shlobj.h>
#include "main.h"
#include "options.h"
#include "openvpn-gui-res.h"
#include "registry.h"
extern struct options o;
int
GetRegistryKeys()
{
char windows_dir[MAX_PATH];
char temp_path[MAX_PATH];
char openvpn_path[MAX_PATH];
HKEY regkey;
if (!GetWindowsDirectory(windows_dir, sizeof(windows_dir))) {
/* can't get windows dir */
ShowLocalizedMsg(GUI_NAME, ERR_GET_WINDOWS_DIR, "");
return(false);
}
/* Get path to OpenVPN installation. */
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenVPN", 0, KEY_READ, &regkey)
!= ERROR_SUCCESS)
{
/* registry key not found */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_REGISTRY, "");
return(false);
}
if (!GetRegistryValue(regkey, "", openvpn_path, sizeof(openvpn_path)))
{
/* error reading registry value */
ShowLocalizedMsg(GUI_NAME, ERR_READING_REGISTRY, "");
return(false);
}
if(openvpn_path[strlen(openvpn_path) - 1] != '\\')
strcat(openvpn_path, "\\");
mysnprintf(temp_path, "%sconfig", openvpn_path);
if (!GetRegKey("config_dir", o.config_dir,
temp_path, sizeof(o.config_dir))) return(false);
if (!GetRegKey("config_ext", o.ext_string, "ovpn", sizeof(o.ext_string))) return(false);
mysnprintf(temp_path, "%sbin\\openvpn.exe", openvpn_path);
if (!GetRegKey("exe_path", o.exe_path,
temp_path, sizeof(o.exe_path))) return(false);
mysnprintf(temp_path, "%slog", openvpn_path);
if (!GetRegKey("log_dir", o.log_dir,
temp_path, sizeof(o.log_dir))) return(false);
if (!GetRegKey("log_append", o.append_string, "0", sizeof(o.append_string))) return(false);
if (!GetRegKey("priority", o.priority_string,
"NORMAL_PRIORITY_CLASS", sizeof(o.priority_string))) return(false);
mysnprintf(temp_path, "%s\\notepad.exe", windows_dir);
if (!GetRegKey("log_viewer", o.log_viewer,
temp_path, sizeof(o.log_viewer))) return(false);
mysnprintf(temp_path, "%s\\notepad.exe", windows_dir);
if (!GetRegKey("editor", o.editor,
temp_path, sizeof(o.editor))) return(false);
if (!GetRegKey("allow_edit", o.allow_edit, "1", sizeof(o.allow_edit))) return(false);
if (!GetRegKey("allow_service", o.allow_service, "0", sizeof(o.allow_service))) return(false);
if (!GetRegKey("allow_password", o.allow_password, "1", sizeof(o.allow_password))) return(false);
if (!GetRegKey("allow_proxy", o.allow_proxy, "1", sizeof(o.allow_proxy))) return(false);
if (!GetRegKey("service_only", o.service_only, "0", sizeof(o.service_only))) return(false);
if (!GetRegKey("show_balloon", o.show_balloon, "1", sizeof(o.show_balloon))) return(false);
if (!GetRegKey("silent_connection", o.silent_connection, "0", sizeof(o.silent_connection))) return(false);
if (!GetRegKey("show_script_window", o.show_script_window, "1", sizeof(o.show_script_window))) return(false);
if (!GetRegKey("disconnect_on_suspend", o.disconnect_on_suspend, "1",
sizeof(o.disconnect_on_suspend))) return(false);
if (!GetRegKey("passphrase_attempts", o.psw_attempts_string, "3",
sizeof(o.psw_attempts_string))) return(false);
o.psw_attempts = atoi(o.psw_attempts_string);
if ((o.psw_attempts < 1) || (o.psw_attempts > 9))
{
/* 0 <= passphrase_attempts <= 9 */
ShowLocalizedMsg(GUI_NAME, ERR_PASSPHRASE_ATTEMPTS, "");
return(false);
}
if (!GetRegKey("connectscript_timeout", o.connectscript_timeout_string, "15",
sizeof(o.connectscript_timeout_string))) return(false);
o.connectscript_timeout = atoi(o.connectscript_timeout_string);
if ((o.connectscript_timeout < 0) || (o.connectscript_timeout > 99))
{
/* 0 <= connectscript_timeout <= 99 */
ShowLocalizedMsg(GUI_NAME, ERR_CONN_SCRIPT_TIMEOUT, "");
return(false);
}
if (!GetRegKey("disconnectscript_timeout", o.disconnectscript_timeout_string, "10",
sizeof(o.disconnectscript_timeout_string))) return(false);
o.disconnectscript_timeout = atoi(o.disconnectscript_timeout_string);
if ((o.disconnectscript_timeout <= 0) || (o.disconnectscript_timeout > 99))
{
/* 0 < disconnectscript_timeout <= 99 */
ShowLocalizedMsg(GUI_NAME, ERR_DISCONN_SCRIPT_TIMEOUT, "");
return(false);
}
if (!GetRegKey("preconnectscript_timeout", o.preconnectscript_timeout_string, "10",
sizeof(o.preconnectscript_timeout_string))) return(false);
o.preconnectscript_timeout = atoi(o.preconnectscript_timeout_string);
if ((o.preconnectscript_timeout <= 0) || (o.preconnectscript_timeout > 99))
{
/* 0 < disconnectscript_timeout <= 99 */
ShowLocalizedMsg(GUI_NAME, ERR_PRECONN_SCRIPT_TIMEOUT, "");
return(false);
}
return(true);
}
int GetRegKey(const char name[], char *data, const char default_data[], DWORD len)
{
LONG status;
DWORD type;
HKEY openvpn_key;
HKEY openvpn_key_write;
DWORD dwDispos;
char expanded_string[MAX_PATH];
DWORD max_len;
/* Save maximum string length */
max_len=len;
/* If option is already set via cmd-line, return */
if (data[0] != 0)
{
// Expand environment variables inside the string.
ExpandEnvironmentStrings(data, expanded_string, sizeof(expanded_string));
strncpy(data, expanded_string, max_len);
return(true);
}
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\OpenVPN-GUI",
0,
KEY_READ,
&openvpn_key);
if (status != ERROR_SUCCESS)
{
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"Software\\OpenVPN-GUI",
0,
(LPTSTR) "",
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&openvpn_key,
&dwDispos) != ERROR_SUCCESS)
{
/* error creating registry key */
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_REG_KEY, "");
return(false);
}
}
/* get a registry string */
status = RegQueryValueEx(openvpn_key, name, NULL, &type, (byte *) data, &len);
if (status != ERROR_SUCCESS || type != REG_SZ)
{
/* key did not exist - set default value */
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\OpenVPN-GUI",
0,
KEY_READ | KEY_WRITE,
&openvpn_key_write);
if (status != ERROR_SUCCESS) {
/* can't open registry for writing */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_WRITE_REG, "");
return(false);
}
if(RegSetValueEx(openvpn_key_write,
name,
0,
REG_SZ,
default_data,
strlen(default_data)+1))
{
/* cant read / set reg-key */
ShowLocalizedMsg(GUI_NAME, ERR_READ_SET_KEY, name);
return(false);
}
strncpy(data, default_data, max_len);
RegCloseKey(openvpn_key_write);
}
RegCloseKey(openvpn_key);
// Expand environment variables inside the string.
ExpandEnvironmentStrings(data, expanded_string, sizeof(expanded_string));
strncpy(data, expanded_string, max_len);
return(true);
}
LONG GetRegistryValue(HKEY regkey, const char *name, char *data, DWORD len)
{
LONG status;
DWORD type;
DWORD data_len;
data_len = len;
/* get a registry string */
status = RegQueryValueEx(regkey, name, NULL, &type, (byte *) data, &data_len);
if (status != ERROR_SUCCESS || type != REG_SZ)
return(0);
return(data_len);
}
int SetRegistryValue(HKEY regkey, const char *name, char *data)
{
/* set a registry string */
if(RegSetValueEx(regkey, name, 0, REG_SZ, data, strlen(data)+1) != ERROR_SUCCESS)
{
/* Error writing registry value */
ShowLocalizedMsg(GUI_NAME, ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name);
return(0);
}
return(1);
}

27
registry.h Normal file
View File

@ -0,0 +1,27 @@
/*
* 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
*/
int GetRegistryKeys();
//int SetRegistryKeys();
int GetRegKey(const char name[], char data[], const char default_data[], DWORD len);
LONG GetRegistryValue(HKEY regkey, const char *name, char *data, DWORD len);
int SetRegistryValue(HKEY regkey, const char *name, char *data);

291
scripts.c Normal file
View File

@ -0,0 +1,291 @@
/*
* 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
*/
#include <windows.h>
//#include <stdlib.h>
//#include <stdio.h>
#include <process.h>
#include "main.h"
#include "openvpn-gui-res.h"
#include "options.h"
extern struct options o;
void RunConnectScript(int config, int run_as_service)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
char command_line[256];
char batch_file[100];
DWORD ExitCode;
int i, TimeOut;
TCHAR buf[1000];
/* Cut of extention from config filename and add "_up.bat". */
strncpy(batch_file, o.cnn[config].config_file, sizeof(batch_file));
batch_file[strlen(batch_file) - (strlen(o.ext_string)+1)]=0;
strncat(batch_file, "_up.bat", sizeof(batch_file) - strlen(batch_file) - 1);
mysnprintf(command_line, "%s\\%s", o.cnn[config].config_dir, batch_file);
/* Return if no script exists */
hFind = FindFirstFile(command_line, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
FindClose(hFind);
if (!run_as_service)
{
/* UserInfo: Connect Script running */
myLoadString(INFO_STATE_CONN_SCRIPT);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
}
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.cnn[config].config_dir, //start-up dir
&start_info,
&proc_info))
{
/* Running Script failed */
ShowLocalizedMsg(GUI_NAME, 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(GUI_NAME, ERR_GET_EXIT_CODE, command_line);
return;
}
if (ExitCode != STILL_ACTIVE)
{
if (ExitCode != 0)
{
/* ConnectScript failed */
ShowLocalizedMsg(GUI_NAME, ERR_CONN_SCRIPT_FAILED, ExitCode);
return;
}
return;
}
Sleep(1000);
}
/* UserInfo: Timeout */
ShowLocalizedMsg(GUI_NAME, ERR_RUN_CONN_SCRIPT_TIMEOUT, TimeOut);
}
void RunDisconnectScript(int config, int run_as_service)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
char command_line[256];
char batch_file[100];
DWORD ExitCode;
int i, TimeOut;
TCHAR buf[1000];
/* Append "_down.bat" to config name. */
strncpy(batch_file, o.cnn[config].config_name, sizeof(batch_file));
strncat(batch_file, "_down.bat", sizeof(batch_file) - strlen(batch_file) - 1);
mysnprintf(command_line, "%s\\%s", o.cnn[config].config_dir, batch_file);
/* Return if no script exists */
hFind = FindFirstFile(command_line, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
FindClose(hFind);
if (!run_as_service)
{
/* UserInfo: Disconnect Script running */
myLoadString(INFO_STATE_DISCONN_SCRIPT);
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
}
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.cnn[config].config_dir, //start-up dir
&start_info,
&proc_info))
{
return;
}
TimeOut = o.disconnectscript_timeout;
for (i=0; i <= TimeOut; i++)
{
if (!GetExitCodeProcess(proc_info.hProcess, &ExitCode))
{
return;
}
if (ExitCode != STILL_ACTIVE)
{
return;
}
Sleep(1000);
}
}
void RunPreconnectScript(int config)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
char command_line[256];
char batch_file[100];
DWORD ExitCode;
int i, TimeOut;
TCHAR buf[1000];
/* Append "_pre.bat" to config name. */
strncpy(batch_file, o.cnn[config].config_name, sizeof(batch_file));
strncat(batch_file, "_pre.bat", sizeof(batch_file) - strlen(batch_file) - 1);
mysnprintf(command_line, "%s\\%s", o.cnn[config].config_dir, batch_file);
/* Return if no script exists */
hFind = FindFirstFile(command_line, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
return;
}
FindClose(hFind);
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.cnn[config].config_dir, //start-up dir
&start_info,
&proc_info))
{
return;
}
TimeOut = o.preconnectscript_timeout;
for (i=0; i <= TimeOut; i++)
{
if (!GetExitCodeProcess(proc_info.hProcess, &ExitCode))
{
return;
}
if (ExitCode != STILL_ACTIVE)
{
return;
}
Sleep(1000);
}
}

24
scripts.h Normal file
View File

@ -0,0 +1,24 @@
/*
* 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 RunConnectScript(int config, int run_as_service);
void RunDisconnectScript(int config, int run_as_service);
void RunPreconnectScript(int config);

304
service.c Normal file
View File

@ -0,0 +1,304 @@
/*
* 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
*/
#include <windows.h>
#include "tray.h"
#include "service.h"
#include "openvpn.h"
#include "options.h"
#include "scripts.h"
#include "main.h"
#include <stdio.h>
#include "openvpn-gui-res.h"
extern struct options o;
int MyStartService()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
SERVICE_STATUS ssStatus;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;
char msg[200];
TCHAR buf[1000];
int i;
/* Set Service Status = Connecting */
o.service_running = SERVICE_CONNECTING;
SetServiceMenuStatus();
CheckAndSetTrayIcon();
// Open a handle to the SC Manager database.
schSCManager = OpenSCManager(
NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_CONNECT); // Connect rights
if (NULL == schSCManager) {
/* open SC manager failed */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_SCMGR, "");
goto failed;
}
schService = OpenService(
schSCManager, // SCM database
"OpenVPNService", // service name
SERVICE_START | SERVICE_QUERY_STATUS);
if (schService == NULL) {
/* can't open VPN service */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_VPN_SERVICE, "");
goto failed;
}
/* Run Pre-connect script */
for (i=0; i<o.num_configs; i++)
RunPreconnectScript(i);
if (!StartService(
schService, // handle to service
0, // number of arguments
NULL) ) // no arguments
{
/* can't start */
ShowLocalizedMsg(NULL, ERR_START_SERVICE, "");
goto failed;
}
else
{
//printf("Service start pending.\n");
}
// Check the status until the service is no longer start pending.
if (!QueryServiceStatus(
schService, // handle to service
&ssStatus) ) // address of status information structure
{
/* query failed */
ShowLocalizedMsg(GUI_NAME, ERR_QUERY_SERVICE, "");
goto failed;
}
// Save the tick count and initial checkpoint.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
{
// Do not wait longer than the wait hint. A good interval is
// one tenth the wait hint, but no less than 1 second and no
// more than 5 seconds.
dwWaitTime = ssStatus.dwWaitHint / 10;
if( dwWaitTime < 1000 )
dwWaitTime = 1000;
else if ( dwWaitTime > 5000 )
dwWaitTime = 5000;
Sleep( dwWaitTime );
// Check the status again.
if (!QueryServiceStatus(
schService, // handle to service
&ssStatus) ) // address of structure
break;
if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
{
// The service is making progress.
dwStartTickCount = GetTickCount();
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
{
// No progress made within the wait hint
break;
}
}
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
if (ssStatus.dwCurrentState != SERVICE_RUNNING)
{
/* service hasn't started */
ShowLocalizedMsg(GUI_NAME, ERR_SERVICE_START_FAILED, "");
goto failed;
}
/* Run Connect script */
for (i=0; i<o.num_configs; i++)
RunConnectScript(i, true);
/* Set Service Status = Connected */
o.service_running = SERVICE_CONNECTED;
SetServiceMenuStatus();
CheckAndSetTrayIcon();
/* Show "OpenVPN Service Started" Tray Balloon msg */
myLoadString(INFO_SERVICE_STARTED);
mysnprintf(msg," ");
ShowTrayBalloon(buf, msg);
return(true);
failed:
/* Set Service Status = Disconnecting */
o.service_running = SERVICE_DISCONNECTED;
SetServiceMenuStatus();
CheckAndSetTrayIcon();
return(false);
}
int MyStopService()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
SERVICE_STATUS ssStatus;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;
int i;
// Open a handle to the SC Manager database.
schSCManager = OpenSCManager(
NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_CONNECT); // Connect rights
if (NULL == schSCManager) {
/* can't open SCManager */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_SCMGR, (int) GetLastError());
return(false);
}
schService = OpenService(
schSCManager, // SCM database
"OpenVPNService", // service name
SERVICE_STOP);
if (schService == NULL) {
/* can't open vpn service */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_VPN_SERVICE, "");
return(false);
}
/* Run DisConnect script */
for (i=0; i<o.num_configs; i++)
RunDisconnectScript(i, true);
if (!ControlService(
schService, // handle to service
SERVICE_CONTROL_STOP, // control value to send
&ssStatus) ) // address of status info
{
/* stop failed */
ShowLocalizedMsg(GUI_NAME, ERR_STOP_SERVICE, "");
return(false);
}
o.service_running = SERVICE_DISCONNECTED;
SetServiceMenuStatus();
CheckAndSetTrayIcon();
return(true);
}
int MyReStartService()
{
MyStopService();
Sleep(1000);
if (MyStartService()) {
return(true);
}
return(false);
}
int CheckServiceStatus()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
SERVICE_STATUS ssStatus;
DWORD dwOldCheckPoint;
DWORD dwStartTickCount;
DWORD dwWaitTime;
// Open a handle to the SC Manager database.
schSCManager = OpenSCManager(
NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_CONNECT); // Connect rights
if (NULL == schSCManager) {
o.service_running = SERVICE_NOACCESS;
SetServiceMenuStatus();
return(false);
}
schService = OpenService(
schSCManager, // SCM database
"OpenVPNService", // service name
SERVICE_QUERY_STATUS);
if (schService == NULL) {
/* open vpn service failed */
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_VPN_SERVICE, "");
o.service_running = SERVICE_NOACCESS;
SetServiceMenuStatus();
return(false);
}
if (!QueryServiceStatus(
schService, // handle to service
&ssStatus) ) // address of status information structure
{
/* query failed */
ShowLocalizedMsg(GUI_NAME, ERR_QUERY_SERVICE, "");
return(false);
}
if (ssStatus.dwCurrentState == SERVICE_RUNNING)
{
o.service_running = SERVICE_CONNECTED;
SetServiceMenuStatus();
SetTrayIcon(CONNECTED);
return(true);
}
else
{
o.service_running = SERVICE_DISCONNECTED;
SetServiceMenuStatus();
SetTrayIcon(DISCONNECTED);
return(false);
}
}

25
service.h Normal file
View File

@ -0,0 +1,25 @@
/*
* 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
*/
int MyStartService();
int MyStopService();
int MyReStartService();
int CheckServiceStatus();

326
shellapi.h Normal file
View File

@ -0,0 +1,326 @@
#ifndef _SHELLAPI_H
#define _SHELLAPI_H
#if __GNUC__ >= 3
#pragma GCC system_header
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define WINSHELLAPI DECLSPEC_IMPORT
#define ABE_LEFT 0
#define ABE_TOP 1
#define ABE_RIGHT 2
#define ABE_BOTTOM 3
#define ABS_AUTOHIDE 1
#define ABS_ALWAYSONTOP 2
#define SEE_MASK_CLASSNAME 1
#define SEE_MASK_CLASSKEY 3
#define SEE_MASK_IDLIST 4
#define SEE_MASK_INVOKEIDLIST 12
#define SEE_MASK_ICON 0x10
#define SEE_MASK_HOTKEY 0x20
#define SEE_MASK_NOCLOSEPROCESS 0x40
#define SEE_MASK_CONNECTNETDRV 0x80
#define SEE_MASK_FLAG_DDEWAIT 0x100
#define SEE_MASK_DOENVSUBST 0x200
#define SEE_MASK_FLAG_NO_UI 0x400
#define SEE_MASK_NO_CONSOLE 0x8000
#define SEE_MASK_UNICODE 0x10000
#define SEE_MASK_ASYNCOK 0x100000
#define SEE_MASK_HMONITOR 0x200000
#define ABM_NEW 0
#define ABM_REMOVE 1
#define ABM_QUERYPOS 2
#define ABM_SETPOS 3
#define ABM_GETSTATE 4
#define ABM_GETTASKBARPOS 5
#define ABM_ACTIVATE 6
#define ABM_GETAUTOHIDEBAR 7
#define ABM_SETAUTOHIDEBAR 8
#define ABM_WINDOWPOSCHANGED 9
#define ABN_STATECHANGE 0
#define ABN_POSCHANGED 1
#define ABN_FULLSCREENAPP 2
#define ABN_WINDOWARRANGE 3
#define NIM_ADD 0
#define NIM_MODIFY 1
#define NIM_DELETE 2
#if _WIN32_IE >= 0x0500
#define NOTIFYICON_VERSION 3
#define NIM_SETFOCUS 3
#define NIM_SETVERSION 4
#endif
#define NIF_MESSAGE 1
#define NIF_ICON 2
#define NIF_TIP 4
#define NIF_STATE 8
#define NIS_HIDDEN 1
#define NIS_SHAREDICON 2
#define SE_ERR_FNF 2
#define SE_ERR_PNF 3
#define SE_ERR_ACCESSDENIED 5
#define SE_ERR_OOM 8
#define SE_ERR_DLLNOTFOUND 32
#define SE_ERR_SHARE 26
#define SE_ERR_ASSOCINCOMPLETE 27
#define SE_ERR_DDETIMEOUT 28
#define SE_ERR_DDEFAIL 29
#define SE_ERR_DDEBUSY 30
#define SE_ERR_NOASSOC 31
#define FO_MOVE 1
#define FO_COPY 2
#define FO_DELETE 3
#define FO_RENAME 4
#define FOF_MULTIDESTFILES 1
#define FOF_CONFIRMMOUSE 2
#define FOF_SILENT 4
#define FOF_RENAMEONCOLLISION 8
#define FOF_NOCONFIRMATION 16
#define FOF_WANTMAPPINGHANDLE 32
#define FOF_ALLOWUNDO 64
#define FOF_FILESONLY 128
#define FOF_SIMPLEPROGRESS 256
#define FOF_NOCONFIRMMKDIR 512
#define FOF_NOERRORUI 1024
#define FOF_NOCOPYSECURITYATTRIBS 2048
#define PO_DELETE 19
#define PO_RENAME 20
#define PO_PORTCHANGE 32
#define PO_REN_PORT 52
#define SHGFI_ICON 256
#define SHGFI_DISPLAYNAME 512
#define SHGFI_TYPENAME 1024
#define SHGFI_ATTRIBUTES 2048
#define SHGFI_ICONLOCATION 4096
#define SHGFI_EXETYPE 8192
#define SHGFI_SYSICONINDEX 16384
#define SHGFI_LINKOVERLAY 32768
#define SHGFI_SELECTED 65536
#define SHGFI_ATTR_SPECIFIED 131072
#define SHGFI_LARGEICON 0
#define SHGFI_SMALLICON 1
#define SHGFI_OPENICON 2
#define SHGFI_SHELLICONSIZE 4
#define SHGFI_PIDL 8
#define SHGFI_USEFILEATTRIBUTES 16
#define SHERB_NOCONFIRMATION 1
#define SHERB_NOPROGRESSUI 2
#define SHERB_NOSOUND 4
typedef WORD FILEOP_FLAGS;
typedef WORD PRINTEROP_FLAGS;
#include <pshpack2.h>
typedef struct _AppBarData {
DWORD cbSize;
HWND hWnd;
UINT uCallbackMessage;
UINT uEdge;
RECT rc;
LPARAM lParam;
} APPBARDATA,*PAPPBARDATA;
DECLARE_HANDLE(HDROP);
typedef struct _NOTIFYICONDATAA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if _WIN32_IE >= 0x0500
CHAR szTip[128];
DWORD dwState;
DWORD dwStateMask;
CHAR szInfo[256];
_ANONYMOUS_UNION union {
UINT uTimeout;
UINT uVersion;
} DUMMYUNIONNAME;
CHAR szInfoTitle[64];
DWORD dwInfoFlags;
#else
CHAR szTip[64];
#endif
#if _WIN32_IE >= 0x600
GUID guidItem;
#endif
} NOTIFYICONDATAA,*PNOTIFYICONDATAA;
typedef struct _NOTIFYICONDATAW {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if _WIN32_IE >= 0x0500
WCHAR szTip[128];
DWORD dwState;
DWORD dwStateMask;
WCHAR szInfo[256];
_ANONYMOUS_UNION union {
UINT uTimeout;
UINT uVersion;
} DUMMYUNIONNAME;
WCHAR szInfoTitle[64];
DWORD dwInfoFlags;
#else
WCHAR szTip[64];
#endif
#if _WIN32_IE >= 0x600
GUID guidItem;
#endif
} NOTIFYICONDATAW,*PNOTIFYICONDATAW;
typedef struct _SHELLEXECUTEINFOA {
DWORD cbSize;
ULONG fMask;
HWND hwnd;
LPCSTR lpVerb;
LPCSTR lpFile;
LPCSTR lpParameters;
LPCSTR lpDirectory;
int nShow;
HINSTANCE hInstApp;
PVOID lpIDList;
LPCSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
HANDLE hIcon;
HANDLE hProcess;
} SHELLEXECUTEINFOA,*LPSHELLEXECUTEINFOA;
typedef struct _SHELLEXECUTEINFOW {
DWORD cbSize;
ULONG fMask;
HWND hwnd;
LPCWSTR lpVerb;
LPCWSTR lpFile;
LPCWSTR lpParameters;
LPCWSTR lpDirectory;
int nShow;
HINSTANCE hInstApp;
PVOID lpIDList;
LPCWSTR lpClass;
HKEY hkeyClass;
DWORD dwHotKey;
HANDLE hIcon;
HANDLE hProcess;
} SHELLEXECUTEINFOW,*LPSHELLEXECUTEINFOW;
typedef struct _SHFILEOPSTRUCTA {
HWND hwnd;
UINT wFunc;
LPCSTR pFrom;
LPCSTR pTo;
FILEOP_FLAGS fFlags;
BOOL fAnyOperationsAborted;
PVOID hNameMappings;
LPCSTR lpszProgressTitle;
} SHFILEOPSTRUCTA,*LPSHFILEOPSTRUCTA;
typedef struct _SHFILEOPSTRUCTW {
HWND hwnd;
UINT wFunc;
LPCWSTR pFrom;
LPCWSTR pTo;
FILEOP_FLAGS fFlags;
BOOL fAnyOperationsAborted;
PVOID hNameMappings;
LPCWSTR lpszProgressTitle;
} SHFILEOPSTRUCTW,*LPSHFILEOPSTRUCTW;
typedef struct _SHFILEINFOA {
HICON hIcon;
int iIcon;
DWORD dwAttributes;
CHAR szDisplayName[MAX_PATH];
CHAR szTypeName[80];
} SHFILEINFOA;
typedef struct _SHFILEINFOW {
HICON hIcon;
int iIcon;
DWORD dwAttributes;
WCHAR szDisplayName[MAX_PATH];
WCHAR szTypeName[80];
} SHFILEINFOW;
typedef struct _SHQUERYRBINFO {
DWORD cbSize;
__int64 i64Size;
__int64 i64NumItems;
} SHQUERYRBINFO, *LPSHQUERYRBINFO;
#include <poppack.h>
LPWSTR * WINAPI CommandLineToArgvW(LPCWSTR,int*);
void WINAPI DragAcceptFiles(HWND,BOOL);
void WINAPI DragFinish(HDROP);
UINT WINAPI DragQueryFileA(HDROP,UINT,LPSTR,UINT);
UINT WINAPI DragQueryFileW(HDROP,UINT,LPWSTR,UINT);
BOOL WINAPI DragQueryPoint(HDROP,LPPOINT);
HICON WINAPI DuplicateIcon(HINSTANCE,HICON);
HICON WINAPI ExtractAssociatedIconA(HINSTANCE,LPCSTR,PWORD);
HICON WINAPI ExtractAssociatedIconW(HINSTANCE,LPCWSTR,PWORD);
HICON WINAPI ExtractIconA(HINSTANCE,LPCSTR,UINT);
HICON WINAPI ExtractIconW(HINSTANCE,LPCWSTR,UINT);
UINT WINAPI ExtractIconExA(LPCSTR,int,HICON*,HICON*,UINT);
UINT WINAPI ExtractIconExW(LPCWSTR,int,HICON*,HICON*,UINT);
HINSTANCE WINAPI FindExecutableA(LPCSTR,LPCSTR,LPSTR);
HINSTANCE WINAPI FindExecutableW(LPCWSTR,LPCWSTR,LPWSTR);
UINT WINAPI SHAppBarMessage(DWORD,PAPPBARDATA);
BOOL WINAPI Shell_NotifyIconA(DWORD,PNOTIFYICONDATAA);
BOOL WINAPI Shell_NotifyIconW(DWORD,PNOTIFYICONDATAW);
int WINAPI ShellAboutA(HWND,LPCSTR,LPCSTR,HICON);
int WINAPI ShellAboutW(HWND,LPCWSTR,LPCWSTR,HICON);
HINSTANCE WINAPI ShellExecuteA(HWND,LPCSTR,LPCSTR,LPCSTR,LPCSTR,INT);
HINSTANCE WINAPI ShellExecuteW(HWND,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,INT);
BOOL WINAPI ShellExecuteExA(LPSHELLEXECUTEINFOA);
BOOL WINAPI ShellExecuteExW(LPSHELLEXECUTEINFOW);
int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA);
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW);
void WINAPI SHFreeNameMappings(HANDLE);
DWORD WINAPI SHGetFileInfoA(LPCSTR,DWORD,SHFILEINFOA*,UINT,UINT);
DWORD WINAPI SHGetFileInfoW(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
HRESULT WINAPI SHQueryRecycleBinA(LPCSTR, LPSHQUERYRBINFO);
HRESULT WINAPI SHQueryRecycleBinW(LPCWSTR, LPSHQUERYRBINFO);
HRESULT WINAPI SHEmptyRecycleBinA(HWND,LPCSTR,DWORD);
HRESULT WINAPI SHEmptyRecycleBinW(HWND,LPCWSTR,DWORD);
#ifdef UNICODE
typedef NOTIFYICONDATAW NOTIFYICONDATA,*PNOTIFYICONDATA;
typedef SHELLEXECUTEINFOW SHELLEXECUTEINFO,*LPSHELLEXECUTEINFO;
typedef SHFILEOPSTRUCTW SHFILEOPSTRUCT,*LPSHFILEOPSTRUCT;
typedef SHFILEINFOW SHFILEINFO;
#define DragQueryFile DragQueryFileW
#define ExtractAssociatedIcon ExtractAssociatedIconW
#define ExtractIcon ExtractIconW
#define ExtractIconEx ExtractIconExW
#define FindExecutable FindExecutableW
#define Shell_NotifyIcon Shell_NotifyIconW
#define ShellAbout ShellAboutW
#define ShellExecute ShellExecuteW
#define ShellExecuteEx ShellExecuteExW
#define SHFileOperation SHFileOperationW
#define SHGetFileInfo SHGetFileInfoW
#define SHQueryRecycleBin SHQueryRecycleBinW
#define SHEmptyRecycleBin SHEmptyRecycleBinW
#else
typedef NOTIFYICONDATAA NOTIFYICONDATA,*PNOTIFYICONDATA;
typedef SHELLEXECUTEINFOA SHELLEXECUTEINFO,*LPSHELLEXECUTEINFO;
typedef SHFILEOPSTRUCTA SHFILEOPSTRUCT,*LPSHFILEOPSTRUCT;
typedef SHFILEINFOA SHFILEINFO;
#define DragQueryFile DragQueryFileA
#define ExtractAssociatedIcon ExtractAssociatedIconA
#define ExtractIcon ExtractIconA
#define ExtractIconEx ExtractIconExA
#define FindExecutable FindExecutableA
#define Shell_NotifyIcon Shell_NotifyIconA
#define ShellAbout ShellAboutA
#define ShellExecute ShellExecuteA
#define ShellExecuteEx ShellExecuteExA
#define SHFileOperation SHFileOperationA
#define SHGetFileInfo SHGetFileInfoA
#define SHQueryRecycleBin SHQueryRecycleBinA
#define SHEmptyRecycleBin SHEmptyRecycleBinA
#endif
#ifdef __cplusplus
}
#endif
#endif

591
tray.c Normal file
View File

@ -0,0 +1,591 @@
/*
* 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
*/
#define _WIN32_IE 0x0500
#define NIF_INFO 0x00000010
// Notify Icon Infotip flags
#define NIIF_NONE 0x00000000
// icon flags are mutually exclusive
// and take only the lowest 2 bits
#define NIIF_INFO 0x00000001
#define NIIF_WARNING 0x00000002
#define NIIF_ERROR 0x00000003
#define NIIF_ICON_MASK 0x0000000F
#include <windows.h>
#include <time.h>
#include "tray.h"
#include "service.h"
#include "shellapi.h"
#include "main.h"
#include "options.h"
#include "openvpn.h"
#include "openvpn_config.h"
#include "openvpn-gui-res.h"
//POPUP MENU
HMENU hMenu;
HMENU hMenuConn[MAX_CONFIGS];
HMENU hMenuService;
NOTIFYICONDATA ni;
extern struct options o;
// Mouse clicks on tray
void OnNotifyTray(LPARAM lParam)
{
POINT pt; // point structure
int connected_config;
int i;
TCHAR buf[1000];
// Right click, show the menu
switch(lParam) {
case WM_RBUTTONDOWN:
/* Re-read configs and re-create menus if no connection is running */
if (CountConnectedState(DISCONNECTED) == o.num_configs)
{
DestroyPopupMenus();
BuildFileList();
CreatePopupMenus();
}
GetCursorPos(&pt); // get the cursors position
SetForegroundWindow(o.hWnd); // set the foreground window
TrackPopupMenu(hMenu,TPM_RIGHTALIGN,pt.x,pt.y,0,o.hWnd,NULL);// track the popup
break;
case WM_LBUTTONDOWN:
break;
case WM_LBUTTONDBLCLK:
if (o.service_only[0]=='1')
{
/* Start OpenVPN Service */
if (o.service_running == SERVICE_DISCONNECTED)
{
MyStartService();
}
else if (o.service_running == SERVICE_CONNECTED)
{
/* Stop OpenVPN service */
myLoadString(IDM_TEXT_ASK_STOP_SERVICE);
if (MessageBox(NULL, buf, GUI_NAME, MB_YESNO | MB_SETFOREGROUND) == IDYES)
{
MyStopService();
}
}
}
else
{
/* Open Status window if only one connection is running */
connected_config = -1;
for (i=0; i < o.num_configs; i++)
{
if(o.cnn[i].connect_status != DISCONNECTED)
{
if (connected_config == -1)
{
connected_config = i;
}
else
{
connected_config = -1;
break;
}
}
}
if (connected_config != -1)
{
ShowWindow(o.cnn[connected_config].hwndStatus, SW_SHOW);
SetForegroundWindow(o.cnn[connected_config].hwndStatus);
}
/* Re-read configs and re-create menus if no connection is running */
if (CountConnectedState(DISCONNECTED) == o.num_configs)
{
DestroyPopupMenus();
BuildFileList();
CreatePopupMenus();
/* Start connection if only one config exist */
if ((o.num_configs == 1) && (o.cnn[0].connect_status == DISCONNECTED))
StartOpenVPN(0);
}
}
break;
}
PostMessage(o.hWnd,WM_NULL,0,0);// post a null message
}
void OnDestroyTray()
{
//Destroy popup menu
DestroyMenu(hMenu);
//Remove Icon from Tray
Shell_NotifyIcon(NIM_DELETE, &ni);
}
/* Create Popup Menus */
void CreatePopupMenus()
{
int i;
//extern struct options o;
/* Create Main menu */
hMenu=CreatePopupMenu();
/* Create a menu for every config */
for (i=0; i < o.num_configs; i++)
hMenuConn[i]=CreatePopupMenu();
/* Create the Service Menu */
hMenuService=CreatePopupMenu();
/* Put something on the menus */
CreateItemList(hMenu);
}
/* Destroy Popup Menus */
void DestroyPopupMenus()
{
int i;
/* Destroy Main menu */
DestroyMenu(hMenu);
/* Destroy all config submenus */
for (i=0; i < o.num_configs; i++)
DestroyMenu(hMenuConn[i]);
/* Destroy the Service Menu */
DestroyMenu(hMenuService);
}
void CreateItemList()
{
extern char ext_string[];
extern char allow_edit[2];
extern char allow_service[2];
int i;
TCHAR buf[1000];
if (o.num_configs == 1)
{
/* Create Main menu with actions */
if (o.service_only[0]=='0')
{
myLoadString(IDM_TEXT_CONNECT);
AppendMenu(hMenu,MF_STRING, IDM_CONNECTMENU, buf);
myLoadString(IDM_TEXT_DISCONNECT);
AppendMenu(hMenu,MF_STRING, IDM_DISCONNECTMENU, buf);
myLoadString(IDM_TEXT_STATUS);
AppendMenu(hMenu,MF_STRING, IDM_STATUSMENU, buf);
AppendMenu(hMenu,MF_SEPARATOR,0,0);
}
else
{
myLoadString(IDM_TEXT_SERVICEONLY_START);
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_START, buf);
myLoadString(IDM_TEXT_SERVICEONLY_STOP);
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_STOP, buf);
myLoadString(IDM_TEXT_SERVICEONLY_RESTART);
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_RESTART, buf);
AppendMenu(hMenu,MF_SEPARATOR,0,0);
}
myLoadString(IDM_TEXT_VIEWLOG);
AppendMenu(hMenu,MF_STRING, IDM_VIEWLOGMENU, buf);
if (o.allow_edit[0]=='1')
{
myLoadString(IDM_TEXT_EDITCONFIG);
AppendMenu(hMenu,MF_STRING, IDM_EDITMENU, buf);
}
#ifndef DISABLE_CHANGE_PASSWORD
if (o.allow_password[0]=='1')
{
myLoadString(IDM_TEXT_PASSPHRASE);
AppendMenu(hMenu,MF_STRING, IDM_PASSPHRASEMENU, buf);
}
#endif
AppendMenu(hMenu,MF_SEPARATOR,0,0);
if (o.allow_service[0]=='1' && o.service_only[0]=='0')
{
myLoadString(IDM_TEXT_SERVICE);
AppendMenu(hMenu,MF_POPUP,(UINT) hMenuService, buf);
AppendMenu(hMenu,MF_SEPARATOR,0,0);
}
if (o.allow_proxy[0]=='1' && o.service_only[0]=='0')
{
myLoadString(IDM_TEXT_PROXY);
AppendMenu(hMenu,MF_STRING ,IDM_PROXY, buf);
AppendMenu(hMenu,MF_SEPARATOR,0,0);
}
myLoadString(IDM_TEXT_ABOUT);
AppendMenu(hMenu,MF_STRING ,IDM_ABOUT, buf);
myLoadString(IDM_TEXT_CLOSE);
AppendMenu(hMenu,MF_STRING ,IDM_CLOSE, buf);
SetMenuStatus(0, DISCONNECTED);
}
else
{
/* Create Main menu with all connections */
for (i=0; i < o.num_configs; i++)
AppendMenu(hMenu,MF_POPUP,(UINT) hMenuConn[i],o.cnn[i].config_name);
if (o.num_configs > 0)
AppendMenu(hMenu,MF_SEPARATOR,0,0);
if (o.allow_service[0]=='1' && o.service_only[0]=='0')
{
myLoadString(IDM_TEXT_SERVICE);
AppendMenu(hMenu,MF_POPUP,(UINT) hMenuService, buf);
AppendMenu(hMenu,MF_SEPARATOR,0,0);
}
if (o.service_only[0]=='1')
{
myLoadString(IDM_TEXT_SERVICEONLY_START);
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_START, buf);
myLoadString(IDM_TEXT_SERVICEONLY_STOP);
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_STOP, buf);
myLoadString(IDM_TEXT_SERVICEONLY_RESTART);
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_RESTART, buf);
AppendMenu(hMenu,MF_SEPARATOR,0,0);
}
if (o.allow_proxy[0]=='1' && o.service_only[0]=='0')
{
myLoadString(IDM_TEXT_PROXY);
AppendMenu(hMenu,MF_STRING ,IDM_PROXY, buf);
AppendMenu(hMenu,MF_SEPARATOR,0,0);
}
myLoadString(IDM_TEXT_ABOUT);
AppendMenu(hMenu,MF_STRING ,IDM_ABOUT, buf);
myLoadString(IDM_TEXT_CLOSE);
AppendMenu(hMenu,MF_STRING ,IDM_CLOSE, buf);
/* Create PopUp menus for every connection */
for (i=0; i < o.num_configs; i++)
{
if (o.service_only[0]=='0')
{
myLoadString(IDM_TEXT_CONNECT);
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_CONNECTMENU+i, buf);
myLoadString(IDM_TEXT_DISCONNECT);
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_DISCONNECTMENU+i, buf);
myLoadString(IDM_TEXT_STATUS);
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_STATUSMENU+i, buf);
AppendMenu(hMenuConn[i],MF_SEPARATOR,0,0);
}
myLoadString(IDM_TEXT_VIEWLOG);
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_VIEWLOGMENU+i, buf);
if (o.allow_edit[0]=='1') {
myLoadString(IDM_TEXT_EDITCONFIG);
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_EDITMENU+i, buf);
}
#ifndef DISABLE_CHANGE_PASSWORD
if (o.allow_password[0]=='1')
{
myLoadString(IDM_TEXT_PASSPHRASE);
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_PASSPHRASEMENU+i, buf);
}
#endif
SetMenuStatus(i, DISCONNECTED);
}
}
/* Create Service menu */
if (o.allow_service[0]=='1' && o.service_only[0]=='0')
{
myLoadString(IDM_TEXT_SERVICE_START);
AppendMenu(hMenuService,MF_STRING, IDM_SERVICE_START, buf);
myLoadString(IDM_TEXT_SERVICE_STOP);
AppendMenu(hMenuService,MF_STRING, IDM_SERVICE_STOP, buf);
myLoadString(IDM_TEXT_SERVICE_RESTART);
AppendMenu(hMenuService,MF_STRING, IDM_SERVICE_RESTART, buf);
}
SetServiceMenuStatus();
}
BOOL LoadAppIcon()
{
// Load icon from resource
HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(APP_ICON),
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
if (hIcon) {
SendMessage(o.hWnd, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
SendMessage(o.hWnd, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); //ALT+TAB icon
return TRUE;
}
return FALSE;
}
void ShowTrayIcon()
{
TCHAR buf[1000];
ni.cbSize = sizeof(ni);
ni.uID = 0;
myLoadString(MSG_TIP);
lstrcpyn(ni.szTip, buf, sizeof(ni.szTip));
ni.hWnd = o.hWnd;
ni.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON; // We want to use icon, tip, and callback message
ni.uCallbackMessage = WM_NOTIFYICONTRAY; // Our custom callback message (WM_APP + 1)
//Load selected icon
ni.hIcon = (HICON)LoadIcon(o.hInstance, MAKEINTRESOURCE(APP_ICON_DISCONNECTED));
Shell_NotifyIcon(NIM_ADD, &ni);
}
/* SetTrayIcon(int connected)
* connected=0 -> DisConnected
* connected=1 -> Connecting
* connected=2 -> Connected
*/
void SetTrayIcon(int connected)
{
char msg[500];
char msg_connected[100];
char msg_connecting[100];
char conn_name[200];
char connected_since[50];
int i, first_conn;
int config=0;
TCHAR buf[1000];
ni.cbSize = sizeof(ni);
ni.uID = 0;
ni.hWnd = o.hWnd;
ni.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON; // We want to use icon, tip, and callback message
ni.uCallbackMessage = WM_NOTIFYICONTRAY; // Our custom callback message (WM_APP + 1)
myLoadString(MSG_TIP);
strncpy(msg, buf, sizeof(ni.szTip));
myLoadString(MSG_TIP_CONNECTED);
strncpy(msg_connected, buf, sizeof(msg_connected));
myLoadString(MSG_TIP_CONNECTING);
strncpy(msg_connecting, buf, sizeof(msg_connecting));
first_conn=1;
for (i=0; i < o.num_configs; i++)
{
if(o.cnn[i].connect_status == CONNECTED)
{
/* Append connection name to Icon Tip Msg */
if (first_conn)
strncat(msg, msg_connected, sizeof(msg) - strlen(msg) - 1);
else
strncat(msg, ", ", sizeof(msg) - strlen(msg) - 1);
strncat(msg, o.cnn[i].config_name, sizeof(msg) - strlen(msg) - 1);
first_conn=0;
config=i;
}
}
first_conn=1;
for (i=0; i < o.num_configs; i++)
{
if((o.cnn[i].connect_status == CONNECTING) ||
(o.cnn[i].connect_status == RECONNECTING))
{
/* Append connection name to Icon Tip Msg */
if (first_conn)
strncat(msg, msg_connecting, sizeof(msg) - strlen(msg) - 1);
else
strncat(msg, ", ", sizeof(msg) - strlen(msg) - 1);
strncat(msg, o.cnn[i].config_name, sizeof(msg) - strlen(msg) - 1);
first_conn=0;
}
}
if (CountConnectedState(CONNECTED) == 1)
{
/* Append "Connected Since and Assigned IP msg" */
time_t con_time;
con_time=time(NULL);
strftime(connected_since, sizeof(connected_since), "%b %d, %H:%M",
localtime(&o.cnn[config].connected_since));
myLoadString(MSG_TIP_CONNECTED_SINCE);
strncat(msg, buf, sizeof(msg) - strlen(msg) - 1);
strncat(msg, connected_since, sizeof(msg) - strlen(msg) - 1);
if (strlen(o.cnn[config].ip) > 0)
{
char assigned_ip[100];
myLoadString(MSG_TIP_ASSIGNED_IP);
mysnprintf(assigned_ip, buf, o.cnn[config].ip);
strncat(msg, assigned_ip, sizeof(msg) - strlen(msg) - 1);
}
}
strncpy(ni.szTip, msg, sizeof(ni.szTip));
//Load selected icon
if (connected==2)
ni.hIcon = (HICON)LoadIcon(o.hInstance, MAKEINTRESOURCE(APP_ICON_CONNECTED));
else if (connected==1)
ni.hIcon = (HICON)LoadIcon(o.hInstance, MAKEINTRESOURCE(APP_ICON_CONNECTING));
else if (connected==0)
ni.hIcon = (HICON)LoadIcon(o.hInstance, MAKEINTRESOURCE(APP_ICON_DISCONNECTED));
Shell_NotifyIcon(NIM_MODIFY, &ni);
}
void ShowTrayBalloon(char *infotitle_msg, char *info_msg)
{
ni.cbSize = sizeof(ni);
ni.uID = 0;
ni.hWnd = o.hWnd;
ni.uFlags = NIF_INFO; /* We want to show a balloon */
ni.uTimeout = 5000;
ni.dwInfoFlags = NIIF_INFO; /* Show an Info Icon */
strncpy(ni.szInfo, info_msg, sizeof(ni.szInfo));
strncpy(ni.szInfoTitle, infotitle_msg, sizeof(ni.szInfoTitle));
Shell_NotifyIcon(NIM_MODIFY, &ni);
}
void SetMenuStatus (int config, int bCheck)
{
/* bCheck values:
* 0 - Not Connected
* 1 - Connecting
* 2 - Connected
* 4 - Disconnecting
*/
unsigned int iState;
if (o.num_configs == 1)
{
if (bCheck == DISCONNECTED)
{
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_GRAYED);
}
if (bCheck == CONNECTING)
{
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
}
if (bCheck == CONNECTED)
{
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_ENABLED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
}
if (bCheck == DISCONNECTING)
{
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED);
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
}
}
else
{
iState = ((bCheck == CONNECTED) || (bCheck == DISCONNECTING)) ?
MF_CHECKED : MF_UNCHECKED ;
CheckMenuItem (hMenu, (UINT) hMenuConn[config], iState) ;
if (bCheck == 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);
}
if (bCheck == CONNECTING)
{
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);
}
if (bCheck == 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);
}
if (bCheck == 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);
}
}
}
void SetServiceMenuStatus()
{
HMENU hMenuHandle;
if (o.allow_service[0]=='0' && o.service_only[0]=='0')
return;
if (o.service_only[0]=='1')
hMenuHandle = hMenu;
else
hMenuHandle = hMenuService;
if ((o.service_running == SERVICE_NOACCESS) ||
(o.service_running == SERVICE_CONNECTING))
{
/* Service is disabled */
EnableMenuItem(hMenuHandle, IDM_SERVICE_START, MF_GRAYED);
EnableMenuItem(hMenuHandle, IDM_SERVICE_STOP, MF_GRAYED);
EnableMenuItem(hMenuHandle, IDM_SERVICE_RESTART, MF_GRAYED);
}
else if (o.service_running == SERVICE_CONNECTED)
{
/* Service is running */
EnableMenuItem(hMenuHandle, IDM_SERVICE_START, MF_GRAYED);
EnableMenuItem(hMenuHandle, IDM_SERVICE_STOP, MF_ENABLED);
EnableMenuItem(hMenuHandle, IDM_SERVICE_RESTART, MF_ENABLED);
}
else
{
/* Service is not running */
EnableMenuItem(hMenuHandle, IDM_SERVICE_START, MF_ENABLED);
EnableMenuItem(hMenuHandle, IDM_SERVICE_STOP, MF_GRAYED);
EnableMenuItem(hMenuHandle, IDM_SERVICE_RESTART, MF_GRAYED);
}
}

61
tray.h Normal file
View File

@ -0,0 +1,61 @@
/*
* 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
*/
#define WM_NOTIFYICONTRAY (WM_APP + 1)
//Popup Menu items
#define IDM_PROXY 221
#define IDM_ABOUT 222
#define IDM_CLOSE 223
#define IDM_TEXT_CONN1 "Office"
#define IDM_CONN1 301
#define IDM_TEXT_CONN2 "Home"
#define IDM_CONN2 302
#define IDM_CONNECTMENU 300
#define IDM_DISCONNECTMENU 400
#define IDM_STATUSMENU 500
#define IDM_VIEWLOGMENU 600
#define IDM_EDITMENU 700
#define IDM_PASSPHRASEMENU 800
/* Service submenu */
#define IDM_SERVICEMENU 900
#define IDM_SERVICE_START 901
#define IDM_SERVICE_STOP 902
#define IDM_SERVICE_RESTART 903
void CreatePopupMenus(); //Create popup menus
void DestroyPopupMenus(); //Destroy popup menus
void OnNotifyTray(LPARAM lParam); //Tray message (mouse clicks on tray icon)
void OnDestroyTray(void); //WM_DESTROY message
void ShowTrayIcon(); //Put app icon in systray
void SetTrayIcon(int connected); //Change systray icon
BOOL LoadAppIcon(); //Application icon
void CreateItemList(); //Crate Popup menu
void SetMenuStatus (int config, int bCheck); //Mark connection as connected/disconnected
void SetServiceMenuStatus(); //Diabled Service menu items.
void ShowTrayBalloon(char *infotitle_msg, char *info_msg);

121
viewlog.c Normal file
View File

@ -0,0 +1,121 @@
/*
* 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
*/
#include <windows.h>
#include "tray.h"
#include "openvpn.h"
#include <stdio.h>
#include "main.h"
#include "options.h"
#include "openvpn-gui-res.h"
extern struct options o;
void ViewLog(int config)
{
char filename[200];
extern char log_viewer[MAX_PATH];
extern char log_dir[MAX_PATH];
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
char command_line[256];
CLEAR (start_info);
CLEAR (proc_info);
CLEAR (sa);
CLEAR (sd);
mysnprintf(filename, "%s \"%s\"", o.log_viewer, o.cnn[config].log_path);
/* fill in STARTUPINFO struct */
GetStartupInfo(&start_info);
start_info.cb = sizeof(start_info);
start_info.dwFlags = 0;
start_info.wShowWindow = SW_SHOWDEFAULT;
start_info.hStdInput = NULL;
start_info.hStdOutput = NULL;
if (!CreateProcess(NULL,
filename, //commandline
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
o.log_dir, //start-up dir
&start_info,
&proc_info))
{
/* could not start log viewer */
ShowLocalizedMsg(GUI_NAME, ERR_START_LOG_VIEWER, o.log_viewer);
}
}
void EditConfig(int config)
{
char filename[200];
extern char config_dir[MAX_PATH];
extern char editor[MAX_PATH];
STARTUPINFO start_info;
PROCESS_INFORMATION proc_info;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
char command_line[256];
CLEAR (start_info);
CLEAR (proc_info);
CLEAR (sa);
CLEAR (sd);
mysnprintf(filename, "%s \"%s\\%s\"", o.editor, o.cnn[config].config_dir, o.cnn[config].config_file);
/* fill in STARTUPINFO struct */
GetStartupInfo(&start_info);
start_info.cb = sizeof(start_info);
start_info.dwFlags = 0;
start_info.wShowWindow = SW_SHOWDEFAULT;
start_info.hStdInput = NULL;
start_info.hStdOutput = NULL;
if (!CreateProcess(NULL,
filename, //commandline
NULL,
NULL,
TRUE,
CREATE_NEW_CONSOLE,
NULL,
o.cnn[config].config_dir, //start-up dir
&start_info,
&proc_info))
{
/* could not start editor */
ShowLocalizedMsg(GUI_NAME, ERR_START_CONF_EDITOR, o.editor);
}
}

23
viewlog.h Normal file
View File

@ -0,0 +1,23 @@
/*
* 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 ViewLog(int config);
void EditConfig(int config);