forked from lavina/lavina
				
			Compare commits
	
		
			No commits in common. "7613055ddefa9de66243d177518f27c7178dd5a4" and "77d175ccd9b976db6271ebe42f774758e9139675" have entirely different histories.
		
	
	
		
			7613055dde
			...
			77d175ccd9
		
	
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -180,16 +180,14 @@ async fn handle_registration<'a>( | ||||||
|                     writer.flush().await?; |                     writer.flush().await?; | ||||||
|                 } |                 } | ||||||
|                 CapabilitySubcommand::End => { |                 CapabilitySubcommand::End => { | ||||||
|                     let Some((ref username, ref realname)) = future_username else { |                     let Some((username, realname)) = future_username else { | ||||||
|                         todo!(); |                         todo!() | ||||||
|                     }; |                     }; | ||||||
|                     let Some(nickname) = future_nickname.clone() else { |                     let Some(nickname) = future_nickname.clone() else { | ||||||
|                         todo!(); |                         todo!() | ||||||
|                     }; |                     }; | ||||||
|                     let username = username.clone(); |  | ||||||
|                     let realname = realname.clone(); |  | ||||||
|                     let candidate_user = RegisteredUser { |                     let candidate_user = RegisteredUser { | ||||||
|                         nickname: nickname.clone(), |                         nickname, | ||||||
|                         username, |                         username, | ||||||
|                         realname, |                         realname, | ||||||
|                     }; |                     }; | ||||||
|  | @ -199,15 +197,7 @@ async fn handle_registration<'a>( | ||||||
|                         break Ok(candidate_user); |                         break Ok(candidate_user); | ||||||
|                     } else { |                     } else { | ||||||
|                         let Some(candidate_password) = pass else { |                         let Some(candidate_password) = pass else { | ||||||
|                             sasl_fail_message( |                             todo!(); | ||||||
|                                 config.server_name.clone(), |  | ||||||
|                                 nickname.clone(), |  | ||||||
|                                 "User credentials was not provided".into(), |  | ||||||
|                             ) |  | ||||||
|                             .write_async(writer) |  | ||||||
|                             .await?; |  | ||||||
|                             writer.flush().await?; |  | ||||||
|                             continue; |  | ||||||
|                         }; |                         }; | ||||||
|                         auth_user(storage, &*candidate_user.nickname, &*candidate_password).await?; |                         auth_user(storage, &*candidate_user.nickname, &*candidate_password).await?; | ||||||
|                         break Ok(candidate_user); |                         break Ok(candidate_user); | ||||||
|  | @ -219,20 +209,12 @@ async fn handle_registration<'a>( | ||||||
|                     future_nickname = Some(nickname); |                     future_nickname = Some(nickname); | ||||||
|                 } else if let Some((username, realname)) = future_username.clone() { |                 } else if let Some((username, realname)) = future_username.clone() { | ||||||
|                     let candidate_user = RegisteredUser { |                     let candidate_user = RegisteredUser { | ||||||
|                         nickname: nickname.clone(), |                         nickname, | ||||||
|                         username, |                         username, | ||||||
|                         realname, |                         realname, | ||||||
|                     }; |                     }; | ||||||
|                     let Some(candidate_password) = pass else { |                     let Some(candidate_password) = pass else { | ||||||
|                         sasl_fail_message( |                         todo!(); | ||||||
|                             config.server_name.clone(), |  | ||||||
|                             nickname.clone(), |  | ||||||
|                             "User credentials was not provided".into(), |  | ||||||
|                         ) |  | ||||||
|                         .write_async(writer) |  | ||||||
|                         .await?; |  | ||||||
|                         writer.flush().await?; |  | ||||||
|                         continue; |  | ||||||
|                     }; |                     }; | ||||||
|                     auth_user(storage, &*candidate_user.nickname, &*candidate_password).await?; |                     auth_user(storage, &*candidate_user.nickname, &*candidate_password).await?; | ||||||
|                     break Ok(candidate_user); |                     break Ok(candidate_user); | ||||||
|  | @ -245,20 +227,12 @@ async fn handle_registration<'a>( | ||||||
|                     future_username = Some((username, realname)); |                     future_username = Some((username, realname)); | ||||||
|                 } else if let Some(nickname) = future_nickname.clone() { |                 } else if let Some(nickname) = future_nickname.clone() { | ||||||
|                     let candidate_user = RegisteredUser { |                     let candidate_user = RegisteredUser { | ||||||
|                         nickname: nickname.clone(), |                         nickname, | ||||||
|                         username, |                         username, | ||||||
|                         realname, |                         realname, | ||||||
|                     }; |                     }; | ||||||
|                     let Some(candidate_password) = pass else { |                     let Some(candidate_password) = pass else { | ||||||
|                         sasl_fail_message( |                         todo!(); | ||||||
|                             config.server_name.clone(), |  | ||||||
|                             nickname.clone(), |  | ||||||
|                             "User credentials was not provided".into(), |  | ||||||
|                         ) |  | ||||||
|                         .write_async(writer) |  | ||||||
|                         .await?; |  | ||||||
|                         writer.flush().await?; |  | ||||||
|                         continue; |  | ||||||
|                     }; |                     }; | ||||||
|                     auth_user(storage, &*candidate_user.nickname, &*candidate_password).await?; |                     auth_user(storage, &*candidate_user.nickname, &*candidate_password).await?; | ||||||
|                     break Ok(candidate_user); |                     break Ok(candidate_user); | ||||||
|  | @ -281,31 +255,12 @@ async fn handle_registration<'a>( | ||||||
|                         .await?; |                         .await?; | ||||||
|                         writer.flush().await?; |                         writer.flush().await?; | ||||||
|                     } else { |                     } else { | ||||||
|                         if let Some(nickname) = future_nickname.clone() { |                         // TODO respond with 904
 | ||||||
|                             sasl_fail_message( |                         todo!(); | ||||||
|                                 config.server_name.clone(), |  | ||||||
|                                 nickname.clone(), |  | ||||||
|                                 "Unsupported mechanism".into(), |  | ||||||
|                             ) |  | ||||||
|                             .write_async(writer) |  | ||||||
|                             .await?; |  | ||||||
|                             writer.flush().await?; |  | ||||||
|                         } else { |  | ||||||
|                             break Err(anyhow::Error::msg("Wrong authentication sequence")); |  | ||||||
|                         } |  | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
|                     let body = AuthBody::from_str(body.as_bytes())?; |                     let body = AuthBody::from_str(body.as_bytes())?; | ||||||
|                     if let Err(e) = auth_user(storage, &body.login, &body.password).await { |                     auth_user(storage, &body.login, &body.password).await?; | ||||||
|                         tracing::warn!("Authentication failed: {:?}", e); |  | ||||||
|                         if let Some(nickname) = future_nickname.clone() { |  | ||||||
|                             sasl_fail_message(config.server_name.clone(), nickname.clone(), "Bad credentials".into()) |  | ||||||
|                                 .write_async(writer) |  | ||||||
|                                 .await?; |  | ||||||
|                             writer.flush().await?; |  | ||||||
|                         } else { |  | ||||||
|                         } |  | ||||||
|                     } else { |  | ||||||
|                     let login: Str = body.login.into(); |                     let login: Str = body.login.into(); | ||||||
|                     validated_user = Some(login.clone()); |                     validated_user = Some(login.clone()); | ||||||
|                     ServerMessage { |                     ServerMessage { | ||||||
|  | @ -332,8 +287,6 @@ async fn handle_registration<'a>( | ||||||
|                     .await?; |                     .await?; | ||||||
|                     writer.flush().await?; |                     writer.flush().await?; | ||||||
|                 } |                 } | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 // TODO handle abortion of authentication
 |                 // TODO handle abortion of authentication
 | ||||||
|             } |             } | ||||||
|             _ => {} |             _ => {} | ||||||
|  | @ -344,14 +297,6 @@ async fn handle_registration<'a>( | ||||||
|     Ok(user) |     Ok(user) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn sasl_fail_message(sender: Str, nick: Str, text: Str) -> ServerMessage { |  | ||||||
|     ServerMessage { |  | ||||||
|         tags: vec![], |  | ||||||
|         sender: Some(sender), |  | ||||||
|         body: ServerMessageBody::N904SaslFail { nick, text }, |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| async fn auth_user(storage: &mut Storage, login: &str, plain_password: &str) -> Result<()> { | async fn auth_user(storage: &mut Storage, login: &str, plain_password: &str) -> Result<()> { | ||||||
|     let stored_user = storage.retrieve_user_by_name(login).await?; |     let stored_user = storage.retrieve_user_by_name(login).await?; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -218,51 +218,3 @@ async fn scenario_cap_short_negotiation() -> Result<()> { | ||||||
|     server.server.terminate().await?; |     server.server.terminate().await?; | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #[tokio::test] |  | ||||||
| async fn scenario_cap_sasl_fail() -> Result<()> { |  | ||||||
|     let mut server = TestServer::start().await?; |  | ||||||
| 
 |  | ||||||
|     // test scenario
 |  | ||||||
| 
 |  | ||||||
|     server.storage.create_user("tester").await?; |  | ||||||
|     server.storage.set_password("tester", "password").await?; |  | ||||||
| 
 |  | ||||||
|     let mut stream = TcpStream::connect(server.server.addr).await?; |  | ||||||
|     let mut s = TestScope::new(&mut stream); |  | ||||||
| 
 |  | ||||||
|     s.send("CAP LS 302").await?; |  | ||||||
|     s.send("NICK tester").await?; |  | ||||||
|     s.send("USER UserName 0 * :Real Name").await?; |  | ||||||
|     s.expect(":testserver CAP * LS :sasl=PLAIN").await?; |  | ||||||
|     s.send("CAP REQ :sasl").await?; |  | ||||||
|     s.expect(":testserver CAP tester ACK :sasl").await?; |  | ||||||
|     s.send("AUTHENTICATE SHA256").await?; |  | ||||||
|     s.expect(":testserver 904 tester :Unsupported mechanism").await?; |  | ||||||
|     s.send("AUTHENTICATE PLAIN").await?; |  | ||||||
|     s.expect(":testserver AUTHENTICATE +").await?; |  | ||||||
|     s.send("AUTHENTICATE dGVzdGVyAHRlc3RlcgBwYXNzd29yZDE=").await?; |  | ||||||
|     s.expect(":testserver 904 tester :Bad credentials").await?; |  | ||||||
|     s.send("AUTHENTICATE dGVzdGVyAHRlc3RlcgBwYXNzd29yZA==").await?; // base64-encoded 'tester\x00tester\x00password'
 |  | ||||||
|     s.expect(":testserver 900 tester tester tester :You are now logged in as tester").await?; |  | ||||||
|     s.expect(":testserver 903 tester :SASL authentication successful").await?; |  | ||||||
| 
 |  | ||||||
|     s.send("CAP END").await?; |  | ||||||
| 
 |  | ||||||
|     s.expect(":testserver 001 tester :Welcome to Kek Server").await?; |  | ||||||
|     s.expect(":testserver 002 tester :Welcome to Kek Server").await?; |  | ||||||
|     s.expect(":testserver 003 tester :Welcome to Kek Server").await?; |  | ||||||
|     s.expect(":testserver 004 tester testserver kek-0.1.alpha.3 r CFILPQbcefgijklmnopqrstvz").await?; |  | ||||||
|     s.expect(":testserver 005 tester CHANTYPES=# :are supported by this server").await?; |  | ||||||
|     s.expect_nothing().await?; |  | ||||||
|     s.send("QUIT :Leaving").await?; |  | ||||||
|     s.expect(":testserver ERROR :Leaving the server").await?; |  | ||||||
|     s.expect_eof().await?; |  | ||||||
| 
 |  | ||||||
|     stream.shutdown().await?; |  | ||||||
| 
 |  | ||||||
|     // wrap up
 |  | ||||||
| 
 |  | ||||||
|     server.server.terminate().await?; |  | ||||||
|     Ok(()) |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -83,7 +83,7 @@ pub async fn launch( | ||||||
| 
 | 
 | ||||||
|     let key = match read_one(&mut SyncBufReader::new(File::open(config.key)?))? { |     let key = match read_one(&mut SyncBufReader::new(File::open(config.key)?))? { | ||||||
|         Some(PemItem::ECKey(k) | PemItem::PKCS8Key(k) | PemItem::RSAKey(k)) => PrivateKey(k), |         Some(PemItem::ECKey(k) | PemItem::PKCS8Key(k) | PemItem::RSAKey(k)) => PrivateKey(k), | ||||||
|         _ => return Err(fail("no keys in file")), |         _ => panic!("no keys in file"), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     let loaded_config = Arc::new(LoadedConfig { |     let loaded_config = Arc::new(LoadedConfig { | ||||||
|  |  | ||||||
|  | @ -30,10 +30,6 @@ fn token(input: &str) -> IResult<&str, &str> { | ||||||
|     take_while(|i| i != '\n' && i != '\r')(input) |     take_while(|i| i != '\n' && i != '\r')(input) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn params(input: &str) -> IResult<&str, &str> { |  | ||||||
|     take_while(|i| i != '\n' && i != '\r' && i != ':')(input) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Clone, Debug, PartialEq, Eq)] | #[derive(Clone, Debug, PartialEq, Eq)] | ||||||
| pub enum Chan { | pub enum Chan { | ||||||
|     /// #<name> — network-global channel, available from any server in the network.
 |     /// #<name> — network-global channel, available from any server in the network.
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,3 @@ | ||||||
| use std::sync::Arc; |  | ||||||
| 
 |  | ||||||
| use nonempty::NonEmpty; | use nonempty::NonEmpty; | ||||||
| use tokio::io::AsyncWrite; | use tokio::io::AsyncWrite; | ||||||
| use tokio::io::AsyncWriteExt; | use tokio::io::AsyncWriteExt; | ||||||
|  | @ -154,10 +152,6 @@ pub enum ServerMessageBody { | ||||||
|     N903SaslSuccess { |     N903SaslSuccess { | ||||||
|         nick: Str, |         nick: Str, | ||||||
|         message: Str, |         message: Str, | ||||||
|     }, |  | ||||||
|     N904SaslFail { |  | ||||||
|         nick: Str, |  | ||||||
|         text: Str, |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -375,13 +369,6 @@ impl ServerMessageBody { | ||||||
|                 writer.write_all(b" :").await?; |                 writer.write_all(b" :").await?; | ||||||
|                 writer.write_all(message.as_bytes()).await?; |                 writer.write_all(message.as_bytes()).await?; | ||||||
|             } |             } | ||||||
|             ServerMessageBody::N904SaslFail { nick, text } => { |  | ||||||
|                 writer.write_all(b"904").await?; |  | ||||||
|                 writer.write_all(b" ").await?; |  | ||||||
|                 writer.write_all(nick.as_bytes()).await?; |  | ||||||
|                 writer.write_all(b" :").await?; |  | ||||||
|                 writer.write_all(text.as_bytes()).await?; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  | @ -404,7 +391,7 @@ fn server_message_body(input: &str) -> IResult<&str, ServerMessageBody> { | ||||||
|         server_message_body_notice, |         server_message_body_notice, | ||||||
|         server_message_body_ping, |         server_message_body_ping, | ||||||
|         server_message_body_pong, |         server_message_body_pong, | ||||||
|         server_message_body_cap |         server_message_body_cap, | ||||||
|     ))(input) |     ))(input) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -28,10 +28,10 @@ impl ClientStreamStart { | ||||||
|         if let Event::Start(e) = incoming { |         if let Event::Start(e) = incoming { | ||||||
|             let (ns, local) = reader.resolve_element(e.name()); |             let (ns, local) = reader.resolve_element(e.name()); | ||||||
|             if ns != ResolveResult::Bound(Namespace(XMLNS.as_bytes())) { |             if ns != ResolveResult::Bound(Namespace(XMLNS.as_bytes())) { | ||||||
|                 return Err(anyhow!("Invalid namespace for stream element")); |                 return Err(panic!()); | ||||||
|             } |             } | ||||||
|             if local.into_inner() != b"stream" { |             if local.into_inner() != b"stream" { | ||||||
|                 return Err(anyhow!("Invalid local name for stream element")); |                 return Err(panic!()); | ||||||
|             } |             } | ||||||
|             let mut to = None; |             let mut to = None; | ||||||
|             let mut lang = None; |             let mut lang = None; | ||||||
|  | @ -64,7 +64,7 @@ impl ClientStreamStart { | ||||||
|                 version: version.unwrap(), |                 version: version.unwrap(), | ||||||
|             }) |             }) | ||||||
|         } else { |         } else { | ||||||
|             Err(anyhow!("Incoming message does not belong XML Start Event")) |             Err(panic!()) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1 +1 @@ | ||||||
| nightly-2024-02-08 | nightly-2023-12-07 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue