Compare commits

...

40 Commits

Author SHA1 Message Date
Kevin Yue
4fada9bd14 Release 1.4.6 2022-06-01 23:55:50 +08:00
Kevin Yue
b57fb993ca Updated VERSION, Bumped 1.4.5 –> 1.4.6 2022-06-01 23:55:40 +08:00
Kevin Yue
f6d06ed978 feat: display address in gateway menu item 2022-06-01 23:53:02 +08:00
Kevin Yue
cc67de3a2b fix: fix bug of parsing the portal respponse 2022-06-01 23:52:12 +08:00
Kevin Yue
e2d28c83b2 Release 1.4.5 2022-05-29 21:15:40 +08:00
Kevin Yue
a489c5881b Updated VERSION, Bumped 1.4.4 –> 1.4.5 2022-05-29 21:15:32 +08:00
Kevin Yue
44fd2f1d3f chore: refine vscode settings 2022-05-29 21:15:01 +08:00
Kevin Yue
9c9b42b87f fix: rollback dbus configuration 2022-05-29 21:00:37 +08:00
Kevin Yue
fb2b148b72 feat: add option to start minimized 2022-05-29 17:33:12 +08:00
Kevin Yue
64bec9660a packaging: fix postinst for debian 2022-05-27 21:32:33 +08:00
Kevin Yue
0619e91bf5 packaging: add postinst for debian 2022-05-26 21:44:31 +08:00
Kevin Yue
048aa4799f test: test debian packaging 2022-05-26 15:33:39 +08:00
Kevin Yue
db0e8b801d test: test debian packaging 2022-05-26 15:12:25 +08:00
Kevin Yue
d03bbc339e test: test debian packaging 2022-05-26 15:06:17 +08:00
Kevin Yue
1312d54d08 test: test debian packaging 2022-05-26 14:41:10 +08:00
Kevin Yue
39f99d9143 test: test debian packaging 2022-05-26 14:23:29 +08:00
Kevin Yue
7a4eb0def3 ci: fix the foder path 2022-05-26 14:13:47 +08:00
Kevin Yue
d9b2094edd chore: apt -> apt-get 2022-05-26 14:11:38 +08:00
Kevin Yue
e6118af9f3 ci: verify debian package 2022-05-26 14:05:59 +08:00
Kevin Yue
108b4be3ec test: test debian packaging 2022-05-26 13:16:20 +08:00
Kevin Yue
65c59e47ec Revert "Revert "fix: improve the dbus security""
This reverts commit 4940830885.
2022-05-26 11:56:14 +08:00
Kevin Yue
177da7f3a2 Revert "Revert "fix: improve the dbus security""
This reverts commit ffa99d3783.
2022-05-26 11:56:06 +08:00
Kevin Yue
d5cd90373b fix: improve the portal config parsing 2022-05-26 11:48:55 +08:00
Kevin Yue
ffa99d3783 Revert "fix: improve the dbus security"
This reverts commit 829298bb84.
2022-05-23 22:20:06 +08:00
Kevin Yue
4940830885 Revert "fix: improve the dbus security"
This reverts commit ad178fe56c.
2022-05-23 22:20:03 +08:00
Kevin Yue
ad178fe56c fix: improve the dbus security 2022-05-23 21:55:21 +08:00
Kevin Yue
829298bb84 fix: improve the dbus security 2022-05-23 21:24:22 +08:00
Kevin Yue
8fe717d844 fix: free resources in slots 2022-05-22 23:17:11 +08:00
Kevin Yue
dffbc64ef5 chore: refine cmake files 2022-05-21 20:55:05 +08:00
Kevin Yue
b99c5a8391 fix: support high DPI screen 2022-05-21 11:43:17 +08:00
Kevin Yue
c2f7576d10 Release 1.4.4 2022-05-14 19:21:14 +08:00
Kevin Yue
4327235093 Updated VERSION, Bumped 1.4.3 –> 1.4.4 2022-05-14 19:21:03 +08:00
Kevin Yue
0699878b92 fix: support the HighDPI displays
Refs: #115
2022-05-14 19:12:07 +08:00
Kevin Yue
e3aba11506 [misc] update the build script 2022-05-09 22:40:00 +08:00
Kevin Yue
ff58258d5c [ci] Enable build job for master branch 2022-05-09 22:26:22 +08:00
Kevin Yue
991cf25a7b [ci] Add ubuntu 22.04 2022-05-09 22:23:08 +08:00
Kevin Yue
02c70150ba Release 1.4.3 2022-05-09 22:20:54 +08:00
Kevin Yue
28d8321958 Updated VERSION, Bumped 1.4.2 –> 1.4.3 2022-05-09 22:20:46 +08:00
Kevin Yue
e1c9180cae refine AUR packaging 2022-05-09 22:09:27 +08:00
Kevin Yue
57df34fd1e Prepare release 1.4.3 (#149)
* add inih

* add configuration file for gpservice

* Disable the UI configuration for extra args

* remove VERSION_SUFFIX

* remove ppa-publish.sh

* Use Git repo as the source for PKGBUILD

* remove VERSION_SUFFIX

* Use Git repo as the source for PKGBUILD

* add .install for PKGBUILD

* add configuration file

* Fix cmake

* Fix cmake

* Disable snap job

* update AUR packaging

* Disable the UI configuration for extra args

* improve packaging script

* update README.md

* restart gpservice after package upgrading
2022-05-09 21:58:58 +08:00
51 changed files with 1164 additions and 218 deletions

View File

@@ -9,8 +9,5 @@ trim_trailing_whitespace=true
indent_style = space
indent_size = 4
[{VERSION,VERSION_SUFFIX}]
insert_final_newline = false
[*.sh]
indent_style = tab

View File

@@ -3,6 +3,7 @@ name: Build
on:
push:
branches:
- master
- develop
tags:
- "v*.*.*"
@@ -17,8 +18,8 @@ jobs:
build:
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-20.04]
os: [ubuntu-18.04, ubuntu-20.04, ubuntu-22.04]
runs-on: ${{ matrix.os }}
steps:
@@ -41,16 +42,20 @@ jobs:
with:
submodules: recursive
fetch-depth: 0
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install git-archive-all
- name: Archive all
run: |
./scripts/snapshot-archive-all.sh
- name: Verify debian package
run: |
./scripts/verify-debian-package.sh
- uses: actions/upload-artifact@v2
with:
name: snapshot-source-code
@@ -66,7 +71,7 @@ jobs:
with:
name: snapshot-source-code
path: artifacts
- name: Extract source code
run: |
cd $GITHUB_WORKSPACE/artifacts
@@ -80,7 +85,7 @@ jobs:
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
gpg_passphrase: ${{ secrets.PPA_GPG_PASSPHRASE }}
pkgdir: '${{ github.workspace }}/artifacts/deb-build/globalprotect-openconnect*/'
snapshot-aur:
if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/develop' }}
needs: snapshot-archive-all
@@ -93,13 +98,11 @@ jobs:
path: artifacts
- name: Publish AUR package
env:
VERSION: $(cat ./artifacts/VERSION)
uses: yuezk/github-actions-deploy-aur@update-pkgver
with:
pkgname: globalprotect-openconnect-git
pkgbuild: ./artifacts/aur/PKGBUILD
assets: ./artifacts/aur/*.tar.gz
assets: ./artifacts/aur/gp.install
update_pkgver: true
commit_username: ${{ secrets.AUR_USERNAME }}
commit_email: ${{ secrets.AUR_EMAIL }}
@@ -126,7 +129,8 @@ jobs:
files: ./artifacts/obs/*
snapshot-snap:
if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/develop' }}
# if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/develop' }}
if: ${{ false }}
needs: snapshot-archive-all
runs-on: ubuntu-latest
@@ -135,14 +139,14 @@ jobs:
with:
name: snapshot-source-code
path: artifacts
- name: Extract source code
run: |
mkdir snap-source
tar xvf ./artifacts/globalprotect-openconnect-*tar.gz \
--directory snap-source \
--strip 1
- uses: snapcore/action-build@v1
id: build
with:
@@ -164,16 +168,20 @@ jobs:
with:
submodules: recursive
fetch-depth: 0
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install git-archive-all
- name: Archive all
run: |
./scripts/release-archive-all.sh
- name: Verify debian package
run: |
./scripts/verify-debian-package.sh
- uses: actions/upload-artifact@v2
with:
name: release-source-code
@@ -203,7 +211,7 @@ jobs:
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
gpg_passphrase: ${{ secrets.PPA_GPG_PASSPHRASE }}
pkgdir: '${{ github.workspace }}/artifacts/deb-build/globalprotect-openconnect*/'
release-aur:
if: startsWith(github.ref, 'refs/tags/v')
needs: release-archive-all
@@ -216,19 +224,17 @@ jobs:
path: artifacts
- name: Publish AUR package
env:
VERSION: $(cat ./artifacts/VERSION)
uses: yuezk/github-actions-deploy-aur@update-pkgver
with:
pkgname: globalprotect-openconnect-git
pkgbuild: ./artifacts/aur/PKGBUILD
assets: ./artifacts/aur/*.tar.gz
assets: ./artifacts/aur/gp.install
update_pkgver: true
commit_username: ${{ secrets.AUR_USERNAME }}
commit_email: ${{ secrets.AUR_EMAIL }}
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: 'Release ${{ github.ref }}'
release-obs:
if: startsWith(github.ref, 'refs/tags/v')
needs: release-archive-all
@@ -247,7 +253,7 @@ jobs:
username: yuezk
password: ${{ secrets.OBS_PASSWORD }}
files: ./artifacts/obs/*
release-github:
if: startsWith(github.ref, 'refs/tags/v')
needs:

3
.gitignore vendored
View File

@@ -8,6 +8,7 @@ build
artifacts
.cmake
.idea
# Auto generated DBus files
*_adaptor.cpp
@@ -62,7 +63,7 @@ target_wrapper.*
# QtCreator CMake
CMakeLists.txt.user*
# QtCreator 4.8< compilation database
# QtCreator 4.8< compilation database
compile_commands.json
# QtCreator local machine specific files for imported projects

View File

@@ -23,4 +23,4 @@
"qsslsocket": "cpp",
"qapplication": "cpp"
}
}
}

11
3rdparty/inih/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.10.0)
project(inih)
add_library(inih STATIC
ini.h
ini.c
cpp/INIReader.h
cpp/INIReader.cpp
)
target_include_directories(inih PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/cpp")

27
3rdparty/inih/LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,27 @@
The "inih" library is distributed under the New BSD license:
Copyright (c) 2009, Ben Hoyt
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Ben Hoyt nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY BEN HOYT ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL BEN HOYT BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

116
3rdparty/inih/cpp/INIReader.cpp vendored Normal file
View File

@@ -0,0 +1,116 @@
// Read an INI file into easy-to-access name/value pairs.
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (C) 2009-2020, Ben Hoyt
// inih and INIReader are released under the New BSD license (see LICENSE.txt).
// Go to the project home page for more info:
//
// https://github.com/benhoyt/inih
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include "../ini.h"
#include "INIReader.h"
using std::string;
INIReader::INIReader(const string& filename)
{
_error = ini_parse(filename.c_str(), ValueHandler, this);
}
INIReader::INIReader(const char *buffer, size_t buffer_size)
{
string content(buffer, buffer_size);
_error = ini_parse_string(content.c_str(), ValueHandler, this);
}
int INIReader::ParseError() const
{
return _error;
}
string INIReader::Get(const string& section, const string& name, const string& default_value) const
{
string key = MakeKey(section, name);
// Use _values.find() here instead of _values.at() to support pre C++11 compilers
return _values.count(key) ? _values.find(key)->second : default_value;
}
string INIReader::GetString(const string& section, const string& name, const string& default_value) const
{
const string str = Get(section, name, "");
return str.empty() ? default_value : str;
}
long INIReader::GetInteger(const string& section, const string& name, long default_value) const
{
string valstr = Get(section, name, "");
const char* value = valstr.c_str();
char* end;
// This parses "1234" (decimal) and also "0x4D2" (hex)
long n = strtol(value, &end, 0);
return end > value ? n : default_value;
}
double INIReader::GetReal(const string& section, const string& name, double default_value) const
{
string valstr = Get(section, name, "");
const char* value = valstr.c_str();
char* end;
double n = strtod(value, &end);
return end > value ? n : default_value;
}
bool INIReader::GetBoolean(const string& section, const string& name, bool default_value) const
{
string valstr = Get(section, name, "");
// Convert to lower case to make string comparisons case-insensitive
std::transform(valstr.begin(), valstr.end(), valstr.begin(), ::tolower);
if (valstr == "true" || valstr == "yes" || valstr == "on" || valstr == "1")
return true;
else if (valstr == "false" || valstr == "no" || valstr == "off" || valstr == "0")
return false;
else
return default_value;
}
bool INIReader::HasSection(const string& section) const
{
const string key = MakeKey(section, "");
std::map<string, string>::const_iterator pos = _values.lower_bound(key);
if (pos == _values.end())
return false;
// Does the key at the lower_bound pos start with "section"?
return pos->first.compare(0, key.length(), key) == 0;
}
bool INIReader::HasValue(const string& section, const string& name) const
{
string key = MakeKey(section, name);
return _values.count(key);
}
string INIReader::MakeKey(const string& section, const string& name)
{
string key = section + "=" + name;
// Convert to lower case to make section/name lookups case-insensitive
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
return key;
}
int INIReader::ValueHandler(void* user, const char* section, const char* name,
const char* value)
{
if (!name) // Happens when INI_CALL_HANDLER_ON_NEW_SECTION enabled
return 1;
INIReader* reader = static_cast<INIReader*>(user);
string key = MakeKey(section, name);
if (reader->_values[key].size() > 0)
reader->_values[key] += "\n";
reader->_values[key] += value ? value : "";
return 1;
}

94
3rdparty/inih/cpp/INIReader.h vendored Normal file
View File

@@ -0,0 +1,94 @@
// Read an INI file into easy-to-access name/value pairs.
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (C) 2009-2020, Ben Hoyt
// inih and INIReader are released under the New BSD license (see LICENSE.txt).
// Go to the project home page for more info:
//
// https://github.com/benhoyt/inih
#ifndef INIREADER_H
#define INIREADER_H
#include <map>
#include <string>
// Visibility symbols, required for Windows DLLs
#ifndef INI_API
#if defined _WIN32 || defined __CYGWIN__
# ifdef INI_SHARED_LIB
# ifdef INI_SHARED_LIB_BUILDING
# define INI_API __declspec(dllexport)
# else
# define INI_API __declspec(dllimport)
# endif
# else
# define INI_API
# endif
#else
# if defined(__GNUC__) && __GNUC__ >= 4
# define INI_API __attribute__ ((visibility ("default")))
# else
# define INI_API
# endif
#endif
#endif
// Read an INI file into easy-to-access name/value pairs. (Note that I've gone
// for simplicity here rather than speed, but it should be pretty decent.)
class INIReader
{
public:
// Construct INIReader and parse given filename. See ini.h for more info
// about the parsing.
INI_API explicit INIReader(const std::string& filename);
// Construct INIReader and parse given buffer. See ini.h for more info
// about the parsing.
INI_API explicit INIReader(const char *buffer, size_t buffer_size);
// Return the result of ini_parse(), i.e., 0 on success, line number of
// first error on parse error, or -1 on file open error.
INI_API int ParseError() const;
// Get a string value from INI file, returning default_value if not found.
INI_API std::string Get(const std::string& section, const std::string& name,
const std::string& default_value) const;
// Get a string value from INI file, returning default_value if not found,
// empty, or contains only whitespace.
INI_API std::string GetString(const std::string& section, const std::string& name,
const std::string& default_value) const;
// Get an integer (long) value from INI file, returning default_value if
// not found or not a valid integer (decimal "1234", "-1234", or hex "0x4d2").
INI_API long GetInteger(const std::string& section, const std::string& name, long default_value) const;
// Get a real (floating point double) value from INI file, returning
// default_value if not found or not a valid floating point value
// according to strtod().
INI_API double GetReal(const std::string& section, const std::string& name, double default_value) const;
// Get a boolean value from INI file, returning default_value if not found or if
// not a valid true/false value. Valid true values are "true", "yes", "on", "1",
// and valid false values are "false", "no", "off", "0" (not case sensitive).
INI_API bool GetBoolean(const std::string& section, const std::string& name, bool default_value) const;
// Return true if the given section exists (section must contain at least
// one name=value pair).
INI_API bool HasSection(const std::string& section) const;
// Return true if a value exists with the given section and field names.
INI_API bool HasValue(const std::string& section, const std::string& name) const;
private:
int _error;
std::map<std::string, std::string> _values;
static std::string MakeKey(const std::string& section, const std::string& name);
static int ValueHandler(void* user, const char* section, const char* name,
const char* value);
};
#endif // INIREADER_H

298
3rdparty/inih/ini.c vendored Normal file
View File

@@ -0,0 +1,298 @@
/* inih -- simple .INI file parser
SPDX-License-Identifier: BSD-3-Clause
Copyright (C) 2009-2020, Ben Hoyt
inih is released under the New BSD license (see LICENSE.txt). Go to the project
home page for more info:
https://github.com/benhoyt/inih
*/
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "ini.h"
#if !INI_USE_STACK
#if INI_CUSTOM_ALLOCATOR
#include <stddef.h>
void* ini_malloc(size_t size);
void ini_free(void* ptr);
void* ini_realloc(void* ptr, size_t size);
#else
#include <stdlib.h>
#define ini_malloc malloc
#define ini_free free
#define ini_realloc realloc
#endif
#endif
#define MAX_SECTION 50
#define MAX_NAME 50
/* Used by ini_parse_string() to keep track of string parsing state. */
typedef struct {
const char* ptr;
size_t num_left;
} ini_parse_string_ctx;
/* Strip whitespace chars off end of given string, in place. Return s. */
static char* rstrip(char* s)
{
char* p = s + strlen(s);
while (p > s && isspace((unsigned char)(*--p)))
*p = '\0';
return s;
}
/* Return pointer to first non-whitespace char in given string. */
static char* lskip(const char* s)
{
while (*s && isspace((unsigned char)(*s)))
s++;
return (char*)s;
}
/* Return pointer to first char (of chars) or inline comment in given string,
or pointer to NUL at end of string if neither found. Inline comment must
be prefixed by a whitespace character to register as a comment. */
static char* find_chars_or_comment(const char* s, const char* chars)
{
#if INI_ALLOW_INLINE_COMMENTS
int was_space = 0;
while (*s && (!chars || !strchr(chars, *s)) &&
!(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
was_space = isspace((unsigned char)(*s));
s++;
}
#else
while (*s && (!chars || !strchr(chars, *s))) {
s++;
}
#endif
return (char*)s;
}
/* Similar to strncpy, but ensures dest (size bytes) is
NUL-terminated, and doesn't pad with NULs. */
static char* strncpy0(char* dest, const char* src, size_t size)
{
/* Could use strncpy internally, but it causes gcc warnings (see issue #91) */
size_t i;
for (i = 0; i < size - 1 && src[i]; i++)
dest[i] = src[i];
dest[i] = '\0';
return dest;
}
/* See documentation in header file. */
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
void* user)
{
/* Uses a fair bit of stack (use heap instead if you need to) */
#if INI_USE_STACK
char line[INI_MAX_LINE];
int max_line = INI_MAX_LINE;
#else
char* line;
size_t max_line = INI_INITIAL_ALLOC;
#endif
#if INI_ALLOW_REALLOC && !INI_USE_STACK
char* new_line;
size_t offset;
#endif
char section[MAX_SECTION] = "";
char prev_name[MAX_NAME] = "";
char* start;
char* end;
char* name;
char* value;
int lineno = 0;
int error = 0;
#if !INI_USE_STACK
line = (char*)ini_malloc(INI_INITIAL_ALLOC);
if (!line) {
return -2;
}
#endif
#if INI_HANDLER_LINENO
#define HANDLER(u, s, n, v) handler(u, s, n, v, lineno)
#else
#define HANDLER(u, s, n, v) handler(u, s, n, v)
#endif
/* Scan through stream line by line */
while (reader(line, (int)max_line, stream) != NULL) {
#if INI_ALLOW_REALLOC && !INI_USE_STACK
offset = strlen(line);
while (offset == max_line - 1 && line[offset - 1] != '\n') {
max_line *= 2;
if (max_line > INI_MAX_LINE)
max_line = INI_MAX_LINE;
new_line = ini_realloc(line, max_line);
if (!new_line) {
ini_free(line);
return -2;
}
line = new_line;
if (reader(line + offset, (int)(max_line - offset), stream) == NULL)
break;
if (max_line >= INI_MAX_LINE)
break;
offset += strlen(line + offset);
}
#endif
lineno++;
start = line;
#if INI_ALLOW_BOM
if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
(unsigned char)start[1] == 0xBB &&
(unsigned char)start[2] == 0xBF) {
start += 3;
}
#endif
start = lskip(rstrip(start));
if (strchr(INI_START_COMMENT_PREFIXES, *start)) {
/* Start-of-line comment */
}
#if INI_ALLOW_MULTILINE
else if (*prev_name && *start && start > line) {
/* Non-blank line with leading whitespace, treat as continuation
of previous name's value (as per Python configparser). */
if (!HANDLER(user, section, prev_name, start) && !error)
error = lineno;
}
#endif
else if (*start == '[') {
/* A "[section]" line */
end = find_chars_or_comment(start + 1, "]");
if (*end == ']') {
*end = '\0';
strncpy0(section, start + 1, sizeof(section));
*prev_name = '\0';
#if INI_CALL_HANDLER_ON_NEW_SECTION
if (!HANDLER(user, section, NULL, NULL) && !error)
error = lineno;
#endif
}
else if (!error) {
/* No ']' found on section line */
error = lineno;
}
}
else if (*start) {
/* Not a comment, must be a name[=:]value pair */
end = find_chars_or_comment(start, "=:");
if (*end == '=' || *end == ':') {
*end = '\0';
name = rstrip(start);
value = end + 1;
#if INI_ALLOW_INLINE_COMMENTS
end = find_chars_or_comment(value, NULL);
if (*end)
*end = '\0';
#endif
value = lskip(value);
rstrip(value);
/* Valid name[=:]value pair found, call handler */
strncpy0(prev_name, name, sizeof(prev_name));
if (!HANDLER(user, section, name, value) && !error)
error = lineno;
}
else if (!error) {
/* No '=' or ':' found on name[=:]value line */
#if INI_ALLOW_NO_VALUE
*end = '\0';
name = rstrip(start);
if (!HANDLER(user, section, name, NULL) && !error)
error = lineno;
#else
error = lineno;
#endif
}
}
#if INI_STOP_ON_FIRST_ERROR
if (error)
break;
#endif
}
#if !INI_USE_STACK
ini_free(line);
#endif
return error;
}
/* See documentation in header file. */
int ini_parse_file(FILE* file, ini_handler handler, void* user)
{
return ini_parse_stream((ini_reader)fgets, file, handler, user);
}
/* See documentation in header file. */
int ini_parse(const char* filename, ini_handler handler, void* user)
{
FILE* file;
int error;
file = fopen(filename, "r");
if (!file)
return -1;
error = ini_parse_file(file, handler, user);
fclose(file);
return error;
}
/* An ini_reader function to read the next line from a string buffer. This
is the fgets() equivalent used by ini_parse_string(). */
static char* ini_reader_string(char* str, int num, void* stream) {
ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream;
const char* ctx_ptr = ctx->ptr;
size_t ctx_num_left = ctx->num_left;
char* strp = str;
char c;
if (ctx_num_left == 0 || num < 2)
return NULL;
while (num > 1 && ctx_num_left != 0) {
c = *ctx_ptr++;
ctx_num_left--;
*strp++ = c;
if (c == '\n')
break;
num--;
}
*strp = '\0';
ctx->ptr = ctx_ptr;
ctx->num_left = ctx_num_left;
return str;
}
/* See documentation in header file. */
int ini_parse_string(const char* string, ini_handler handler, void* user) {
ini_parse_string_ctx ctx;
ctx.ptr = string;
ctx.num_left = strlen(string);
return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler,
user);
}

