mirror of
https://github.com/yuezk/GlobalProtect-openconnect.git
synced 2025-05-20 07:26:58 -04:00
Compare commits
2 Commits
4191e9a19f
...
f91f0bcd17
Author | SHA1 | Date | |
---|---|---|---|
|
f91f0bcd17 | ||
|
5603157679 |
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -18,6 +18,7 @@
|
|||||||
"tauri",
|
"tauri",
|
||||||
"unlisten",
|
"unlisten",
|
||||||
"userauthcookie",
|
"userauthcookie",
|
||||||
|
"vpnc",
|
||||||
"vpninfo"
|
"vpninfo"
|
||||||
],
|
],
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
|
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -1122,6 +1122,7 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"cc",
|
"cc",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
|
"is_executable",
|
||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1416,6 +1417,15 @@ dependencies = [
|
|||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_executable"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa9acdc6d67b75e626ad644734e8bc6df893d9cd2a834129065d3dd6158ea9c8"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.8"
|
version = "0.4.8"
|
||||||
|
@ -16,6 +16,7 @@ async-trait = "0.1"
|
|||||||
ring = "0.16"
|
ring = "0.16"
|
||||||
data-encoding = "2.3"
|
data-encoding = "2.3"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
is_executable = "1.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "1.0"
|
cc = "1.0"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::vpn::vpnc_script::find_default_vpnc_script;
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::ffi::{c_void, CString};
|
use std::ffi::{c_void, CString};
|
||||||
@ -7,6 +8,7 @@ use tokio::sync::watch;
|
|||||||
use tokio::sync::{mpsc, Mutex};
|
use tokio::sync::{mpsc, Mutex};
|
||||||
|
|
||||||
mod ffi;
|
mod ffi;
|
||||||
|
mod vpnc_script;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
@ -87,11 +89,21 @@ impl Vpn {
|
|||||||
server: &str,
|
server: &str,
|
||||||
cookie: &str,
|
cookie: &str,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let script = match find_default_vpnc_script() {
|
||||||
|
Some(script) => {
|
||||||
|
debug!("Using default vpnc-script: {}", script);
|
||||||
|
script
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return Err("Failed to find default vpnc-script".into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Save the VPN options so we can use them later, e.g. reconnect
|
// Save the VPN options so we can use them later, e.g. reconnect
|
||||||
*self.vpn_options.lock().await = Some(VpnOptions {
|
*self.vpn_options.lock().await = Some(VpnOptions {
|
||||||
server: VpnOptions::to_cstr(server),
|
server: VpnOptions::to_cstr(server),
|
||||||
cookie: VpnOptions::to_cstr(cookie),
|
cookie: VpnOptions::to_cstr(cookie),
|
||||||
script: VpnOptions::to_cstr("/usr/share/vpnc-scripts/vpnc-script"),
|
script: VpnOptions::to_cstr(script),
|
||||||
});
|
});
|
||||||
|
|
||||||
let vpn_options = self.vpn_options.clone();
|
let vpn_options = self.vpn_options.clone();
|
||||||
|
21
gpcommon/src/vpn/vpnc_script.rs
Normal file
21
gpcommon/src/vpn/vpnc_script.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use is_executable::IsExecutable;
|
||||||
|
|
||||||
|
const VPNC_SCRIPT_LOCATIONS: [&str; 4] = [
|
||||||
|
"/usr/local/share/vpnc-scripts/vpnc-script",
|
||||||
|
"/usr/local/sbin/vpnc-script",
|
||||||
|
"/usr/share/vpnc-scripts/vpnc-script",
|
||||||
|
"/usr/sbin/vpnc-script /etc/vpnc/vpnc-script",
|
||||||
|
];
|
||||||
|
|
||||||
|
pub(crate) fn find_default_vpnc_script() -> Option<&'static str> {
|
||||||
|
for location in VPNC_SCRIPT_LOCATIONS.iter() {
|
||||||
|
let path = Path::new(location);
|
||||||
|
if path.is_executable() {
|
||||||
|
return Some(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
@ -4,12 +4,13 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0" />
|
||||||
<title>Vite + React + TS</title>
|
<title>GlobalProtect</title>
|
||||||
</head>
|
</head>
|
||||||
<body data-tauri-drag-region>
|
<body data-tauri-drag-region>
|
||||||
<script>
|
<script>
|
||||||
|
/* workaround to webview font size auto scaling */
|
||||||
var htmlFontSize = getComputedStyle(document.documentElement).fontSize;
|
var htmlFontSize = getComputedStyle(document.documentElement).fontSize;
|
||||||
var ratio = parseInt(htmlFontSize) / 16;
|
var ratio = parseInt(htmlFontSize, 10) / 16;
|
||||||
document.documentElement.style.fontSize = (16 / ratio) + 'px';
|
document.documentElement.style.fontSize = (16 / ratio) + 'px';
|
||||||
</script>
|
</script>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
@ -35,7 +35,7 @@ export default function PortalForm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit} data-tauri-drag-region>
|
||||||
<TextField
|
<TextField
|
||||||
autoFocus
|
autoFocus
|
||||||
label="Portal address"
|
label="Portal address"
|
||||||
|
@ -93,17 +93,11 @@ function InnerStatusIcon() {
|
|||||||
return <DisconnectedIcon />;
|
return <DisconnectedIcon />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DragRegion = styled(Box)(({ theme }) => ({
|
|
||||||
position: "absolute",
|
|
||||||
inset: 0,
|
|
||||||
}));
|
|
||||||
|
|
||||||
export default function StatusIcon() {
|
export default function StatusIcon() {
|
||||||
return (
|
return (
|
||||||
<IconContainer>
|
<IconContainer>
|
||||||
<BackgroundIcon />
|
<BackgroundIcon />
|
||||||
<InnerStatusIcon />
|
<InnerStatusIcon />
|
||||||
<DragRegion data-tauri-drag-region />
|
|
||||||
</IconContainer>
|
</IconContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ export default function StatusText() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Typography
|
<Typography
|
||||||
data-tauri-drag-region
|
|
||||||
textAlign="center"
|
textAlign="center"
|
||||||
mt={1.5}
|
mt={1.5}
|
||||||
variant="subtitle1"
|
variant="subtitle1"
|
||||||
|
@ -4,9 +4,10 @@ import StatusText from "./StatusText";
|
|||||||
|
|
||||||
export default function ConnectionStatus() {
|
export default function ConnectionStatus() {
|
||||||
return (
|
return (
|
||||||
<Box data-tauri-drag-region>
|
<Box position="relative">
|
||||||
<StatusIcon />
|
<StatusIcon />
|
||||||
<StatusText />
|
<StatusText />
|
||||||
|
<Box data-tauri-drag-region position="absolute" sx={{ inset: 0 }} />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,12 @@ const LinkChip = (props: ChipProps<"a">) => (
|
|||||||
|
|
||||||
export default function Feedback() {
|
export default function Feedback() {
|
||||||
return (
|
return (
|
||||||
<Stack direction="row" justifyContent="space-evenly" mt={1}>
|
<Stack
|
||||||
|
direction="row"
|
||||||
|
justifyContent="space-evenly"
|
||||||
|
mt={1}
|
||||||
|
data-tauri-drag-region
|
||||||
|
>
|
||||||
<LinkChip
|
<LinkChip
|
||||||
avatar={<BugReport />}
|
avatar={<BugReport />}
|
||||||
label="Feedback"
|
label="Feedback"
|
||||||
|
@ -16,6 +16,7 @@ import { isProcessingAtom, statusAtom } from "../../atoms/status";
|
|||||||
|
|
||||||
const MenuContainer = styled(Box)(({ theme }) => ({
|
const MenuContainer = styled(Box)(({ theme }) => ({
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
|
zIndex: 1,
|
||||||
left: theme.spacing(1),
|
left: theme.spacing(1),
|
||||||
top: theme.spacing(1),
|
top: theme.spacing(1),
|
||||||
}));
|
}));
|
||||||
@ -100,6 +101,7 @@ export default function MainMenu() {
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
sx={{
|
sx={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
|
zIndex: 1,
|
||||||
right: (theme) => theme.spacing(1),
|
right: (theme) => theme.spacing(1),
|
||||||
top: (theme) => theme.spacing(1),
|
top: (theme) => theme.spacing(1),
|
||||||
}}
|
}}
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
import { Alert, AlertTitle, Box, Slide, SlideProps, Snackbar } from "@mui/material";
|
import {
|
||||||
|
Alert,
|
||||||
|
AlertTitle,
|
||||||
|
Box,
|
||||||
|
Slide,
|
||||||
|
SlideProps,
|
||||||
|
Snackbar,
|
||||||
|
} from "@mui/material";
|
||||||
import { useAtom, useAtomValue } from "jotai";
|
import { useAtom, useAtomValue } from "jotai";
|
||||||
import {
|
import {
|
||||||
closeNotificationAtom,
|
closeNotificationAtom,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user