├── .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 | --------------------------------------------------------------------------------