178
3rdparty/inih/ini.h vendored Normal file
View File

@@ -0,0 +1,178 @@
/* inih -- simple .INI file parser
SPDX-License-Identifier: BSD-3-Clause
Copyright (C) 2009-2020, Ben Hoyt
inih is released under the New BSD license (see LICENSE.txt). Go to the project
home page for more info:
https://github.com/benhoyt/inih
*/
#ifndef INI_H
#define INI_H
/* Make this header file easier to include in C++ code */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
/* Nonzero if ini_handler callback should accept lineno parameter. */
#ifndef INI_HANDLER_LINENO
#define INI_HANDLER_LINENO 0
#endif
/* Visibility symbols, required for Windows DLLs */
#ifndef INI_API
#if defined _WIN32 || defined __CYGWIN__
# ifdef INI_SHARED_LIB
# ifdef INI_SHARED_LIB_BUILDING
# define INI_API __declspec(dllexport)
# else
# define INI_API __declspec(dllimport)
# endif
# else
# define INI_API
# endif
#else
# if defined(__GNUC__) && __GNUC__ >= 4
# define INI_API __attribute__ ((visibility ("default")))
# else
# define INI_API
# endif
#endif
#endif
/* Typedef for prototype of handler function. */
#if INI_HANDLER_LINENO
typedef int (*ini_handler)(void* user, const char* section,
const char* name, const char* value,
int lineno);
#else
typedef int (*ini_handler)(void* user, const char* section,
const char* name, const char* value);
#endif
/* Typedef for prototype of fgets-style reader function. */
typedef char* (*ini_reader)(char* str, int num, void* stream);
/* Parse given INI-style file. May have [section]s, name=value pairs
(whitespace stripped), and comments starting with ';' (semicolon). Section
is "" if name=value pair parsed before any section heading. name:value
pairs are also supported as a concession to Python's configparser.
For each name=value pair parsed, call handler function with given user
pointer as well as section, name, and value (data only valid for duration
of handler call). Handler should return nonzero on success, zero on error.
Returns 0 on success, line number of first error on parse error (doesn't
stop on first error), -1 on file open error, or -2 on memory allocation
error (only when INI_USE_STACK is zero).
*/
INI_API int ini_parse(const char* filename, ini_handler handler, void* user);
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
close the file when it's finished -- the caller must do that. */
INI_API int ini_parse_file(FILE* file, ini_handler handler, void* user);
/* Same as ini_parse(), but takes an ini_reader function pointer instead of
filename. Used for implementing custom or string-based I/O (see also
ini_parse_string). */
INI_API int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
void* user);
/* Same as ini_parse(), but takes a zero-terminated string with the INI data
instead of a file. Useful for parsing INI data from a network socket or
already in memory. */
INI_API int ini_parse_string(const char* string, ini_handler handler, void* user);
/* Nonzero to allow multi-line value parsing, in the style of Python's
configparser. If allowed, ini_parse() will call the handler with the same
name for each subsequent line parsed. */
#ifndef INI_ALLOW_MULTILINE
#define INI_ALLOW_MULTILINE 1
#endif
/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
the file. See https://github.com/benhoyt/inih/issues/21 */
#ifndef INI_ALLOW_BOM
#define INI_ALLOW_BOM 1
#endif
/* Chars that begin a start-of-line comment. Per Python configparser, allow
both ; and # comments at the start of a line by default. */
#ifndef INI_START_COMMENT_PREFIXES
#define INI_START_COMMENT_PREFIXES ";#"
#endif
/* Nonzero to allow inline comments (with valid inline comment characters
specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match
Python 3.2+ configparser behaviour. */
#ifndef INI_ALLOW_INLINE_COMMENTS
#define INI_ALLOW_INLINE_COMMENTS 1
#endif
#ifndef INI_INLINE_COMMENT_PREFIXES
#define INI_INLINE_COMMENT_PREFIXES ";"
#endif
/* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */
#ifndef INI_USE_STACK
#define INI_USE_STACK 1
#endif
/* Maximum line length for any line in INI file (stack or heap). Note that
this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */
#ifndef INI_MAX_LINE
#define INI_MAX_LINE 200
#endif
/* Nonzero to allow heap line buffer to grow via realloc(), zero for a
fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is
zero. */
#ifndef INI_ALLOW_REALLOC
#define INI_ALLOW_REALLOC 0
#endif
/* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK
is zero. */
#ifndef INI_INITIAL_ALLOC
#define INI_INITIAL_ALLOC 200
#endif
/* Stop parsing on first error (default is to keep parsing). */
#ifndef INI_STOP_ON_FIRST_ERROR
#define INI_STOP_ON_FIRST_ERROR 0
#endif
/* Nonzero to call the handler at the start of each new section (with
name and value NULL). Default is to only call the handler on
each name=value pair. */
#ifndef INI_CALL_HANDLER_ON_NEW_SECTION
#define INI_CALL_HANDLER_ON_NEW_SECTION 0
#endif
/* Nonzero to allow a name without a value (no '=' or ':' on the line) and
call the handler with value NULL in this case. Default is to treat
no-value lines as an error. */
#ifndef INI_ALLOW_NO_VALUE
#define INI_ALLOW_NO_VALUE 0
#endif
/* Nonzero to use custom ini_malloc, ini_free, and ini_realloc memory
allocation functions (INI_USE_STACK must also be 0). These functions must
have the same signatures as malloc/free/realloc and behave in a similar
way. ini_realloc is only needed if INI_ALLOW_REALLOC is set. */
#ifndef INI_CUSTOM_ALLOCATOR
#define INI_CUSTOM_ALLOCATOR 0
#endif
#ifdef __cplusplus
}
#endif
#endif /* INI_H */

