├── .gitignore
├── fwknop-gui.png
├── win32
├── fwknop-gui.ico
└── minimal.rc
├── MacOS
├── fwknop-gui.icns
└── MacOSXBundleInfo.plist.in
├── fwknop-gui.desktop
├── Changes
├── cmake
└── Modules
│ ├── FindLibFko.cmake
│ ├── FindLibQrencode.cmake
│ └── FindGpgme.cmake
├── rc_export.h
├── fwknop-gui.appdata.xml
├── fwknop-gui.8.asciidoc
├── help.html
├── qr_export.h
├── fwknop_guiApp.cpp
├── general_config.h
├── timer.h
├── fwknop_guiApp.h
├── rc_import.h
├── gpgme_wrapper.h
├── wizard.h
├── README.md
├── configs.h
├── qr_export.cpp
├── timer.cpp
├── CMakeLists.txt
├── general_config.cpp
├── wizard.cpp
├── rc_export.cpp
├── fwknop_guiMain.h
├── rc_import.cpp
├── gpgme_wrapper.cpp
├── configs.cpp
├── LICENSE
└── fwknop_guiMain.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore build directories
2 | build*
3 | bin
4 | obj
5 |
--------------------------------------------------------------------------------
/fwknop-gui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jp-bennett/fwknop-gui/HEAD/fwknop-gui.png
--------------------------------------------------------------------------------
/win32/fwknop-gui.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jp-bennett/fwknop-gui/HEAD/win32/fwknop-gui.ico
--------------------------------------------------------------------------------
/MacOS/fwknop-gui.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jp-bennett/fwknop-gui/HEAD/MacOS/fwknop-gui.icns
--------------------------------------------------------------------------------
/win32/minimal.rc:
--------------------------------------------------------------------------------
1 | a ICON "fwknop-gui.ico"
2 | #define wxUSE_NO_MANIFEST 0
3 | #include "wx/msw/wx.rc"
4 |
--------------------------------------------------------------------------------
/fwknop-gui.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Name=Fwknop-gui
3 | GenericName=fwknop-gui
4 | Keywords=SPA;client
5 | Comment=send spa packets
6 | Exec=fwknop-gui
7 | Icon=fwknop-gui
8 | Terminal=false
9 | Type=Application
10 | Categories=Network;
11 |
--------------------------------------------------------------------------------
/Changes:
--------------------------------------------------------------------------------
1 | New in V1.3.1
2 | Changes to the QR export feature, fixes a bug on some platforms where the QR
3 | code was truncated.
4 |
5 | New in V1.3
6 | A countdown timer that keeps track of how long the port will remain open
7 | The ability to automatically resend knocks to keep a port open
8 | GPG support
9 | .fwknoprc import and export
10 | An access.conf wizard
11 | QR code export
12 |
--------------------------------------------------------------------------------
/cmake/Modules/FindLibFko.cmake:
--------------------------------------------------------------------------------
1 | # Try to find Libfko
2 |
3 | find_path(LIBFKO_INCLUDE_DIR fko.h)
4 |
5 | find_library(LIBFKO_LIBRARY NAMES fko libfko)
6 |
7 | set(LIBFKO_LIBRARIES ${LIBFKO_LIBRARY} )
8 | set(LIBFKO_INCLUDE_DIRS ${LIBFKO_INCLUDE_DIR} )
9 |
10 | include(FindPackageHandleStandardArgs)
11 | find_package_handle_standard_args(LibFko DEFAULT_MSG
12 | LIBFKO_LIBRARY LIBFKO_INCLUDE_DIR)
13 |
14 | mark_as_advanced(LIBFKO_INCLUDE_DIR LIBFKO_LIBRARY )
15 |
--------------------------------------------------------------------------------
/rc_export.h:
--------------------------------------------------------------------------------
1 | /* rc_export.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header for rc_export.cpp
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include "configs.h"
22 |
23 | class rc_export : public wxDialog
24 | {
25 | public:
26 | rc_export(const wxString& title, const Config *selectedConfig);
27 |
28 | private:
29 | wxTextCtrl *tc;
30 | };
31 |
--------------------------------------------------------------------------------
/fwknop-gui.appdata.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | fwknop-gui.desktop
5 | CC0-1.0
6 | GPL-3.0+
7 | Fwknop-gui
8 | Sends SPA packets
9 |
10 |
11 | Fwknop-gui is a user-friendly gui interface for sending SPA packets,
12 | intended to talk the fwknop server application.
13 |
14 |
15 | Also supported is qr code exporting, and a rudimentary config wizard for fwknop.
16 |
17 |
18 |
19 |
20 | https://incomsystems.biz/fwknop-gui/media/fwknop-gui-screenshot1.png
21 |
22 |
23 | https://incomsystems.biz/fwknop-gui/media/fwknop-gui-screenshot2.png
24 |
25 |
26 | https://incomsystems.biz/fwknop-gui
27 | jbennett@incomsystems.biz
28 |
29 |
--------------------------------------------------------------------------------
/fwknop-gui.8.asciidoc:
--------------------------------------------------------------------------------
1 | :man source: Fwknop-gui Client
2 | :man manual: Fwknop-gui Client
3 |
4 | FWKNOP-GUI(8)
5 | =============
6 |
7 | NAME
8 | ----
9 | fwknop-gui - Firewall Knock Operator Graphical User Interface
10 |
11 |
12 | SYNOPSIS
13 | --------
14 | *fwknop-gui*
15 |
16 | DESCRIPTION
17 | -----------
18 | *fwknop-gui* is a graphical user interface integrated with an Fwknop
19 | client that provides the ability to send SPA packets to a remote
20 | Fwknop server, as well as a front-end for creating and managing
21 | client configurations for multiple Fwknop servers.
22 |
23 | It supports exporting saved configuration data to a QR code format
24 | readable by the Android client, as well as to the .fwknoprc format
25 | readable by the command line client.
26 |
27 | It supports AES and GPG encrypted SPA packets.
28 |
29 | BUGS
30 | ----
31 | To report a bug, please visit https://github.com/jp-bennett/fwknop-gui
32 |
33 | SEE ALSO
34 | --------
35 | fwknop(8), fwknopd(8)
36 |
37 | More information on Single Packet Authorization can be found in the paper
38 | ``Single Packet Authorization with fwknop'' available at
39 | 'http://www.cipherdyne.org/fwknop/docs/SPA.html'.
40 |
41 | AUTHORS
42 | -------
43 | The primary developer of *fwknop-gui* is Jonathan Bennett .
44 |
--------------------------------------------------------------------------------
/help.html:
--------------------------------------------------------------------------------
1 |
2 | Welcome to fwknop-gui! This app is for the sending of SPA Packets to a Linux host or router, mainly
3 | for opening ports in an iptables firewall. More info
4 | at the Cipherdyne web site.
5 |
6 |
7 | Get started by selecting "New Config" from the menu, and then filling in at least "Nickname", "Server Address",
8 | and "Rijndael Key." It is also recommended to set an "HMAC Key" as well for strong authentication of SPA packets.
9 |
10 |
11 | Once the data is filled in, select "Save Config" from the menu. Then, to send a SPA knock, select the
12 | Saved config you want to use, and click the "Send Knock" button at the bottom of the list.
13 |
14 | This app is open source software, Licensed GPLv3+. The source can be found on github. Please report any bugs there.
15 | Credits: Based on fwknop and libfko written by Michael Rash
16 | This app was written by Jonathan Bennett
17 | The fwknop-gui icon is derived from on a photo by Peter O'Connor
18 |
19 |
--------------------------------------------------------------------------------
/qr_export.h:
--------------------------------------------------------------------------------
1 | /* qr_export.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header for qr_export.cpp
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include "configs.h"
22 | #include
23 |
24 | class qr_export : public wxDialog
25 | {
26 | public:
27 | qr_export(const wxString& title, const Config *selectedConfig);
28 |
29 |
30 |
31 | private:
32 | wxBitmap bmp;
33 |
34 |
35 | void paintEvent(wxPaintEvent & evt);
36 | void paintNow();
37 | void render(wxDC& dc);
38 | DECLARE_EVENT_TABLE()
39 | };
40 |
--------------------------------------------------------------------------------
/fwknop_guiApp.cpp:
--------------------------------------------------------------------------------
1 | /* fwknop_guiApp.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Fwknop-gui application class
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #ifdef WX_PRECOMP
21 | #include "wx_pch.h"
22 | #endif
23 |
24 | #ifdef __BORLANDC__
25 | #pragma hdrstop
26 | #endif //__BORLANDC__
27 |
28 | #include "fwknop_guiApp.h"
29 | #include "fwknop_guiMain.h"
30 |
31 | IMPLEMENT_APP(fwknop_guiApp);
32 |
33 | bool fwknop_guiApp::OnInit()
34 | {
35 |
36 | fwknop_guiFrame* frame = new fwknop_guiFrame(0L, _("Fwknop-gui"));
37 | frame->Show();
38 |
39 | return true;
40 | }
41 |
--------------------------------------------------------------------------------
/general_config.h:
--------------------------------------------------------------------------------
1 | /* general_config.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header file for general_config.cpp
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 |
23 | class gConfigDialog : public wxDialog
24 | {
25 | public:
26 | gConfigDialog(wxFileConfig *configFile);
27 |
28 | private:
29 |
30 | wxTextCtrl *url_txt;
31 | wxFileConfig *privateConfigFile;
32 | wxCheckBox *countdownCheck;
33 | wxCheckBox *debugCheck;
34 |
35 | enum
36 | {
37 | ID_OKButton = 1200,
38 | ID_DefButton,
39 | ID_CancelButton
40 | };
41 |
42 | void OnDef(wxCommandEvent& event);
43 | void OnOK(wxCommandEvent& event);
44 | void OnCancel(wxCommandEvent& event);
45 | DECLARE_EVENT_TABLE()
46 | };
47 |
--------------------------------------------------------------------------------
/timer.h:
--------------------------------------------------------------------------------
1 | /* timer.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header for timer.cpp
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include "configs.h"
22 |
23 | class timerDialog : public wxDialog
24 | {
25 | public:
26 | timerDialog(const wxString& title, Config *selectedConfig, wxIPV4address *serverAddr, gpgme_wrapper *ourGPG, bool debug);
27 | private:
28 | bool ourDebug;
29 | wxTextCtrl *tc;
30 | int time_left;
31 | wxStaticText *timerText;
32 | wxStopWatch *main_timer;
33 | wxTimer *second_timer;
34 | Config *ourConfig;
35 | wxIPV4address ourAddr;
36 | //gpgme_wrapper *ourLocalGPG;
37 | wxString gpgEngine;
38 | wxString gpgHomeFolder;
39 |
40 | void onClose(wxCloseEvent& event);
41 | enum
42 | {
43 | ID_SECOND_TIMER
44 | };
45 | void tickTock(wxTimerEvent& event);
46 |
47 | DECLARE_EVENT_TABLE()
48 | };
49 |
50 |
--------------------------------------------------------------------------------
/MacOS/MacOSXBundleInfo.plist.in:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${MACOSX_BUNDLE_EXECUTABLE_NAME}
9 | CFBundleGetInfoString
10 | ${MACOSX_BUNDLE_INFO_STRING}
11 | CFBundleIconFile
12 | ${MACOSX_BUNDLE_ICON_FILE}
13 | CFBundleIdentifier
14 | ${MACOSX_BUNDLE_GUI_IDENTIFIER}
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleLongVersionString
18 | ${MACOSX_BUNDLE_LONG_VERSION_STRING}
19 | CFBundleName
20 | ${MACOSX_BUNDLE_BUNDLE_NAME}
21 | CFBundlePackageType
22 | APPL
23 | CFBundleShortVersionString
24 | ${MACOSX_BUNDLE_SHORT_VERSION_STRING}
25 | CFBundleSignature
26 | ????
27 | CFBundleVersion
28 | ${MACOSX_BUNDLE_BUNDLE_VERSION}
29 | CSResourcesFileMapped
30 |
31 | LSRequiresCarbon
32 |
33 | NSHumanReadableCopyright
34 | ${MACOSX_BUNDLE_COPYRIGHT}
35 | LSEnvironment
36 |
37 | PATH
38 | /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/MacGPG2/bin:
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/fwknop_guiApp.h:
--------------------------------------------------------------------------------
1 | /* fwknop_guiApp.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header file for fwknop_guiApp.cpp
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #ifndef FWKNOP_GUIAPP_H
21 | #define FWKNOP_GUIAPP_H
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 |
43 |
44 | #include
45 |
46 |
47 |
48 |
49 | class fwknop_guiApp : public wxApp
50 | {
51 | public:
52 | virtual bool OnInit();
53 |
54 | // wxDECLARE_EVENT_TABLE();
55 | };
56 |
57 | #endif // FWKNOP_GUIAPP_H
58 |
--------------------------------------------------------------------------------
/rc_import.h:
--------------------------------------------------------------------------------
1 | /* rc_import.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header for rc_import.cpp
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include "configs.h"
23 | #include
24 |
25 | class rc_import : public wxDialog
26 | {
27 | public:
28 | rc_import(const wxString& title, Config *ourGivenConfig, bool *is_changed);
29 |
30 | private:
31 | wxListBox *listbox;
32 | wxArrayString *configs;
33 | wxArrayString rc_Pair;
34 | wxString filename;
35 | wxTextFile rcFile;
36 | Config *ourConfig;
37 | wxTextCtrl *tc;
38 | wxString preview;
39 | bool *InternalIsChanged;
40 |
41 | enum
42 | {
43 | ID_OKButton = 1200,
44 | ID_ListBox,
45 | ID_CancelButton
46 | };
47 |
48 | void OnOK(wxCommandEvent& event);
49 | void OnList(wxCommandEvent& event);
50 | void OnCancel(wxCommandEvent& event);
51 | DECLARE_EVENT_TABLE()
52 | };
53 |
--------------------------------------------------------------------------------
/gpgme_wrapper.h:
--------------------------------------------------------------------------------
1 | /* gpgme_wrapper.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header for gpgme_wrapper.c
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #ifndef GPGME_WRAPPER
21 | #define GPGME_WRAPPER
22 | #include //This seems strange, not sure how to handle this. Ship with my code?
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | class gpgme_wrapper {
30 | public:
31 | bool enabled;
32 | bool doInit(wxFileConfig * configFile);
33 | void getAllKeys(wxArrayString * keys);
34 | bool selectHomeDir(wxFileConfig * configFile);
35 | bool selectEngine(wxFileConfig * configFile);
36 | bool setDefaults(wxFileConfig * configFile);
37 | wxString gpgEngine;
38 | wxString gpgHomeFolder;
39 | private:
40 | gpgme_ctx_t gpgcon;
41 | gpgme_error_t gpgerr;
42 | wxString gpgEngineDefault;
43 | wxString gpgFolderDefault;
44 |
45 | };
46 | #endif
47 |
--------------------------------------------------------------------------------
/cmake/Modules/FindLibQrencode.cmake:
--------------------------------------------------------------------------------
1 | # - Try to find the LibQrencode QRCode generator library,
2 | # written by Jim Evins, LGPLv3+
3 | # Once done this will define
4 | #
5 | # LIBQRENCODE_FOUND - System has LibQrencode
6 | # LIBQRENCODE_INCLUDE_DIR - The LibQrencode include directory
7 | # LIBQRENCODE_LIBRARIES - The libraries needed to use LibQrencode
8 | # LIBQRENCODE_DEFINITIONS - Compiler switches required for using LibQrencode
9 | # LIBQRENCODE_XMLLINT_EXECUTABLE - The XML checking tool xmllint coming with LibQrencode
10 | # LIBQRENCODE_VERSION_STRING - the version of LibQrencode found
11 |
12 | # use pkg-config to get the directories and then use these values with find_path() and find_library()
13 | find_package(PkgConfig QUIET)
14 | PKG_CHECK_MODULES(PC_LIBQRENCODE QUIET libqrencode)
15 | set(LIBQRENCODE_DEFINITIONS ${PC_LIBQRENCODE_CFLAGS_OTHER})
16 |
17 | find_path(LIBQRENCODE_INCLUDE_DIR NAMES qrencode.h
18 | HINTS
19 | ${PC_LIBQRENCODE_INCLUDEDIR}
20 | ${PC_LIBQRENCODE_INCLUDE_DIRS}
21 | PATH_SUFFIXES libqrencode
22 | )
23 |
24 | find_library(LIBQRENCODE_LIBRARIES NAMES qrencode libqrencode
25 | HINTS
26 | ${PC_LIBQRENCODE_LIBDIR}
27 | ${PC_LIBQRENCODE_LIBRARY_DIRS}
28 | )
29 |
30 | if(PC_LIBQRENCODE_VERSION)
31 | set(LIBQRENCODE_VERSION_STRING ${PC_LIBQRENCODE_VERSION})
32 | endif()
33 |
34 | # handle the QUIETLY and REQUIRED arguments and set LIBQRENCODE_FOUND to TRUE if
35 | # all listed variables are TRUE
36 | include(FindPackageHandleStandardArgs)
37 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibQrencode
38 | REQUIRED_VARS LIBQRENCODE_LIBRARIES LIBQRENCODE_INCLUDE_DIR
39 | VERSION_VAR LIBQRENCODE_VERSION_STRING)
40 |
41 | mark_as_advanced(LIBQRENCODE_INCLUDE_DIR LIBQRENCODE_LIBRARIES)
42 |
--------------------------------------------------------------------------------
/wizard.h:
--------------------------------------------------------------------------------
1 | /* wizard.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header for wizard.cpp
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include
21 | #include
22 | #include
23 | #include "configs.h"
24 | #define MAX_KEY_LEN 128
25 | #define MAX_B64_KEY_LEN 180
26 | class wizardDialog : public wxDialog
27 | {
28 | public:
29 | wizardDialog(const wxString& title);
30 |
31 | Config *tmp_config;
32 |
33 | private:
34 |
35 | wxTextCtrl *key_txt;
36 | wxCheckBox *ChkAllowCmd;
37 | wxCheckBox *ChkReqSrc;
38 | wxString keyString;
39 | char generatedKey[MAX_B64_KEY_LEN+1];
40 | char generatedHMAC[MAX_B64_KEY_LEN+1];
41 |
42 | wxString access_conf;
43 | wxString hmacString;
44 | wxTextCtrl *tc;
45 | enum
46 | {
47 | ID_OKButton = 1100,
48 | ID_CopyButton,
49 | ID_KEY_TXT,
50 | ID_CMD_CHK,
51 | ID_SRC_CHK
52 | };
53 |
54 | void OnUpdate(wxCommandEvent& event);
55 | void OnOK(wxCommandEvent& event);
56 | void OnCopy(wxCommandEvent& event);
57 | DECLARE_EVENT_TABLE()
58 | };
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Fwknop-gui is intended to be a cross platform graphical client for sending SPA knocks to fwknopd.
2 | It is based on the interface of Fwknop2 on Android.
3 |
4 | Binary downloads for Windows and Mac are hosted at http://incomsystems.biz/fwknop-gui
5 |
6 | Building from source is generally done by creating a build folder in the source directory, and running "cmake .." in that build folder. Then run make and sudo make install.
7 | I have run into an issue in Fedora where cmake will try to use wxWidgets 2.8.12 instead of a 3.0 version. The solution seems to be to run
8 | cmake ../ -DwxWidgets_CONFIG_EXECUTABLE='/usr/bin/wx-config-3.0'
9 |
10 |
11 | To build on Windows, use the msys2 project from http://msys2.github.io/
12 | Once installed, don't launch the msys2 shell. Instead, use the "MinGW-w64 Win32 Shell" Start by running "update-core", installing those updates, and then closing that shell and reopening it.
13 |
14 | From there, run:
15 | pacman -S mingw-w64-i686-toolchain
16 | pacman -S make mingw-w64-i686-make mingw-w64-i686-libtool texinfo autoconf automake tar
17 |
18 | Download the latest tarball from http://www.cipherdyne.org/fwknop/download/ and use tar -xf fwknop-2.* to unpack. Then run:
19 |
20 | ./configure --disable-server --disable-client --disable-stack-protector
21 | mingw32-make
22 |
23 | This should just work as of Fwknop 2.6.9.
24 |
25 | For qrcode support, download the latest realease from https://fukuchi.org/works/qrencode/
26 | ./configure, build, and build install
27 |
28 | Next, unpack the fwknop-gui source, and create a build directory. Run cmake .. -G"MSYS Makefiles" twice! and then make to build.
29 |
30 |
31 | On Mac, I've had to compile both wxWidgets and libqrencode from source.
32 | Macports or Homebrew should suffice to install a usable toolchain to bootstrap compiling. Gpgme must also be installed. I used homebrew for this.
33 | To make a portable bundle, use "make install".
34 |
--------------------------------------------------------------------------------
/configs.h:
--------------------------------------------------------------------------------
1 | /* configs.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header file for configs.cpp
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #ifndef FWKNOP_CONFIGS
21 | #define FWKNOP_CONFIGS
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include "gpgme_wrapper.h"
36 |
37 |
38 |
39 | class Config
40 | {
41 | public:
42 | wxString NICK_NAME;
43 | wxString SERVER_IP;
44 | bool LEGACY;
45 | wxString SERVER_PORT;
46 | wxString PROTOCOL;
47 | wxString KEY;
48 | bool KEY_BASE64;
49 | wxString HMAC;
50 | bool HMAC_BASE64;
51 | wxString MESS_TYPE;
52 | wxString ACCESS_IP;
53 | wxString PORTS;
54 | wxString SERVER_TIMEOUT;
55 | wxString NAT_IP;
56 | wxString NAT_PORT;
57 | wxString SERVER_CMD;
58 | wxString SPA_STRING;
59 | wxString DIGEST_TYPE;
60 | wxString HMAC_TYPE;
61 | bool KEEP_OPEN;
62 | bool USE_GPG_CRYPT;
63 | wxString GPG_CRYPT_ID;
64 | wxString GPG_SIG_ID;
65 |
66 |
67 | void getAllConfigs(wxArrayString * configs, wxFileConfig *configFile);
68 | wxString validateConfig();
69 | void saveConfig(wxFileConfig *configFile);
70 | void loadConfig(wxString Nick, wxFileConfig *configFile);
71 | void defaultConfig();
72 | wxString gen_SPA(wxString ip_resolver_url, wxString gpgEngine, wxString gpgHomeFolder, bool debug); // returns status.
73 | wxString send_SPA(wxIPV4address *serverAddr);
74 |
75 | private:
76 | typedef struct fwknop_options
77 | {
78 | char *spa_server_str;
79 | unsigned int spa_dst_port;
80 | char *spa_data;
81 |
82 | //nat access options // am I using these?
83 | char nat_access_str[1024];
84 | int nat_local;
85 | int nat_port;
86 | int nat_rand_port;
87 | char server_command[1024];
88 | } fwknop_options_t;
89 | };
90 | #endif
91 |
--------------------------------------------------------------------------------
/qr_export.cpp:
--------------------------------------------------------------------------------
1 | /* qr_export.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * QR export class
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include "qr_export.h"
21 |
22 | BEGIN_EVENT_TABLE(qr_export, wxDialog)
23 |
24 | // catch paint events
25 | EVT_PAINT(qr_export::paintEvent)
26 |
27 | END_EVENT_TABLE()
28 |
29 | qr_export::qr_export(const wxString & title, const Config *selectedConfig)
30 | : wxDialog(NULL, -1, title, wxDefaultPosition, wxSize(150, 150))
31 | {
32 | int i;
33 | char tmpString[10024];
34 | QRcode *ourQR = NULL;
35 | wxImage *ourQRImage;
36 | wxString QRBuf = wxT("");
37 |
38 | wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
39 | if (selectedConfig->KEY_BASE64)
40 | QRBuf = (wxT("KEY_BASE64:"));
41 | else
42 | QRBuf = (wxT("KEY:"));
43 | QRBuf.Append(selectedConfig->KEY);
44 | if (!selectedConfig->HMAC.IsEmpty()) {
45 | if (selectedConfig->HMAC_BASE64)
46 | QRBuf.Append(wxT(" HMAC_KEY_BASE64:"));
47 | else
48 | QRBuf.Append(wxT(" HMAC_KEY:"));
49 | QRBuf.Append(selectedConfig->HMAC);
50 | }
51 | strncpy(tmpString, (const char*)QRBuf.mb_str(wxConvUTF8), 10023);
52 | ourQR = QRcode_encodeString((char *)tmpString, 0, QR_ECLEVEL_Q, QR_MODE_8, 1);
53 |
54 | unsigned char *rawImage = new unsigned char[ourQR->width * ourQR->width * 3];
55 | unsigned char *p = ourQR->data;
56 | for (i=0; i < (ourQR->width * ourQR->width); i++) {
57 | if (p[i] & 0x00000001) {
58 | rawImage[i * 3] = 0x00;
59 | rawImage[i * 3 + 1] = 0x00;
60 | rawImage[i * 3 + 2] = 0x00;
61 | } else {
62 | rawImage[i * 3] = 0xff;
63 | rawImage[i * 3 + 1] = 0xff;
64 | rawImage[i * 3 + 2] = 0xff;
65 |
66 | }
67 |
68 | }
69 | ourQRImage = new wxImage(ourQR->width, ourQR->width, rawImage);
70 | ourQRImage->Rescale(ourQR->width * 4, ourQR->width * 4);
71 | bmp = wxBitmap(*ourQRImage);
72 | sizer->SetMinSize(bmp.GetHeight(), bmp.GetHeight());
73 | SetSizer(sizer);
74 | Layout();
75 | this->Fit();
76 | Centre();
77 | ShowModal();
78 | Destroy();
79 | QRcode_free(ourQR);
80 | }
81 |
82 | void qr_export::paintEvent(wxPaintEvent & evt)
83 | {
84 | // depending on your system you may need to look at double-buffered dcs
85 | wxPaintDC dc(this);
86 | render(dc);
87 |
88 | }
89 |
90 | void qr_export::paintNow()
91 | {
92 | // depending on your system you may need to look at double-buffered dcs
93 | wxClientDC dc(this);
94 | render(dc);
95 | }
96 |
97 | void qr_export::render(wxDC& dc)
98 | {
99 | dc.DrawBitmap( bmp, 0, 0, false );
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/timer.cpp:
--------------------------------------------------------------------------------
1 | /* timer.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Countdown timer class
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include "timer.h"
21 |
22 | BEGIN_EVENT_TABLE(timerDialog, wxDialog)
23 | EVT_CLOSE(timerDialog::onClose)
24 | EVT_TIMER(ID_SECOND_TIMER, timerDialog::tickTock)
25 | END_EVENT_TABLE()
26 |
27 | timerDialog::timerDialog(const wxString & title, Config *selectedConfig, wxIPV4address *serverAddr, gpgme_wrapper *ourGPG, bool debug)
28 | : wxDialog(NULL, -1, title, wxDefaultPosition, wxSize(250, 200))
29 | {
30 | ourDebug = debug;
31 | gpgEngine = ourGPG->gpgEngine;
32 | gpgHomeFolder = ourGPG->gpgHomeFolder;
33 | ourConfig = new Config (*selectedConfig); //Need to copy the whole object for the timer
34 | ourAddr = *serverAddr;
35 | time_left = wxAtoi(ourConfig->SERVER_TIMEOUT);
36 | wxFont* font = new wxFont();
37 | //wxPanel *panel = new wxPanel(this, -1);
38 | wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
39 | main_timer = new wxStopWatch();
40 | main_timer->Start();
41 | second_timer = new wxTimer(this, ID_SECOND_TIMER);
42 | second_timer->Start(1000);
43 | timerText = new wxStaticText(this,wxID_ANY,wxEmptyString, wxPoint(10,10), wxSize(100, 100), wxALIGN_CENTRE_HORIZONTAL);
44 | font->SetPointSize(50);
45 | timerText->SetFont(*font);
46 | timerText->SetLabel(ourConfig->SERVER_TIMEOUT);
47 | wxStaticText * descText = new wxStaticText(this,wxID_ANY, _("The SPA request will timeout in:"), wxPoint(10,10), wxSize(200, 40), wxALIGN_CENTER_HORIZONTAL);
48 | vbox->Add(descText, 0, wxALIGN_CENTER_HORIZONTAL);
49 | vbox->Add(timerText, 0, wxALIGN_CENTER_HORIZONTAL);
50 |
51 |
52 |
53 | SetSizer(vbox);
54 | Centre();
55 | Show();
56 |
57 | }
58 |
59 | void timerDialog::tickTock(wxTimerEvent &event)
60 | {
61 | timerText->SetLabel(wxString::Format(wxT("%ld"), time_left - (main_timer->Time()/1000)));
62 | if (time_left - (main_timer->Time()/1000) < 1) {
63 | second_timer->Stop();
64 | this->EndDialog(wxID_OK);
65 | }
66 | if (time_left - (main_timer->Time()/1000) < 11 && ourConfig->KEEP_OPEN) {
67 | //ourConfig->gen_SPA(_(""), ourLocalGPG);
68 | if (ourConfig->gen_SPA(_(""), gpgEngine, gpgHomeFolder, ourDebug).CmpNoCase(_("Success")) == 0) {
69 | if(ourConfig->send_SPA(&ourAddr).CmpNoCase(_("Knock sent successfully.")) == 0) {
70 | main_timer->Start();
71 | }
72 | }
73 | }
74 | }
75 |
76 | void timerDialog::onClose(wxCloseEvent& event) {
77 | second_timer->Stop();
78 | delete second_timer;
79 | delete main_timer;
80 | delete timerText;
81 | Destroy();
82 | }
83 |
84 | //Start with the time specified
85 |
86 | //when we hit 10 seconds, resend if that option is set
87 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | include(FeatureSummary)
2 | cmake_minimum_required(VERSION 2.8)
3 | project(fwknop-gui CXX C)
4 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
5 | if(NOT(DEFINED IS_WIN32 OR DEFINED IS_LINUX OR DEFINED IS_APPLE))
6 | if(WIN32)
7 | set(IS_WIN32 TRUE)
8 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
9 | set(IS_APPLE TRUE)
10 | set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
11 | else()
12 | set(IS_LINUX TRUE)
13 | endif()
14 | endif()
15 |
16 | if (IS_WIN32)
17 | set( wxWidgets_USE_STATIC ON)
18 | set(CODE_FILES win32/minimal.rc)
19 | endif()
20 |
21 | find_package(wxWidgets 3.0.0 COMPONENTS xml html adv qa richtext net core base REQUIRED)
22 |
23 | include(${wxWidgets_USE_FILE})
24 | include_directories(${CMAKE_SOURCE_DIR})
25 |
26 | find_package(LibFko REQUIRED)
27 | find_package(CURL REQUIRED)
28 | find_package(LibQrencode REQUIRED)
29 | find_package(Gpgme REQUIRED)
30 |
31 | set(CODE_FILES
32 | ${CODE_FILES}
33 | configs.cpp
34 | fwknop_guiApp.cpp
35 | fwknop_guiMain.cpp
36 | wizard.cpp
37 | general_config.cpp
38 | rc_import.cpp
39 | rc_export.cpp
40 | qr_export.cpp
41 | timer.cpp
42 | gpgme_wrapper.cpp
43 | )
44 |
45 | if(IS_APPLE)
46 |
47 | set_source_files_properties(MacOS/fwknop-gui.icns PROPERTIES
48 | MACOSX_PACKAGE_LOCATION "Resources")
49 | set(CODE_FILES
50 | ${CODE_FILES}
51 | MacOS/fwknop-gui.icns
52 | )
53 | endif()
54 | add_executable(fwknop-gui WIN32 MACOSX_BUNDLE
55 | ${CODE_FILES}
56 | )
57 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
58 |
59 | SET_TARGET_PROPERTIES(fwknop-gui PROPERTIES POSITION_INDEPENDENT_CODE ON)
60 |
61 | target_link_libraries(fwknop-gui ${wxWidgets_LIBRARIES} ${LIBFKO_LIBRARIES} ${CURL_LIBRARIES} ${LIBQRENCODE_LIBRARIES} ${GPGME_VANILLA_LIBRARIES})
62 | if(IS_LINUX)
63 | find_program(A2X_EXECUTABLE NAMES a2x a2x.py)
64 | set(A2X_OPTS
65 | -D ${CMAKE_BINARY_DIR}
66 | -d manpage
67 | -f manpage
68 | )
69 |
70 | set(MAN_NAMES fwknop-gui.8)
71 | set(MAN_FILES)
72 | foreach(m IN LISTS MAN_NAMES)
73 | set(mf ${CMAKE_BINARY_DIR}/${m})
74 | set(ms ${CMAKE_SOURCE_DIR}/${m}.asciidoc)
75 | add_custom_command(OUTPUT ${mf}
76 | COMMAND ${A2X_EXECUTABLE} ${A2X_OPTS} ${ms}
77 | DEPENDS ${ms}
78 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
79 | COMMENT "Building manpage ${mf}"
80 | VERBATIM)
81 | list(APPEND MAN_FILES ${mf})
82 | endforeach()
83 |
84 | add_custom_target(man ALL DEPENDS ${MAN_FILES})
85 |
86 | install(FILES help.html DESTINATION share/fwknop-gui)
87 | install(TARGETS fwknop-gui DESTINATION bin)
88 | install(PROGRAMS fwknop-gui.desktop DESTINATION share/applications)
89 | install(FILES fwknop-gui.png DESTINATION share/pixmaps)
90 | INSTALL(FILES fwknop-gui.8 DESTINATION share/man/man8)
91 | endif()
92 | if(IS_WIN32)
93 | include_directories( ${LIBQRENCODE_INCLUDE_DIR} )
94 | target_link_libraries(fwknop-gui wsock32 ws2_32 ${wxWidgets_LIBRARIES} ${LIBFKO_LIBRARIES} ${CURL_LIBRARIES} ${GPGME_VANILLA_LIBRARIES})
95 | set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
96 | include_directories(${LIBQRENCODE_INCLUDE_DIR})
97 | endif()
98 | if(IS_APPLE)
99 | set(MACOSX_BUNDLE_BUNDLE_NAME fwknop-gui)
100 | set(MACOSX_BUNDLE_ICON_FILE fwknop-gui.icns)
101 | set_property(TARGET fwknop-gui PROPERTY MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/MacOS/MacOSXBundleInfo.plist.in")
102 | INSTALL(CODE "
103 | set(BU_CHMOD_BUNDLE_ITEMS ON)
104 | include(BundleUtilities)
105 | file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/fwknop-gui.app/Contents/SharedSupport)
106 | file(INSTALL ${CMAKE_SOURCE_DIR}/help.html DESTINATION ${CMAKE_INSTALL_PREFIX}/fwknop-gui.app/Contents/SharedSupport/)
107 | fixup_bundle(${CMAKE_INSTALL_PREFIX}/fwknop-gui.app \"\" \"\")
108 | ")
109 | endif()
110 |
--------------------------------------------------------------------------------
/general_config.cpp:
--------------------------------------------------------------------------------
1 | /* general_config.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * General config class
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include "general_config.h"
21 |
22 | BEGIN_EVENT_TABLE(gConfigDialog, wxDialog)
23 | EVT_BUTTON(ID_DefButton, gConfigDialog::OnDef)
24 | EVT_BUTTON(ID_OKButton, gConfigDialog::OnOK)
25 | EVT_BUTTON(ID_CancelButton, gConfigDialog::OnCancel)
26 | END_EVENT_TABLE()
27 |
28 |
29 | gConfigDialog::gConfigDialog(wxFileConfig *configFile)
30 | : wxDialog(NULL, -1, _("Config"), wxDefaultPosition, wxSize(-1, -1))
31 | {
32 | privateConfigFile = configFile;
33 | wxPanel *panel = new wxPanel(this, -1);
34 | wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
35 | wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
36 |
37 | privateConfigFile->SetPath(wxT("/"));
38 |
39 | new wxStaticText(panel, -1, wxT("Enter URL to use to resolve the local IP."),
40 | wxPoint(15, 5));
41 |
42 | url_txt = new wxTextCtrl(panel, -1,
43 | configFile->Read(wxT("ip_resolver_url"), _("https://api.ipify.org")) , wxPoint(15, 30), wxSize(350, 30));
44 |
45 | new wxButton(panel, ID_DefButton, wxT("Set to Default"), wxPoint(15, 70));
46 |
47 | countdownCheck = new wxCheckBox(panel, wxID_ANY, _("Show server timeout popup"), wxPoint(15, 110));
48 | if (configFile->Read(wxT("show_timer"), _("true")).CmpNoCase(_("true")) == 0 ) {
49 | countdownCheck->SetValue(true);
50 | } else {
51 | countdownCheck->SetValue(false);
52 | }
53 | debugCheck = new wxCheckBox(panel, wxID_ANY, _("Show Debug information"), wxPoint(15, 150));
54 | if (configFile->Read(wxT("debug"), _("false")).CmpNoCase(_("true")) == 0 ) {
55 | debugCheck->SetValue(true);
56 | } else {
57 | debugCheck->SetValue(false);
58 | }
59 |
60 | wxButton *okButton = new wxButton(this, ID_OKButton, wxT("Ok"),
61 | wxDefaultPosition, wxSize(70, 30));
62 |
63 | wxButton *cancelButton = new wxButton(this, ID_CancelButton, wxT("Cancel"),
64 | wxDefaultPosition, wxSize(70, 30));
65 |
66 | hbox->Add(okButton, 1);
67 | hbox->Add(cancelButton, 1);
68 | //vbox->Add(key_lbl, 1);
69 |
70 | vbox->Add(panel, 1);
71 | vbox->Add(hbox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10);
72 |
73 | SetSizer(vbox);
74 |
75 | Centre();
76 | ShowModal();
77 |
78 | Destroy();
79 | }
80 |
81 | void gConfigDialog::OnDef(wxCommandEvent &event)
82 | {
83 | url_txt->ChangeValue(wxT("https://api.ipify.org"));
84 | }
85 |
86 | void gConfigDialog::OnOK(wxCommandEvent &event)
87 | {
88 | wxString tmp_url = url_txt->GetValue();
89 | if (tmp_url.IsEmpty()) {
90 | wxMessageBox(_("URL cannot be empty!"));
91 | return;
92 | } else {
93 | privateConfigFile->Write(wxT("ip_resolver_url"), tmp_url);
94 | if (countdownCheck->IsChecked()) {
95 | privateConfigFile->Write(wxT("show_timer"), _("true"));
96 | } else {
97 | privateConfigFile->Write(wxT("show_timer"), _("false"));
98 | }
99 | if (debugCheck->IsChecked()) {
100 | privateConfigFile->Write(wxT("debug"), _("true"));
101 | } else {
102 | privateConfigFile->Write(wxT("debug"), _("false"));
103 | }
104 | privateConfigFile->Flush();
105 | EndModal(wxID_OK);
106 | Destroy();
107 | }
108 | }
109 |
110 | void gConfigDialog::OnCancel(wxCommandEvent &event)
111 | {
112 | EndModal(wxID_CANCEL);
113 | Destroy();
114 | }
115 |
--------------------------------------------------------------------------------
/wizard.cpp:
--------------------------------------------------------------------------------
1 | /* wizard.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Access.conf wizard class
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include "wizard.h"
21 |
22 | BEGIN_EVENT_TABLE(wizardDialog, wxDialog)
23 | EVT_BUTTON(ID_OKButton, wizardDialog::OnOK)
24 | EVT_BUTTON(ID_CopyButton, wizardDialog::OnCopy)
25 | EVT_CHECKBOX(ID_CMD_CHK, wizardDialog::OnUpdate)
26 | EVT_CHECKBOX(ID_SRC_CHK, wizardDialog::OnUpdate)
27 | EVT_TEXT(ID_KEY_TXT, wizardDialog::OnUpdate)
28 | END_EVENT_TABLE()
29 |
30 | wizardDialog::wizardDialog(const wxString & title)
31 | : wxDialog(NULL, -1, title, wxDefaultPosition, wxSize(900, 360))
32 | {
33 |
34 | tmp_config = new Config;
35 | fko_key_gen(generatedKey, FKO_DEFAULT_KEY_LEN, generatedHMAC, FKO_DEFAULT_HMAC_KEY_LEN, FKO_DEFAULT_HMAC_MODE);
36 |
37 | wxPanel *panel = new wxPanel(this, -1);
38 |
39 | wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
40 | wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
41 |
42 | new wxStaticText(panel, -1, wxT("Enter text to use as key, or leave blank to use the generated key."),
43 | wxPoint(15, 5));
44 |
45 | key_txt = new wxTextCtrl(panel, ID_KEY_TXT,
46 | wxT(""), wxPoint(15, 30));
47 |
48 | ChkAllowCmd = new wxCheckBox(panel, ID_CMD_CHK,
49 | wxT("Allow Command Message"), wxPoint(15, 70));
50 |
51 | ChkReqSrc = new wxCheckBox(panel, ID_SRC_CHK,
52 | wxT("Require Source Address"), wxPoint(15, 100));
53 | ChkReqSrc->SetValue(true);
54 |
55 | tc = new wxTextCtrl(panel, -1, wxT(""),
56 | wxPoint(15, 135), wxSize(875, 225), wxTE_MULTILINE | wxTE_READONLY);
57 |
58 | wxButton *okButton = new wxButton(this, ID_OKButton, wxT("Ok"),
59 | wxDefaultPosition, wxSize(70, 30));
60 |
61 | wxButton *copyButton = new wxButton(this, ID_CopyButton, wxT("Copy to Clipboard"),
62 | wxDefaultPosition, wxSize(170, 30));
63 |
64 | hbox->Add(okButton, 1);
65 | hbox->Add(copyButton, 1);
66 |
67 | vbox->Add(panel, 1);
68 | vbox->Add(hbox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10);
69 |
70 | SetSizer(vbox);
71 |
72 | Centre();
73 | wxCommandEvent *initEvent = new wxCommandEvent(wxEVT_COMMAND_CHOICE_SELECTED, ID_KEY_TXT);
74 | OnUpdate(*initEvent);
75 | ShowModal();
76 |
77 | Destroy();
78 | }
79 |
80 | void wizardDialog::OnUpdate(wxCommandEvent &event)
81 | {
82 | if (key_txt->GetLineText(0).IsEmpty()){
83 | keyString = _("KEY_BASE64 ");
84 | keyString.Append(wxString::FromAscii(generatedKey));
85 | keyString.Append(_("\n"));
86 | } else {
87 | keyString = _("KEY ");
88 | keyString.Append(key_txt->GetLineText(0));
89 | keyString.Append(_("\n"));
90 | }
91 | access_conf = _("SOURCE ANY\n");
92 | access_conf.Append(keyString);
93 |
94 | hmacString = _("HMAC_KEY_BASE64 ");
95 | hmacString.Append(wxString::FromAscii(generatedHMAC));
96 | hmacString.Append(_("\n"));
97 | access_conf.Append(hmacString);
98 |
99 | if (ChkAllowCmd->GetValue()) {
100 | access_conf.Append(_("ENABLE_CMD_EXEC "));
101 | access_conf.Append(_("Y\n"));
102 | }
103 | if (ChkReqSrc->GetValue()) {
104 | access_conf.Append(_("REQUIRE_SOURCE_ADDRESS "));
105 | access_conf.Append(_("Y\n"));
106 | }
107 | tc->ChangeValue(access_conf);
108 | }
109 |
110 | void wizardDialog::OnCopy(wxCommandEvent &event)
111 | {
112 | if (wxTheClipboard->Open()) {
113 | wxTheClipboard->SetData( new wxTextDataObject(access_conf) );
114 | wxTheClipboard->Close();
115 | }
116 | }
117 |
118 | void wizardDialog::OnOK(wxCommandEvent &event)
119 | {
120 | if (key_txt->GetLineText(0).IsEmpty()){
121 | tmp_config->KEY = wxString::FromAscii(generatedKey);
122 | tmp_config->KEY_BASE64 = true;
123 | } else {
124 | tmp_config->KEY = key_txt->GetLineText(0);
125 | tmp_config->KEY_BASE64 = false;
126 | }
127 | tmp_config->HMAC = wxString::FromAscii(generatedHMAC);
128 | EndModal( wxID_OK);
129 | }
130 |
131 |
--------------------------------------------------------------------------------
/rc_export.cpp:
--------------------------------------------------------------------------------
1 | /* rc_export.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * RC export class
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include "rc_export.h"
21 |
22 | rc_export::rc_export(const wxString & title, const Config *selectedConfig)
23 | : wxDialog(NULL, -1, title, wxDefaultPosition, wxSize(900, 330))
24 | {
25 | wxString configBuf = wxT("");
26 | wxPanel *panel = new wxPanel(this, -1);
27 |
28 | wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
29 | //wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
30 | // hbox->Add(okButton, 1);
31 | // hbox->Add(copyButton, 1);
32 |
33 | tc = new wxTextCtrl(panel, -1, wxT(""),
34 | wxPoint(15, 80), wxSize(875, 200), wxTE_MULTILINE | wxTE_READONLY);
35 | tc->SetFont(wxFont(10, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
36 |
37 | configBuf = wxT("[");
38 | configBuf.Append(selectedConfig->NICK_NAME);
39 | configBuf.Append(wxT("]"));
40 | configBuf.Append(wxT("\nSPA_SERVER "));
41 | configBuf.Append(selectedConfig->SERVER_IP);
42 | if (selectedConfig->LEGACY)
43 | configBuf.Append(wxT("\nENCRYPTION_MODE legacy"));
44 |
45 | if (selectedConfig->SERVER_PORT.CmpNoCase(_("random")) == 0) {
46 | configBuf.Append(wxT("\nRAND_PORT Y"));
47 | } else {
48 | configBuf.Append(wxT("\nSPA_SERVER_PORT "));
49 | configBuf.Append(selectedConfig->SERVER_PORT);
50 | }
51 | configBuf.Append(wxT("\nSPA_SERVER_PROTO "));
52 | configBuf.Append(selectedConfig->PROTOCOL);
53 | configBuf.Append(wxT("\nDIGEST_TYPE "));
54 | configBuf.Append(selectedConfig->DIGEST_TYPE);
55 | configBuf.Append(wxT("\nHMAC_DIGEST_TYPE "));
56 | configBuf.Append(selectedConfig->HMAC_TYPE);
57 |
58 | if (!selectedConfig->HMAC.IsEmpty()) {
59 | configBuf.Append(wxT("\nUSE_HMAC Y"));
60 | if (selectedConfig->HMAC_BASE64)
61 | configBuf.Append(wxT("\nHMAC_KEY_BASE64 "));
62 | else
63 | configBuf.Append(wxT("\nHMAC_KEY "));
64 | configBuf.Append(selectedConfig->HMAC);
65 | }
66 |
67 | if (!selectedConfig->KEY.IsEmpty()) {
68 | if (selectedConfig->KEY_BASE64)
69 | configBuf.Append(wxT("\nKEY_BASE64 "));
70 | else
71 | configBuf.Append(wxT("\nKEY "));
72 | configBuf.Append(selectedConfig->KEY);
73 | }
74 |
75 | if (selectedConfig->MESS_TYPE.CmpNoCase(_("Server Command")) == 0) { // fwknoprc seems not to have support for server commands
76 |
77 | } else if (selectedConfig->MESS_TYPE.CmpNoCase(_("Open Port")) == 0) {
78 | configBuf.Append(wxT("\nACCESS "));
79 | configBuf.Append(selectedConfig->PORTS);
80 | if(!selectedConfig->SERVER_TIMEOUT.IsEmpty()) {
81 | configBuf.Append(wxT("\nCLIENT_TIMEOUT "));
82 | configBuf.Append(selectedConfig->SERVER_TIMEOUT);
83 | }
84 | } else if (selectedConfig->MESS_TYPE.CmpNoCase(_("Nat Access")) == 0) {
85 | configBuf.Append(wxT("\nACCESS "));
86 | configBuf.Append(selectedConfig->PORTS);
87 | configBuf.Append(wxT("\nNAT_ACCESS "));
88 | configBuf.Append(selectedConfig->NAT_IP);
89 | configBuf.Append(wxT(","));
90 | configBuf.Append(selectedConfig->NAT_PORT);
91 |
92 | if(!selectedConfig->SERVER_TIMEOUT.IsEmpty()) {
93 | configBuf.Append(wxT("\nCLIENT_TIMEOUT "));
94 | configBuf.Append(selectedConfig->SERVER_TIMEOUT);
95 | }
96 | } else if (selectedConfig->MESS_TYPE.CmpNoCase(_("Local Nat Access")) == 0) {
97 | configBuf.Append(wxT("\nACCESS "));
98 | configBuf.Append(selectedConfig->PORTS);
99 | configBuf.Append(wxT("\nNAT_LOCAL Y"));
100 | configBuf.Append(wxT("\nNAT_PORT "));
101 | configBuf.Append(selectedConfig->NAT_PORT);
102 |
103 | if(!selectedConfig->SERVER_TIMEOUT.IsEmpty()) {
104 | configBuf.Append(wxT("\nCLIENT_TIMEOUT "));
105 | configBuf.Append(selectedConfig->SERVER_TIMEOUT);
106 | }
107 | }
108 |
109 |
110 |
111 | tc->ChangeValue(configBuf);
112 | vbox->Add(panel, 1);
113 | //vbox->Add(hbox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10);
114 |
115 | SetSizer(vbox);
116 |
117 |
118 |
119 | Centre();
120 |
121 | ShowModal();
122 |
123 | Destroy();
124 | }
125 |
--------------------------------------------------------------------------------
/fwknop_guiMain.h:
--------------------------------------------------------------------------------
1 | /* fwknop_guiMain.h
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Header file for fwknop_guiMain.cpp
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #ifndef FWKNOP_GUIMAIN_H
21 | #define FWKNOP_GUIMAIN_H
22 |
23 | #ifndef WX_PRECOMP
24 | #include
25 | #endif
26 |
27 | #include "fwknop_guiApp.h"
28 | #include "wizard.h"
29 | #include "general_config.h"
30 | #include "rc_export.h"
31 | #include "rc_import.h"
32 | #include "qr_export.h"
33 | #include "timer.h"
34 | #include "gpgme_wrapper.h"
35 | #include
36 | #include
37 | class fwknop_guiFrame: public wxFrame
38 | {
39 | public:
40 | fwknop_guiFrame(wxFrame *frame, const wxString& title);
41 |
42 | private:
43 | wxBoxSizer *hbox;
44 | wxBoxSizer *vConfigBox;
45 | wxBoxSizer *vConfigBoxSuper;
46 | wxBoxSizer *hIPToAllowBox;
47 | wxBoxSizer *hServPortBox;
48 | wxChoice *AllowIPChoice;
49 | wxChoice *MessTypeChoice;
50 | wxBoxSizer *hAccessPortsBox;
51 | wxBoxSizer *hFwTimeBox;
52 | wxBoxSizer *hKeepAliveBox;
53 | wxBoxSizer *hInternalIPBox;
54 | wxBoxSizer *hInternalPortBox;
55 | wxBoxSizer *hServCmdBox;
56 | wxFileConfig *configFile;
57 | wxTextCtrl *NickTxt;
58 | Config *ourConfig;
59 | wxArrayString *ourConfigList;
60 | wxListBox *listbox;
61 | wxTextCtrl *ServAddrTxt;
62 | wxCheckBox *LegacyChk;
63 | wxCheckBox *RandomChk;
64 | wxTextCtrl *ServPortTxt;
65 | wxCheckBox *GPGChk;
66 | wxTextCtrl *KeyTxt;
67 | wxCheckBox *KeyB64Chk;
68 | wxChoice *ProtoChoice;
69 | wxTextCtrl *HmacKeyTxt;
70 | wxCheckBox *HmacKeyB64Chk;
71 | wxTextCtrl *IPToAllowTxt;
72 | wxTextCtrl *AccessPortsTxt;
73 | wxTextCtrl *FwTimeTxt;
74 | wxCheckBox *TimerChk;
75 | wxCheckBox *KeepOpenChk;
76 | wxTextCtrl *InternalIPTxt;
77 | wxTextCtrl *InternalPortTxt;
78 | wxTextCtrl *ServCmdTxt;
79 | wxChoice *DigestTypeChoice;
80 | wxChoice *HmacTypeChoice;
81 | wxCommandEvent *initMessTypeEvent;
82 | wxCommandEvent *initAllowIPEvent;
83 | wxCommandEvent *initCheckboxEvent;
84 | gpgme_wrapper *ourGPG;
85 | wxArrayString *GPGKeys;
86 | wxArrayString *GPGSigKeys;
87 | wxBoxSizer *hKeyBox;
88 | wxBoxSizer *hKeyB64Box;
89 | wxBoxSizer *hGPGChoiceBox;
90 | wxChoice *GPGEncryptKey;
91 | wxChoice *GPGSignatureKey;
92 | wxScrolledWindow *vConfigScroll;
93 |
94 |
95 |
96 |
97 |
98 | enum
99 | {
100 | idMenuQuit = 1000,
101 | idMenuAbout,
102 | idMenuHelpScreen,
103 | idMenuSettings,
104 | idMenuNew,
105 | idMenuDelete,
106 | idMenuLocation,
107 | idMenuWizard,
108 | idMenuImport,
109 | idMenuExport,
110 | idMenuQR,
111 | idMenugpgEngine,
112 | idMenugpgFolder,
113 | idMenugpgDefaults,
114 | idMenuGPGTools,
115 | ID_AllowIP,
116 | ID_MessType,
117 | ID_SaveButton,
118 | ID_List,
119 | ID_KnockButton,
120 | ID_Random,
121 | ID_DigestType,
122 | ID_HmacType,
123 | ID_USE_GPG,
124 | ID_html
125 | };
126 |
127 | void populate();
128 | void OnClose(wxCloseEvent& event);
129 | void OnQuit(wxCommandEvent& event);
130 | void OnNew(wxCommandEvent& event);
131 | void OnDelete(wxCommandEvent& event);
132 | void OnLocation(wxCommandEvent& event);
133 | void OnAbout(wxCommandEvent& event);
134 | void OnHelpScreen(wxCommandEvent& event);
135 | void OnSettings(wxCommandEvent& event);
136 | void OnWizard(wxCommandEvent& event);
137 | void OnImport(wxCommandEvent& event);
138 | void OnExport(wxCommandEvent& event);
139 | void OnQR(wxCommandEvent& event);
140 | void gpgEngine(wxCommandEvent& event);
141 | void gpgFolder(wxCommandEvent& event);
142 | void gpgDefaults(wxCommandEvent& event);
143 | void OnChoice(wxCommandEvent& event);
144 | void OnSave(wxCommandEvent& event);
145 | void OnLoad(wxCommandEvent& event);
146 | void OnLink(wxHtmlLinkEvent& event);
147 | void OnKnock(wxCommandEvent& event);
148 | DECLARE_EVENT_TABLE()
149 | };
150 |
151 |
152 |
153 | #endif // FWKNOP_GUIMAIN_H
154 |
--------------------------------------------------------------------------------
/rc_import.cpp:
--------------------------------------------------------------------------------
1 | /* rc_import.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * RC import class
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include "rc_import.h"
21 |
22 | BEGIN_EVENT_TABLE(rc_import, wxDialog)
23 | EVT_BUTTON(ID_OKButton, rc_import::OnOK)
24 | EVT_LISTBOX(ID_ListBox, rc_import::OnList)
25 | EVT_BUTTON(ID_CancelButton, rc_import::OnCancel)
26 | END_EVENT_TABLE()
27 |
28 | rc_import::rc_import(const wxString & title, Config *ourGivenConfig, bool *is_changed)
29 | : wxDialog(NULL, -1, title, wxDefaultPosition, wxSize(900, 300))
30 | {
31 | ourConfig = ourGivenConfig;
32 | InternalIsChanged = is_changed;
33 | configs = new wxArrayString;
34 | wxString singleLine;
35 |
36 | wxStandardPathsBase& stdp = wxStandardPaths::Get();
37 | wxFileDialog getRC(this, _("fwknoprc file to import"), stdp.GetDocumentsDir(), wxT(".fwknoprc"));
38 | if (getRC.ShowModal() == wxID_CANCEL){
39 | Destroy();
40 | return;
41 | }
42 |
43 | filename = getRC.GetPath();
44 | if (!rcFile.Open(filename)) {
45 | wxMessageBox(_("Could not open file"));
46 | Destroy();
47 | return;
48 | }
49 |
50 | rcFile.GoToLine(0);
51 |
52 | while(!rcFile.Eof())
53 | {
54 | singleLine = rcFile.GetNextLine();
55 | singleLine.Trim(0);
56 | singleLine.Trim(1);
57 | if (singleLine.StartsWith(wxT("#")) || singleLine.IsEmpty())
58 | continue;
59 | if (singleLine.StartsWith(wxT("[")) && singleLine.EndsWith(wxT("]"))){
60 | singleLine.RemoveLast();
61 | singleLine.Remove(0, 1);
62 | if (singleLine.CmpNoCase(wxT("default")) != 0)
63 | configs->Add(singleLine);
64 | }
65 |
66 | }
67 | if (configs->GetCount() == 0){
68 | wxMessageBox(_("No stanzas in file"));
69 | Destroy();
70 | return;
71 | }
72 | //if configs are blank, then bail
73 |
74 | //open file, find the stanza names, let the user select which stanza/s to import (first iteration
75 |
76 | wxPanel *panel = new wxPanel(this, -1);
77 |
78 | wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
79 | wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
80 | wxButton *okButton = new wxButton(this, ID_OKButton, wxT("Ok"),
81 | wxDefaultPosition, wxSize(70, 30));
82 | wxButton *cancelButton = new wxButton(this, ID_CancelButton, wxT("Cancel"),
83 | wxDefaultPosition, wxSize(70, 30));
84 |
85 | hbox->Add(okButton, 1);
86 | hbox->Add(cancelButton, 1);
87 |
88 | listbox = new wxListBox(this, ID_ListBox, wxPoint(10, 10), wxSize(200, 200));
89 | listbox->InsertItems(*configs, 0);
90 |
91 | tc = new wxTextCtrl(panel, -1, wxT(""),
92 | wxPoint(220, 10), wxSize(650, 200), wxTE_MULTILINE | wxTE_READONLY);
93 | tc->SetFont(wxFont(10, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
94 |
95 | vbox->Add(panel, 1);
96 | vbox->Add(hbox, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 10);
97 |
98 | SetSizer(vbox);
99 |
100 | Centre();
101 |
102 | ShowModal();
103 |
104 | Destroy();
105 | }
106 |
107 | void rc_import::OnCancel(wxCommandEvent &event)
108 | {
109 | Destroy();
110 | }
111 |
112 | void rc_import::OnOK(wxCommandEvent &event)
113 | {
114 | wxString singleLine;
115 | //ourConfig = new Config;
116 | ourConfig->defaultConfig();
117 |
118 | rcFile.GoToLine(0);
119 |
120 | while(!rcFile.Eof())
121 | {
122 | singleLine = rcFile.GetNextLine();
123 | singleLine.Trim(0);
124 | singleLine.Trim(1);
125 | if (singleLine.StartsWith(wxT("#")) || singleLine.IsEmpty())
126 | continue;
127 | if (singleLine.StartsWith(wxT("[")) && singleLine.EndsWith(wxT("]"))){
128 | singleLine.RemoveLast();
129 | singleLine.Remove(0, 1);
130 | if (singleLine.CmpNoCase(listbox->GetString(listbox->GetSelection())) == 0)
131 | break;
132 | }
133 |
134 | }
135 | ourConfig->NICK_NAME = singleLine;
136 | ourConfig->MESS_TYPE = wxT("");
137 | //rc_Pair = new wxArrayString;
138 | while(!rcFile.Eof())
139 | {
140 | singleLine = rcFile.GetNextLine();
141 | singleLine.Trim(0);
142 | singleLine.Trim(1);
143 | if (singleLine.StartsWith(wxT("#")) || singleLine.IsEmpty())
144 | continue;
145 | if (singleLine.StartsWith(wxT("[")) && singleLine.EndsWith(wxT("]"))){
146 | break; //once we hit the next stanza, we're done
147 | }
148 | rc_Pair = wxStringTokenize(singleLine);//buse wxStringTokenize
149 | if (rc_Pair[0].CmpNoCase(wxT("SPA_SERVER")) == 0)
150 | ourConfig->SERVER_IP = rc_Pair[1];
151 | else if (rc_Pair[0].CmpNoCase(wxT("ENCRYPTION_MODE")) == 0 && rc_Pair[1].CmpNoCase(wxT("legacy")) == 0)
152 | ourConfig->LEGACY = true;
153 | else if (rc_Pair[0].CmpNoCase(wxT("RAND_PORT")) == 0 && rc_Pair[1].CmpNoCase(wxT("Y")) == 0)
154 | ourConfig->SERVER_PORT = wxT("random");
155 | else if (rc_Pair[0].CmpNoCase(wxT("SPA_SERVER_PORT")) == 0)
156 | ourConfig->SERVER_PORT = rc_Pair[1];
157 | else if (rc_Pair[0].CmpNoCase(wxT("SPA_SERVER_PROTO")) == 0)
158 | ourConfig->PROTOCOL = rc_Pair[1];
159 | else if (rc_Pair[0].CmpNoCase(wxT("DIGEST_TYPE")) == 0)
160 | ourConfig->DIGEST_TYPE = rc_Pair[1];
161 | else if (rc_Pair[0].CmpNoCase(wxT("HMAC_DIGEST_TYPE")) == 0)
162 | ourConfig->HMAC_TYPE = rc_Pair[1];
163 | else if (rc_Pair[0].CmpNoCase(wxT("HMAC_KEY_BASE64")) == 0){
164 | ourConfig->HMAC = rc_Pair[1];
165 | ourConfig->HMAC_BASE64 = true;
166 | }
167 | else if (rc_Pair[0].CmpNoCase(wxT("HMAC_KEY")) == 0){
168 | ourConfig->HMAC = rc_Pair[1];
169 | ourConfig->HMAC_BASE64 = false;
170 | }
171 | else if (rc_Pair[0].CmpNoCase(wxT("KEY_BASE64")) == 0){
172 | ourConfig->KEY = rc_Pair[1];
173 | ourConfig->KEY_BASE64 = true;
174 | }
175 | else if (rc_Pair[0].CmpNoCase(wxT("KEY")) == 0){
176 | ourConfig->KEY = rc_Pair[1];
177 | ourConfig->KEY_BASE64 = false;
178 | }
179 | else if (rc_Pair[0].CmpNoCase(wxT("CLIENT_TIMEOUT")) == 0)
180 | ourConfig->SERVER_TIMEOUT = rc_Pair[1];
181 | else if (rc_Pair[0].CmpNoCase(wxT("ACCESS")) == 0)
182 | ourConfig->PORTS = rc_Pair[1];
183 | else if (rc_Pair[0].CmpNoCase(wxT("NAT_LOCAL")) == 0 && rc_Pair[1].CmpNoCase(wxT("Y")) == 0)
184 | ourConfig->MESS_TYPE = wxT("Local Nat Access");
185 | else if (rc_Pair[0].CmpNoCase(wxT("NAT_PORT")) == 0)
186 | ourConfig->NAT_PORT = rc_Pair[1];
187 | else if (rc_Pair[0].CmpNoCase(wxT("NAT_ACCESS")) == 0) {
188 | ourConfig->NAT_IP = rc_Pair[1].BeforeFirst(',');
189 | ourConfig->NAT_PORT = rc_Pair[1].AfterLast(',');
190 | }
191 |
192 |
193 |
194 | if (ourConfig->MESS_TYPE.IsEmpty())
195 | ourConfig->MESS_TYPE = wxT("Open Port");
196 |
197 |
198 | }
199 |
200 | //itirate through file to find stanza start, and specified options
201 | //fill config
202 | //save
203 |
204 | wxMessageBox(wxT("Import Successful, Press Save to confirm"));
205 | *InternalIsChanged = true;
206 | Destroy();
207 | }
208 |
209 | void rc_import::OnList(wxCommandEvent &event)
210 | {
211 | wxString singleLine;
212 | preview = wxT("[");
213 | rcFile.GoToLine(0);
214 |
215 | while(!rcFile.Eof()) //this loop puts our file cursor at the first line of the config we are importing
216 | {
217 |
218 | singleLine = rcFile.GetNextLine();
219 | singleLine.Trim(0);
220 | singleLine.Trim(1);
221 | if (singleLine.StartsWith(wxT("#")) || singleLine.IsEmpty())
222 | continue;
223 | if (singleLine.StartsWith(wxT("[")) && singleLine.EndsWith(wxT("]"))){
224 | singleLine.RemoveLast();
225 | singleLine.Remove(0, 1);
226 | if (singleLine.CmpNoCase(listbox->GetString(listbox->GetSelection())) == 0)
227 | break;
228 | }
229 |
230 | }
231 | preview.Append(singleLine);
232 | preview.Append(wxT("]\n"));
233 |
234 | while(!rcFile.Eof()) //This loop dumps that stanza to the preview
235 | {
236 | singleLine = rcFile.GetNextLine();
237 | if (singleLine.Find(wxT("[")) != wxNOT_FOUND && singleLine.Find(wxT("]")) != wxNOT_FOUND )
238 | break; //once we hit the next stanza, we're done
239 | preview.Append(singleLine);
240 | preview.Append(wxT("\n"));
241 | }
242 |
243 |
244 |
245 | tc->ChangeValue(preview);
246 |
247 | }
248 |
--------------------------------------------------------------------------------
/gpgme_wrapper.cpp:
--------------------------------------------------------------------------------
1 | /* gpgme_wrapper.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Gpgme wrapper class
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include "gpgme_wrapper.h"
21 |
22 | bool gpgme_wrapper::doInit(wxFileConfig * configFile) {
23 | gpgme_engine_info_t tmp_Info;
24 | configFile->SetPath(wxT("/"));
25 |
26 | //Starts the actual init
27 | gpgme_check_version(nullptr);
28 | gpgerr = gpgme_new(&gpgcon);
29 | if (gpgerr != GPG_ERR_NO_ERROR) {
30 | wxMessageBox(_("GPG returned the error: ") + _(gpgme_strerror(gpgerr)));
31 | return 0;
32 | }
33 |
34 | tmp_Info = gpgme_ctx_get_engine_info(gpgcon);
35 | if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) != GPG_ERR_NO_ERROR && (configFile->Read(wxT("show_gpg"), _("true")).CmpNoCase(_("true")) == 0))
36 | {
37 | if (wxGetOsVersion() & wxOS_WINDOWS) {
38 | wxRichMessageDialog dlg(NULL, _("GPG engine missing, launch browser to download?"), _("GPG engine missing"), wxYES_NO);
39 | dlg.ShowCheckBox("Don't show this dialog again");
40 | if (dlg.ShowModal() == wxID_YES) {
41 | wxMessageBox(_("The download will now begin, start fwknop-gui again after the installation is complete"));
42 | wxLaunchDefaultBrowser(_("https://files.gpg4win.org/gpg4win-latest.exe"));
43 | }
44 | if ( dlg.IsCheckBoxChecked() ) {
45 | configFile->Write(wxT("show_gpg"), _("false"));
46 | configFile->Flush();
47 | }
48 | } else if (wxGetOsVersion() & wxOS_MAC) {
49 | wxRichMessageDialog dlg(NULL, _("GPG engine missing, launch browser to download?"), _("GPG engine missing"), wxYES_NO);
50 | dlg.ShowCheckBox("Don't show this dialog again");
51 | if (dlg.ShowModal() == wxID_YES) {
52 | wxMessageBox(_("The gpgtools page will launch. Please download and install the gpg suite and start fwknop-gui again after the installation is complete"));
53 | wxLaunchDefaultBrowser(_("https://gpgtools.org/"));
54 | }
55 | if ( dlg.IsCheckBoxChecked() ) {
56 | configFile->Write(wxT("show_gpg"), _("false"));
57 | configFile->Flush();
58 | }
59 | enabled = false;
60 | return 0;
61 | } else {
62 | wxRichMessageDialog dlg(NULL, _("GPG engine missing, please install gpg or gp2"), _("GPG engine missing"), wxOK|wxCENTER);
63 | dlg.ShowCheckBox("Don't show this dialog again");
64 | dlg.ShowModal();
65 | if ( dlg.IsCheckBoxChecked() ) {
66 | configFile->Write(wxT("show_gpg"), _("false"));
67 | configFile->Flush();
68 | }
69 | enabled = false;
70 | return 0;
71 | }
72 | }
73 | if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) != GPG_ERR_NO_ERROR)
74 | return 0;
75 | //We grab the default settings before loading in the saved stuff
76 | gpgEngineDefault = _(tmp_Info->file_name);
77 | gpgFolderDefault = _(tmp_Info ->home_dir);
78 | gpgEngine = configFile->Read(wxT("gpg_engine"), _(tmp_Info->file_name));
79 | gpgHomeFolder = configFile->Read(wxT("gpg_home_folder"), _(tmp_Info->home_dir));
80 | if (gpgHomeFolder.IsEmpty())
81 | gpgme_ctx_set_engine_info(gpgcon, GPGME_PROTOCOL_OpenPGP, (const char*)gpgEngine.mb_str(wxConvUTF8), nullptr);
82 | else
83 | gpgme_ctx_set_engine_info(gpgcon, GPGME_PROTOCOL_OpenPGP, (const char*)gpgEngine.mb_str(wxConvUTF8), (const char*)gpgHomeFolder.mb_str(wxConvUTF8));
84 | enabled = true;
85 | return 1;
86 | }
87 |
88 | void gpgme_wrapper::getAllKeys(wxArrayString * keys) {
89 | gpgme_key_t tmpKey;
90 | keys->Empty();
91 | gpgerr = gpgme_op_keylist_start(gpgcon, 0, 0);
92 | if (gpgerr != GPG_ERR_NO_ERROR){
93 | wxMessageBox(_("GPG returned the error: ") + _(gpgme_strerror(gpgerr)));
94 | return;
95 | }
96 | while (gpgme_op_keylist_next(gpgcon, &tmpKey) != GPG_ERR_EOF) {
97 | if (tmpKey == 0)
98 | break;
99 | //keys->Insert(_(gpgme_key_get_string_attr(tmpKey, GPGME_ATTR_KEYID, 0, 0)).Right(8), 0);
100 | keys->Insert(_(tmpKey->subkeys->keyid).Right(8), 0);
101 | }
102 | gpgme_op_keylist_end(gpgcon);
103 |
104 | }
105 | //This function is not used, but is temporarily left for reference
106 | /*
107 | bool gpgme_wrapper::encryptAndSign(wxString encryptKey, wxString sigKey, char * plaintext, char * cipher) {
108 | gpgme_data_t plain_data;
109 | gpgme_data_t cipher_data;
110 | gpgme_key_t key[2] = { NULL, NULL };
111 | gpgme_key_t sig_key;
112 | size_t * buf_len;
113 | char *buf;
114 | char key_buf[64] = {0};
115 | buf_len = new size_t;
116 | char *ndx;
117 |
118 | gpgerr = gpgme_data_new_from_mem(&plain_data, plaintext, strlen(plaintext), 1);
119 | if (gpgerr != GPG_ERR_NO_ERROR) {
120 | wxMessageBox(_("GPG returned the error: ") + _(gpgme_strerror(gpgerr)));
121 | return 0;
122 | }
123 | gpgerr = gpgme_data_new(&cipher_data);
124 | if (gpgerr != GPG_ERR_NO_ERROR) {
125 | wxMessageBox(_("GPG returned the error: ") + _(gpgme_strerror(gpgerr)));
126 | return 0;
127 | }
128 | strcpy(key_buf, (const char*)encryptKey.mb_str(wxConvUTF8));
129 | gpgerr = gpgme_get_key(gpgcon, key_buf, &key[0], 0);
130 | if (gpgerr != GPG_ERR_NO_ERROR) {
131 | wxMessageBox(_("GPG returned the error: ") + _(gpgme_strerror(gpgerr)));
132 | return 0;
133 | }
134 | gpgme_set_protocol(gpgcon, GPGME_PROTOCOL_OpenPGP);
135 | gpgme_set_armor(gpgcon, 0);
136 |
137 | gpgme_signers_clear(gpgcon);
138 | if (sigKey.CmpNoCase(wxT("None")) == 0) {
139 | gpgerr = gpgme_op_encrypt(gpgcon, key, GPGME_ENCRYPT_ALWAYS_TRUST, plain_data, cipher_data);
140 | if (gpgerr != GPG_ERR_NO_ERROR) {
141 | wxMessageBox(_("GPG returned the error: ") + _(gpgme_strerror(gpgerr)));
142 | return 0;
143 | }
144 |
145 |
146 |
147 | } else {
148 | strcpy(key_buf, (const char*)sigKey.mb_str(wxConvUTF8));
149 | gpgerr = gpgme_get_key(gpgcon, key_buf, &sig_key, 0);
150 | if (gpgerr != GPG_ERR_NO_ERROR) {
151 | wxMessageBox(_("GPG returned the error: ") + _(gpgme_strerror(gpgerr)));
152 | return 0;
153 | }
154 | gpgme_signers_add(gpgcon, sig_key);
155 | gpgme_op_encrypt_sign(gpgcon, key, GPGME_ENCRYPT_ALWAYS_TRUST, plain_data, cipher_data);
156 | }
157 | buf = gpgme_data_release_and_get_mem(cipher_data, buf_len);
158 | if (buf == nullptr)
159 | return 0;
160 | wxBase64Encode(cipher, 4096, buf, *buf_len);
161 | if((ndx = strchr(cipher, '=')) != NULL)
162 | *ndx = '\0';
163 | //base64 encode before returning
164 | return 1;
165 | }
166 | */
167 | bool gpgme_wrapper::selectHomeDir(wxFileConfig * configFile) {
168 | configFile->SetPath(wxT("/"));
169 | wxDirDialog dlg(NULL, _("Choose GPG directory"), gpgHomeFolder, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
170 | if (wxGetOsVersion() & wxOS_MAC) {
171 | dlg.SetMessage(_("Choose GPG directory, use Shift+Command+.(period) to show hidden files"));
172 | }
173 | if(dlg.ShowModal() == wxID_OK){
174 | gpgHomeFolder = dlg.GetPath();
175 | configFile->Write(_("gpg_home_folder"), gpgHomeFolder);
176 | configFile->Flush();
177 | gpgme_ctx_set_engine_info(gpgcon, GPGME_PROTOCOL_OpenPGP, (const char*)gpgEngine.mb_str(wxConvUTF8), (const char*)gpgHomeFolder.mb_str(wxConvUTF8));
178 | return true;
179 | } else {
180 | return false;
181 | }
182 |
183 | }
184 |
185 | bool gpgme_wrapper::selectEngine(wxFileConfig * configFile) {
186 | configFile->SetPath(wxT("/"));
187 | wxFileDialog dlg(NULL, _("Choose gpg or gpg2 executable"), wxEmptyString, gpgEngine);
188 | if (wxGetOsVersion() & wxOS_MAC) {
189 | dlg.SetMessage(_("Choose gpg or gpg2 executable, use Shift+Command+.(period) to show hidden files"));
190 | }
191 |
192 | if (dlg.ShowModal() == wxID_OK){
193 | gpgEngine = dlg.GetPath();
194 | configFile->Write(_("gpg_engine"), gpgEngine);
195 | configFile->Flush();
196 | gpgme_ctx_set_engine_info(gpgcon, GPGME_PROTOCOL_OpenPGP, (const char*)gpgEngine.mb_str(wxConvUTF8), (const char*)gpgHomeFolder.mb_str(wxConvUTF8));
197 | return true;
198 | } else {
199 | return false;
200 | }
201 | }
202 |
203 | bool gpgme_wrapper::setDefaults(wxFileConfig * configFile) {
204 | configFile->SetPath(wxT("/"));
205 | wxMessageDialog dlg(NULL, _("Are you sure you want to reset GPG?"), _("Confirm"), wxYES_NO);
206 | if (dlg.ShowModal() == wxID_YES){
207 | gpgEngine = gpgEngineDefault;
208 | gpgHomeFolder = gpgFolderDefault;
209 | configFile->Write(_("gpg_engine"), gpgEngine);
210 | configFile->Write(_("gpg_home_folder"), wxEmptyString);
211 | configFile->Flush();
212 | gpgme_ctx_set_engine_info(gpgcon, GPGME_PROTOCOL_OpenPGP, (const char*)gpgEngine.mb_str(wxConvUTF8), nullptr);
213 | return true;
214 | } else {
215 | return false;
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/cmake/Modules/FindGpgme.cmake:
--------------------------------------------------------------------------------
1 | # - Try to find the gpgme library
2 | #
3 | # Algorithm:
4 | # - Windows:
5 | # On Windows, there's three gpgme variants: gpgme{,-glib,-qt}.
6 | # - The variant used determines the event loop integration possible:
7 | # - gpgme: no event loop integration possible, only synchronous operations supported
8 | # - gpgme-glib: glib event loop integration possible, only asynchronous operations supported
9 | # - gpgme-qt: qt event loop integration possible, only asynchronous operations supported
10 | # - GPGME_{VANILLA,GLIB,QT}_{FOUND,LIBRARIES} will be set for each of the above
11 | # - GPGME_INCLUDES is the same for all of the above
12 | # - GPGME_FOUND is set if any of the above was found
13 | # - *nix:
14 | # There's also three variants: gpgme{,-pthread,-pth}.
15 | # - The variant used determines the multithreaded use possible:
16 | # - gpgme: no multithreading support available
17 | # - gpgme-pthread: multithreading available using POSIX threads
18 | # - gpgme-pth: multithreading available using GNU PTH (cooperative multithreading)
19 | # - GPGME_{VANILLA,PTH,PTHREAD}_{FOUND,LIBRARIES} will be set for each of the above
20 | # - GPGME_INCLUDES is the same for all of the above
21 | # - GPGME_FOUND is set if any of the above was found
22 | #
23 | # GPGME_LIBRARY_DIR - the directory where the libraries are located
24 |
25 | #
26 | # THIS IS ALMOST A 1:1 COPY OF FindAssuan.cmake in kdepim.
27 | # Any changes here likely apply there, too.
28 | #
29 |
30 | # do away with crappy condition repetition on else/endfoo
31 | set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS_gpgme_saved ${CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS} )
32 | set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true )
33 |
34 | #if this is built-in, please replace, if it isn't, export into a MacroToBool.cmake of it's own
35 | macro( macro_bool_to_bool FOUND_VAR )
36 | foreach( _current_VAR ${ARGN} )
37 | if ( ${FOUND_VAR} )
38 | set( ${_current_VAR} TRUE )
39 | else()
40 | set( ${_current_VAR} FALSE )
41 | endif()
42 | endforeach()
43 | endmacro()
44 |
45 | #HACK: local copy...
46 | MACRO(MACRO_BOOL_TO_01 FOUND_VAR )
47 | FOREACH (_current_VAR ${ARGN})
48 | IF(${FOUND_VAR})
49 | SET(${_current_VAR} 1)
50 | ELSE(${FOUND_VAR})
51 | SET(${_current_VAR} 0)
52 | ENDIF(${FOUND_VAR})
53 | ENDFOREACH(_current_VAR)
54 | ENDMACRO(MACRO_BOOL_TO_01)
55 |
56 |
57 | if ( WIN32 )
58 |
59 | # On Windows, we don't have a gpgme-config script, so we need to
60 | # look for the stuff ourselves:
61 |
62 | # in cmake, AND and OR have the same precedence, there's no
63 | # subexpressions, and expressions are evaluated short-circuit'ed
64 | # IOW: CMake if() suxx.
65 | # Starting with CMake 2.6.3 you can group if expressions with (), but we
66 | # don't require 2.6.3 but 2.6.2, we can't use it. Alex
67 | set( _seem_to_have_cached_gpgme false )
68 | if ( GPGME_INCLUDES )
69 | if ( GPGME_VANILLA_LIBRARIES OR GPGME_QT_LIBRARIES OR GPGME_GLIB_LIBRARIES )
70 | set( _seem_to_have_cached_gpgme true )
71 | endif()
72 | endif()
73 |
74 | if ( _seem_to_have_cached_gpgme )
75 |
76 | macro_bool_to_bool( GPGME_VANILLA_LIBRARIES GPGME_VANILLA_FOUND )
77 | macro_bool_to_bool( GPGME_GLIB_LIBRARIES GPGME_GLIB_FOUND )
78 | macro_bool_to_bool( GPGME_QT_LIBRARIES GPGME_QT_FOUND )
79 | # this would have been preferred:
80 | #set( GPGME_*_FOUND macro_bool_to_bool(GPGME_*_LIBRARIES) )
81 |
82 | if ( GPGME_VANILLA_FOUND OR GPGME_GLIB_FOUND OR GPGME_QT_FOUND )
83 | set( GPGME_FOUND true )
84 | else()
85 | set( GPGME_FOUND false )
86 | endif()
87 |
88 | else()
89 |
90 | set( GPGME_FOUND false )
91 | set( GPGME_VANILLA_FOUND false )
92 | set( GPGME_GLIB_FOUND false )
93 | set( GPGME_QT_FOUND false )
94 |
95 | find_path( GPGME_INCLUDES gpgme.h
96 | ${CMAKE_INCLUDE_PATH}
97 | ${CMAKE_INSTALL_PREFIX}/include
98 | )
99 |
100 | find_library( _gpgme_vanilla_library NAMES gpgme libgpgme gpgme-11 libgpgme-11
101 | PATHS
102 | ${CMAKE_LIBRARY_PATH}
103 | ${CMAKE_INSTALL_PREFIX}/lib
104 | )
105 |
106 | find_library( _gpgme_glib_library NAMES gpgme-glib libgpgme-glib gpgme-glib-11 libgpgme-glib-11
107 | PATHS
108 | ${CMAKE_LIBRARY_PATH}
109 | ${CMAKE_INSTALL_PREFIX}/lib
110 | )
111 |
112 | find_library( _gpgme_qt_library NAMES gpgme-qt libgpgme-qt gpgme-qt-11 libgpgme-qt-11
113 | PATHS
114 | ${CMAKE_LIBRARY_PATH}
115 | ${CMAKE_INSTALL_PREFIX}/lib
116 | )
117 |
118 | find_library( _gpg_error_library NAMES gpg-error libgpg-error gpg-error-0 libgpg-error-0
119 | PATHS
120 | ${CMAKE_LIBRARY_PATH}
121 | ${CMAKE_INSTALL_PREFIX}/lib
122 | )
123 |
124 | set( GPGME_INCLUDES ${GPGME_INCLUDES} )
125 |
126 | if ( _gpgme_vanilla_library AND _gpg_error_library )
127 | set( GPGME_VANILLA_LIBRARIES ${_gpgme_vanilla_library} ${_gpg_error_library} )
128 | set( GPGME_VANILLA_FOUND true )
129 | set( GPGME_FOUND true )
130 | endif()
131 |
132 | if ( _gpgme_glib_library AND _gpg_error_library )
133 | set( GPGME_GLIB_LIBRARIES ${_gpgme_glib_library} ${_gpg_error_library} )
134 | set( GPGME_GLIB_FOUND true )
135 | set( GPGME_FOUND true )
136 | endif()
137 |
138 | if ( _gpgme_qt_library AND _gpg_error_library )
139 | set( GPGME_QT_LIBRARIES ${_gpgme_qt_library} ${_gpg_error_library} )
140 | set( GPGME_QT_FOUND true )
141 | set( GPGME_FOUND true )
142 | endif()
143 |
144 | endif()
145 |
146 | # these are Unix-only:
147 | set( GPGME_PTHREAD_FOUND false )
148 | set( GPGME_PTH_FOUND false )
149 | set( HAVE_GPGME_PTHREAD 0 )
150 | set( HAVE_GPGME_PTH 0 )
151 |
152 | macro_bool_to_01( GPGME_FOUND HAVE_GPGME )
153 | macro_bool_to_01( GPGME_VANILLA_FOUND HAVE_GPGME_VANILLA )
154 | macro_bool_to_01( GPGME_GLIB_FOUND HAVE_GPGME_GLIB )
155 | macro_bool_to_01( GPGME_QT_FOUND HAVE_GPGME_QT )
156 |
157 | else() # not WIN32
158 |
159 | # On *nix, we have the gpgme-config script which can tell us all we
160 | # need to know:
161 |
162 | # see WIN32 case for an explanation of what this does:
163 | set( _seem_to_have_cached_gpgme false )
164 | if ( GPGME_INCLUDES )
165 | if ( GPGME_VANILLA_LIBRARIES OR GPGME_PTHREAD_LIBRARIES OR GPGME_PTH_LIBRARIES )
166 | set( _seem_to_have_cached_gpgme true )
167 | endif()
168 | endif()
169 |
170 | if ( _seem_to_have_cached_gpgme )
171 |
172 | macro_bool_to_bool( GPGME_VANILLA_LIBRARIES GPGME_VANILLA_FOUND )
173 | macro_bool_to_bool( GPGME_PTHREAD_LIBRARIES GPGME_PTHREAD_FOUND )
174 | macro_bool_to_bool( GPGME_PTH_LIBRARIES GPGME_PTH_FOUND )
175 |
176 | if ( GPGME_VANILLA_FOUND OR GPGME_PTHREAD_FOUND OR GPGME_PTH_FOUND )
177 | set( GPGME_FOUND true )
178 | else()
179 | set( GPGME_FOUND false )
180 | endif()
181 |
182 | else()
183 |
184 | set( GPGME_FOUND false )
185 | set( GPGME_VANILLA_FOUND false )
186 | set( GPGME_PTHREAD_FOUND false )
187 | set( GPGME_PTH_FOUND false )
188 |
189 | find_program( _GPGMECONFIG_EXECUTABLE NAMES gpgme-config )
190 |
191 | # if gpgme-config has been found
192 | if ( _GPGMECONFIG_EXECUTABLE )
193 |
194 | message( STATUS "Found gpgme-config at ${_GPGMECONFIG_EXECUTABLE}" )
195 |
196 | exec_program( ${_GPGMECONFIG_EXECUTABLE} ARGS --version OUTPUT_VARIABLE GPGME_VERSION )
197 |
198 | set( _GPGME_MIN_VERSION "1.1.7" )
199 |
200 | if ( ${GPGME_VERSION} VERSION_LESS ${_GPGME_MIN_VERSION} )
201 |
202 | message( STATUS "The installed version of gpgme is too old: ${GPGME_VERSION} (required: >= ${_GPGME_MIN_VERSION})" )
203 |
204 | else()
205 |
206 | message( STATUS "Found gpgme v${GPGME_VERSION}, checking for flavours..." )
207 |
208 | exec_program( ${_GPGMECONFIG_EXECUTABLE} ARGS --libs OUTPUT_VARIABLE _gpgme_config_vanilla_libs RETURN_VALUE _ret )
209 | if ( _ret )
210 | set( _gpgme_config_vanilla_libs )
211 | endif()
212 |
213 | exec_program( ${_GPGMECONFIG_EXECUTABLE} ARGS --thread=pthread --libs OUTPUT_VARIABLE _gpgme_config_pthread_libs RETURN_VALUE _ret )
214 | if ( _ret )
215 | set( _gpgme_config_pthread_libs )
216 | endif()
217 |
218 | exec_program( ${_GPGMECONFIG_EXECUTABLE} ARGS --thread=pth --libs OUTPUT_VARIABLE _gpgme_config_pth_libs RETURN_VALUE _ret )
219 | if ( _ret )
220 | set( _gpgme_config_pth_libs )
221 | endif()
222 |
223 | # append -lgpg-error to the list of libraries, if necessary
224 | foreach ( _flavour vanilla pthread pth )
225 | if ( _gpgme_config_${_flavour}_libs AND NOT _gpgme_config_${_flavour}_libs MATCHES "lgpg-error" )
226 | set( _gpgme_config_${_flavour}_libs "${_gpgme_config_${_flavour}_libs} -lgpg-error" )
227 | endif()
228 | endforeach()
229 |
230 | if ( _gpgme_config_vanilla_libs OR _gpgme_config_pthread_libs OR _gpgme_config_pth_libs )
231 |
232 | exec_program( ${_GPGMECONFIG_EXECUTABLE} ARGS --cflags OUTPUT_VARIABLE _GPGME_CFLAGS )
233 |
234 | if ( _GPGME_CFLAGS )
235 | string( REGEX REPLACE "(\r?\n)+$" " " _GPGME_CFLAGS "${_GPGME_CFLAGS}" )
236 | string( REGEX REPLACE " *-I" ";" GPGME_INCLUDES "${_GPGME_CFLAGS}" )
237 | endif()
238 |
239 | foreach ( _flavour vanilla pthread pth )
240 | if ( _gpgme_config_${_flavour}_libs )
241 |
242 | set( _gpgme_library_dirs )
243 | set( _gpgme_library_names )
244 | string( TOUPPER "${_flavour}" _FLAVOUR )
245 |
246 | string( REGEX REPLACE " +" ";" _gpgme_config_${_flavour}_libs "${_gpgme_config_${_flavour}_libs}" )
247 |
248 | foreach( _flag ${_gpgme_config_${_flavour}_libs} )
249 | if ( "${_flag}" MATCHES "^-L" )
250 | string( REGEX REPLACE "^-L" "" _dir "${_flag}" )
251 | file( TO_CMAKE_PATH "${_dir}" _dir )
252 | set( _gpgme_library_dirs ${_gpgme_library_dirs} "${_dir}" )
253 | elseif( "${_flag}" MATCHES "^-l" )
254 | string( REGEX REPLACE "^-l" "" _name "${_flag}" )
255 | set( _gpgme_library_names ${_gpgme_library_names} "${_name}" )
256 | endif()
257 | endforeach()
258 |
259 | set( GPGME_${_FLAVOUR}_FOUND true )
260 |
261 | foreach( _name ${_gpgme_library_names} )
262 | set( _gpgme_${_name}_lib )
263 |
264 | # if -L options were given, look only there
265 | if ( _gpgme_library_dirs )
266 | find_library( _gpgme_${_name}_lib NAMES ${_name} PATHS ${_gpgme_library_dirs} NO_DEFAULT_PATH )
267 | endif()
268 |
269 | # if not found there, look in system directories
270 | if ( NOT _gpgme_${_name}_lib )
271 | find_library( _gpgme_${_name}_lib NAMES ${_name} )
272 | endif()
273 |
274 | # if still not found, then the whole flavour isn't found
275 | if ( NOT _gpgme_${_name}_lib )
276 | if ( GPGME_${_FLAVOUR}_FOUND )
277 | set( GPGME_${_FLAVOUR}_FOUND false )
278 | set( _not_found_reason "dependant library ${_name} wasn't found" )
279 | endif()
280 | endif()
281 |
282 | set( GPGME_${_FLAVOUR}_LIBRARIES ${GPGME_${_FLAVOUR}_LIBRARIES} "${_gpgme_${_name}_lib}" )
283 | endforeach()
284 |
285 | #check_c_library_exists_explicit( gpgme gpgme_check_version "${_GPGME_CFLAGS}" "${GPGME_LIBRARIES}" GPGME_FOUND )
286 | if ( GPGME_${_FLAVOUR}_FOUND )
287 | message( STATUS " Found flavour '${_flavour}', checking whether it's usable...yes" )
288 | else()
289 | message( STATUS " Found flavour '${_flavour}', checking whether it's usable...no" )
290 | message( STATUS " (${_not_found_reason})" )
291 | endif()
292 | endif()
293 |
294 | endforeach( _flavour )
295 |
296 | # ensure that they are cached
297 | # This comment above doesn't make sense, the four following lines seem to do nothing. Alex
298 | set( GPGME_INCLUDES ${GPGME_INCLUDES} )
299 | set( GPGME_VANILLA_LIBRARIES ${GPGME_VANILLA_LIBRARIES} )
300 | set( GPGME_PTHREAD_LIBRARIES ${GPGME_PTHREAD_LIBRARIES} )
301 | set( GPGME_PTH_LIBRARIES ${GPGME_PTH_LIBRARIES} )
302 |
303 | if ( GPGME_VANILLA_FOUND OR GPGME_PTHREAD_FOUND OR GPGME_PTH_FOUND )
304 | set( GPGME_FOUND true )
305 | else()
306 | set( GPGME_FOUND false )
307 | endif()
308 |
309 | endif()
310 |
311 | endif()
312 |
313 | endif()
314 |
315 | endif()
316 |
317 | # these are Windows-only:
318 | set( GPGME_GLIB_FOUND false )
319 | set( GPGME_QT_FOUND false )
320 | set( HAVE_GPGME_GLIB 0 )
321 | set( HAVE_GPGME_QT 0 )
322 |
323 | macro_bool_to_01( GPGME_FOUND HAVE_GPGME )
324 | macro_bool_to_01( GPGME_VANILLA_FOUND HAVE_GPGME_VANILLA )
325 | macro_bool_to_01( GPGME_PTHREAD_FOUND HAVE_GPGME_PTHREAD )
326 | macro_bool_to_01( GPGME_PTH_FOUND HAVE_GPGME_PTH )
327 |
328 | endif() # WIN32 | Unix
329 |
330 |
331 | set( _gpgme_flavours "" )
332 |
333 | if ( GPGME_VANILLA_FOUND )
334 | set( _gpgme_flavours "${_gpgme_flavours} vanilla" )
335 | endif()
336 |
337 | if ( GPGME_GLIB_FOUND )
338 | set( _gpgme_flavours "${_gpgme_flavours} Glib" )
339 | endif()
340 |
341 | if ( GPGME_QT_FOUND )
342 | set( _gpgme_flavours "${_gpgme_flavours} Qt" )
343 | endif()
344 |
345 | if ( GPGME_PTHREAD_FOUND )
346 | set( _gpgme_flavours "${_gpgme_flavours} pthread" )
347 | endif()
348 |
349 | if ( GPGME_PTH_FOUND )
350 | set( _gpgme_flavours "${_gpgme_flavours} pth" )
351 | endif()
352 |
353 | # determine the library in one of the found flavours, can be reused e.g. by FindQgpgme.cmake, Alex
354 | foreach(_currentFlavour vanilla glib qt pth pthread)
355 | if(NOT GPGME_LIBRARY_DIR)
356 | get_filename_component(GPGME_LIBRARY_DIR "${_gpgme_${_currentFlavour}_lib}" PATH)
357 | endif()
358 | endforeach()
359 |
360 | if ( NOT Gpgme_FIND_QUIETLY )
361 |
362 | if ( GPGME_FOUND )
363 | message( STATUS "Usable gpgme flavours found: ${_gpgme_flavours}" )
364 | else()
365 | message( STATUS "No usable gpgme flavours found." )
366 | endif()
367 |
368 | macro_bool_to_bool( Gpgme_FIND_REQUIRED _req )
369 |
370 | if ( WIN32 )
371 | set( _gpgme_homepage "http://www.gpg4win.org" )
372 | else()
373 | set( _gpgme_homepage "http://www.gnupg.org/related_software/gpgme" )
374 | endif()
375 |
376 | set_package_properties(Gpgme PROPERTIES DESCRIPTION "GNU Privacy Guard (GPG/PGP) support" URL ${_gpgme_homepage} PURPOSE "Necessary to compile many PIM applications, including KMail")
377 |
378 | else()
379 |
380 | if ( Gpgme_FIND_REQUIRED AND NOT GPGME_FOUND )
381 | message( FATAL_ERROR "Did not find GPGME" )
382 | endif()
383 |
384 | endif()
385 |
386 | set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS_gpgme_saved )
387 |
--------------------------------------------------------------------------------
/configs.cpp:
--------------------------------------------------------------------------------
1 | /* configs.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Defines the central class of fwknop-gui, holds the SPA data
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #include "configs.h"
21 | CURLcode curl_read(const std::string& url, std::ostream& os, long timeout = 30);
22 |
23 | void Config::getAllConfigs(wxArrayString * configs, wxFileConfig *configFile)
24 | {
25 | configFile->SetPath(wxT("/"));
26 | int numGroups = configFile->GetNumberOfGroups();
27 | wxString tmpGroup;
28 | long tmpindex;
29 | configs->Empty();
30 |
31 | if (numGroups > 0 )
32 | {
33 | configFile->GetFirstGroup(tmpGroup, tmpindex);
34 | configs->Insert(tmpGroup,0);
35 | numGroups--;
36 | while(numGroups > 0)
37 | {
38 | numGroups--;
39 | configFile->GetNextGroup(tmpGroup,tmpindex );
40 | configs->Insert(tmpGroup,0);
41 | }
42 | }
43 | configs->Sort();
44 | }
45 |
46 | wxString Config::validateConfig()
47 | {
48 | wxRegEx findIP( wxT("^(([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])$"));
49 | wxRegEx b64Validate( wxT("^[A-Za-z0-9+/]+={0,3}$"));
50 | wxRegEx portStringValidate( wxT("(tcp|udp)/+[0-9]"));
51 |
52 | if (this->NICK_NAME.CmpNoCase(wxEmptyString) == 0 ) {
53 | return wxT("You must choose a Nickname.");
54 | } else if (this->SERVER_IP.Find(_(".")) == wxNOT_FOUND) { //check for valid ip or hostname -- Relex this check greatly and throw the error when trying to send.
55 | return wxT("You must supply a valid server address.");
56 | } else if((wxAtoi(this->SERVER_PORT) < 1 || wxAtoi(this->SERVER_PORT) > 65535) && this->SERVER_PORT.CmpNoCase(wxT("Random")) != 0){
57 | return wxT("Invalid Server Port"); //check server port is valid port or random
58 | } else if (this->LEGACY == true && this->HMAC.CmpNoCase(wxEmptyString) != 0) {//check no hmac with legacy
59 | return wxT("You cannot use an HMAC in legacy mode.");
60 | } else if (this->KEY_BASE64 && wxStrlen(this->KEY) % 4 != 0) { //check base64 must have a multiple of 4 length
61 | return wxT("Invalid Base64 Key Length.");
62 | } else if (this->KEY_BASE64 && !b64Validate.Matches(this->KEY)) { // looks for disallowed b64 characters
63 | return wxT("Invalid Base64 Key.");
64 | } else if (this->HMAC_BASE64 && wxStrlen(this->HMAC) % 4 != 0) { //check base64 must have a multiple of 4 length
65 | return wxT("Invalid Base64 HMAC Length.");
66 | } else if (this->HMAC_BASE64 && !b64Validate.Matches(this->HMAC)) { // looks for disallowed b64 characters
67 | return wxT("Invalid Base64 HMAC.");
68 | } else if (!(this->MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0 || portStringValidate.Matches(this->PORTS))) { //If not a server command, make sure the port string is valid
69 | return wxT("Invalid Port string. Must look like tcp/22.");
70 | } else if (!(this->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0 || this->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0 || this->ACCESS_IP.CmpNoCase(wxT("Prompt IP")) == 0 || findIP.Matches(this->ACCESS_IP) )) { //if specifying ip, make sure is valid
71 | return wxT("Invalid IP to allow."); // Have to have a valid ip to allow, if using allow ip
72 | } else if (this->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0 && !(0 < wxAtoi(NAT_PORT) && wxAtoi(NAT_PORT) < 65536)) { //NAT_IP must be a valid ip, and NAT_PORT must be a valid port
73 | return wxT("Invalid NAT port.");
74 | } else if (!(this->DIGEST_TYPE.CmpNoCase(wxT("MD5")) == 0
75 | || this->DIGEST_TYPE.CmpNoCase(wxT("SHA1")) == 0
76 | || this->DIGEST_TYPE.CmpNoCase(wxT("SHA256")) == 0
77 | || this->DIGEST_TYPE.CmpNoCase(wxT("SHA384")) == 0
78 | || this->DIGEST_TYPE.CmpNoCase(wxT("SHA512")) == 0)) {
79 | return wxT("Invalid SPA digest type.");
80 | } else if (!(this->HMAC_TYPE.CmpNoCase(wxT("MD5")) == 0
81 | || this->HMAC_TYPE.CmpNoCase(wxT("SHA1")) == 0
82 | || this->HMAC_TYPE.CmpNoCase(wxT("SHA256")) == 0
83 | || this->HMAC_TYPE.CmpNoCase(wxT("SHA384")) == 0
84 | || this->HMAC_TYPE.CmpNoCase(wxT("SHA512")) == 0)) {
85 | return wxT("Invalid HMAC digest type.");
86 | } else { //Could check for valid looking gpg keys if enabled
87 | return wxT("valid");
88 | }
89 | }
90 |
91 | void Config::saveConfig(wxFileConfig *configFile)
92 | {
93 | configFile->SetPath(wxT("/") + this->NICK_NAME);
94 | configFile->Write(wxT("SERVER_IP"), this->SERVER_IP);
95 | configFile->Write(wxT("LEGACY"), this->LEGACY);
96 | configFile->Write(wxT("SERVER_PORT"), this->SERVER_PORT);
97 | configFile->Write(wxT("PROTOCOL"), this->PROTOCOL);
98 | configFile->Write(wxT("KEY"), this->KEY);
99 | configFile->Write(wxT("KEY_BASE64"), this->KEY_BASE64);
100 | configFile->Write(wxT("HMAC"), this->HMAC);
101 | configFile->Write(wxT("HMAC_BASE64"), this->HMAC_BASE64);
102 | configFile->Write(wxT("MESS_TYPE"), this->MESS_TYPE);
103 | configFile->Write(wxT("ACCESS_IP"), this->ACCESS_IP);
104 | configFile->Write(wxT("PORTS"), this->PORTS);
105 | configFile->Write(wxT("SERVER_TIMEOUT"), this->SERVER_TIMEOUT);
106 | configFile->Write(wxT("NAT_IP"), this->NAT_IP);
107 | configFile->Write(wxT("NAT_PORT"), this->NAT_PORT);
108 | configFile->Write(wxT("SERVER_CMD"), this->SERVER_CMD);
109 | configFile->Write(wxT("DIGEST_TYPE"), this->DIGEST_TYPE);
110 | configFile->Write(wxT("HMAC_TYPE"), this->HMAC_TYPE);
111 | configFile->Write(wxT("KEEP_OPEN"), this->KEEP_OPEN);
112 | configFile->Write(wxT("USE_GPG_CRYPT"), this->USE_GPG_CRYPT);
113 | configFile->Write(wxT("GPG_CRYPT_ID"), this->GPG_CRYPT_ID);
114 | configFile->Write(wxT("GPG_SIG_ID"), this->GPG_SIG_ID);
115 | configFile->Flush();
116 |
117 | }
118 |
119 | void Config::loadConfig(wxString Nick, wxFileConfig *configFile)
120 | {
121 | configFile->SetPath(wxT("/") + Nick);
122 |
123 | this->NICK_NAME = Nick;
124 | this->SERVER_IP = configFile->Read(wxT("SERVER_IP"));
125 | configFile->Read(wxT("LEGACY"), &this->LEGACY, false);
126 | this->SERVER_PORT = configFile->Read(wxT("SERVER_PORT"));
127 | this->PROTOCOL = configFile->Read(wxT("PROTOCOL"));
128 | this->KEY = configFile->Read(wxT("KEY"));
129 | configFile->Read(wxT("KEY_BASE64"), &this->KEY_BASE64, false);
130 | this->HMAC = configFile->Read(wxT("HMAC"));
131 | configFile->Read(wxT("HMAC_BASE64"), &this->HMAC_BASE64, false);
132 | this->MESS_TYPE = configFile->Read(wxT("MESS_TYPE"));
133 | this->ACCESS_IP = configFile->Read(wxT("ACCESS_IP"));
134 | this->PORTS = configFile->Read(wxT("PORTS"));
135 | this->SERVER_TIMEOUT = configFile->Read(wxT("SERVER_TIMEOUT"));
136 | this->NAT_IP = configFile->Read(wxT("NAT_IP"));
137 | this->NAT_PORT = configFile->Read(wxT("NAT_PORT"));
138 | this->SERVER_CMD = configFile->Read(wxT("SERVER_CMD"));
139 | this->DIGEST_TYPE = configFile->Read(wxT("DIGEST_TYPE"), wxT("SHA256"));
140 | this->HMAC_TYPE = configFile->Read(wxT("HMAC_TYPE"), wxT("SHA256"));
141 | configFile->Read(wxT("KEEP_OPEN"), &this->KEEP_OPEN, false);
142 |
143 | configFile->Read(wxT("USE_GPG_CRYPT"), &this->USE_GPG_CRYPT, false);
144 | this->GPG_CRYPT_ID = configFile->Read(wxT("GPG_CRYPT_ID"), wxEmptyString);
145 | this->GPG_SIG_ID = configFile->Read(wxT("GPG_SIG_ID"), wxEmptyString);
146 | }
147 |
148 | void Config::defaultConfig()
149 | {
150 |
151 | this->NICK_NAME = wxEmptyString;
152 | this->SERVER_IP = wxEmptyString;
153 | this->LEGACY = false;
154 | this->SERVER_PORT = wxT("62201");
155 | this->PROTOCOL = wxT("UDP");
156 | this->KEY = wxEmptyString;
157 | this->KEY_BASE64 = false;
158 | this->HMAC = wxEmptyString;
159 | this->HMAC_BASE64 = false;
160 | this->MESS_TYPE = wxT("Open Port");
161 | this->ACCESS_IP = wxT("Resolve IP");
162 | this->PORTS = wxT("tcp/22");
163 | this->SERVER_TIMEOUT = wxT("60");
164 | this->NAT_IP = wxEmptyString;
165 | this->NAT_PORT = wxEmptyString;
166 | this->SERVER_CMD = wxEmptyString;
167 | this->DIGEST_TYPE = wxT("SHA256");
168 | this->HMAC_TYPE = wxT("SHA256");
169 | this->KEEP_OPEN = false;
170 | this->USE_GPG_CRYPT = false;
171 | this->GPG_CRYPT_ID = wxEmptyString;
172 | this->GPG_SIG_ID = wxEmptyString;
173 | }
174 |
175 | wxString Config::gen_SPA(wxString ip_resolver_url, wxString gpgEngine, wxString gpgHomeFolder, bool debug)
176 | {
177 | CURLcode curl_Res;
178 | fko_ctx_t ctx;
179 | fwknop_options_t opts;
180 | int key_len = 0;
181 | int res;
182 | int hmac_str_len = 0;
183 | short message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG;
184 | short digest_type = FKO_DIGEST_SHA256;
185 | short hmac_type = FKO_HMAC_SHA256;
186 | char key_str[129] = {0}, hmac_str[129] = {0};
187 | char spa_msg[256] = {0};
188 | // char spa_buf[4096] = {0};
189 | // char * spa_buf_ptr;
190 | // char crypt_buf[4096] = {0};
191 | char nat_access_str[25] = {0};
192 | // char * hmac_buf;
193 | // char * spa_digest_ptr;
194 |
195 |
196 | memset(&opts, 0, sizeof(fwknop_options_t));
197 |
198 | if (this->KEY.IsEmpty() && !this->USE_GPG_CRYPT)
199 | return _("Key cannot be blank!");
200 |
201 | wxBusyInfo wait(_("Please wait, working..."));
202 | if (this->SERVER_PORT.CmpNoCase(wxT("random")) == 0)
203 | {
204 | srand((int)wxGetLocalTime());
205 | this->SERVER_PORT.Empty();
206 | this->SERVER_PORT << (rand()%55535 + 10000); // do this better, this isn't a horribly good random function
207 | }
208 | if (this->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0)
209 | this->ACCESS_IP = wxT("0.0.0.0");
210 | else if (this->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0)
211 | {
212 | std::ostringstream oss;
213 | curl_Res = curl_read(std::string(ip_resolver_url.mb_str()), oss);
214 | if (curl_Res == CURLE_OK)
215 | {
216 | wxString result_tmp = wxString::FromUTF8(oss.str().c_str());
217 | wxRegEx findIP( wxT("(([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]{1}|[0-9]{2}|[0-1][0-9]{2}|2[0-4][0-9]|25[0-5])"));
218 | if (!findIP.Matches(result_tmp))
219 | return _("Unable to resolve our IP!");
220 |
221 | this->ACCESS_IP = findIP.GetMatch(result_tmp);
222 | } else
223 | return _("Libcurl returned the error: ") + wxString::FromUTF8(curl_easy_strerror(curl_Res));
224 |
225 | } //end resolve ip
226 | if (fko_new(&ctx) != FKO_SUCCESS)
227 | return _("Could not get new FKO context");
228 |
229 | if (USE_GPG_CRYPT) {
230 | fko_set_spa_encryption_type(ctx, FKO_ENCRYPTION_GPG);
231 | fko_set_gpg_exe(ctx, gpgEngine.mb_str());
232 | fko_set_gpg_home_dir(ctx, gpgHomeFolder.mb_str());
233 |
234 |
235 | fko_set_gpg_recipient(ctx, GPG_CRYPT_ID.mb_str());
236 | if (GPG_SIG_ID.CmpNoCase(_("None")) != 0)
237 | fko_set_gpg_signer(ctx, GPG_SIG_ID.mb_str());
238 |
239 |
240 |
241 | fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_ASYMMETRIC);
242 |
243 | } else {
244 | if (this->KEY_BASE64)
245 | {
246 | key_len = fko_base64_decode(this->KEY.mb_str(), (unsigned char *)key_str);
247 | } else {
248 | strncpy(key_str, (const char*)this->KEY.mb_str(wxConvUTF8), 128);
249 | key_len = (int)strlen(key_str);
250 | }
251 | }
252 |
253 | if (this->HMAC_BASE64)
254 | {
255 | hmac_str_len = fko_base64_decode(this->HMAC.mb_str(), (unsigned char *)hmac_str);
256 | } else {
257 | strncpy(hmac_str, (const char*)this->HMAC.mb_str(wxConvUTF8), 128);
258 | hmac_str_len = (int)strlen(hmac_str);
259 | }
260 |
261 |
262 |
263 | if (MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0)
264 | {
265 | message_type = FKO_COMMAND_MSG;
266 | if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
267 | return _("Could not set message type");
268 |
269 | snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->SERVER_CMD.mb_str(wxConvUTF8));
270 | res = fko_set_spa_message(ctx, spa_msg);
271 | if (res != FKO_SUCCESS)
272 | return _("Could not set command message");
273 |
274 | } else {
275 | if (fko_set_spa_client_timeout(ctx, wxAtoi(this->SERVER_TIMEOUT)) != FKO_SUCCESS)
276 | return _("Could not set SPA timeout");
277 |
278 | snprintf(spa_msg, 256, "%s,%s", (const char*)this->ACCESS_IP.mb_str(wxConvUTF8), (const char*)this->PORTS.mb_str(wxConvUTF8));
279 | if (fko_set_spa_message(ctx, spa_msg) != FKO_SUCCESS)
280 | return _("Could not set SPA Message");
281 |
282 | }
283 | if (this->LEGACY) { // technically should trim hmac keys
284 | if (fko_set_spa_encryption_mode(ctx, FKO_ENC_MODE_CBC_LEGACY_IV) != FKO_SUCCESS)
285 | return _("Could not set Legacy mode.");
286 |
287 | }
288 | if (!this->HMAC.IsEmpty()){
289 | if (this->HMAC_TYPE.CmpNoCase(wxT("MD5"))==0)
290 | hmac_type = FKO_HMAC_MD5;
291 | else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA1"))==0)
292 | hmac_type = FKO_HMAC_SHA1;
293 | else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA256"))==0)
294 | hmac_type = FKO_HMAC_SHA256;
295 | else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA384"))==0)
296 | hmac_type = FKO_HMAC_SHA384;
297 | else if (this->HMAC_TYPE.CmpNoCase(wxT("SHA512"))==0)
298 | hmac_type = FKO_HMAC_SHA512;
299 | if (fko_set_spa_hmac_type(ctx, hmac_type) != FKO_SUCCESS)
300 | return _("Could not set HMAC type.");
301 |
302 | }
303 | if (this->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0)
304 | {
305 | sprintf(nat_access_str, "%s,%s", (const char*)this->NAT_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
306 | if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
307 | return _("Could not set nat access string.");
308 |
309 | } else if (this->MESS_TYPE.CmpNoCase(wxT("Local Nat Access")) == 0) {
310 | message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG;
311 | if (fko_set_spa_message_type(ctx, message_type) != FKO_SUCCESS)
312 | return _("Chould not set message type");
313 | sprintf(nat_access_str, "%s,%s", (const char*)this->SERVER_IP.mb_str(wxConvUTF8), (const char*)this->NAT_PORT.mb_str(wxConvUTF8));
314 | if (fko_set_spa_nat_access(ctx, nat_access_str) != FKO_SUCCESS)
315 | return _("Could not set nat access string.");
316 | }
317 | if (this->DIGEST_TYPE.CmpNoCase(wxT("MD5"))==0)
318 | digest_type = FKO_DIGEST_MD5;
319 | else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA1"))==0)
320 | digest_type = FKO_DIGEST_SHA1;
321 | else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA256"))==0)
322 | digest_type = FKO_DIGEST_SHA256;
323 | else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA384"))==0)
324 | digest_type = FKO_DIGEST_SHA384;
325 | else if (this->DIGEST_TYPE.CmpNoCase(wxT("SHA512"))==0)
326 | digest_type = FKO_DIGEST_SHA512;
327 | if (fko_set_spa_digest_type(ctx, digest_type) != FKO_SUCCESS)
328 | return _("Could not set SPA digest type.");
329 | if (fko_spa_data_final(ctx, key_str, key_len, hmac_str, hmac_str_len) != FKO_SUCCESS)
330 | return _("Could not generate SPA data.");
331 |
332 | if (fko_get_spa_data(ctx, &opts.spa_data) != FKO_SUCCESS)
333 | return _("Could not retrieve SPA data.");
334 | // if (!USE_GPG_CRYPT) {
335 | this->SPA_STRING = wxString::FromUTF8(opts.spa_data);
336 | /*} else { //could retain this for libfko without gpg support
337 | fko_get_encoded_data(ctx, &spa_buf_ptr);
338 | fko_get_spa_digest(ctx, &spa_digest_ptr);
339 | sprintf(spa_buf,"%s:%s", spa_buf_ptr, spa_digest_ptr);
340 | ourGPG->encryptAndSign(GPG_CRYPT_ID, GPG_SIG_ID, spa_buf, crypt_buf);
341 | fko_set_spa_data(ctx, crypt_buf);
342 | fko_set_spa_hmac(ctx, hmac_str, hmac_str_len);
343 | fko_get_spa_hmac(ctx, &hmac_buf);
344 | strcat(crypt_buf, hmac_buf);
345 | this->SPA_STRING = wxString::FromUTF8(crypt_buf + 2);
346 |
347 | }*/
348 |
349 | if (debug) {
350 | wxTextEntryDialog *debugMessage = new wxTextEntryDialog(NULL, _("Debug info"), _("Debug info"), "Source IP: " + this->ACCESS_IP +"\n" + "SPA String: " + this->SPA_STRING, wxOK | wxTE_MULTILINE );
351 | debugMessage->SetSize(620, 320);
352 | debugMessage->ShowModal();
353 | debugMessage->Destroy();
354 | }
355 | return _("Success");
356 | }
357 |
358 | wxString Config::send_SPA(wxIPV4address *serverAddr)
359 | {
360 | //wxGetTextFromUser(wxEmptyString, wxEmptyString, this->SPA_STRING);//Make this part of debug
361 |
362 | if (this->PROTOCOL.CmpNoCase(wxT("UDP")) == 0) {
363 |
364 | wxIPV4address ourAddr;
365 | ourAddr.AnyAddress();
366 | ourAddr.Service(0);
367 |
368 | if (serverAddr->Service(this->SERVER_PORT))
369 | {
370 | wxDatagramSocket *m_socket;
371 | m_socket = new wxDatagramSocket(ourAddr, wxSOCKET_NOWAIT);
372 | m_socket->SendTo(*serverAddr, this->SPA_STRING.mb_str(), this->SPA_STRING.Len());
373 | m_socket->WaitForWrite();
374 | if (m_socket->Error()) {
375 | m_socket->Destroy();
376 | return(_("Could not send knock: Error sending."));
377 | } else {
378 | m_socket->Destroy();
379 | return(_("Knock sent successfully."));
380 | }
381 |
382 |
383 | } else
384 | return(_("Could not send knock: could not set server port."));
385 |
386 | } else if (this->PROTOCOL.CmpNoCase(wxT("TCP")) == 0) {
387 | wxIPV4address ourAddr;
388 | ourAddr.AnyAddress();
389 | ourAddr.Service(0);
390 |
391 | if (serverAddr->Service(this->SERVER_PORT))
392 | {
393 | wxSocketClient *tcp_socket = new wxSocketClient;
394 | tcp_socket->Connect(*serverAddr);
395 | tcp_socket->WaitForWrite();
396 | tcp_socket->Write(this->SPA_STRING.mb_str(), this->SPA_STRING.Len());
397 | tcp_socket->WaitForWrite();
398 | if (tcp_socket->Error()) {
399 | tcp_socket->Destroy();
400 | return(_("Could not send knock: Error sending."));
401 | } else {
402 | tcp_socket->Destroy();
403 | return(_("Knock sent successfully."));
404 | }
405 |
406 |
407 | } else
408 | return(_("Could not send knock: could not set server address."));
409 |
410 | } else if (this->PROTOCOL.CmpNoCase(wxT("HTTP")) == 0) {
411 | wxHTTP *http_serv = new wxHTTP;
412 | http_serv->Connect(this->SERVER_IP, wxAtoi(this->SERVER_PORT));
413 | wxInputStream *tmp_stream;
414 | tmp_stream = http_serv->GetInputStream(this->SPA_STRING);
415 | delete tmp_stream;
416 | http_serv->Destroy();
417 | return(_("Knock sent successfully."));
418 |
419 | } else
420 | return(_("Not implemented yet"));
421 | return(_("Unknown error"));
422 |
423 | }
424 |
425 | static size_t data_write(void* buf, size_t size, size_t nmemb, void* userp)
426 | {
427 | if(userp)
428 | {
429 | std::ostream& os = *static_cast(userp);
430 | std::streamsize len = size * nmemb;
431 | if(os.write(static_cast(buf), len))
432 | return len;
433 | }
434 |
435 | return 0;
436 | }
437 |
438 | /**
439 | * timeout is in seconds
440 | **/
441 | CURLcode curl_read(const std::string& url, std::ostream& os, long timeout)
442 | {
443 | CURLcode code(CURLE_FAILED_INIT);
444 | CURL* curl = curl_easy_init();
445 |
446 | if(curl)
447 | {
448 | if(CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &data_write))
449 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L))
450 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L))
451 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FILE, &os))
452 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout))
453 | #ifdef __WIN32__
454 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_CAINFO, "./ca-bundle.crt"))
455 | #endif
456 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_URL, url.c_str())))
457 |
458 | {
459 | code = curl_easy_perform(curl);
460 | }
461 | curl_easy_cleanup(curl);
462 | }
463 | return code;
464 | }
465 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 | {one line to give the program's name and a brief idea of what it does.}
635 | Copyright (C) {year} {name of author}
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | {project} Copyright (C) {year} {fullname}
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
676 |
--------------------------------------------------------------------------------
/fwknop_guiMain.cpp:
--------------------------------------------------------------------------------
1 | /* fwknop_guiMain.cpp
2 | * Copyright (C) 2016 Jonathan Bennett
3 | * Application frame
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 | */
19 |
20 | #ifdef WX_PRECOMP
21 | #include "wx_pch.h"
22 | #endif
23 |
24 | #ifdef __BORLANDC__
25 | #pragma hdrstop
26 | #endif //__BORLANDC__
27 |
28 | #include "fwknop_guiMain.h"
29 | CURLcode curl_read(const std::string& url, std::ostream& os, long timeout = 30);
30 |
31 | //helper functions
32 | enum wxbuildinfoformat {
33 | short_f, long_f };
34 |
35 | wxString wxbuildinfo(wxbuildinfoformat format)
36 | {
37 | wxString wxbuild(wxVERSION_STRING);
38 |
39 | if (format == long_f )
40 | {
41 | #if defined(__WXMSW__)
42 | wxbuild << _T("-Windows");
43 | #elif defined(__WXMAC__)
44 | wxbuild << _T("-Mac");
45 | #elif defined(__UNIX__)
46 | wxbuild << _T("-Linux");
47 | #endif
48 |
49 | #if wxUSE_UNICODE
50 | wxbuild << _T("-Unicode build");
51 | #else
52 | wxbuild << _T("-ANSI build");
53 | #endif // wxUSE_UNICODE
54 | }
55 |
56 | return wxbuild;
57 | }
58 |
59 | BEGIN_EVENT_TABLE(fwknop_guiFrame, wxFrame)
60 | EVT_CLOSE(fwknop_guiFrame::OnClose)
61 | EVT_MENU(idMenuQuit, fwknop_guiFrame::OnQuit)
62 | EVT_MENU(idMenuNew, fwknop_guiFrame::OnNew)
63 | EVT_MENU(idMenuLocation, fwknop_guiFrame::OnLocation)
64 | EVT_MENU(idMenuDelete, fwknop_guiFrame::OnDelete)
65 | EVT_MENU(idMenuAbout, fwknop_guiFrame::OnAbout)
66 | EVT_MENU(idMenuHelpScreen, fwknop_guiFrame::OnHelpScreen)
67 | EVT_MENU(idMenuSettings, fwknop_guiFrame::OnSettings)
68 | EVT_MENU(idMenuWizard, fwknop_guiFrame::OnWizard)
69 | EVT_MENU(idMenuImport, fwknop_guiFrame::OnImport)
70 | EVT_MENU(idMenuExport, fwknop_guiFrame::OnExport)
71 | EVT_MENU(idMenuQR, fwknop_guiFrame::OnQR)
72 | EVT_MENU(idMenugpgEngine, fwknop_guiFrame::gpgEngine)
73 | EVT_MENU(idMenugpgFolder, fwknop_guiFrame::gpgFolder)
74 | EVT_MENU(idMenugpgDefaults, fwknop_guiFrame::gpgDefaults)
75 | EVT_CHECKBOX(ID_Random, fwknop_guiFrame::OnChoice)
76 | EVT_CHOICE(ID_AllowIP, fwknop_guiFrame::OnChoice)
77 | EVT_CHOICE(ID_MessType, fwknop_guiFrame::OnChoice)
78 | EVT_CHECKBOX(ID_USE_GPG, fwknop_guiFrame::OnChoice)
79 | EVT_BUTTON(ID_SaveButton, fwknop_guiFrame::OnSave)
80 | EVT_BUTTON(ID_KnockButton, fwknop_guiFrame::OnKnock)
81 | EVT_LISTBOX(ID_List, fwknop_guiFrame::OnLoad)
82 | EVT_HTML_LINK_CLICKED(ID_html, fwknop_guiFrame::OnLink)
83 | END_EVENT_TABLE()
84 |
85 | fwknop_guiFrame::fwknop_guiFrame(wxFrame *frame, const wxString& title)
86 | : wxFrame(frame, wxID_ANY, title, wxPoint(-1, -1), wxSize(800, 600))
87 | {
88 | configFile = new wxFileConfig (wxT("fwknop-gui"));
89 | if (wxGetOsVersion() & wxOS_WINDOWS) {
90 | if (configFile->GetNumberOfEntries(true) == 0) {
91 | if (wxFileExists(_(wxGetHomeDir() + "\\fwknop-gui.ini"))) {
92 | wxRenameFile(wxGetHomeDir() + "\\fwknop-gui.ini", wxStandardPaths::Get().GetUserConfigDir() + "\\fwknop-gui.ini", false);
93 | delete configFile;
94 | configFile = new wxFileConfig (wxT("fwknop-gui"));
95 | }
96 | }
97 | }
98 |
99 | //#if wxUSE_MENUS
100 | // create a menu bar
101 | wxMenuBar* mbar = new wxMenuBar();
102 | wxMenu* fileMenu = new wxMenu(_T(""));
103 | fileMenu->Append(idMenuSettings, _("Settings"));
104 | fileMenu->Append(idMenuNew, _("&New Config"));
105 | fileMenu->Append(idMenuDelete, _("&Delete Config"));
106 | fileMenu->Append(idMenuLocation, _("&Choose Config File"));
107 | fileMenu->Append(idMenuQuit, _("&Quit\tAlt-F4"), _("Quit the application"));
108 | mbar->Append(fileMenu, _("&File"));
109 |
110 | wxMenu* toolsMenu = new wxMenu(_T(""));
111 | toolsMenu->Append(idMenuWizard, _("&Access.conf wizard"));
112 | toolsMenu->Append(idMenuImport, _("&Import from fwknoprc file"));
113 | toolsMenu->Append(idMenuExport, _("&Export as fwknoprc file"));
114 | toolsMenu->Append(idMenuQR, _("&Export as QR code"));
115 | mbar->Append(toolsMenu, _("&Tools"));
116 |
117 | wxMenu* GPGMenu = new wxMenu(_T(""));
118 |
119 | mbar->Append(GPGMenu, _("&GPG"));
120 | ourGPG = new gpgme_wrapper;
121 | GPGKeys = new wxArrayString;
122 | GPGSigKeys = new wxArrayString;
123 | GPGMenu->Append(idMenugpgFolder, _("&GPG Home"), _("GPG Home Directory"));
124 | GPGMenu->Append(idMenugpgEngine, _("&GPG Engine"), _("GPG Engine"));
125 | GPGMenu->Append(idMenugpgDefaults, _("&GPG Defaults"), _("Resets GPG Engine and Folder to defaults"));
126 | if (ourGPG->doInit(configFile)) {
127 | ourGPG->getAllKeys(GPGKeys);
128 | ourGPG->getAllKeys(GPGSigKeys);
129 | GPGSigKeys->Insert( _("None"), 0);
130 | } else {
131 | GPGKeys->Insert( _("Disabled"), 0);
132 | GPGSigKeys->Insert( _("Disabled"), 0);
133 |
134 | }
135 |
136 |
137 | wxMenu* helpMenu = new wxMenu(_T(""));
138 | helpMenu->Append(idMenuAbout, _("&About\tF1"), _("Show info about this application"));
139 | helpMenu->Append(idMenuHelpScreen, _("&Help Screen"), _("Show help screen"));
140 | mbar->Append(helpMenu, _("&Help"));
141 |
142 | SetMenuBar(mbar);
143 |
144 | // Where we set up the gui. All the interesting things will happen in event handlers
145 |
146 | curl_global_init(CURL_GLOBAL_DEFAULT);
147 | wxColour *BackGround = new wxColour(233,233,233);
148 | this->SetBackgroundColour(*BackGround);
149 |
150 | hbox = new wxBoxSizer(wxHORIZONTAL);
151 | wxBoxSizer *vListBox = new wxBoxSizer(wxVERTICAL);
152 | vConfigBox = new wxBoxSizer(wxVERTICAL);
153 | vConfigBoxSuper = new wxBoxSizer(wxVERTICAL);
154 | vConfigScroll = new wxScrolledWindow(this);
155 |
156 |
157 | //The following are the sizers for each line of config:
158 | wxBoxSizer *hNickBox = new wxBoxSizer(wxHORIZONTAL);
159 | wxBoxSizer *hServAddrBox = new wxBoxSizer(wxHORIZONTAL);
160 | wxBoxSizer *hLegacyBox = new wxBoxSizer(wxHORIZONTAL);
161 | wxBoxSizer *hRandomBox = new wxBoxSizer(wxHORIZONTAL);
162 | hServPortBox = new wxBoxSizer(wxHORIZONTAL);
163 | wxBoxSizer *hProtoBox = new wxBoxSizer(wxHORIZONTAL);
164 | wxBoxSizer *hUseGPGBox = new wxBoxSizer(wxHORIZONTAL);
165 | hGPGChoiceBox = new wxBoxSizer(wxHORIZONTAL);
166 | hKeyBox = new wxBoxSizer(wxHORIZONTAL);
167 | hKeyB64Box = new wxBoxSizer(wxHORIZONTAL);
168 | wxBoxSizer *hHmacKeyBox = new wxBoxSizer(wxHORIZONTAL);
169 | wxBoxSizer *hHmacB64Box = new wxBoxSizer(wxHORIZONTAL);
170 | wxBoxSizer *hAllowIPBox = new wxBoxSizer(wxHORIZONTAL);
171 | hIPToAllowBox = new wxBoxSizer(wxHORIZONTAL);
172 | wxBoxSizer *hMessTypeBox = new wxBoxSizer(wxHORIZONTAL);
173 | hAccessPortsBox = new wxBoxSizer(wxHORIZONTAL);
174 | hFwTimeBox = new wxBoxSizer(wxHORIZONTAL);
175 | hKeepAliveBox = new wxBoxSizer(wxHORIZONTAL);
176 | hInternalIPBox = new wxBoxSizer(wxHORIZONTAL);
177 | hInternalPortBox = new wxBoxSizer(wxHORIZONTAL);
178 | hServCmdBox = new wxBoxSizer(wxHORIZONTAL);
179 | wxBoxSizer *hDigestTypeBox = new wxBoxSizer(wxHORIZONTAL);
180 | wxBoxSizer *hHmacTypeBox = new wxBoxSizer(wxHORIZONTAL);
181 |
182 | initMessTypeEvent = new wxCommandEvent(wxEVT_COMMAND_CHOICE_SELECTED, ID_MessType);
183 | initAllowIPEvent = new wxCommandEvent(wxEVT_COMMAND_CHOICE_SELECTED, ID_AllowIP);
184 | initCheckboxEvent = new wxCommandEvent(wxEVT_COMMAND_CHOICE_SELECTED, ID_Random);
185 |
186 |
187 | ourConfigList = new wxArrayString;
188 | ourConfig = new Config;
189 |
190 | wxButton *save = new wxButton(this, ID_SaveButton, wxT("Save Config"), wxDefaultPosition, wxSize(250, 40));
191 |
192 |
193 | wxStaticText *NickLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Nickname: "));
194 | NickTxt = new wxTextCtrl(vConfigScroll, wxID_ANY);
195 |
196 | hNickBox->Add(NickLbl,0,wxALIGN_BOTTOM);
197 | hNickBox->Add(NickTxt,1, wxEXPAND);
198 |
199 |
200 | wxStaticText *ServAddrLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Server Address: "));
201 | ServAddrTxt = new wxTextCtrl(vConfigScroll, wxID_ANY);
202 |
203 | hServAddrBox->Add(ServAddrLbl,0,wxALIGN_BOTTOM);
204 | hServAddrBox->Add(ServAddrTxt,1, wxEXPAND);
205 |
206 |
207 | LegacyChk = new wxCheckBox(vConfigScroll, wxID_ANY,wxT("Use Legacy Mode"));
208 | hLegacyBox->Add(LegacyChk);
209 |
210 | RandomChk = new wxCheckBox(vConfigScroll, ID_Random,wxT("Use Random Port"));
211 | hRandomBox->Add(RandomChk);
212 |
213 | wxStaticText *ServPortLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Server Port: "));
214 | ServPortTxt = new wxTextCtrl(vConfigScroll, wxID_ANY,wxT("62201"));
215 |
216 | hServPortBox->Add(ServPortLbl,0,wxALIGN_BOTTOM);
217 | hServPortBox->Add(ServPortTxt,1, wxEXPAND);
218 |
219 | //Protocol choice
220 | wxStaticText *ProtoLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Protocol: "));
221 |
222 | wxArrayString Protos;
223 | Protos.Add(wxT("UDP"));
224 | Protos.Add(wxT("TCP"));
225 | Protos.Add(wxT("HTTP"));
226 | ProtoChoice = new wxChoice(vConfigScroll,wxID_ANY, wxDefaultPosition, wxDefaultSize, Protos);
227 |
228 | hProtoBox->Add(ProtoLbl,0,wxALIGN_BOTTOM);
229 | hProtoBox->Add(ProtoChoice);
230 | ProtoChoice->SetSelection(0);
231 |
232 |
233 | //GPG Checkbox
234 | wxStaticText *GPGLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Use GPG: "));
235 | GPGChk = new wxCheckBox(vConfigScroll, ID_USE_GPG, wxT(""));
236 |
237 | hUseGPGBox->Add(GPGLbl);
238 | hUseGPGBox->Add(GPGChk);
239 |
240 |
241 | //GPG field
242 | wxStaticText *GPGChoiceLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("GPG Encryption Key: "));
243 | GPGEncryptKey = new wxChoice(vConfigScroll,wxID_ANY, wxDefaultPosition, wxDefaultSize, *GPGKeys);
244 | wxStaticText *GPGChoiceLbl2 = new wxStaticText(vConfigScroll,wxID_ANY, wxT("GPG Signature Key: "));
245 | GPGSignatureKey = new wxChoice(vConfigScroll,wxID_ANY, wxDefaultPosition, wxDefaultSize, *GPGSigKeys);
246 | hGPGChoiceBox->Add(GPGChoiceLbl);
247 | hGPGChoiceBox->Add(GPGEncryptKey);
248 | hGPGChoiceBox->Add(GPGChoiceLbl2);
249 | hGPGChoiceBox->Add(GPGSignatureKey);
250 | //Key field
251 | wxStaticText *KeyLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Rijndael Key: "));
252 | KeyTxt = new wxTextCtrl(vConfigScroll, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD);
253 | //KeyTxt->SetWindowStyleFlag(wxTE_PASSWORD);
254 |
255 | hKeyBox->Add(KeyLbl,0,wxALIGN_BOTTOM);
256 | hKeyBox->Add(KeyTxt,1, wxEXPAND);
257 |
258 |
259 | KeyB64Chk = new wxCheckBox(vConfigScroll, wxID_ANY,wxT("Key Is Base 64"));
260 |
261 | hKeyB64Box->Add(KeyB64Chk);
262 |
263 | wxStaticText *DigestTypeLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("SPA Digest Type: "));
264 | wxArrayString DigestType;
265 | DigestType.Add(wxT("MD5"));
266 | DigestType.Add(wxT("SHA1"));
267 | DigestType.Add(wxT("SHA256"));
268 | DigestType.Add(wxT("SHA384"));
269 | DigestType.Add(wxT("SHA512"));
270 | DigestTypeChoice = new wxChoice(vConfigScroll, ID_DigestType, wxDefaultPosition, wxDefaultSize,
271 | DigestType);
272 |
273 | hDigestTypeBox->Add(DigestTypeLbl,0,wxALIGN_BOTTOM);
274 | hDigestTypeBox->Add(DigestTypeChoice);
275 | DigestTypeChoice->SetSelection(2);
276 |
277 |
278 |
279 | wxStaticText *HmacKeyLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("HMAC Key: "));
280 | HmacKeyTxt = new wxTextCtrl(vConfigScroll, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD);
281 | //HmacKeyTxt->SetWindowStyleFlag(wxTE_PASSWORD);
282 |
283 |
284 | hHmacKeyBox->Add(HmacKeyLbl,0,wxALIGN_BOTTOM);
285 | hHmacKeyBox->Add(HmacKeyTxt,1, wxEXPAND);
286 |
287 |
288 | HmacKeyB64Chk = new wxCheckBox(vConfigScroll, wxID_ANY,wxT("HMAC Is Base 64"));
289 |
290 | hHmacB64Box->Add(HmacKeyB64Chk);
291 |
292 |
293 |
294 |
295 | wxStaticText *HmacTypeLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("SPA HMAC Type: "));
296 | wxArrayString HmacType;
297 | HmacType.Add(wxT("MD5"));
298 | HmacType.Add(wxT("SHA1"));
299 | HmacType.Add(wxT("SHA256"));
300 | HmacType.Add(wxT("SHA384"));
301 | HmacType.Add(wxT("SHA512"));
302 | HmacTypeChoice = new wxChoice(vConfigScroll, ID_HmacType, wxDefaultPosition, wxDefaultSize,
303 | HmacType);
304 |
305 | hHmacTypeBox->Add(HmacTypeLbl,0,wxALIGN_BOTTOM);
306 | hHmacTypeBox->Add(HmacTypeChoice);
307 | HmacTypeChoice->SetSelection(2);
308 |
309 | wxStaticText *AllowIPLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Allow IP: "));
310 |
311 | wxArrayString AllowIP;
312 | AllowIP.Add(wxT("Resolve IP"));
313 | AllowIP.Add(wxT("Source IP"));
314 | AllowIP.Add(wxT("Allow IP"));
315 | AllowIP.Add(wxT("Prompt IP"));
316 |
317 | AllowIPChoice = new wxChoice(vConfigScroll, ID_AllowIP, wxDefaultPosition, wxDefaultSize,
318 | AllowIP);
319 |
320 |
321 | hAllowIPBox->Add(AllowIPLbl,0,wxALIGN_BOTTOM);
322 | hAllowIPBox->Add(AllowIPChoice);
323 | AllowIPChoice->SetSelection(0);
324 |
325 | wxStaticText *IPToAllowLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("IP To Allow: "));
326 | IPToAllowTxt = new wxTextCtrl(vConfigScroll, wxID_ANY);
327 |
328 | hIPToAllowBox->Add(IPToAllowLbl,0,wxALIGN_BOTTOM);
329 | hIPToAllowBox->Add(IPToAllowTxt,1, wxEXPAND);
330 |
331 |
332 | wxStaticText *MessTypeLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Message Type: "));
333 |
334 | wxArrayString MessType;
335 | MessType.Add(wxT("Open Port"));
336 | MessType.Add(wxT("Nat Access"));
337 | MessType.Add(wxT("Local Nat Access"));
338 | MessType.Add(wxT("Server Command"));
339 | MessTypeChoice = new wxChoice(vConfigScroll,ID_MessType, wxDefaultPosition, wxDefaultSize,
340 | MessType);
341 |
342 | hMessTypeBox->Add(MessTypeLbl,0,wxALIGN_BOTTOM);
343 | hMessTypeBox->Add(MessTypeChoice);
344 | MessTypeChoice->SetSelection(0);
345 |
346 |
347 | wxStaticText *AccessPortsLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Access Ports: "));
348 | AccessPortsTxt = new wxTextCtrl(vConfigScroll, wxID_ANY, wxT("tcp/22"));
349 |
350 | hAccessPortsBox->Add(AccessPortsLbl,0,wxALIGN_BOTTOM);
351 | hAccessPortsBox->Add(AccessPortsTxt,1, wxEXPAND);
352 |
353 |
354 | wxStaticText *FwTimeLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Firewall Timeout: "));
355 | FwTimeTxt = new wxTextCtrl(vConfigScroll, wxID_ANY, wxT("60"));
356 |
357 | hFwTimeBox->Add(FwTimeLbl,0,wxALIGN_BOTTOM);
358 | hFwTimeBox->Add(FwTimeTxt,1, wxEXPAND);
359 |
360 | //TimerChk = new wxCheckBox(vConfigScroll, wxID_ANY,wxT("Show countdown timer"));
361 | KeepOpenChk = new wxCheckBox(vConfigScroll, wxID_ANY,wxT("Automatically resend SPA packets"));
362 | //hKeepAliveBox->Add(TimerChk);
363 | hKeepAliveBox->Add(KeepOpenChk);
364 |
365 |
366 |
367 | wxStaticText *InternalIPLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Internal IP: "));
368 | InternalIPTxt = new wxTextCtrl(vConfigScroll, wxID_ANY);
369 |
370 | hInternalIPBox->Add(InternalIPLbl,0,wxALIGN_BOTTOM);
371 | hInternalIPBox->Add(InternalIPTxt,1, wxEXPAND);
372 |
373 |
374 | wxStaticText *InternalPortLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Internal Port: "));
375 | InternalPortTxt = new wxTextCtrl(vConfigScroll, wxID_ANY);
376 |
377 | hInternalPortBox->Add(InternalPortLbl,0,wxALIGN_BOTTOM);
378 | hInternalPortBox->Add(InternalPortTxt,1, wxEXPAND);
379 |
380 |
381 | wxStaticText *ServCmdLbl = new wxStaticText(vConfigScroll,wxID_ANY, wxT("Server Command: "));
382 | ServCmdTxt = new wxTextCtrl(vConfigScroll, wxID_ANY);
383 |
384 | hServCmdBox->Add(ServCmdLbl,0,wxALIGN_BOTTOM);
385 | hServCmdBox->Add(ServCmdTxt,1, wxEXPAND);
386 |
387 |
388 |
389 | listbox = new wxListBox(this, ID_List, wxPoint(-1, -1), wxSize(200, -1));
390 | ourConfig->getAllConfigs(ourConfigList, configFile);
391 | if (!ourConfigList->IsEmpty())
392 | listbox->InsertItems(*ourConfigList,0);
393 |
394 | wxButton *ok = new wxButton(this, ID_KnockButton, wxT("Send Knock"), wxDefaultPosition, wxSize(130, 40));
395 |
396 |
397 |
398 | vListBox->Add(listbox,1,wxBOTTOM, 5);
399 | vListBox->Add(ok, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP);
400 |
401 |
402 | hbox->Add(vListBox, 0, wxEXPAND);
403 |
404 | vConfigBox->Add(hNickBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
405 | vConfigBox->Add(hServAddrBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
406 | vConfigBox->Add(hLegacyBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
407 | vConfigBox->Add(hRandomBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
408 | vConfigBox->Add(hServPortBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
409 | vConfigBox->Add(hProtoBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
410 | vConfigBox->Add(hUseGPGBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
411 | vConfigBox->Add(hGPGChoiceBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
412 | vConfigBox->Add(hKeyBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
413 | vConfigBox->Add(hKeyB64Box,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
414 | vConfigBox->Add(hDigestTypeBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
415 | vConfigBox->Add(hHmacKeyBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
416 | vConfigBox->Add(hHmacB64Box,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
417 | vConfigBox->Add(hHmacTypeBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
418 | vConfigBox->Add(hAllowIPBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
419 | vConfigBox->Add(hIPToAllowBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
420 | vConfigBox->Add(hMessTypeBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
421 | vConfigBox->Add(hAccessPortsBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
422 | vConfigBox->Add(hFwTimeBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
423 | vConfigBox->Add(hKeepAliveBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
424 | vConfigBox->Add(hInternalIPBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
425 | vConfigBox->Add(hInternalPortBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
426 | vConfigBox->Add(hServCmdBox,1,wxALIGN_LEFT | wxEXPAND | wxALL,2);
427 |
428 | OnChoice(*initMessTypeEvent);
429 | OnChoice(*initAllowIPEvent);
430 |
431 | vConfigScroll->SetSizer(vConfigBox);
432 | vConfigScroll->FitInside(); // ask the sizer about the needed size
433 | vConfigScroll->SetScrollRate(5, 5);
434 |
435 |
436 | vConfigBoxSuper->Add(vConfigScroll, 1, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM | wxEXPAND, 5);
437 | vConfigBoxSuper->Add(save, 0, wxALIGN_CENTER_HORIZONTAL);
438 | hbox->Add(vConfigBoxSuper, 1, wxEXPAND);
439 | this->SetSizer(hbox);
440 |
441 | }
442 |
443 | void fwknop_guiFrame::OnSave(wxCommandEvent &event)
444 | {
445 |
446 | //also, on android, need to detect changes to the config, because send knock with edits is broken. Similar idea, perhaps.
447 |
448 | //also need to be able to rename and have a dedicated copy button. Perhaps name is immutable when editing.
449 | ourConfig->NICK_NAME = NickTxt->GetLineText(0);
450 | ourConfig->SERVER_IP = ServAddrTxt->GetLineText(0);
451 | ourConfig->LEGACY = LegacyChk->GetValue();
452 | if (RandomChk->GetValue()) {
453 | ourConfig->SERVER_PORT = wxT("random");
454 | } else {
455 | ourConfig->SERVER_PORT = ServPortTxt->GetLineText(0);
456 | }
457 | ourConfig->PROTOCOL = ProtoChoice->GetString(ProtoChoice->GetSelection()); //Change this for i18n
458 | if (GPGChk->IsChecked()) {
459 | ourConfig->USE_GPG_CRYPT = true;
460 | ourConfig->GPG_CRYPT_ID = GPGEncryptKey->GetString(GPGEncryptKey->GetSelection());
461 | ourConfig->GPG_SIG_ID = GPGSignatureKey->GetString(GPGSignatureKey->GetSelection());
462 | } else {
463 | ourConfig->USE_GPG_CRYPT = false;
464 | ourConfig->KEY = KeyTxt->GetLineText(0);
465 | ourConfig->KEY_BASE64 = KeyB64Chk->GetValue();
466 | }
467 | ourConfig->HMAC = HmacKeyTxt->GetLineText(0);
468 | ourConfig->HMAC_BASE64 = HmacKeyB64Chk->GetValue();
469 | ourConfig->MESS_TYPE = MessTypeChoice->GetString(MessTypeChoice->GetSelection()); //Change this for i18n
470 | if (AllowIPChoice->GetSelection() == 0) {
471 | ourConfig->ACCESS_IP = wxT("Resolve IP");
472 | } else if (AllowIPChoice->GetSelection() == 1) {
473 | ourConfig->ACCESS_IP = wxT("Source IP");
474 | } else if (AllowIPChoice->GetSelection() == 3) {
475 | ourConfig->ACCESS_IP = wxT("Prompt IP");
476 | } else {
477 | ourConfig->ACCESS_IP = IPToAllowTxt->GetLineText(0);
478 | }
479 | ourConfig->PORTS = AccessPortsTxt->GetLineText(0);
480 | ourConfig->SERVER_TIMEOUT = FwTimeTxt->GetLineText(0);
481 | ourConfig->KEEP_OPEN = KeepOpenChk->IsChecked();
482 | ourConfig->NAT_IP = InternalIPTxt->GetLineText(0);
483 | ourConfig->NAT_PORT = InternalPortTxt->GetLineText(0);
484 | ourConfig->SERVER_CMD = ServCmdTxt->GetLineText(0);
485 | ourConfig->DIGEST_TYPE = DigestTypeChoice->GetString(DigestTypeChoice->GetSelection()); //Change this for i18n
486 | ourConfig->HMAC_TYPE = HmacTypeChoice->GetString(HmacTypeChoice->GetSelection()); //Change this for i18n
487 | ourConfig->PORTS.Replace(_(" "), _(""));
488 | wxString result = ourConfig->validateConfig();
489 | if (result.CmpNoCase(wxT("valid")) == 0)
490 | {
491 | ourConfig->saveConfig(configFile);
492 | ourConfig->getAllConfigs(ourConfigList, configFile);
493 | listbox->Clear();
494 | listbox->InsertItems(*ourConfigList,0);
495 | listbox->SetStringSelection(ourConfig->NICK_NAME);
496 | wxMessageBox(_("Save Successful."));
497 | } else {
498 | wxMessageBox(result);
499 |
500 | }
501 |
502 | }
503 |
504 | void fwknop_guiFrame::OnChoice(wxCommandEvent &event)
505 | {
506 |
507 | if (RandomChk->GetValue()) {
508 | vConfigBox->Hide(hServPortBox);
509 | } else {
510 | vConfigBox->Show(hServPortBox);
511 | }
512 |
513 | if (GPGChk->GetValue()) {
514 | vConfigBox->Hide(hKeyBox);
515 | vConfigBox->Hide(hKeyB64Box);
516 | vConfigBox->Show(hGPGChoiceBox);
517 | } else {
518 | vConfigBox->Show(hKeyBox);
519 | vConfigBox->Show(hKeyB64Box);
520 | vConfigBox->Hide(hGPGChoiceBox);
521 | }
522 |
523 | if (AllowIPChoice->GetSelection() == 2)
524 | {
525 | vConfigBox->Show(hIPToAllowBox);
526 | } else {
527 | vConfigBox->Hide(hIPToAllowBox);
528 | }
529 |
530 | switch (MessTypeChoice->GetSelection())
531 | {
532 | case 0:
533 | vConfigBox->Show(hAccessPortsBox);
534 | vConfigBox->Show(hFwTimeBox);
535 | vConfigBox->Show(hKeepAliveBox);
536 | vConfigBox->Hide(hInternalIPBox);
537 | vConfigBox->Hide(hInternalPortBox);
538 | vConfigBox->Hide(hServCmdBox);
539 | break;
540 | case 1:
541 | vConfigBox->Show(hAccessPortsBox);
542 | vConfigBox->Show(hFwTimeBox);
543 | vConfigBox->Show(hKeepAliveBox);
544 | vConfigBox->Show(hInternalIPBox);
545 | vConfigBox->Show(hInternalPortBox);
546 | vConfigBox->Hide(hServCmdBox);
547 | break;
548 | case 2:
549 | vConfigBox->Show(hAccessPortsBox);
550 | vConfigBox->Show(hFwTimeBox);
551 | vConfigBox->Show(hKeepAliveBox);
552 | vConfigBox->Hide(hInternalIPBox);
553 | vConfigBox->Show(hInternalPortBox);
554 | vConfigBox->Hide(hServCmdBox);
555 | break;
556 | case 3:
557 | vConfigBox->Show(hServCmdBox);
558 | vConfigBox->Hide(hAccessPortsBox);
559 | vConfigBox->Hide(hFwTimeBox);
560 | vConfigBox->Hide(hKeepAliveBox);
561 | vConfigBox->Hide(hInternalIPBox);
562 | vConfigBox->Hide(hInternalPortBox);
563 | break;
564 | }
565 | hbox->Layout();
566 | }
567 |
568 | void fwknop_guiFrame::OnLoad(wxCommandEvent &event)
569 | {
570 | ourConfig->loadConfig(listbox->GetString(listbox->GetSelection()), configFile);
571 | this->populate();
572 | }
573 |
574 | void fwknop_guiFrame::OnKnock(wxCommandEvent &event)
575 | {
576 | wxIPV4address serverAddr;
577 | wxString serverHost;
578 |
579 | if (listbox->GetSelection() == wxNOT_FOUND) // want to return before even using the memory if nothing is selected
580 | {
581 | wxMessageBox(_("No config selected!"));
582 | return;
583 | }
584 |
585 | // CURL *curl;
586 | // CURLcode curl_Res; //Use these when we switch to curl for sending http knocks
587 | wxString SPA_Result;
588 |
589 | ourConfig->loadConfig(listbox->GetString(listbox->GetSelection()), configFile);
590 | if (ourConfig->KEY.CmpNoCase(wxEmptyString) == 0 && !ourConfig->USE_GPG_CRYPT) {
591 | ourConfig->KEY = wxGetPasswordFromUser(_("Please enter your Rijndael key"));
592 | if (ourConfig->KEY.CmpNoCase(wxEmptyString) == 0)
593 | return;
594 | }
595 |
596 | if (ourConfig->ACCESS_IP.CmpNoCase(_("Prompt IP")) == 0)
597 | ourConfig->ACCESS_IP = wxGetTextFromUser(_("Please enter your Access IP"));
598 |
599 | if (ourConfig->ACCESS_IP.CmpNoCase(wxEmptyString) == 0)
600 | return;
601 |
602 | if (!serverAddr.Hostname(ourConfig->SERVER_IP)) {
603 | wxMessageBox(_("Could not resolve server!"));
604 | return;
605 | }
606 | serverHost = ourConfig->SERVER_IP; //HTTP and eventually HTTPS should be sent to the hostname rather than the IP
607 | ourConfig->SERVER_IP = serverAddr.IPAddress();
608 |
609 | configFile->SetPath(wxT("/"));
610 | SPA_Result = ourConfig->gen_SPA(configFile->Read(wxT("ip_resolver_url"), _("https://api.ipify.org")), ourGPG->gpgEngine, ourGPG->gpgHomeFolder, configFile->Read(wxT("debug"), _("false")).CmpNoCase("true") == 0);
611 | if (SPA_Result.CmpNoCase(wxT("Success")) != 0 ) {
612 | wxMessageBox(SPA_Result);
613 | return;
614 | }
615 |
616 | SPA_Result = ourConfig->send_SPA(&serverAddr);
617 | if (SPA_Result.CmpNoCase(wxT("Knock sent successfully.")) != 0 ) {
618 | wxMessageBox(SPA_Result);
619 | return;
620 | } else if ((configFile->Read(wxT("show_timer"), _("true")).CmpNoCase(_("true")) == 0) || (ourConfig->KEEP_OPEN)){
621 | timerDialog *ourTimer = new timerDialog(ourConfig->NICK_NAME, ourConfig, &serverAddr, ourGPG, configFile->Read(wxT("debug"), _("false")).CmpNoCase("true") == 0);
622 | ourTimer->Show();
623 | return;
624 | } else {
625 | wxMessageBox(SPA_Result);
626 | return;
627 | }
628 | }
629 |
630 |
631 | void fwknop_guiFrame::OnNew(wxCommandEvent &event)
632 | {
633 | listbox->SetSelection(wxNOT_FOUND);
634 | ourConfig->defaultConfig();
635 | this->populate();
636 |
637 | }
638 |
639 | void fwknop_guiFrame::OnSettings(wxCommandEvent &event)
640 | {
641 | gConfigDialog *gConfig = new gConfigDialog(configFile);
642 | gConfig->Show();
643 | }
644 |
645 | void fwknop_guiFrame::OnWizard(wxCommandEvent &event)
646 | {
647 | wizardDialog *wizard = new wizardDialog(_("Access.conf wizard"));
648 | wizard->Show(true);
649 | if (wizard->GetReturnCode() == wxID_OK) {
650 | listbox->SetSelection(wxNOT_FOUND);
651 | ourConfig->defaultConfig();
652 | ourConfig->KEY = wizard->tmp_config->KEY;
653 | ourConfig->KEY_BASE64 = wizard->tmp_config->KEY_BASE64;
654 | ourConfig->HMAC = wizard->tmp_config->HMAC;
655 | ourConfig->HMAC_BASE64 = true;
656 | this->populate();
657 | wxMessageBox(_("Generated keys imported into a blank config"));
658 | }
659 |
660 | }
661 |
662 | void fwknop_guiFrame::OnImport(wxCommandEvent &event)
663 | {
664 | bool is_changed = false;
665 | rc_import *import_dialog = new rc_import(_("RC Import"), ourConfig, &is_changed);
666 | import_dialog->Show(true);
667 | if (is_changed) { //could check for a dup, save if no dupe, message if there is
668 | listbox->SetSelection(wxNOT_FOUND);
669 | this->populate();
670 | }
671 |
672 | }
673 |
674 | void fwknop_guiFrame::OnExport(wxCommandEvent &event)
675 | {
676 | if (ourConfig != NULL) {
677 | rc_export *export_dialog = new rc_export(_("RC Export"), ourConfig);
678 | export_dialog->Show(true);
679 | }
680 | }
681 |
682 | void fwknop_guiFrame::OnQR(wxCommandEvent &event)
683 | {
684 | if (ourConfig != NULL) {
685 | qr_export *qr_export_dialog = new qr_export(ourConfig->NICK_NAME, ourConfig);
686 | }
687 | }
688 |
689 | void fwknop_guiFrame::OnLocation(wxCommandEvent &event)
690 | {
691 | wxFileDialog getRC(this, _("Saved Config File to Use"), _(""), _(""), wxFileSelectorDefaultWildcardStr, wxFD_SAVE);
692 | if (getRC.ShowModal() == wxID_CANCEL) {
693 | return;
694 | }
695 | free(configFile);
696 | configFile = new wxFileConfig (wxT(""), wxT(""), getRC.GetPath());
697 | ourConfig->getAllConfigs(ourConfigList, configFile);
698 | listbox->Clear();
699 | if (!ourConfigList->IsEmpty())
700 | listbox->InsertItems(*ourConfigList,0);
701 | listbox->SetSelection(wxNOT_FOUND);
702 | ourConfig->defaultConfig();
703 | this->populate();
704 |
705 |
706 | }
707 |
708 | void fwknop_guiFrame::OnDelete(wxCommandEvent &event)
709 | {
710 | if (listbox->GetSelection() == wxNOT_FOUND)
711 | {
712 | wxMessageBox(_("No config selected!"));
713 | return;
714 | }
715 | if (wxMessageBox(_("Are you sure you want to delete '") + listbox->GetString(listbox->GetSelection()) + _("'"),
716 | _("Delete saved knock"), wxYES_NO) == wxYES)
717 | {
718 | configFile->SetPath(wxT("/"));
719 | configFile->DeleteGroup(listbox->GetString(listbox->GetSelection()));
720 | configFile->Flush();
721 | listbox->Delete(listbox->GetSelection());
722 | listbox->SetSelection(wxNOT_FOUND);
723 | ourConfig->defaultConfig();
724 | this->populate();
725 |
726 | }
727 | }
728 |
729 | void fwknop_guiFrame::OnClose(wxCloseEvent &event)
730 | {
731 | curl_global_cleanup();
732 | Destroy();
733 | }
734 |
735 | void fwknop_guiFrame::OnQuit(wxCommandEvent &event)
736 | {
737 | curl_global_cleanup();
738 | Destroy();
739 | }
740 |
741 | void fwknop_guiFrame::OnAbout(wxCommandEvent &event)
742 | {
743 | //wxString msg = _("Fwknop-gui was created by Jonathan Bennett \nBased on fwknop and libfko written by Michael Rash");
744 | //wxMessageBox(msg, _("Fwknop-gui"));
745 | wxAboutDialogInfo aboutInfo;
746 | aboutInfo.SetName(_("Fwknop-gui"));
747 | aboutInfo.SetVersion(_("Version 1.3.1"));
748 | aboutInfo.SetDescription(_("Fwknop-gui is a cross platform graphical fwknop client."));
749 | aboutInfo.SetWebSite(_("https://github.com/jp-bennett/fwknop-gui"));
750 | aboutInfo.AddDeveloper(_("Jonathan Bennett"));
751 | wxAboutBox(aboutInfo);
752 | }
753 |
754 | void fwknop_guiFrame::OnHelpScreen(wxCommandEvent &event)
755 | {
756 | wxFrame *frame = new wxFrame(this, wxID_ANY, _("Fwknop-gui help"));
757 | wxHtmlWindow *html = new wxHtmlWindow(frame, ID_html);
758 | if (wxFileExists(_("help.html"))) {
759 | html->LoadPage(_("help.html"));
760 | frame->Show(true);
761 | } else if(wxFileExists(wxStandardPaths::Get().GetDataDir() + _("/help.html"))) {
762 | html->LoadPage(wxStandardPaths::Get().GetDataDir() + _("/help.html"));
763 | frame->Show(true);
764 | } else {
765 | wxMessageBox(_("Could not open help file at: ") + wxStandardPaths::Get().GetDataDir());
766 | }
767 |
768 |
769 | }
770 |
771 | void fwknop_guiFrame::OnLink(wxHtmlLinkEvent &event)
772 | {
773 | wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref());
774 |
775 | }
776 |
777 | void fwknop_guiFrame::gpgEngine(wxCommandEvent &event)
778 | {
779 | if (ourGPG->selectEngine(configFile)) {
780 | ourGPG->getAllKeys(GPGKeys);
781 | ourGPG->getAllKeys(GPGSigKeys);
782 | GPGSigKeys->Insert( _("None"), 0);
783 | GPGEncryptKey->Clear();
784 | GPGEncryptKey->Append(*GPGKeys);
785 | GPGSignatureKey->Clear();
786 | GPGSignatureKey->Append(*GPGSigKeys);
787 | }
788 |
789 | }
790 |
791 | void fwknop_guiFrame::gpgFolder(wxCommandEvent &event)
792 | {
793 | if (ourGPG->selectHomeDir(configFile)) {
794 | ourGPG->getAllKeys(GPGKeys);
795 | ourGPG->getAllKeys(GPGSigKeys);
796 | GPGSigKeys->Insert( _("None"), 0);
797 | GPGEncryptKey->Clear();
798 | GPGEncryptKey->Append(*GPGKeys);
799 | GPGSignatureKey->Clear();
800 | GPGSignatureKey->Append(*GPGSigKeys);
801 | }
802 | }
803 |
804 | void fwknop_guiFrame::gpgDefaults(wxCommandEvent &event)
805 | {
806 | if (ourGPG->setDefaults(configFile)) { //ask if sure
807 | ourGPG->getAllKeys(GPGKeys);
808 | ourGPG->getAllKeys(GPGSigKeys);
809 | GPGSigKeys->Insert( _("None"), 0);
810 | GPGEncryptKey->Clear();
811 | GPGEncryptKey->Append(*GPGKeys);
812 | GPGSignatureKey->Clear();
813 | GPGSignatureKey->Append(*GPGSigKeys);
814 | }
815 | }
816 |
817 | void fwknop_guiFrame::populate()
818 | {
819 |
820 | NickTxt->ChangeValue(ourConfig->NICK_NAME);
821 | ServAddrTxt->ChangeValue(ourConfig->SERVER_IP);
822 | LegacyChk->SetValue(ourConfig->LEGACY);
823 | if (ourConfig->SERVER_PORT.CmpNoCase(wxT("Random")) == 0) {
824 | RandomChk->SetValue(true);
825 | } else {
826 | RandomChk->SetValue(false);
827 | ServPortTxt->SetValue(ourConfig->SERVER_PORT);
828 | }
829 | if (ourConfig->PROTOCOL.CmpNoCase(wxT("UDP")) == 0)
830 | ProtoChoice->SetSelection(0);
831 | else if (ourConfig->PROTOCOL.CmpNoCase(wxT("TCP")) == 0)
832 | ProtoChoice->SetSelection(1);
833 | else if (ourConfig->PROTOCOL.CmpNoCase(wxT("HTTP")) == 0)
834 | ProtoChoice->SetSelection(2);
835 |
836 | GPGChk->SetValue(ourConfig->USE_GPG_CRYPT);
837 | if (!ourConfig->USE_GPG_CRYPT) {
838 | KeyTxt->SetValue(ourConfig->KEY);
839 | KeyB64Chk->SetValue(ourConfig->KEY_BASE64);
840 | } else {
841 | GPGEncryptKey->SetSelection(GPGEncryptKey->FindString(ourConfig->GPG_CRYPT_ID));
842 | GPGSignatureKey->SetSelection(GPGSignatureKey->FindString(ourConfig->GPG_SIG_ID));
843 | }
844 | HmacKeyTxt->SetValue(ourConfig->HMAC);
845 | HmacKeyB64Chk->SetValue(ourConfig->HMAC_BASE64);
846 |
847 | if (ourConfig->ACCESS_IP.CmpNoCase(wxT("Resolve IP")) == 0)
848 | AllowIPChoice->SetSelection(0);
849 | else if (ourConfig->ACCESS_IP.CmpNoCase(wxT("Source IP")) == 0)
850 | AllowIPChoice->SetSelection(1);
851 | else if (ourConfig->ACCESS_IP.CmpNoCase(wxT("Prompt IP")) == 0)
852 | AllowIPChoice->SetSelection(3);
853 | else {
854 | AllowIPChoice->SetSelection(2);
855 | IPToAllowTxt->SetValue(ourConfig->ACCESS_IP);
856 | }
857 |
858 | if (ourConfig->MESS_TYPE.CmpNoCase(wxT("Open Port")) == 0)
859 | MessTypeChoice->SetSelection(0);
860 | else if (ourConfig->MESS_TYPE.CmpNoCase(wxT("Nat Access")) == 0)
861 | MessTypeChoice->SetSelection(1);
862 | else if (ourConfig->MESS_TYPE.CmpNoCase(wxT("Local Nat Access")) == 0)
863 | MessTypeChoice->SetSelection(2);
864 | else if (ourConfig->MESS_TYPE.CmpNoCase(wxT("Server Command")) == 0)
865 | MessTypeChoice->SetSelection(3);
866 |
867 | AccessPortsTxt->SetValue(ourConfig->PORTS);
868 | FwTimeTxt->SetValue(ourConfig->SERVER_TIMEOUT);
869 | KeepOpenChk->SetValue(ourConfig->KEEP_OPEN);
870 | InternalIPTxt->SetValue(ourConfig->NAT_IP);
871 | InternalPortTxt->SetValue(ourConfig->NAT_PORT);
872 | ServCmdTxt->SetValue(ourConfig->SERVER_CMD);
873 |
874 | if (ourConfig->DIGEST_TYPE.CmpNoCase(wxT("MD5")) == 0)
875 | DigestTypeChoice->SetSelection(0);
876 | else if (ourConfig->DIGEST_TYPE.CmpNoCase(wxT("SHA1")) == 0)
877 | DigestTypeChoice->SetSelection(1);
878 | else if (ourConfig->DIGEST_TYPE.CmpNoCase(wxT("SHA256")) == 0)
879 | DigestTypeChoice->SetSelection(2);
880 | else if (ourConfig->DIGEST_TYPE.CmpNoCase(wxT("SHA384")) == 0)
881 | DigestTypeChoice->SetSelection(3);
882 | else if (ourConfig->DIGEST_TYPE.CmpNoCase(wxT("SHA512")) == 0)
883 | DigestTypeChoice->SetSelection(4);
884 |
885 | if (ourConfig->HMAC_TYPE.CmpNoCase(wxT("MD5")) == 0)
886 | HmacTypeChoice->SetSelection(0);
887 | else if (ourConfig->HMAC_TYPE.CmpNoCase(wxT("SHA1")) == 0)
888 | HmacTypeChoice->SetSelection(1);
889 | else if (ourConfig->HMAC_TYPE.CmpNoCase(wxT("SHA256")) == 0)
890 | HmacTypeChoice->SetSelection(2);
891 | else if (ourConfig->HMAC_TYPE.CmpNoCase(wxT("SHA384")) == 0)
892 | HmacTypeChoice->SetSelection(3);
893 | else if (ourConfig->HMAC_TYPE.CmpNoCase(wxT("SHA512")) == 0)
894 | HmacTypeChoice->SetSelection(4);
895 |
896 | OnChoice(*initMessTypeEvent);
897 | // OnChoice(*initAllowIPEvent);
898 | // OnChoice(*initCheckboxEvent);
899 |
900 | }
901 |
902 |
903 | /*static size_t data_write(void* buf, size_t size, size_t nmemb, void* userp)
904 | {
905 | if(userp)
906 | {
907 | std::ostream& os = *static_cast(userp);
908 | std::streamsize len = size * nmemb;
909 | if(os.write(static_cast(buf), len))
910 | return len;
911 | }
912 |
913 | return 0;
914 | } */
915 |
916 | /**
917 | * timeout is in seconds
918 | **/
919 | /*
920 | CURLcode curl_read(const std::string& url, std::ostream& os, long timeout)
921 | {
922 | CURLcode code(CURLE_FAILED_INIT);
923 | CURL* curl = curl_easy_init();
924 |
925 | if(curl)
926 | {
927 | if(CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &data_write))
928 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L))
929 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L))
930 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_FILE, &os))
931 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout))
932 | #ifdef __WIN32__
933 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_CAINFO, "./ca-bundle.crt"))
934 | #endif
935 | && CURLE_OK == (code = curl_easy_setopt(curl, CURLOPT_URL, url.c_str())))
936 |
937 | {
938 | code = curl_easy_perform(curl);
939 | }
940 | curl_easy_cleanup(curl);
941 | }
942 | return code;
943 | }
944 | */
945 |
--------------------------------------------------------------------------------