@@ -48,11 +48,11 @@ use super::dev_tunnels::ActiveTunnel;
4848use super :: paths:: prune_stopped_servers;
4949use super :: port_forwarder:: { PortForwarding , PortForwardingProcessor } ;
5050use super :: protocol:: {
51- AcquireCliParams , CallServerHttpParams , CallServerHttpResult , ChallengeIssueResponse ,
52- ChallengeVerifyParams , ClientRequestMethod , EmptyObject , ForwardParams , ForwardResult ,
53- FsStatRequest , FsStatResponse , GetEnvResponse , GetHostnameResponse , HttpBodyParams ,
54- HttpHeadersParams , ServeParams , ServerLog , ServerMessageParams , SpawnParams , SpawnResult ,
55- ToClientRequest , UnforwardParams , UpdateParams , UpdateResult , VersionResponse ,
51+ AcquireCliParams , CallServerHttpParams , CallServerHttpResult , ChallengeIssueParams ,
52+ ChallengeIssueResponse , ChallengeVerifyParams , ClientRequestMethod , EmptyObject , ForwardParams ,
53+ ForwardResult , FsStatRequest , FsStatResponse , GetEnvResponse , GetHostnameResponse ,
54+ HttpBodyParams , HttpHeadersParams , ServeParams , ServerLog , ServerMessageParams , SpawnParams ,
55+ SpawnResult , ToClientRequest , UnforwardParams , UpdateParams , UpdateResult , VersionResponse ,
5656 METHOD_CHALLENGE_VERIFY ,
5757} ;
5858use super :: server_bridge:: ServerBridge ;
@@ -94,8 +94,8 @@ struct HandlerContext {
9494
9595/// Handler auth state.
9696enum AuthState {
97- /// Auth is required, we're waiting for the client to send its challenge.
98- WaitingForChallenge ,
97+ /// Auth is required, we're waiting for the client to send its challenge optionally bearing a token .
98+ WaitingForChallenge ( Option < String > ) ,
9999 /// A challenge has been issued. Waiting for a verification.
100100 ChallengeIssued ( String ) ,
101101 /// Auth is no longer required.
@@ -215,7 +215,7 @@ pub async fn serve(
215215 code_server_args: own_code_server_args,
216216 platform,
217217 exit_barrier: own_exit,
218- requires_auth: false ,
218+ requires_auth: AuthRequired :: None ,
219219 } ) . with_context( cx. clone( ) ) . await ;
220220
221221 cx. span( ) . add_event(
@@ -233,13 +233,20 @@ pub async fn serve(
233233 }
234234}
235235
236+ #[ derive( Clone ) ]
237+ pub enum AuthRequired {
238+ None ,
239+ VSDA ,
240+ VSDAWithToken ( String ) ,
241+ }
242+
236243#[ derive( Clone ) ]
237244pub struct ServeStreamParams {
238245 pub log : log:: Logger ,
239246 pub launcher_paths : LauncherPaths ,
240247 pub code_server_args : CodeServerArgs ,
241248 pub platform : Platform ,
242- pub requires_auth : bool ,
249+ pub requires_auth : AuthRequired ,
243250 pub exit_barrier : Barrier < ShutdownSignal > ,
244251}
245252
@@ -269,16 +276,17 @@ fn make_socket_rpc(
269276 launcher_paths : LauncherPaths ,
270277 code_server_args : CodeServerArgs ,
271278 port_forwarding : Option < PortForwarding > ,
272- requires_auth : bool ,
279+ requires_auth : AuthRequired ,
273280 platform : Platform ,
274281) -> RpcDispatcher < MsgPackSerializer , HandlerContext > {
275282 let http_requests = Arc :: new ( std:: sync:: Mutex :: new ( HashMap :: new ( ) ) ) ;
276283 let server_bridges = ServerMultiplexer :: new ( ) ;
277284 let mut rpc = RpcBuilder :: new ( MsgPackSerializer { } ) . methods ( HandlerContext {
278285 did_update : Arc :: new ( AtomicBool :: new ( false ) ) ,
279286 auth_state : Arc :: new ( std:: sync:: Mutex :: new ( match requires_auth {
280- true => AuthState :: WaitingForChallenge ,
281- false => AuthState :: Authenticated ,
287+ AuthRequired :: VSDAWithToken ( t) => AuthState :: WaitingForChallenge ( Some ( t) ) ,
288+ AuthRequired :: VSDA => AuthState :: WaitingForChallenge ( None ) ,
289+ AuthRequired :: None => AuthState :: Authenticated ,
282290 } ) ) ,
283291 socket_tx,
284292 log : log. clone ( ) ,
@@ -305,8 +313,8 @@ fn make_socket_rpc(
305313 ensure_auth ( & c. auth_state ) ?;
306314 handle_get_env ( )
307315 } ) ;
308- rpc. register_sync ( METHOD_CHALLENGE_ISSUE , |_ : EmptyObject , c| {
309- handle_challenge_issue ( & c. auth_state )
316+ rpc. register_sync ( METHOD_CHALLENGE_ISSUE , |p : ChallengeIssueParams , c| {
317+ handle_challenge_issue ( p , & c. auth_state )
310318 } ) ;
311319 rpc. register_sync ( METHOD_CHALLENGE_VERIFY , |p : ChallengeVerifyParams , c| {
312320 handle_challenge_verify ( p. response , & c. auth_state )
@@ -423,6 +431,7 @@ async fn process_socket(
423431 let rx_counter = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
424432 let http_requests = Arc :: new ( std:: sync:: Mutex :: new ( HashMap :: new ( ) ) ) ;
425433
434+ let already_authed = matches ! ( requires_auth, AuthRequired :: None ) ;
426435 let rpc = make_socket_rpc (
427436 log. clone ( ) ,
428437 socket_tx. clone ( ) ,
@@ -440,7 +449,7 @@ async fn process_socket(
440449 let socket_tx = socket_tx. clone ( ) ;
441450 let exit_barrier = exit_barrier. clone ( ) ;
442451 tokio:: spawn ( async move {
443- if !requires_auth {
452+ if already_authed {
444453 send_version ( & socket_tx) . await ;
445454 }
446455
@@ -826,13 +835,22 @@ fn handle_get_env() -> Result<GetEnvResponse, AnyError> {
826835}
827836
828837fn handle_challenge_issue (
838+ params : ChallengeIssueParams ,
829839 auth_state : & Arc < std:: sync:: Mutex < AuthState > > ,
830840) -> Result < ChallengeIssueResponse , AnyError > {
831841 let challenge = create_challenge ( ) ;
832842
833843 let mut auth_state = auth_state. lock ( ) . unwrap ( ) ;
834- * auth_state = AuthState :: ChallengeIssued ( challenge. clone ( ) ) ;
844+ if let AuthState :: WaitingForChallenge ( Some ( s) ) = & * auth_state {
845+ println ! ( "looking for token {}, got {:?}" , s, params. token) ;
846+ match & params. token {
847+ Some ( t) if s != t => return Err ( CodeError :: AuthChallengeBadToken . into ( ) ) ,
848+ None => return Err ( CodeError :: AuthChallengeBadToken . into ( ) ) ,
849+ _ => { }
850+ }
851+ }
835852
853+ * auth_state = AuthState :: ChallengeIssued ( challenge. clone ( ) ) ;
836854 Ok ( ChallengeIssueResponse { challenge } )
837855}
838856
@@ -844,7 +862,7 @@ fn handle_challenge_verify(
844862
845863 match & * auth_state {
846864 AuthState :: Authenticated => Ok ( EmptyObject { } ) ,
847- AuthState :: WaitingForChallenge => Err ( CodeError :: AuthChallengeNotIssued . into ( ) ) ,
865+ AuthState :: WaitingForChallenge ( _ ) => Err ( CodeError :: AuthChallengeNotIssued . into ( ) ) ,
848866 AuthState :: ChallengeIssued ( c) => match verify_challenge ( c, & response) {
849867 false => Err ( CodeError :: AuthChallengeNotIssued . into ( ) ) ,
850868 true => {
0 commit comments