View File

@@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.10.0)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -7,9 +8,8 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
file(STRINGS "VERSION" ver)
file(STRINGS "VERSION_SUFFIX" VERSION_SUFFIX)
project(GlobalProtect-openconnect VERSION ${ver} LANGUAGES CXX)
file(STRINGS "VERSION" version)
project(GlobalProtect-openconnect LANGUAGES CXX)
# Set the CMAKE_INSTALL_PREFIX to /usr if not specified
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
@@ -31,6 +31,7 @@ find_package(Qt5 REQUIRED COMPONENTS
)
add_subdirectory(3rdparty/qt-unix-signals)
add_subdirectory(3rdparty/inih)
add_subdirectory(GPService)
add_subdirectory(GPClient)
add_dependencies(gpclient gpservice)

View File

@@ -92,7 +92,7 @@ target_link_libraries(gpclient
QtSignals
)
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0)
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0 AND CMAKE_BUILD_TYPE STREQUAL Release)
target_compile_options(gpclient PUBLIC "-ffile-prefix-map=${CMAKE_SOURCE_DIR}=.")
endif()

View File

@@ -6,7 +6,7 @@ Name=GlobalProtect VPN
Comment=A GlobalProtect VPN client (GUI) for Linux based on OpenConnect and built with Qt5, supports SAML auth mode.
GenericName=GlobalProtect VPN client, supports SAML auth mode
Categories=Network;Dialup;
Exec=@CMAKE_INSTALL_PREFIX@/bin/gpclient
Exec=env QT_AUTO_SCREEN_SCALE_FACTOR=1 @CMAKE_INSTALL_PREFIX@/bin/gpclient
Icon=com.yuezk.qt.gpclient
Keywords=GlobalProtect;Openconnect;SAML;connection;VPN;
StartupWMClass=gpclient

