mirror of
				https://github.com/yuezk/GlobalProtect-openconnect.git
				synced 2025-05-20 07:26:58 -04:00 
			
		
		
		
	refactor: add the process check
This commit is contained in:
		| @@ -15,13 +15,25 @@ async fn handle_read( | ||||
|     read_stream: ReadHalf<UnixStream>, | ||||
|     server_context: Arc<ServerContext>, | ||||
|     response_tx: mpsc::Sender<Response>, | ||||
|     peer_pid: Option<i32>, | ||||
|     cancel_token: CancellationToken, | ||||
| ) { | ||||
|     let mut reader: Reader = read_stream.into(); | ||||
|     let mut authenticated: Option<bool> = None; | ||||
|  | ||||
|     loop { | ||||
|         match reader.read::<Request>().await { | ||||
|             Ok(request) => { | ||||
|                 if authenticated.is_none() { | ||||
|                     authenticated = Some(authenticate(peer_pid)); | ||||
|                 } | ||||
|  | ||||
|                 if !authenticated.unwrap_or(false) { | ||||
|                     println!("Client not authenticated"); | ||||
|                     cancel_token.cancel(); | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 println!("Received request: {:?}", request); | ||||
|                 let command = request.command(); | ||||
|                 let context = server_context.clone().into(); | ||||
| @@ -114,6 +126,7 @@ async fn send_status(status_rx: &watch::Receiver<VpnStatus>, response_tx: &mpsc: | ||||
| } | ||||
|  | ||||
| pub(crate) async fn handle_connection(socket: UnixStream, context: Arc<ServerContext>) { | ||||
|     let peer_pid = peer_pid(&socket); | ||||
|     let (read_stream, write_stream) = io::split(socket); | ||||
|     let (response_tx, response_rx) = mpsc::channel::<Response>(32); | ||||
|     let cancel_token = CancellationToken::new(); | ||||
| @@ -123,6 +136,7 @@ pub(crate) async fn handle_connection(socket: UnixStream, context: Arc<ServerCon | ||||
|         read_stream, | ||||
|         context.clone(), | ||||
|         response_tx.clone(), | ||||
|         peer_pid, | ||||
|         cancel_token.clone(), | ||||
|     )); | ||||
|  | ||||
| @@ -142,3 +156,19 @@ pub(crate) async fn handle_connection(socket: UnixStream, context: Arc<ServerCon | ||||
|  | ||||
|     println!("Connection closed") | ||||
| } | ||||
|  | ||||
| fn peer_pid(socket: &UnixStream) -> Option<i32> { | ||||
|     match socket.peer_cred() { | ||||
|         Ok(ucred) => ucred.pid(), | ||||
|         Err(_) => None, | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn authenticate(peer_pid: Option<i32>) -> bool { | ||||
|     if let Some(pid) = peer_pid { | ||||
|         println!("Peer PID: {}", pid); | ||||
|         true | ||||
|     } else { | ||||
|         false | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { Box, TextField } from "@mui/material"; | ||||
| import Button from "@mui/material/Button"; | ||||
| import { ChangeEvent, useEffect, useState } from "react"; | ||||
| import { ChangeEvent, FormEvent, useEffect, useState } from "react"; | ||||
|  | ||||
| import "./App.css"; | ||||
| import ConnectionStatus, { Status } from "./components/ConnectionStatus"; | ||||
| @@ -18,7 +18,7 @@ export default function App() { | ||||
|   const [status, setStatus] = useState<Status>("disconnected"); | ||||
|   const [processing, setProcessing] = useState(false); | ||||
|   const [passwordAuthOpen, setPasswordAuthOpen] = useState(false); | ||||
|   const [passwordAuthenticating, setPasswordAuthenticating] = useState(false); `` | ||||
|   const [passwordAuthenticating, setPasswordAuthenticating] = useState(false); | ||||
|   const [passwordAuth, setPasswordAuth] = useState<PasswordAuthData>(); | ||||
|   const [notification, setNotification] = useState<NotificationConfig>({ | ||||
|     open: false, | ||||
| @@ -43,9 +43,9 @@ export default function App() { | ||||
|   } | ||||
|  | ||||
|   function clearOverlays() { | ||||
|     closeNotification() | ||||
|     setPasswordAuthenticating(false) | ||||
|     setPasswordAuthOpen(false) | ||||
|     closeNotification(); | ||||
|     setPasswordAuthenticating(false); | ||||
|     setPasswordAuthOpen(false); | ||||
|   } | ||||
|  | ||||
|   function handlePortalChange(e: ChangeEvent<HTMLInputElement>) { | ||||
| @@ -53,9 +53,10 @@ export default function App() { | ||||
|     setPortalAddress(value.trim()); | ||||
|   } | ||||
|  | ||||
|   async function handleConnect() { | ||||
|   async function handleConnect(e: FormEvent<HTMLFormElement>) { | ||||
|     e.preventDefault(); | ||||
|  | ||||
|     setProcessing(true); | ||||
|     // setStatus("connecting"); | ||||
|  | ||||
|     try { | ||||
|       const response = await portalService.prelogin(portalAddress); | ||||
| @@ -79,7 +80,7 @@ export default function App() { | ||||
|  | ||||
|   function handleCancel() { | ||||
|     // TODO cancel the request first | ||||
|     setProcessing(false) | ||||
|     setProcessing(false); | ||||
|   } | ||||
|  | ||||
|   async function handleDisconnect() { | ||||
| @@ -145,50 +146,56 @@ export default function App() { | ||||
|   } | ||||
|   return ( | ||||
|     <Box padding={2} paddingTop={3}> | ||||
|       <ConnectionStatus sx={{ mb: 2 }} status={processing ? "processing" : status} /> | ||||
|  | ||||
|       <TextField | ||||
|         autoFocus | ||||
|         label="Portal address" | ||||
|         placeholder="Hostname or IP address" | ||||
|         fullWidth | ||||
|         size="small" | ||||
|         value={portalAddress} | ||||
|         onChange={handlePortalChange} | ||||
|         InputProps={{ readOnly: status !== "disconnected" }} | ||||
|       <ConnectionStatus | ||||
|         sx={{ mb: 2 }} | ||||
|         status={processing ? "processing" : status} | ||||
|       /> | ||||
|       <Box sx={{ mt: 1.5 }}> | ||||
|         {status === "disconnected" && ( | ||||
|           <Button | ||||
|             variant="contained" | ||||
|             fullWidth | ||||
|             onClick={handleConnect} | ||||
|             sx={{ textTransform: "none" }} | ||||
|           > | ||||
|             Connect | ||||
|           </Button> | ||||
|         )} | ||||
|         {status === "connecting" && ( | ||||
|           <Button | ||||
|             variant="outlined" | ||||
|             fullWidth | ||||
|             onClick={handleCancel} | ||||
|             sx={{ textTransform: "none" }} | ||||
|           > | ||||
|             Cancel | ||||
|           </Button> | ||||
|         )} | ||||
|         {status === "connected" && ( | ||||
|           <Button | ||||
|             variant="contained" | ||||
|             fullWidth | ||||
|             onClick={handleDisconnect} | ||||
|             sx={{ textTransform: "none" }} | ||||
|           > | ||||
|             Disconnect | ||||
|           </Button> | ||||
|         )} | ||||
|       </Box> | ||||
|  | ||||
|       <form onSubmit={handleConnect}> | ||||
|         <TextField | ||||
|           autoFocus | ||||
|           label="Portal address" | ||||
|           placeholder="Hostname or IP address" | ||||
|           fullWidth | ||||
|           size="small" | ||||
|           value={portalAddress} | ||||
|           onChange={handlePortalChange} | ||||
|           InputProps={{ readOnly: status !== "disconnected" }} | ||||
|         /> | ||||
|         <Box sx={{ mt: 1.5 }}> | ||||
|           {status === "disconnected" && ( | ||||
|             <Button | ||||
|               type="submit" | ||||
|               variant="contained" | ||||
|               fullWidth | ||||
|               sx={{ textTransform: "none" }} | ||||
|             > | ||||
|               Connect | ||||
|             </Button> | ||||
|           )} | ||||
|           {status === "connecting" && ( | ||||
|             <Button | ||||
|               variant="outlined" | ||||
|               fullWidth | ||||
|               onClick={handleCancel} | ||||
|               sx={{ textTransform: "none" }} | ||||
|             > | ||||
|               Cancel | ||||
|             </Button> | ||||
|           )} | ||||
|           {status === "connected" && ( | ||||
|             <Button | ||||
|               variant="contained" | ||||
|               fullWidth | ||||
|               onClick={handleDisconnect} | ||||
|               sx={{ textTransform: "none" }} | ||||
|             > | ||||
|               Disconnect | ||||
|             </Button> | ||||
|           )} | ||||
|         </Box> | ||||
|       </form> | ||||
|  | ||||
|       <PasswordAuth | ||||
|         open={passwordAuthOpen} | ||||
|         authData={passwordAuth} | ||||
|   | ||||
| @@ -1,16 +1,16 @@ | ||||
| import { invoke } from "@tauri-apps/api"; | ||||
| import { listen } from '@tauri-apps/api/event'; | ||||
| import { listen } from "@tauri-apps/api/event"; | ||||
|  | ||||
| type Status = 'disconnected' | 'connecting' | 'connected' | 'disconnecting' | ||||
| type StatusCallback = (status: Status) => void | ||||
| type Status = "disconnected" | "connecting" | "connected" | "disconnecting"; | ||||
| type StatusCallback = (status: Status) => void; | ||||
| type StatusEvent = { | ||||
|   payload: { | ||||
|     status: Status | ||||
|   } | ||||
| } | ||||
|     status: Status; | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| class VpnService { | ||||
|   private _status: Status = 'disconnected'; | ||||
|   private _status: Status = "disconnected"; | ||||
|   private statusCallbacks: StatusCallback[] = []; | ||||
|  | ||||
|   constructor() { | ||||
| @@ -18,10 +18,10 @@ class VpnService { | ||||
|   } | ||||
|  | ||||
|   private async init() { | ||||
|     const unlisten = await listen('vpn-status-received', (event: StatusEvent) => { | ||||
|       console.log('vpn-status-received', event.payload) | ||||
|     await listen("vpn-status-received", (event: StatusEvent) => { | ||||
|       console.log("vpn-status-received", event.payload); | ||||
|       this.setStatus(event.payload.status); | ||||
|     }) | ||||
|     }); | ||||
|  | ||||
|     const status = await this.status(); | ||||
|     this.setStatus(status); | ||||
| @@ -53,11 +53,11 @@ class VpnService { | ||||
|   } | ||||
|  | ||||
|   private fireStatusCallbacks() { | ||||
|     this.statusCallbacks.forEach(cb => cb(this._status)); | ||||
|     this.statusCallbacks.forEach((cb) => cb(this._status)); | ||||
|   } | ||||
|  | ||||
|   private removeStatusCallback(callback: StatusCallback) { | ||||
|     this.statusCallbacks = this.statusCallbacks.filter(cb => cb !== callback); | ||||
|     this.statusCallbacks = this.statusCallbacks.filter((cb) => cb !== callback); | ||||
|   } | ||||
|  | ||||
|   private async invokeCommand<T>(command: string, args?: any) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user