View File

@@ -162,9 +162,18 @@ void GatewayAuthenticator::samlAuth(QString samlMethod, QString samlRequest, QSt
SAMLLoginWindow *loginWindow = new SAMLLoginWindow;
connect(loginWindow, &SAMLLoginWindow::success, this, &GatewayAuthenticator::onSAMLLoginSuccess);
connect(loginWindow, &SAMLLoginWindow::fail, this, &GatewayAuthenticator::onSAMLLoginFail);
connect(loginWindow, &SAMLLoginWindow::rejected, this, &GatewayAuthenticator::onLoginWindowRejected);
connect(loginWindow, &SAMLLoginWindow::success, [this, loginWindow](const QMap<QString, QString> &samlResult) {
this->onSAMLLoginSuccess(samlResult);
loginWindow->deleteLater();
});
connect(loginWindow, &SAMLLoginWindow::fail, [this, loginWindow](const QString &error) {
this->onSAMLLoginFail(error);
loginWindow->deleteLater();
});
connect(loginWindow, &SAMLLoginWindow::rejected, [this, loginWindow]() {
this->onLoginWindowRejected();
loginWindow->deleteLater();
});
loginWindow->login(samlMethod, samlRequest, preloginUrl);
}

View File

@@ -35,7 +35,7 @@ GPClient::GPClient(QWidget *parent, IVpn *vpn)
connect(ov, SIGNAL(error(QString)), this, SLOT(onVPNError(QString)));
connect(ov, SIGNAL(logAvailable(QString)), this, SLOT(onVPNLogAvailable(QString)));
// Initiallize the context menu of system tray.
// Initialize the context menu of system tray.
initSystemTrayIcon();
initVpnStatus();
}
@@ -68,14 +68,12 @@ void GPClient::setupSettings()
void GPClient::onSettingsButtonClicked()
{
settingsDialog->setExtraArgs(settings::get("extraArgs", "").toString());
settingsDialog->setClientos(settings::get("clientos", "Linux").toString());
settingsDialog->show();
}
void GPClient::onSettingsAccepted()
{
settings::save("extraArgs", settingsDialog->extraArgs());
settings::save("clientos", settingsDialog->clientos());
}
@@ -155,7 +153,7 @@ void GPClient::populateGatewayMenu()
if (g.name() == currentGatewayName) {
iconImage = ":/images/radio_selected.png";
}
gatewaySwitchMenu->addAction(QIcon(iconImage), g.name())->setData(i);
gatewaySwitchMenu->addAction(QIcon(iconImage), QString("%1 (%2)").arg(g.name(), g.address()))->setData(i);
}
}
@@ -281,12 +279,24 @@ void GPClient::portalLogin()
{
PortalAuthenticator *portalAuth = new PortalAuthenticator(portal(), settings::get("clientos", "Linux").toString());
connect(portalAuth, &PortalAuthenticator::success, this, &GPClient::onPortalSuccess);
connect(portalAuth, &PortalAuthenticator::success, [this, portalAuth](const PortalConfigResponse response, const QString region) {
this->onPortalSuccess(response, region);
portalAuth->deleteLater();
});
// Prelogin failed on the portal interface, try to treat the portal as a gateway interface
connect(portalAuth, &PortalAuthenticator::preloginFailed, this, &GPClient::onPortalPreloginFail);
connect(portalAuth, &PortalAuthenticator::portalConfigFailed, this, &GPClient::onPortalConfigFail);
connect(portalAuth, &PortalAuthenticator::preloginFailed, [this, portalAuth](const QString msg) {
this->onPortalPreloginFail(msg);
portalAuth->deleteLater();
});
connect(portalAuth, &PortalAuthenticator::portalConfigFailed, [this, portalAuth](const QString msg) {
this->onPortalConfigFail(msg);
portalAuth->deleteLater();
});
// Portal login failed
connect(portalAuth, &PortalAuthenticator::fail, this, &GPClient::onPortalFail);
connect(portalAuth, &PortalAuthenticator::fail, [this, portalAuth](const QString &msg) {
this->onPortalFail(msg);
portalAuth->deleteLater();
});
ui->statusLabel->setText("Authenticating...");
updateConnectionStatus(VpnStatus::pending);
@@ -361,8 +371,14 @@ void GPClient::gatewayLogin()
GatewayAuthenticator *gatewayAuth = new GatewayAuthenticator(currentGateway().address(), params);
connect(gatewayAuth, &GatewayAuthenticator::success, this, &GPClient::onGatewaySuccess);
connect(gatewayAuth, &GatewayAuthenticator::fail, this, &GPClient::onGatewayFail);
connect(gatewayAuth, &GatewayAuthenticator::success, [this, gatewayAuth](const QString &authToken) {
this->onGatewaySuccess(authToken);
gatewayAuth->deleteLater();
});
connect(gatewayAuth, &GatewayAuthenticator::fail, [this, gatewayAuth](const QString &msg) {
this->onGatewayFail(msg);
gatewayAuth->deleteLater();
});
ui->statusLabel->setText("Authenticating...");
updateConnectionStatus(VpnStatus::pending);
@@ -378,7 +394,7 @@ void GPClient::onGatewaySuccess(const QString &authCookie)
for (GPGateway &gw : allGateways()) {
gatewayAddresses.push_back(gw.address());
}
vpn->connect(currentGateway().address(), gatewayAddresses, portalConfig.username(), authCookie, settings::get("extraArgs", "").toString());
vpn->connect(currentGateway().address(), gatewayAddresses, portalConfig.username(), authCookie);
ui->statusLabel->setText("Connecting...");
updateConnectionStatus(VpnStatus::pending);
}

View File

@@ -9,6 +9,7 @@
#include "portalconfigresponse.h"
#include "settingsdialog.h"
#include "vpn.h"
#include "gatewayauthenticator.h"
QT_BEGIN_NAMESPACE
namespace Ui { class GPClient; }
@@ -80,6 +81,8 @@ private:
SettingsDialog *settingsDialog;
QPushButton *settingsButton;
GatewayAuthenticator *gatewayAuthenticator;
bool isQuickConnect { false };
bool isSwitchingGateway { false };
PortalConfigResponse portalConfig;

View File

@@ -1,6 +1,5 @@
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QDir>
#include <QtCore/QStandardPaths>
#include <plog/Log.h>
#include <plog/Init.h>
@@ -15,6 +14,8 @@
#include "sigwatch.h"
#include "version.h"
#define QT_AUTO_SCREEN_SCALE_FACTOR "QT_AUTO_SCREEN_SCALE_FACTOR"
int main(int argc, char *argv[])
{
plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender(plog::streamStdErr);
@@ -23,11 +24,16 @@ int main(int argc, char *argv[])
PLOGI << "GlobalProtect started, version: " << VERSION;
QString port = QString::fromLocal8Bit(qgetenv(ENV_CDP_PORT));
QString hidpiSupport = QString::fromLocal8Bit(qgetenv(QT_AUTO_SCREEN_SCALE_FACTOR));
if (port == "") {
if (port.isEmpty()) {
qputenv(ENV_CDP_PORT, "12315");
}
if (hidpiSupport.isEmpty()) {
qputenv(QT_AUTO_SCREEN_SCALE_FACTOR, "1");
}
SingleApplication app(argc, argv);
app.setQuitOnLastWindowClosed(false);
@@ -39,6 +45,7 @@ int main(int argc, char *argv[])
parser.addOptions({
{"json", "Write the result of the handshake with the GlobalConnect server to stdout as JSON and terminate. Useful for scripting."},
{"now", "Do not show the dialog with the connect button; connect immediately instead."},
{"start-minimized", "Launch the client minimized."},
});
parser.process(app);
@@ -48,7 +55,7 @@ int main(int argc, char *argv[])
? static_cast<IVpn*>(new VpnJson(nullptr)) // Print to stdout and exit
: static_cast<IVpn*>(new VpnDbus(nullptr)); // Contact GPService daemon via dbus
GPClient w(nullptr, vpn);
w.show();
parser.isSet("start-minimized") ? w.showMinimized() : w.show();
if (positional.size() > 0) {
w.portal(positional.at(0));

View File

@@ -78,10 +78,7 @@ QList<GPGateway> PortalConfigResponse::parseGateways(QXmlStreamReader &xmlReader
// Parse the gateways -> external -> list -> entry
if (xmlReader.name() == "entry" && xmlReader.isStartElement()) {
GPGateway g;
QString address = xmlReader.attributes().value("name").toString();
g.setAddress(address);
g.setPriorityRules(parsePriorityRules(xmlReader));
g.setName(parseGatewayName(xmlReader));
parseGateway(xmlReader, g);
gateways.append(g);
}
}
@@ -91,45 +88,49 @@ QList<GPGateway> PortalConfigResponse::parseGateways(QXmlStreamReader &xmlReader
return gateways;
}
QMap<QString, int> PortalConfigResponse::parsePriorityRules(QXmlStreamReader &xmlReader)
{
PLOGI << "Start parsing the priority rules...";
void PortalConfigResponse::parseGateway(QXmlStreamReader &reader, GPGateway &gateway) {
PLOGI << "Start parsing gateway...";
QMap<QString, int> priorityRules;
while ((xmlReader.name() != "priority-rule" || !xmlReader.isEndElement()) && !xmlReader.hasError()) {
xmlReader.readNext();
if (xmlReader.name() == "entry" && xmlReader.isStartElement()) {
QString ruleName = xmlReader.attributes().value("name").toString();
// Read the priority tag
while (xmlReader.name() != "priority"){
xmlReader.readNext();
}
int ruleValue = xmlReader.readElementText().toUInt();
priorityRules.insert(ruleName, ruleValue);
auto finished = false;
while (!finished) {
if (reader.name() == "entry" && reader.isStartElement()) {
auto address = reader.attributes().value("name").toString();
gateway.setAddress(address);
} else if (reader.name() == "description" && reader.isStartElement()) { // gateway name
gateway.setName(reader.readElementText());
} else if (reader.name() == "priority-rule" && reader.isStartElement()) { // priority rules
parsePriorityRule(reader, gateway);
}
auto result = reader.readNext();
finished = result == QXmlStreamReader::Invalid || (reader.name() == "entry" && reader.isEndElement());
}
PLOGI << "Finished parsing the priority rules.";
return priorityRules;
}
QString PortalConfigResponse::parseGatewayName(QXmlStreamReader &xmlReader)
{
PLOGI << "Start parsing the gateway name...";
void PortalConfigResponse::parsePriorityRule(QXmlStreamReader &reader, GPGateway &gateway) {
PLOGI << "Start parsing priority rule...";
while (xmlReader.name() != "description" || !xmlReader.isEndElement()) {
xmlReader.readNext();
if (xmlReader.name() == "description" && xmlReader.tokenType() == xmlReader.StartElement) {
PLOGI << "Finished parsing the gateway name";
return xmlReader.readElementText();
QMap<QString, int> priorityRules;
auto finished = false;
while (!finished) {
// Parse the priority-rule -> entry
if (reader.name() == "entry" && reader.isStartElement()) {
auto ruleName = reader.attributes().value("name").toString();
// move to the priority value
while (reader.readNextStartElement()) {
if (reader.name() == "priority") {
auto priority = reader.readElementText().toInt();
priorityRules.insert(ruleName, priority);
break;
}
}
}
auto result = reader.readNext();
finished = result == QXmlStreamReader::Invalid || (reader.name() == "priority-rule" && reader.isEndElement());
}
PLOGE << "Error: <description> tag not found";
return "";
gateway.setPriorityRules(priorityRules);
}
QString PortalConfigResponse::userAuthCookie() const
@@ -137,11 +138,6 @@ QString PortalConfigResponse::userAuthCookie() const
return m_userAuthCookie;
}
QString PortalConfigResponse::prelogonUserAuthCookie() const
{
return m_prelogonAuthCookie;
}
QList<GPGateway> PortalConfigResponse::allGateways() const
{
return m_gateways;
@@ -176,3 +172,4 @@ void PortalConfigResponse::setPrelogonUserAuthCookie(const QString cookie)
{
m_prelogonAuthCookie = cookie;
}

View File

@@ -19,7 +19,6 @@ public:
const QString &username() const;
QString password() const;
QString userAuthCookie() const;
QString prelogonUserAuthCookie() const;
QList<GPGateway> allGateways() const;
void setAllGateways(QList<GPGateway> gateways);
@@ -44,8 +43,9 @@ private:
void setPrelogonUserAuthCookie(const QString cookie);
static QList<GPGateway> parseGateways(QXmlStreamReader &xmlReader);
static QMap<QString, int> parsePriorityRules(QXmlStreamReader &xmlReader);
static QString parseGatewayName(QXmlStreamReader &xmlReader);
static void parseGateway(QXmlStreamReader &reader, GPGateway &gateway);
static void parsePriorityRule(QXmlStreamReader &reader, GPGateway &gateway);
};
#endif // PORTALCONFIGRESPONSE_H

View File

@@ -15,6 +15,7 @@ SAMLLoginWindow::SAMLLoginWindow(QWidget *parent)
QVBoxLayout *verticalLayout = new QVBoxLayout(this);
webView->setUrl(QUrl("about:blank"));
webView->setAttribute(Qt::WA_DeleteOnClose);
// webView->page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies);
verticalLayout->addWidget(webView);

View File

@@ -33,8 +33,11 @@
</item>
<item row="0" column="1">
<widget class="QPlainTextEdit" name="extraArgsInput">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="placeholderText">
<string extracomment="Tokens with spaces can be surrounded by double quotes">e.g. --name=value --script=&quot;vpn-slice xxx&quot;</string>
<string>The configuration has been moved to &quot;/etc/gpservice/gp.conf&quot;</string>
</property>
</widget>
</item>

View File

@@ -8,7 +8,7 @@ class IVpn
public:
virtual ~IVpn() = default;
virtual void connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs) = 0;
virtual void connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd) = 0;
virtual void disconnect() = 0;
virtual int status() = 0;

View File

@@ -1,7 +1,7 @@
#include "vpn_dbus.h"
void VpnDbus::connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs) {
inner->connect(preferredServer, username, passwd, extraArgs);
void VpnDbus::connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd) {
inner->connect(preferredServer, username, passwd);
}
void VpnDbus::disconnect() {

View File

@@ -20,7 +20,7 @@ public:
QObject::connect(inner, &com::yuezk::qt::GPService::logAvailable, this, &VpnDbus::logAvailable);
}
void connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs);
void connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd);
void disconnect();
int status();

View File

@@ -4,7 +4,7 @@
#include <QJsonObject>
#include <QJsonArray>
void VpnJson::connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs) {
void VpnJson::connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd) {
QJsonArray sl;
for (const QString &srv : servers) {
sl.push_back(QJsonValue(srv));

View File

@@ -10,7 +10,7 @@ class VpnJson : public QObject, public IVpn
public:
VpnJson(QObject *parent) : QObject(parent) {}
void connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd, const QString &extraArgs);
void connect(const QString &preferredServer, const QList<QString> &servers, const QString &username, const QString &passwd);
void disconnect();
int status();

View File

@@ -4,6 +4,12 @@ project(GPService)
set(gpservice_GENERATED_SOURCES)
execute_process(COMMAND logname OUTPUT_VARIABLE CMAKE_LOGNAME)
string(STRIP "${CMAKE_LOGNAME}" CMAKE_LOGNAME)
message(STATUS "CMAKE_LOGNAME: ${CMAKE_LOGNAME}")
configure_file(dbus/com.yuezk.qt.GPService.conf.in dbus/com.yuezk.qt.GPService.conf)
configure_file(dbus/com.yuezk.qt.GPService.service.in dbus/com.yuezk.qt.GPService.service)
configure_file(systemd/gpservice.service.in systemd/gpservice.service)
@@ -22,6 +28,7 @@ qt5_add_dbus_adaptor(
)
add_executable(gpservice
gpservice.h
gpservice.cpp
main.cpp
${gpservice_GENERATED_SOURCES}
@@ -58,13 +65,15 @@ target_link_libraries(gpservice
Qt5::Network
Qt5::DBus
QtSignals
inih
)
target_compile_definitions(gpservice PUBLIC QAPPLICATION_CLASS=QCoreApplication)
install(TARGETS gpservice DESTINATION bin)
install(FILES "dbus/com.yuezk.qt.GPService.conf" DESTINATION share/dbus-1/system.d )
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/dbus/com.yuezk.qt.GPService.conf" DESTINATION share/dbus-1/system.d )
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/dbus/com.yuezk.qt.GPService.service" DESTINATION share/dbus-1/system-services)
install(FILES "gp.conf" DESTINATION /etc/gpservice)
if("$ENV{DEBIAN_PACKAGE}")
# Install the systemd unit files to /lib/systemd/system for debian package

17
GPService/gp.conf Normal file
View File

@@ -0,0 +1,17 @@
# Configuration file for GlobalProtect-openconnect
#
# Description:
#
# Each section is a VPN gateway address, and [*] is a special section that defines the default configuration.
# See https://github.com/yuezk/GlobalProtect-openconnect/wiki/Configuration for more details.
#
# Example:
#
# [*]
# openconnect-args=<value>
#
# [vpn1.company.com]
# openconnect-args=--script=/path/to/vpnc-script
[*]
openconnect-args=

View File

@@ -5,6 +5,7 @@
#include <QtCore/QRegularExpressionMatch>
#include <QtDBus/QtDBus>
#include "INIReader.h"
#include "gpservice.h"
#include "gpserviceadaptor.h"
@@ -41,8 +42,22 @@ QString GPService::findBinary()
return nullptr;
}
QString GPService::extraOpenconnectArgs(const QString &gateway)
{
INIReader reader("/etc/gpservice/gp.conf");
if (reader.ParseError() < 0) {
return "";
}
std::string defaultArgs = reader.Get("*", "openconnect-args", "");
std::string extraArgs = reader.Get(gateway.toStdString(), "openconnect-args", defaultArgs);
return QString::fromStdString(extraArgs);
}
/* Port from https://github.com/qt/qtbase/blob/11d1dcc6e263c5059f34b44d531c9ccdf7c0b1d6/src/corelib/io/qprocess.cpp#L2115 */
QStringList GPService::splitCommand(QString command)
QStringList GPService::splitCommand(const QString &command)
{
QStringList args;
QString tmp;
@@ -92,7 +107,7 @@ void GPService::quit()
}
}
void GPService::connect(QString server, QString username, QString passwd, QString extraArgs)
void GPService::connect(QString server, QString username, QString passwd)
{
if (vpnStatus != GPService::VpnNotConnected) {
log("VPN status is: " + QVariant::fromValue(vpnStatus).toString());
@@ -110,6 +125,9 @@ void GPService::connect(QString server, QString username, QString passwd, QStrin
return;
}
const QString extraArgs = extraOpenconnectArgs(server);
log(QString("Got extra OpenConnect args for server: %1, %2").arg(server, extraArgs.isEmpty() ? "<empty>" : extraArgs));
QStringList args;
args << QCoreApplication::arguments().mid(1)
<< "--protocol=gp"
@@ -118,7 +136,7 @@ void GPService::connect(QString server, QString username, QString passwd, QStrin
<< "--cookie-on-stdin"
<< server;
log("Start process with arugments: " + args.join(" "));
log("Start process with arugments: " + args.join(", "));
openconnect->start(bin, args);
openconnect->write((passwd + "\n").toUtf8());

View File

@@ -37,7 +37,7 @@ signals:
void logAvailable(QString log);
public slots:
void connect(QString server, QString username, QString passwd, QString extraArgs);
void connect(QString server, QString username, QString passwd);
void disconnect();
int status();
@@ -56,7 +56,8 @@ private:
void log(QString msg);
bool isValidVersion(QString &bin);
static QString findBinary();
static QStringList splitCommand(QString command);
static QString extraOpenconnectArgs(const QString &gateway);
static QStringList splitCommand(const QString &command);
};
#endif // GLOBALPROTECTSERVICE_H

View File

@@ -42,7 +42,7 @@ Add the repository in the above table and install it with your favorite package
```sh
sudo add-apt-repository ppa:yuezk/globalprotect-openconnect
sudo apt-get update
sudo apt install globalprotect-openconnect
sudo apt-get install globalprotect-openconnect
```
> For Linux Mint, you might need to import the GPG key with: `sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7937C393082992E5D6E4A60453FC26B43838D761` if you encountered an error `gpg: keyserver receive failed: General error`.
@@ -87,7 +87,7 @@ sudo dnf install globalprotect-openconnect
1. Add the repository: `https://download.opensuse.org/repositories/home:/yuezk/CentOS_8/home:yuezk.repo`
1. Install `globalprotect-openconnect`
## Build & Install from source code
Clone this repo with:
@@ -100,14 +100,14 @@ cd GlobalProtect-openconnect
### Ubuntu/Mint
> **⚠️ REQUIRED for Ubuntu 18.04 ⚠️**
>
>
> Add this [dwmw2/openconnect](https://launchpad.net/~dwmw2/+archive/ubuntu/openconnect) PPA first to install the latest openconnect.
>
>
> ```sh
> sudo add-apt-repository ppa:dwmw2/openconnect
> sudo apt update
> sudo apt-get update
> ```
Build and install with:
```sh
@@ -155,7 +155,7 @@ Install the Qt5 dependencies and OpenConnect:
# if you need a Host Integrity Protection report
csdWrapper = "${pkgs.openconnect}/libexec/openconnect/hipreport.sh";
};
environment.systemPackages = [ globalprotect-openconnect ];
```
@@ -165,14 +165,8 @@ Once the software is installed, you can run `gpclient` to start the UI.
## Passing the Custom Parameters to `OpenConnect` CLI
Custom parameters can be appended to the `OpenConnect` CLI with the following settings.
See [Configuration](https://github.com/yuezk/GlobalProtect-openconnect/wiki/Configuration)
> Tokens with spaces can be surrounded by double quotes; three consecutive double quotes represent the quote character itself.
<p align="center">
<img src="https://user-images.githubusercontent.com/3297602/130319209-744be02b-d657-4f49-a76d-d2c81b5c46d5.png" />
<p>
## Display the system tray icon on Gnome 40
Install the [AppIndicator and KStatusNotifierItem Support](https://extensions.gnome.org/extension/615/appindicator-support/) extension and you will see the system try icon (Restart the system after the installation).
@@ -181,7 +175,7 @@ Install the [AppIndicator and KStatusNotifierItem Support](https://extensions.gn
<img src="https://user-images.githubusercontent.com/3297602/130831022-b93492fd-46dd-4a8e-94a4-13b5747120b7.png" />
<p>
## Future plan
@@ -189,11 +183,11 @@ Install the [AppIndicator and KStatusNotifierItem Support](https://extensions.gn
- [ ] Process bugs and feature requests
- [ ] Support for bypassing the `gpclient` parameters
- [ ] Support the CLI mode
## Troubleshooting
The application logs can be found at: `~/.cache/GlobalProtect-openconnect/gpclient.log`
Run `gpclient` in the Terminal and collect the logs.
## [License](./LICENSE)
GPLv3

View File

@@ -1 +1 @@
1.4.2
1.4.6

View File

View File

@@ -0,0 +1,59 @@
# - Try to find NetworkManager
# Once done this will define
#
# NETWORKMANAGER_FOUND - system has NetworkManager
# NETWORKMANAGER_INCLUDE_DIRS - the NetworkManager include directories
# NETWORKMANAGER_LIBRARIES - the libraries needed to use NetworkManager
# NETWORKMANAGER_CFLAGS - Compiler switches required for using NetworkManager
# NETWORKMANAGER_VERSION - version number of NetworkManager
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
# Copyright (c) 2007, Will Stephenson, <wstephenson@kde.org>
# Copyright (c) 2015-2018, Jan Grulich, <jgrulich@redhat.com>
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
IF (NETWORKMANAGER_INCLUDE_DIRS)
# in cache already
SET(NetworkManager_FIND_QUIETLY TRUE)
ENDIF (NETWORKMANAGER_INCLUDE_DIRS)
IF (NOT WIN32)
find_package(PkgConfig)
PKG_SEARCH_MODULE(NETWORKMANAGER libnm)
IF (NETWORKMANAGER_FOUND)
IF (NetworkManager_FIND_VERSION AND ("${NETWORKMANAGER_VERSION}" VERSION_LESS "${NetworkManager_FIND_VERSION}"))
MESSAGE(FATAL_ERROR "NetworkManager ${NETWORKMANAGER_VERSION} is too old, need at least ${NetworkManager_FIND_VERSION}")
ELSE ()
IF (NOT NetworkManager_FIND_QUIETLY)
MESSAGE(STATUS "Found NetworkManager: ${NETWORKMANAGER_LIBRARY_DIRS}")
ENDIF ()
ENDIF ()
ELSE ()
MESSAGE(FATAL_ERROR "Could NOT find NetworkManager, check FindPkgConfig output above!")
ENDIF ()
ENDIF (NOT WIN32)
MARK_AS_ADVANCED(NETWORKMANAGER_INCLUDE_DIRS)

48
debian/changelog vendored
View File

@@ -1,3 +1,51 @@
globalprotect-openconnect (1.4.6-1) unstable; urgency=medium
* Updated VERSION, Bumped 1.4.5 > 1.4.6
* feat: display address in gateway menu item
* fix: fix bug of parsing the portal respponse
-- Kevin Yue <k3vinyue@gmail.com> Wed, 01 Jun 2022 23:55:50 +0800
globalprotect-openconnect (1.4.5-1) unstable; urgency=medium
* Updated VERSION, Bumped 1.4.4 > 1.4.5
* chore: refine vscode settings
* fix: rollback dbus configuration
* feat: add option to start minimized
* packaging: fix postinst for debian
* packaging: add postinst for debian
* test: test debian packaging
* ci: fix the foder path
* chore: apt -> apt-get
* ci: verify debian package
* Revert "Revert "fix: improve the dbus security""
* fix: improve the portal config parsing
* Revert "fix: improve the dbus security"
* fix: improve the dbus security
* fix: free resources in slots
* chore: refine cmake files
* fix: support high DPI screen
-- Kevin Yue <k3vinyue@gmail.com> Sun, 29 May 2022 21:15:40 +0800
globalprotect-openconnect (1.4.4-1) unstable; urgency=medium
* Updated VERSION, Bumped 1.4.3 > 1.4.4
* fix: support the HighDPI displays
* [misc] update the build script
* [ci] Enable build job for master branch
* [ci] Add ubuntu 22.04
-- Kevin Yue <k3vinyue@gmail.com> Sat, 14 May 2022 19:21:14 +0800
globalprotect-openconnect (1.4.3-1) unstable; urgency=medium
* Updated VERSION, Bumped 1.4.2 > 1.4.3
* refine AUR packaging
* Prepare release 1.4.3 (#149)
-- Kevin Yue <k3vinyue@gmail.com> Mon, 09 May 2022 22:20:54 +0800
globalprotect-openconnect (1.4.2-1) unstable; urgency=medium
* Updated VERSION, Bumped 1.4.1 > 1.4.2

View File

@@ -1,26 +1,33 @@
# Maintainer: Keinv Yue <yuezk001@gmail.com>
pkgname=globalprotect-openconnect
pkgver=0
_pkgver="1.4.6"
_commit="b57fb993ca6cfb5e42cf77d2d26486ad40c32d23"
pkgname=globalprotect-openconnect-git
pkgver=${_pkgver}
pkgrel=1
pkgdesc="A GlobalProtect VPN client (GUI) for Linux based on Openconnect and built with Qt5, supports SAML auth mode."
pkgdesc="A GlobalProtect VPN client (GUI) for Linux based on Openconnect and built with Qt5, supports SAML auth mode. (development version)"
arch=(x86_64 aarch64)
url="https://github.com/yuezk/GlobalProtect-openconnect"
license=('GPL3')
backup=(
etc/gpservice/gp.conf
)
install=gp.install
depends=('openconnect>=8.0.0' qt5-base qt5-webengine qt5-websockets)
makedepends=(cmake)
provides=('gpclient' 'gpservice')
makedepends=(git cmake)
conflicts=('globalprotect-openconnect')
provides=('globalprotect-openconnect' 'gpclient' 'gpservice')
source=("${pkgname}.tar.gz")
source=(git+https://github.com/yuezk/GlobalProtect-openconnect#commit=${_commit})
sha256sums=('SKIP')
pkgver() {
cd $srcdir/$pkgname-*/
cat VERSION VERSION_SUFFIX
prepare() {
cd GlobalProtect-openconnect
echo "${_pkgver}" > VERSION
}
build() {
cd $srcdir/$pkgname-*/
cd GlobalProtect-openconnect
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS_RELEASE=-s
@@ -28,6 +35,6 @@ build() {
}
package() {
cd $srcdir/$pkgname-*/
cd GlobalProtect-openconnect
make DESTDIR="$pkgdir/" install -C build
}

View File

@@ -1,28 +1,33 @@
# Maintainer: Keinv Yue <yuezk001@gmail.com>
_pkgver="{VERSION}"
_commit="{COMMIT}"
pkgname=globalprotect-openconnect-git
_pkgname=globalprotect-openconnect
pkgver=0
pkgver=${_pkgver}
pkgrel=1
pkgdesc="A GlobalProtect VPN client (GUI) for Linux based on Openconnect and built with Qt5, supports SAML auth mode. (development version)"
arch=(x86_64 aarch64)
url="https://github.com/yuezk/GlobalProtect-openconnect"
license=('GPL3')
backup=(
etc/gpservice/gp.conf
)
install=gp.install
depends=('openconnect>=8.0.0' qt5-base qt5-webengine qt5-websockets)
makedepends=(cmake)
makedepends=(git cmake)
conflicts=('globalprotect-openconnect')
provides=('gpclient' 'gpservice')
provides=('globalprotect-openconnect' 'gpclient' 'gpservice')
source=("${_pkgname}.tar.gz")
source=(git+https://github.com/yuezk/GlobalProtect-openconnect#commit=${_commit})
sha256sums=('SKIP')
pkgver() {
cd $srcdir/$_pkgname-*/
cat VERSION VERSION_SUFFIX
prepare() {
cd GlobalProtect-openconnect
echo "${_pkgver}" > VERSION
}
build() {
cd $srcdir/${_pkgname}-*/
cd GlobalProtect-openconnect
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS_RELEASE=-s
@@ -30,6 +35,6 @@ build() {
}
package() {
cd $srcdir/${_pkgname}-*/
cd GlobalProtect-openconnect
make DESTDIR="$pkgdir/" install -C build
}

8
packaging/aur/gp.install Executable file
View File

@@ -0,0 +1,8 @@
post_install() {
systemctl enable gpservice.service
systemctl restart gpservice.service
}
post_upgrade() {
post_install
}

View File

@@ -1,3 +1,51 @@
-------------------------------------------------------------------
Wed Jun 1 15:55:50 UTC 2022 - k3vinyue@gmail.com - 1.4.6
- Update to 1.4.6
* Updated VERSION, Bumped 1.4.5 > 1.4.6
* feat: display address in gateway menu item
* fix: fix bug of parsing the portal respponse
-------------------------------------------------------------------
Sun May 29 13:15:40 UTC 2022 - k3vinyue@gmail.com - 1.4.5
- Update to 1.4.5
* Updated VERSION, Bumped 1.4.4 > 1.4.5
* chore: refine vscode settings
* fix: rollback dbus configuration
* feat: add option to start minimized
* packaging: fix postinst for debian
* packaging: add postinst for debian
* test: test debian packaging
* ci: fix the foder path
* chore: apt -> apt-get
* ci: verify debian package
* Revert "Revert "fix: improve the dbus security""
* fix: improve the portal config parsing
* Revert "fix: improve the dbus security"
* fix: improve the dbus security
* fix: free resources in slots
* chore: refine cmake files
* fix: support high DPI screen
-------------------------------------------------------------------
Sat May 14 11:21:14 UTC 2022 - k3vinyue@gmail.com - 1.4.4
- Update to 1.4.4
* Updated VERSION, Bumped 1.4.3 > 1.4.4
* fix: support the HighDPI displays
* [misc] update the build script
* [ci] Enable build job for master branch
* [ci] Add ubuntu 22.04
-------------------------------------------------------------------
Mon May 9 14:20:54 UTC 2022 - k3vinyue@gmail.com - 1.4.3
- Update to 1.4.3
* Updated VERSION, Bumped 1.4.2 > 1.4.3
* refine AUR packaging
* Prepare release 1.4.3 (#149)
-------------------------------------------------------------------
Fri May 6 14:18:19 UTC 2022 - k3vinyue@gmail.com - 1.4.2

View File

@@ -1,5 +1,5 @@
Name: globalprotect-openconnect
Version: 1.4.2
Version: 1.4.6
Release: 1
Summary: A GlobalProtect VPN client powered by OpenConnect
Group: Productivity/Networking/PPP
@@ -54,7 +54,7 @@ A GlobalProtect VPN client (GUI) for Linux based on OpenConnect and built with Q
%if 0%{?suse_version}
%service_del_postun gpservice.service
%else
%systemd_postun gpservice.service
%systemd_postun_with_restart gpservice.service
%endif
@@ -73,7 +73,7 @@ A GlobalProtect VPN client (GUI) for Linux based on OpenConnect and built with Q
%install
%if 0%{?fedora_version} && 0%{?fedora_version} <= 32
%make_install
%make_install
%else
%cmake_install
%endif
@@ -88,7 +88,9 @@ A GlobalProtect VPN client (GUI) for Linux based on OpenConnect and built with Q
%{_datadir}/dbus-1/system.d/com.yuezk.qt.GPService.conf
%{_datadir}/icons/hicolor/scalable/apps/com.yuezk.qt.gpclient.svg
%{_datadir}/metainfo/com.yuezk.qt.gpclient.metainfo.xml
%config %{_sysconfdir}/gpservice/gp.conf
%dir %{_sysconfdir}/gpservice
%dir %{_datadir}/icons/hicolor
%dir %{_datadir}/icons/hicolor/scalable
%dir %{_datadir}/icons/hicolor/scalable/apps

View File

@@ -1,6 +1,6 @@
#!/bin/bash -e
VERSION=$(cat VERSION VERSION_SUFFIX)
VERSION="$(cat VERSION)"
rm -rf ./artifacts && mkdir -p ./artifacts/{obs,aur,flatpak}
@@ -18,8 +18,8 @@ cp -r ./packaging/obs ./artifacts
cp ./artifacts/*.tar.gz ./artifacts/obs/globalprotect-openconnect.tar.gz
# Prepare the AUR package
cp ./packaging/aur/PKGBUILD-git ./artifacts/aur/PKGBUILD
cp ./artifacts/*.tar.gz ./artifacts/aur/globalprotect-openconnect.tar.gz
cp ./packaging/aur/PKGBUILD ./artifacts/aur/PKGBUILD
cp ./packaging/aur/gp.install ./artifacts/aur/gp.install
# Prepare the flatpak package
cp ./packaging/flatpak/com.yuezk.qt.gpclient.yml ./artifacts/flatpak

View File

@@ -1,11 +1,11 @@
#!/bin/bash -e
sudo apt update
sudo apt install -y \
sudo apt-get update
sudo apt-get install -y \
build-essential \
qtbase5-dev \
libqt5websockets5-dev \
qtwebengine5-dev \
openconnect
./scripts/install.sh
./scripts/install.sh

View File

@@ -1,53 +0,0 @@
#!/bin/bash -e
VERSION="$(cat VERSION VERSION_SUFFIX)"
OLD_REVISION="1"
PPA_REPO="ppa:yuezk/globalprotect-openconnect-snapshot"
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
--stable)
PPA_REPO="ppa:yuezk/globalprotect-openconnect"
shift
;;
"18.04")
DISTRIBUTION="18.04"
DISTRIBUTION_NAME="bionic"
shift
;;
"20.04")
DISTRIBUTION="20.04"
DISTRIBUTION_NAME="focal"
shift
;;
"21.04")
DISTRIBUTION="21.04"
DISTRIBUTION_NAME="hirsute"
shift
;;
"21.10")
DISTRIBUTION="21.10"
DISTRIBUTION_NAME="impish"
shift
;;
*)
echo "Unkown options $key"
exit 1
;;
esac
done
[ -z $DISTRIBUTION ] && echo "The distribuation is required" && exit 1;
NEW_REVISION="ppa1~ubuntu${DISTRIBUTION}"
sed -i"" "1s/${VERSION}-${OLD_REVISION}/${VERSION}-${NEW_REVISION}/;1s/unstable/${DISTRIBUTION_NAME}/" debian/changelog
debmake
debuild -S -sa \
-k"${PPA_GPG_KEYID}" \
-p"gpg --batch --passphrase ${PPA_GPG_PASSPHRASE} --pinentry-mode loopback"
dput $PPA_REPO ../globalprotect-openconnect_${VERSION}-${NEW_REVISION}_source.changes

View File

@@ -2,14 +2,13 @@
OLD_VERSION=$(git tag --sort=-v:refname --list "v[0-9]*" | head -n 1 | cut -c 2-)
NEW_VERSION="$(cat VERSION)"
FULL_VERSION="$(cat VERSION VERSION_SUFFIX)"
HISTORY_ENTRIES=$(git log --format=" * %s" v${OLD_VERSION}.. | cat -n | sort -uk2 | sort -n | cut -f2-)
function update_debian_changelog() {
local OLD_CHANGELOG=$(cat debian/changelog)
cat > debian/changelog <<-EOF
globalprotect-openconnect (${FULL_VERSION}-1) unstable; urgency=medium
globalprotect-openconnect (${NEW_VERSION}-1) unstable; urgency=medium
${HISTORY_ENTRIES}
@@ -24,17 +23,24 @@ function update_rpm_changelog() {
cat > packaging/obs/globalprotect-openconnect.changes <<-EOF
-------------------------------------------------------------------
$(LC_ALL=en.US date -u "+%a %b %e %T %Z %Y") - k3vinyue@gmail.com - ${FULL_VERSION}
$(LC_ALL=en.US date -u "+%a %b %e %T %Z %Y") - k3vinyue@gmail.com - ${NEW_VERSION}
- Update to ${FULL_VERSION}
- Update to ${NEW_VERSION}
${HISTORY_ENTRIES}
${OLD_CHANGELOG}
EOF
}
function generate_pkgbuild() {
local commit_id="$(git rev-parse HEAD)"
local version="$(cat VERSION)"
sed -e "s/{COMMIT}/${commit_id}/" -e "s/{VERSION}/${version}/" packaging/aur/PKGBUILD.in > packaging/aur/PKGBUILD
}
# Update rpm version
sed -i"" -re "s/(Version:\s+).+/\1${FULL_VERSION}/" packaging/obs/globalprotect-openconnect.spec
sed -i"" -re "s/(Version:\s+).+/\1${NEW_VERSION}/" packaging/obs/globalprotect-openconnect.spec
update_rpm_changelog
update_debian_changelog
generate_pkgbuild

View File

@@ -2,9 +2,6 @@
VERSION=$(cat VERSION)
# Clear the VERSION_SUFFIX
cat /dev/null > VERSION_SUFFIX
# Update packaging, e.g., version, changelog, etc.
./scripts/prepare-packaging.sh

View File

@@ -12,6 +12,3 @@ mv ./artifacts/obs/globalprotect-openconnect-rpmlintrc ./artifacts/obs/globalpro
sed -i"" -re "s/(Name:\s+).+/\1globalprotect-openconnect-snapshot/" \
-re "s/(Conflicts:\s+).+/\1globalprotect-openconnect/" \
./artifacts/obs/globalprotect-openconnect-snapshot.spec
# Update the AUR package
cp ./packaging/aur/PKGBUILD-git ./artifacts/aur/PKGBUILD

View File

@@ -1,3 +1,4 @@
#!/bin/bash -e
git describe --tags --match "v$(cat VERSION)" | sed -r -e 's/v([^-]+)-/+snapshot/' -e 's/-/./' > VERSION_SUFFIX
VERSION="v$(cat VERSION)"
git describe --tags --match "${VERSION}" | sed -re 's/^v([^-]+)-([^-]+)-(.+)/\1+\2snapshot.\3/' > VERSION

View File

@@ -0,0 +1,17 @@
#!/bin/bash -e
sudo apt-get update
sudo apt-get install -y \
build-essential \
qtbase5-dev \
libqt5websockets5-dev \
qtwebengine5-dev \
cmake \
debhelper
mkdir -p build
cp ./artifacts/*.tar.gz build/ && cd build
tar -xzf *.tar.gz && cd globalprotect-openconnect-*/
dpkg-buildpackage -us -uc

View File

@@ -66,7 +66,7 @@ parts:
override-pull: |
snapcraftctl pull
VERSION=$(cat VERSION VERSION_SUFFIX)
VERSION=$(cat VERSION)
GRADE="stable"
if echo "$VERSION" | grep -q "snapshot"

View File

@@ -1 +1 @@
#define VERSION "@GlobalProtect-openconnect_VERSION@@VERSION_SUFFIX@"
#define VERSION "@version@"