1use std::{fmt, future::Future, io, pin::Pin, sync::Arc};
4
5use bytes::Bytes;
6use rustls::{ServerConfig, pki_types::CertificateDer};
7use tokio::io::{AsyncRead, AsyncWrite};
8
9use crate::ServerMiddleware as _;
10use crate::{
11 Conn,
12 auth::{Ready, TlsServerEndPoint},
13 codec::{
14 Backend, BackendMessage, DEFAULT_MAX_FRAME_LEN, Direction as _, Frontend, FrontendMessage,
15 },
16 pre_startup::{DEFAULT_MAX_PRE_STARTUP_PACKET_LEN, PreStartupOffer},
17 server_auth::ServerProtocolOffer,
18 startup::{ProtocolVersion, StartupMessage},
19 tls::ServerTls,
20 transport::Buffered,
21};
22
23#[allow(clippy::type_complexity)]
25pub(crate) trait StartupResolver<State, Peer, Identity> {
26 type Route;
27 type Error;
28
29 fn defer_ready(&self) -> bool {
31 false
32 }
33
34 fn resolve<'a>(
35 &'a mut self,
36 startup: &'a StartupMessage,
37 context: &'a ServerConnectionContext<Peer, Identity>,
38 state: &'a mut State,
39 ) -> Pin<Box<dyn Future<Output = Result<Self::Route, Self::Error>> + 'a>>;
40}
41
42#[derive(Debug)]
44pub(crate) enum RoutedAcceptError<TlsError, AuthenticationError, RouteError> {
45 Accept(AcceptError<TlsError, AuthenticationError>),
46 Route(RouteError),
47}
48
49impl<TlsError, AuthenticationError, RouteError> From<AcceptError<TlsError, AuthenticationError>>
50 for RoutedAcceptError<TlsError, AuthenticationError, RouteError>
51{
52 fn from(error: AcceptError<TlsError, AuthenticationError>) -> Self {
53 Self::Accept(error)
54 }
55}
56
57struct NoStartupRoute;
58
59impl<State, Peer, Identity> StartupResolver<State, Peer, Identity> for NoStartupRoute {
60 type Route = ();
61 type Error = std::convert::Infallible;
62
63 fn resolve<'a>(
64 &'a mut self,
65 _startup: &'a StartupMessage,
66 _context: &'a ServerConnectionContext<Peer, Identity>,
67 _state: &'a mut State,
68 ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + 'a>> {
69 Box::pin(async { Ok(()) })
70 }
71}
72
73#[derive(Clone)]
75pub struct ServerIdentity {
76 config: Arc<ServerConfig>,
77 leaf_certificate: CertificateDer<'static>,
78}
79
80impl ServerIdentity {
81 #[must_use]
87 pub const fn new(config: Arc<ServerConfig>, leaf_certificate: CertificateDer<'static>) -> Self {
88 Self {
89 config,
90 leaf_certificate,
91 }
92 }
93}
94
95impl fmt::Debug for ServerIdentity {
96 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
97 formatter.write_str("ServerIdentity([REDACTED])")
98 }
99}
100
101pub trait ServerIdentityProvider {
103 type Error;
105
106 fn resolve(&self) -> Result<ServerIdentity, Self::Error>;
112}
113
114#[derive(Clone, Debug, Eq, PartialEq)]
116pub enum NegotiatedServerTls {
117 Plaintext,
119 Tls {
121 server_end_point: Bytes,
123 },
124}
125
126pub struct ServerAuthenticationRequest<'a, Peer> {
128 startup: &'a StartupMessage,
129 tls: &'a NegotiatedServerTls,
130 peer: &'a Peer,
131}
132
133impl<Peer> Copy for ServerAuthenticationRequest<'_, Peer> {}
134
135impl<Peer> Clone for ServerAuthenticationRequest<'_, Peer> {
136 fn clone(&self) -> Self {
137 *self
138 }
139}
140
141impl<Peer> ServerAuthenticationRequest<'_, Peer> {
142 #[must_use]
144 pub const fn startup(&self) -> &StartupMessage {
145 self.startup
146 }
147
148 #[must_use]
150 pub const fn tls(&self) -> &NegotiatedServerTls {
151 self.tls
152 }
153
154 #[must_use]
156 pub const fn peer(&self) -> &Peer {
157 self.peer
158 }
159}
160
161#[derive(Clone, Debug, Eq, PartialEq)]
163pub enum ServerAuthenticationAction<Identity> {
164 Accept(Identity),
166 CleartextPassword,
168 Md5Password {
170 salt: [u8; 4],
172 },
173 Sasl {
175 mechanisms: Vec<Bytes>,
177 },
178 SaslContinue(Bytes),
180 SaslFinal {
182 server_final: Bytes,
184 identity: Identity,
186 },
187 KerberosV5,
189 Gss,
191 Sspi,
193 GssContinue(Bytes),
195}
196
197#[derive(Clone, Debug, Eq, PartialEq)]
199pub enum ServerAuthenticationResponse {
200 Password(Bytes),
202 SaslInitial {
204 mechanism: Bytes,
206 response: Option<Bytes>,
208 },
209 Sasl(Bytes),
211 Token(Bytes),
213}
214
215#[allow(async_fn_in_trait)]
219pub trait ServerAuthentication<Peer> {
220 type Identity;
222 type Error;
224
225 async fn start(
227 &mut self,
228 request: ServerAuthenticationRequest<'_, Peer>,
229 ) -> Result<ServerAuthenticationAction<Self::Identity>, Self::Error>;
230
231 async fn respond(
233 &mut self,
234 request: ServerAuthenticationRequest<'_, Peer>,
235 response: ServerAuthenticationResponse,
236 ) -> Result<ServerAuthenticationAction<Self::Identity>, Self::Error>;
237}
238
239pub trait ServerAuthenticationProvider {
241 type Authentication;
243
244 fn create(&self) -> Self::Authentication;
246}
247
248#[derive(Clone, Copy, Debug, Eq, PartialEq)]
250pub struct TrustIdentity;
251
252#[derive(Clone, Copy, Debug, Eq, PartialEq)]
254pub enum BuildServerError {
255 MissingTlsPolicy,
257 MissingAuthenticationPolicy,
259 InvalidProtocolLimits,
261}
262
263impl fmt::Display for BuildServerError {
264 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
265 formatter.write_str(match self {
266 Self::MissingTlsPolicy => "server TLS policy is required",
267 Self::MissingAuthenticationPolicy => "server authentication policy is required",
268 Self::InvalidProtocolLimits => {
269 "server protocol limits cannot support connection establishment"
270 }
271 })
272 }
273}
274
275impl std::error::Error for BuildServerError {}
276
277#[derive(Debug)]
279pub enum AcceptError<TlsError = NoServerIdentity, AuthenticationError = std::convert::Infallible> {
280 Io(io::Error),
282 UnsupportedProtocolVersion,
284 TlsRequired,
286 TlsIdentity(TlsError),
288 Authentication(AuthenticationError),
290 AuthenticationProtocol,
292}
293
294impl<TlsError, AuthenticationError> fmt::Display for AcceptError<TlsError, AuthenticationError> {
295 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
296 match self {
297 Self::Io(error) => error.fmt(formatter),
298 Self::UnsupportedProtocolVersion => {
299 formatter.write_str("unsupported PostgreSQL protocol version")
300 }
301 Self::TlsRequired => formatter.write_str("TLS is required before startup"),
302 Self::TlsIdentity(_) => formatter.write_str("server TLS identity is unavailable"),
303 Self::Authentication(_) => formatter.write_str("authentication rejected"),
304 Self::AuthenticationProtocol => formatter.write_str("invalid authentication response"),
305 }
306 }
307}
308
309impl<TlsError, AuthenticationError> std::error::Error for AcceptError<TlsError, AuthenticationError>
310where
311 TlsError: std::error::Error + 'static,
312 AuthenticationError: std::error::Error + 'static,
313{
314 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
315 match self {
316 Self::Io(error) => Some(error),
317 Self::TlsIdentity(error) => Some(error),
318 Self::Authentication(error) => Some(error),
319 Self::UnsupportedProtocolVersion | Self::TlsRequired | Self::AuthenticationProtocol => {
320 None
321 }
322 }
323 }
324}
325
326#[derive(Clone, Copy, Debug, Eq, PartialEq)]
328pub struct ServerTlsPolicy;
329
330impl ServerTlsPolicy {
331 #[allow(non_upper_case_globals)]
333 pub const Disabled: DisabledServerTls = DisabledServerTls;
334
335 #[allow(non_snake_case)]
337 pub const fn Optional<Provider>(provider: Provider) -> OptionalServerTls<Provider> {
338 OptionalServerTls(provider)
339 }
340
341 #[allow(non_snake_case)]
343 pub const fn Required<Provider>(provider: Provider) -> RequiredServerTls<Provider> {
344 RequiredServerTls(provider)
345 }
346}
347
348#[derive(Clone, Copy, Debug, Eq, PartialEq)]
350pub struct DisabledServerTls;
351
352#[derive(Clone)]
354pub struct OptionalServerTls<Provider>(Provider);
355
356#[derive(Clone)]
358pub struct RequiredServerTls<Provider>(Provider);
359
360impl<Provider> fmt::Debug for OptionalServerTls<Provider> {
361 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
362 formatter.write_str("OptionalServerTls([REDACTED])")
363 }
364}
365
366impl<Provider> fmt::Debug for RequiredServerTls<Provider> {
367 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
368 formatter.write_str("RequiredServerTls([REDACTED])")
369 }
370}
371
372#[derive(Clone, Copy, Debug, Eq, PartialEq)]
374pub struct NoServerIdentityProvider;
375
376#[derive(Clone, Copy, Debug, Eq, PartialEq)]
378pub struct NoServerIdentity;
379
380impl fmt::Display for NoServerIdentity {
381 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
382 formatter.write_str("disabled TLS has no identity")
383 }
384}
385
386impl std::error::Error for NoServerIdentity {}
387
388impl ServerIdentityProvider for NoServerIdentityProvider {
389 type Error = NoServerIdentity;
390
391 fn resolve(&self) -> Result<ServerIdentity, Self::Error> {
392 Err(NoServerIdentity)
393 }
394}
395
396mod sealed {
397 pub trait Sealed {}
398}
399
400#[doc(hidden)]
402pub trait ServerTlsConfiguration: sealed::Sealed {
403 type Provider: ServerIdentityProvider;
405 fn provider(&self) -> Option<&Self::Provider>;
407 fn required(&self) -> bool;
409 fn category(&self) -> &'static str;
411}
412
413impl sealed::Sealed for DisabledServerTls {}
414impl<Provider> sealed::Sealed for OptionalServerTls<Provider> {}
415impl<Provider> sealed::Sealed for RequiredServerTls<Provider> {}
416
417impl ServerTlsConfiguration for DisabledServerTls {
418 type Provider = NoServerIdentityProvider;
419 fn provider(&self) -> Option<&Self::Provider> {
420 None
421 }
422 fn required(&self) -> bool {
423 false
424 }
425 fn category(&self) -> &'static str {
426 "disabled"
427 }
428}
429
430impl<Provider: ServerIdentityProvider> ServerTlsConfiguration for OptionalServerTls<Provider> {
431 type Provider = Provider;
432 fn provider(&self) -> Option<&Self::Provider> {
433 Some(&self.0)
434 }
435 fn required(&self) -> bool {
436 false
437 }
438 fn category(&self) -> &'static str {
439 "optional"
440 }
441}
442
443impl<Provider: ServerIdentityProvider> ServerTlsConfiguration for RequiredServerTls<Provider> {
444 type Provider = Provider;
445 fn provider(&self) -> Option<&Self::Provider> {
446 Some(&self.0)
447 }
448 fn required(&self) -> bool {
449 true
450 }
451 fn category(&self) -> &'static str {
452 "required"
453 }
454}
455
456#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
458pub struct TrustServerAuthentication;
459
460impl ServerAuthenticationProvider for TrustServerAuthentication {
461 type Authentication = Self;
462
463 fn create(&self) -> Self::Authentication {
464 *self
465 }
466}
467
468impl<Peer> ServerAuthentication<Peer> for TrustServerAuthentication {
469 type Identity = TrustIdentity;
470 type Error = std::convert::Infallible;
471
472 async fn start(
473 &mut self,
474 _request: ServerAuthenticationRequest<'_, Peer>,
475 ) -> Result<ServerAuthenticationAction<Self::Identity>, Self::Error> {
476 Ok(ServerAuthenticationAction::Accept(TrustIdentity))
477 }
478
479 async fn respond(
480 &mut self,
481 _request: ServerAuthenticationRequest<'_, Peer>,
482 _response: ServerAuthenticationResponse,
483 ) -> Result<ServerAuthenticationAction<Self::Identity>, Self::Error> {
484 unreachable!("trust authentication accepts before a response")
485 }
486}
487
488#[derive(Clone, Copy, Debug, Eq, PartialEq)]
490pub struct ServerProtocolLimits {
491 max_frame_len: usize,
492 max_pre_startup_packet_len: usize,
493}
494
495impl ServerProtocolLimits {
496 #[must_use]
498 pub const fn with_max_frame_len(mut self, bytes: usize) -> Self {
499 self.max_frame_len = bytes;
500 self
501 }
502
503 #[must_use]
505 pub const fn with_max_pre_startup_packet_len(mut self, bytes: usize) -> Self {
506 self.max_pre_startup_packet_len = bytes;
507 self
508 }
509
510 const fn is_valid(self) -> bool {
511 self.max_frame_len >= 9
512 && self.max_frame_len <= i32::MAX as usize
513 && self.max_pre_startup_packet_len >= 8
514 && self.max_pre_startup_packet_len <= i32::MAX as usize
515 }
516}
517
518impl Default for ServerProtocolLimits {
519 fn default() -> Self {
520 Self {
521 max_frame_len: DEFAULT_MAX_FRAME_LEN,
522 max_pre_startup_packet_len: DEFAULT_MAX_PRE_STARTUP_PACKET_LEN,
523 }
524 }
525}
526
527#[derive(Clone)]
529pub struct Server<
530 Tls = DisabledServerTls,
531 Authentication = TrustServerAuthentication,
532 Middleware = IdentityServerHandler,
533> {
534 tls: Tls,
535 authentication: Authentication,
536 limits: ServerProtocolLimits,
537 middleware: Middleware,
538}
539
540impl Server {
541 #[must_use]
543 pub fn builder() -> ServerBuilder {
544 ServerBuilder::default()
545 }
546}
547
548impl<Tls: ServerTlsConfiguration, Authentication, Middleware> fmt::Debug
549 for Server<Tls, Authentication, Middleware>
550{
551 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
552 formatter
553 .debug_struct("Server")
554 .field("tls", &self.tls.category())
555 .field("authentication", &"<redacted>")
556 .field("limits", &self.limits)
557 .finish_non_exhaustive()
558 }
559}
560
561#[derive(Clone)]
563pub struct ServerBuilder<Tls = (), Authentication = (), Middleware = IdentityServerHandler> {
564 tls: Option<Tls>,
565 authentication: Option<Authentication>,
566 limits: ServerProtocolLimits,
567 middleware: Middleware,
568}
569
570impl<Tls, Authentication> fmt::Debug for ServerBuilder<Tls, Authentication> {
571 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
572 formatter
573 .debug_struct("ServerBuilder")
574 .field("tls_configured", &self.tls.is_some())
575 .field("authentication_configured", &self.authentication.is_some())
576 .field("limits", &self.limits)
577 .finish()
578 }
579}
580
581impl Default for ServerBuilder {
582 fn default() -> Self {
583 Self {
584 tls: None,
585 authentication: None,
586 limits: ServerProtocolLimits::default(),
587 middleware: IdentityServerHandler,
588 }
589 }
590}
591
592impl<Tls, Authentication, Middleware> ServerBuilder<Tls, Authentication, Middleware> {
593 #[must_use]
595 pub fn tls<Next>(self, policy: Next) -> ServerBuilder<Next, Authentication, Middleware> {
596 ServerBuilder {
597 tls: Some(policy),
598 authentication: self.authentication,
599 limits: self.limits,
600 middleware: self.middleware,
601 }
602 }
603
604 #[must_use]
606 pub fn authentication<Next>(self, policy: Next) -> ServerBuilder<Tls, Next, Middleware> {
607 ServerBuilder {
608 tls: self.tls,
609 authentication: Some(policy),
610 limits: self.limits,
611 middleware: self.middleware,
612 }
613 }
614
615 #[must_use]
617 pub fn limits(mut self, limits: ServerProtocolLimits) -> Self {
618 self.limits = limits;
619 self
620 }
621
622 #[must_use]
624 pub fn middleware<Next>(
625 self,
626 factory: Next,
627 ) -> ServerBuilder<Tls, Authentication, crate::MiddlewareChain<Middleware, Next>> {
628 ServerBuilder {
629 tls: self.tls,
630 authentication: self.authentication,
631 limits: self.limits,
632 middleware: crate::MiddlewareChain(self.middleware, factory),
633 }
634 }
635
636 pub fn build(self) -> Result<Server<Tls, Authentication, Middleware>, BuildServerError> {
643 let tls = self.tls.ok_or(BuildServerError::MissingTlsPolicy)?;
644 let authentication = self
645 .authentication
646 .ok_or(BuildServerError::MissingAuthenticationPolicy)?;
647 if !self.limits.is_valid() {
648 return Err(BuildServerError::InvalidProtocolLimits);
649 }
650 Ok(Server {
651 tls,
652 authentication,
653 limits: self.limits,
654 middleware: self.middleware,
655 })
656 }
657}
658
659#[derive(Clone, Debug, Eq, PartialEq)]
661pub struct ServerConnectionContext<Peer, Identity> {
662 peer: Peer,
663 tls: Option<NegotiatedServerTls>,
664 identity: Option<Identity>,
665}
666
667impl<Peer, Identity> ServerConnectionContext<Peer, Identity> {
668 #[must_use]
670 pub const fn peer(&self) -> &Peer {
671 &self.peer
672 }
673
674 #[must_use]
680 pub const fn tls(&self) -> &NegotiatedServerTls {
681 match &self.tls {
682 Some(tls) => tls,
683 None => panic!("TLS is not known before pre-startup negotiation"),
684 }
685 }
686
687 #[must_use]
689 pub const fn tls_if_known(&self) -> Option<&NegotiatedServerTls> {
690 self.tls.as_ref()
691 }
692
693 #[must_use]
699 pub const fn identity(&self) -> &Identity {
700 match &self.identity {
701 Some(identity) => identity,
702 None => panic!("identity is not known before authentication"),
703 }
704 }
705
706 #[must_use]
708 pub const fn identity_if_known(&self) -> Option<&Identity> {
709 self.identity.as_ref()
710 }
711}
712
713#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
715pub struct IdentityServerHandler;
716impl<C> crate::MiddlewareFactory<C> for IdentityServerHandler {
717 type Handler = Self;
718 fn create(&self, _: &C) -> Self {
719 *self
720 }
721}
722impl<S, C> crate::ServerMiddleware<S, C> for IdentityServerHandler {}
723
724#[derive(Clone, Eq, PartialEq)]
726pub struct CancellationRequest {
727 process_id: u32,
728 secret_key: Bytes,
729}
730
731impl fmt::Debug for CancellationRequest {
732 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
733 formatter
734 .debug_struct("CancellationRequest")
735 .field("process_id", &self.process_id)
736 .field("secret_key", &"[REDACTED]")
737 .finish()
738 }
739}
740
741impl CancellationRequest {
742 #[must_use]
744 pub const fn process_id(&self) -> u32 {
745 self.process_id
746 }
747
748 #[must_use]
750 pub fn secret_key(&self) -> &[u8] {
751 &self.secret_key
752 }
753}
754
755#[derive(Debug)]
757#[allow(clippy::large_enum_variant)]
758pub enum ServerAccept<
759 Transport,
760 State,
761 Peer,
762 Identity = TrustIdentity,
763 Handler = IdentityServerHandler,
764> {
765 Session(ServerConnection<Transport, State, Peer, Identity, Handler>),
767 Cancellation(ServerCancellation<Transport, State, Peer, Handler>),
769}
770
771pub type ServerAcceptFuture<
773 'a,
774 Transport,
775 State,
776 Peer,
777 Identity,
778 Handler,
779 TlsError,
780 AuthenticationError,
781> = Pin<
782 Box<
783 dyn Future<
784 Output = Result<
785 ServerAccept<Transport, State, Peer, Identity, Handler>,
786 AcceptError<TlsError, AuthenticationError>,
787 >,
788 > + 'a,
789 >,
790>;
791
792#[derive(Debug)]
794pub struct ServerConnection<
795 Transport,
796 State,
797 Peer,
798 Identity = TrustIdentity,
799 Handler = IdentityServerHandler,
800> {
801 core: ServerConnectionCore<Transport, Peer, Identity, Handler>,
802 state: State,
803}
804
805#[derive(Debug)]
806pub(crate) struct ServerConnectionCore<Transport, Peer, Identity, Handler> {
807 conn: ServerConnectionInner<Transport>,
808 startup: StartupMessage,
809 handler: Handler,
810 context: ServerConnectionContext<Peer, Identity>,
811}
812
813#[derive(Debug)]
814enum ServerConnectionInner<Transport> {
815 Plaintext(Box<Conn<Buffered<Transport, Frontend>, Ready>>),
816 Tls(Box<Conn<Buffered<ServerTls<Transport>, Frontend>, Ready>>),
817}
818
819#[derive(Debug)]
821pub enum AcceptedServerTransport<Transport> {
822 Plaintext(Transport),
824 Tls(Box<ServerTls<Transport>>),
826}
827
828impl<Transport, State, Peer, Identity, Handler>
829 ServerConnection<Transport, State, Peer, Identity, Handler>
830{
831 #[must_use]
833 pub const fn context(&self) -> &ServerConnectionContext<Peer, Identity> {
834 &self.core.context
835 }
836
837 #[must_use]
840 pub const fn state(&self) -> &State {
841 &self.state
842 }
843
844 pub(crate) fn into_core_and_state(
845 self,
846 ) -> (
847 ServerConnectionCore<Transport, Peer, Identity, Handler>,
848 State,
849 ) {
850 (self.core, self.state)
851 }
852
853 #[must_use]
855 pub const fn startup(&self) -> &StartupMessage {
856 &self.core.startup
857 }
858
859 pub async fn receive_wire(&mut self) -> io::Result<FrontendMessage>
870 where
871 Transport: AsyncRead + AsyncWrite + Unpin,
872 Handler: crate::ServerMiddleware<State, ServerConnectionContext<Peer, Identity>>,
873 {
874 let message = self.core.receive_wire_raw().await?;
875 Ok(self.core.intercept_frontend(&mut self.state, message))
876 }
877
878 pub async fn send_wire(&mut self, message: BackendMessage) -> io::Result<()>
887 where
888 Transport: AsyncRead + AsyncWrite + Unpin,
889 Handler: crate::ServerMiddleware<State, ServerConnectionContext<Peer, Identity>>,
890 {
891 let message = self.core.intercept_backend(&mut self.state, message);
892 self.core.send_wire_raw(message).await
893 }
894
895 #[must_use]
898 pub fn teardown(
899 self,
900 ) -> (
901 AcceptedServerTransport<Transport>,
902 State,
903 Handler,
904 ServerConnectionContext<Peer, Identity>,
905 ) {
906 let (transport, handler, context) = self.core.into_parts();
907 (transport, self.state, handler, context)
908 }
909}
910
911impl<Transport, State, Peer, Identity, Handler>
912 ServerConnection<Transport, State, Peer, Identity, Handler>
913where
914 Transport: AsyncRead + AsyncWrite + Unpin,
915 Handler: crate::ServerMiddleware<State, ServerConnectionContext<Peer, Identity>>,
916{
917 pub(crate) async fn send_generated_error(&mut self, message: BackendMessage) -> io::Result<()> {
918 let message = self.core.intercept_backend(&mut self.state, message);
919 if !matches!(message, BackendMessage::ErrorResponse(_)) {
920 return Err(io::Error::new(
921 io::ErrorKind::InvalidData,
922 "middleware rejected generated diagnostic",
923 ));
924 }
925 self.core.send_wire_raw(message).await
926 }
927}
928
929impl<Transport, Peer, Identity, Handler> ServerConnectionCore<Transport, Peer, Identity, Handler> {
930 pub(crate) const fn context(&self) -> &ServerConnectionContext<Peer, Identity> {
931 &self.context
932 }
933
934 pub(crate) async fn receive_wire_raw(&mut self) -> io::Result<FrontendMessage>
935 where
936 Transport: AsyncRead + AsyncWrite + Unpin,
937 {
938 match &mut self.conn {
939 ServerConnectionInner::Plaintext(conn) => conn.receive_frontend_wire().await,
940 ServerConnectionInner::Tls(conn) => conn.receive_frontend_wire().await,
941 }
942 }
943
944 pub(crate) fn intercept_frontend<State>(
945 &mut self,
946 state: &mut State,
947 message: FrontendMessage,
948 ) -> FrontendMessage
949 where
950 Handler: crate::ServerMiddleware<State, ServerConnectionContext<Peer, Identity>>,
951 {
952 self.handler.frontend(&self.context, state, message)
953 }
954
955 pub(crate) fn intercept_backend<State>(
956 &mut self,
957 state: &mut State,
958 message: BackendMessage,
959 ) -> BackendMessage
960 where
961 Handler: crate::ServerMiddleware<State, ServerConnectionContext<Peer, Identity>>,
962 {
963 self.handler.backend(&self.context, state, message)
964 }
965
966 pub(crate) async fn send_wire_raw(&mut self, message: BackendMessage) -> io::Result<()>
967 where
968 Transport: AsyncRead + AsyncWrite + Unpin,
969 {
970 let frame = message.to_frame()?;
971 match &mut self.conn {
972 ServerConnectionInner::Plaintext(conn) => {
973 conn.push_frame(frame)?;
974 conn.flush().await
975 }
976 ServerConnectionInner::Tls(conn) => {
977 conn.push_frame(frame)?;
978 conn.flush().await
979 }
980 }
981 }
982
983 pub(crate) fn into_parts(
984 self,
985 ) -> (
986 AcceptedServerTransport<Transport>,
987 Handler,
988 ServerConnectionContext<Peer, Identity>,
989 ) {
990 let transport = match self.conn {
991 ServerConnectionInner::Plaintext(conn) => {
992 AcceptedServerTransport::Plaintext(conn.into_transport().into_inner())
993 }
994 ServerConnectionInner::Tls(conn) => {
995 AcceptedServerTransport::Tls(Box::new(conn.into_transport().into_inner()))
996 }
997 };
998 (transport, self.handler, self.context)
999 }
1000}
1001
1002#[derive(Debug)]
1004pub struct ServerCancellation<Transport, State, Peer, Handler = IdentityServerHandler> {
1005 transport: AcceptedServerTransport<Transport>,
1006 request: CancellationRequest,
1007 state: State,
1008 handler: Handler,
1009 context: ServerConnectionContext<Peer, ()>,
1010}
1011
1012impl<Transport, State, Peer, Handler> ServerCancellation<Transport, State, Peer, Handler> {
1013 #[must_use]
1015 pub const fn request(&self) -> &CancellationRequest {
1016 &self.request
1017 }
1018
1019 #[must_use]
1021 pub fn teardown(
1022 self,
1023 ) -> (
1024 AcceptedServerTransport<Transport>,
1025 CancellationRequest,
1026 State,
1027 Handler,
1028 ServerConnectionContext<Peer, ()>,
1029 ) {
1030 (
1031 self.transport,
1032 self.request,
1033 self.state,
1034 self.handler,
1035 self.context,
1036 )
1037 }
1038}
1039
1040impl<Tls, Authentication, Middleware> Server<Tls, Authentication, Middleware>
1041where
1042 Tls: ServerTlsConfiguration,
1043 Authentication: ServerAuthenticationProvider,
1044{
1045 #[allow(clippy::type_complexity)]
1061 pub fn accept<'a, Transport, State, Peer>(
1062 &'a self,
1063 transport: Transport,
1064 peer: Peer,
1065 state: State,
1066 ) -> ServerAcceptFuture<
1067 'a,
1068 Transport,
1069 State,
1070 Peer,
1071 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1072 <Middleware as crate::MiddlewareFactory<
1073 ServerConnectionContext<
1074 Peer,
1075 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1076 >,
1077 >>::Handler,
1078 <Tls::Provider as ServerIdentityProvider>::Error,
1079 <Authentication::Authentication as ServerAuthentication<Peer>>::Error,
1080 >
1081 where
1082 Transport: AsyncRead + AsyncWrite + Unpin + 'a,
1083 State: 'a,
1084 Peer: 'a,
1085 Authentication::Authentication: ServerAuthentication<Peer>,
1086 Middleware: crate::MiddlewareFactory<
1087 ServerConnectionContext<
1088 Peer,
1089 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1090 >,
1091 >,
1092 <Middleware as crate::MiddlewareFactory<
1093 ServerConnectionContext<
1094 Peer,
1095 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1096 >,
1097 >>::Handler: crate::ServerMiddleware<
1098 State,
1099 ServerConnectionContext<
1100 Peer,
1101 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1102 >,
1103 >,
1104 {
1105 Box::pin(async move {
1106 let mut resolver = NoStartupRoute;
1107 self.accept_routed(transport, peer, state, &mut resolver)
1108 .await
1109 .map(|(accepted, _)| accepted)
1110 .map_err(|error| match error {
1111 RoutedAcceptError::Accept(error) => error,
1112 RoutedAcceptError::Route(never) => match never {},
1113 })
1114 })
1115 }
1116
1117 #[allow(clippy::too_many_lines)]
1118 pub(crate) async fn accept_routed<Transport, State, Peer, Resolver>(
1119 &self,
1120 transport: Transport,
1121 peer: Peer,
1122 mut state: State,
1123 resolver: &mut Resolver,
1124 ) -> Result<
1125 (
1126 ServerAccept<
1127 Transport,
1128 State,
1129 Peer,
1130 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1131 <Middleware as crate::MiddlewareFactory<
1132 ServerConnectionContext<
1133 Peer,
1134 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1135 >,
1136 >>::Handler,
1137 >,
1138 Option<Resolver::Route>,
1139 ),
1140 RoutedAcceptError<
1141 <Tls::Provider as ServerIdentityProvider>::Error,
1142 <Authentication::Authentication as ServerAuthentication<Peer>>::Error,
1143 Resolver::Error,
1144 >,
1145 >
1146 where
1147 Transport: AsyncRead + AsyncWrite + Unpin,
1148 Authentication::Authentication: ServerAuthentication<Peer>,
1149 Middleware: crate::MiddlewareFactory<
1150 ServerConnectionContext<
1151 Peer,
1152 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1153 >,
1154 >,
1155 <Middleware as crate::MiddlewareFactory<
1156 ServerConnectionContext<
1157 Peer,
1158 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1159 >,
1160 >>::Handler: crate::ServerMiddleware<
1161 State,
1162 ServerConnectionContext<
1163 Peer,
1164 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1165 >,
1166 >,
1167 Resolver: StartupResolver<
1168 State,
1169 Peer,
1170 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1171 >,
1172 {
1173 let mut context = ServerConnectionContext {
1174 peer,
1175 tls: None,
1176 identity: None,
1177 };
1178 let mut handler = self.middleware.create(&context);
1179 let buffered = self
1180 .buffer_transport(transport)
1181 .map_err(AcceptError::Io)
1182 .map_err(RoutedAcceptError::Accept)?;
1183 let mut conn = Conn::new(buffered);
1184
1185 loop {
1186 let message = match conn.receive_pre_startup_wire().await {
1187 Ok(message) => message,
1188 Err(error) => {
1189 let _ = conn.into_transport();
1190 return Err(RoutedAcceptError::Accept(AcceptError::Io(error)));
1191 }
1192 };
1193 let message = handler.pre_startup(&context, &mut state, message);
1194 match conn.offer_pre_startup(message) {
1195 PreStartupOffer::Ssl(decision) => match self.tls.provider() {
1196 None => {
1197 conn = decision.decline_ssl();
1198 conn = flush_or_abort(conn).await?;
1199 }
1200 Some(provider) => {
1201 let identity = match provider.resolve() {
1202 Ok(identity) => identity,
1203 Err(error) => {
1204 let _ = decision.into_transport();
1205 return Err(RoutedAcceptError::Accept(AcceptError::TlsIdentity(
1206 error,
1207 )));
1208 }
1209 };
1210 let handshake = decision.approve_ssl();
1211 let handshake = flush_or_abort(handshake).await?;
1212 let encrypted = handshake
1213 .accept_tls(identity.config, identity.leaf_certificate)
1214 .await
1215 .map_err(AcceptError::Io)?;
1216 return accept_encrypted(
1217 encrypted,
1218 context,
1219 state,
1220 handler,
1221 &self.authentication,
1222 resolver,
1223 )
1224 .await;
1225 }
1226 },
1227 PreStartupOffer::Gss(decision) => {
1228 conn = decision.decline_gss();
1229 conn = flush_or_abort(conn).await?;
1230 }
1231 PreStartupOffer::Cancel {
1232 conn: terminal,
1233 process_id,
1234 secret_key,
1235 } => {
1236 context.tls = Some(NegotiatedServerTls::Plaintext);
1237 let request = handler.cancellation(
1238 &context,
1239 &mut state,
1240 CancellationRequest {
1241 process_id,
1242 secret_key,
1243 },
1244 );
1245 return Ok((
1246 ServerAccept::Cancellation(ServerCancellation {
1247 transport: AcceptedServerTransport::Plaintext(
1248 terminal.into_transport().into_inner(),
1249 ),
1250 request,
1251 state,
1252 handler,
1253 context: ServerConnectionContext {
1254 peer: context.peer,
1255 tls: Some(NegotiatedServerTls::Plaintext),
1256 identity: None,
1257 },
1258 }),
1259 None,
1260 ));
1261 }
1262 PreStartupOffer::Startup {
1263 conn: startup_conn,
1264 message,
1265 } => {
1266 if self.tls.required() {
1267 let _ = startup_conn.into_transport();
1268 return Err(RoutedAcceptError::Accept(AcceptError::TlsRequired));
1269 }
1270 context.tls = Some(NegotiatedServerTls::Plaintext);
1271 let message = handler.startup(&context, &mut state, message);
1272 let route = resolver
1273 .resolve(&message, &context, &mut state)
1274 .await
1275 .map_err(RoutedAcceptError::Route)?;
1276 let ready = complete_auth(
1277 startup_conn,
1278 &message,
1279 &self.authentication,
1280 &mut context,
1281 &mut state,
1282 &mut handler,
1283 resolver.defer_ready(),
1284 )
1285 .await?;
1286 return Ok((
1287 ServerAccept::Session(ServerConnection {
1288 core: ServerConnectionCore {
1289 conn: ServerConnectionInner::Plaintext(Box::new(ready)),
1290 startup: message,
1291 handler,
1292 context,
1293 },
1294 state,
1295 }),
1296 Some(route),
1297 ));
1298 }
1299 }
1300 }
1301 }
1302
1303 fn buffer_transport<Transport>(
1304 &self,
1305 transport: Transport,
1306 ) -> io::Result<Buffered<Transport, Frontend>> {
1307 Buffered::with_limits_frontend(
1308 transport,
1309 self.limits.max_frame_len,
1310 self.limits.max_pre_startup_packet_len,
1311 )
1312 }
1313}
1314
1315async fn accept_encrypted<Transport, State, Peer, Authentication, TlsError, Handler, Resolver>(
1316 mut conn: Conn<Buffered<ServerTls<Transport>, Frontend>, crate::pre_startup::PreStartup>,
1317 mut context: ServerConnectionContext<
1318 Peer,
1319 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1320 >,
1321 mut state: State,
1322 mut handler: Handler,
1323 authentication: &Authentication,
1324 resolver: &mut Resolver,
1325) -> Result<
1326 (
1327 ServerAccept<
1328 Transport,
1329 State,
1330 Peer,
1331 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1332 Handler,
1333 >,
1334 Option<Resolver::Route>,
1335 ),
1336 RoutedAcceptError<
1337 TlsError,
1338 <Authentication::Authentication as ServerAuthentication<Peer>>::Error,
1339 Resolver::Error,
1340 >,
1341>
1342where
1343 Transport: AsyncRead + AsyncWrite + Unpin,
1344 Authentication: ServerAuthenticationProvider,
1345 Authentication::Authentication: ServerAuthentication<Peer>,
1346 Handler: crate::ServerMiddleware<
1347 State,
1348 ServerConnectionContext<
1349 Peer,
1350 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1351 >,
1352 >,
1353 Resolver: StartupResolver<
1354 State,
1355 Peer,
1356 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1357 >,
1358{
1359 let negotiated_tls = NegotiatedServerTls::Tls {
1360 server_end_point: Bytes::copy_from_slice(conn.transport().get_ref().tls_server_end_point()),
1361 };
1362 context.tls = Some(negotiated_tls.clone());
1363 loop {
1364 let message = match conn.receive_pre_startup_wire().await {
1365 Ok(message) => message,
1366 Err(error) => {
1367 let _ = conn.into_transport();
1368 return Err(RoutedAcceptError::Accept(AcceptError::Io(error)));
1369 }
1370 };
1371 let message = handler.pre_startup(&context, &mut state, message);
1372 match conn.offer_pre_startup(message) {
1373 PreStartupOffer::Ssl(decision) => {
1374 conn = decision.decline_ssl();
1375 conn = flush_or_abort(conn).await?;
1376 }
1377 PreStartupOffer::Gss(decision) => {
1378 conn = decision.decline_gss();
1379 conn = flush_or_abort(conn).await?;
1380 }
1381 PreStartupOffer::Cancel {
1382 conn: terminal,
1383 process_id,
1384 secret_key,
1385 } => {
1386 let request = handler.cancellation(
1387 &context,
1388 &mut state,
1389 CancellationRequest {
1390 process_id,
1391 secret_key,
1392 },
1393 );
1394 return Ok((
1395 ServerAccept::Cancellation(ServerCancellation {
1396 transport: AcceptedServerTransport::Tls(Box::new(
1397 terminal.into_transport().into_inner(),
1398 )),
1399 request,
1400 state,
1401 handler,
1402 context: ServerConnectionContext {
1403 peer: context.peer,
1404 tls: context.tls,
1405 identity: None,
1406 },
1407 }),
1408 None,
1409 ));
1410 }
1411 PreStartupOffer::Startup {
1412 conn: startup_conn,
1413 message,
1414 } => {
1415 let message = handler.startup(&context, &mut state, message);
1416 let route = resolver
1417 .resolve(&message, &context, &mut state)
1418 .await
1419 .map_err(RoutedAcceptError::Route)?;
1420 let ready = complete_auth(
1421 startup_conn,
1422 &message,
1423 authentication,
1424 &mut context,
1425 &mut state,
1426 &mut handler,
1427 resolver.defer_ready(),
1428 )
1429 .await?;
1430 return Ok((
1431 ServerAccept::Session(ServerConnection {
1432 core: ServerConnectionCore {
1433 conn: ServerConnectionInner::Tls(Box::new(ready)),
1434 startup: message,
1435 handler,
1436 context,
1437 },
1438 state,
1439 }),
1440 Some(route),
1441 ));
1442 }
1443 }
1444 }
1445}
1446
1447#[allow(clippy::too_many_arguments, clippy::too_many_lines)]
1448async fn complete_auth<I, Authentication, Peer, TlsError, State, Handler>(
1449 startup_conn: Conn<Buffered<I, Frontend>, crate::pre_startup::Startup>,
1450 message: &StartupMessage,
1451 provider: &Authentication,
1452 context: &mut ServerConnectionContext<
1453 Peer,
1454 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1455 >,
1456 state: &mut State,
1457 handler: &mut Handler,
1458 defer_ready: bool,
1459) -> Result<
1460 Conn<Buffered<I, Frontend>, Ready>,
1461 AcceptError<TlsError, <Authentication::Authentication as ServerAuthentication<Peer>>::Error>,
1462>
1463where
1464 I: AsyncRead + AsyncWrite + Unpin,
1465 Authentication: ServerAuthenticationProvider,
1466 Authentication::Authentication: ServerAuthentication<Peer>,
1467 Handler: crate::ServerMiddleware<
1468 State,
1469 ServerConnectionContext<
1470 Peer,
1471 <Authentication::Authentication as ServerAuthentication<Peer>>::Identity,
1472 >,
1473 >,
1474{
1475 let validated = match startup_conn.validate_protocol(message.clone(), ProtocolVersion::V3_2) {
1476 ServerProtocolOffer::Supported { conn, .. } => conn,
1477 ServerProtocolOffer::Rejected { conn, .. } => {
1478 let _ = conn.into_transport();
1479 return Err(AcceptError::UnsupportedProtocolVersion);
1480 }
1481 };
1482 let mut policy = provider.create();
1483 let auth = validated.begin_server_auth();
1484 let request = ServerAuthenticationRequest {
1485 startup: message,
1486 tls: context.tls(),
1487 peer: context.peer(),
1488 };
1489 let action = match policy.start(request).await {
1490 Ok(action) => action,
1491 Err(error) => {
1492 let _ = auth.into_transport();
1493 return Err(AcceptError::Authentication(error));
1494 }
1495 };
1496 let (auth, identity, final_frame) = match action {
1497 ServerAuthenticationAction::Accept(identity) => (auth, identity, None),
1498 action @ (ServerAuthenticationAction::CleartextPassword
1499 | ServerAuthenticationAction::Md5Password { .. }) => {
1500 let (waiting, frame) = match action {
1501 ServerAuthenticationAction::CleartextPassword => auth.request_cleartext(),
1502 ServerAuthenticationAction::Md5Password { salt } => auth.request_md5(salt),
1503 _ => unreachable!("matched password action"),
1504 }
1505 .map_err(AcceptError::Io)?;
1506 let frame = intercept_server_backend(handler, context, state, frame)
1507 .map_err(AcceptError::Io)?;
1508 let waiting = push_or_abort(waiting, frame)?;
1509 let waiting = flush_or_abort(waiting).await?;
1510 let (waiting, wire) = receive_frontend_or_abort(waiting).await?;
1511 let wire = handler.frontend(context, state, wire);
1512 let (auth, credential) = match waiting.receive_password(wire) {
1513 Ok(response) => response,
1514 Err(rejected) => {
1515 let (waiting, _) = *rejected;
1516 let _ = waiting.into_transport();
1517 return Err(AcceptError::AuthenticationProtocol);
1518 }
1519 };
1520 match policy
1521 .respond(request, ServerAuthenticationResponse::Password(credential))
1522 .await
1523 {
1524 Ok(ServerAuthenticationAction::Accept(identity)) => (auth, identity, None),
1525 Ok(_) => {
1526 let _ = auth.into_transport();
1527 return Err(AcceptError::AuthenticationProtocol);
1528 }
1529 Err(error) => {
1530 let _ = auth.into_transport();
1531 return Err(AcceptError::Authentication(error));
1532 }
1533 }
1534 }
1535 ServerAuthenticationAction::Sasl { mechanisms } => {
1536 authenticate_sasl(
1537 auth,
1538 mechanisms,
1539 &mut policy,
1540 request,
1541 context,
1542 state,
1543 handler,
1544 )
1545 .await?
1546 }
1547 action @ (ServerAuthenticationAction::KerberosV5
1548 | ServerAuthenticationAction::Gss
1549 | ServerAuthenticationAction::Sspi) => {
1550 authenticate_token(auth, action, &mut policy, request, context, state, handler).await?
1551 }
1552 ServerAuthenticationAction::SaslContinue(_)
1553 | ServerAuthenticationAction::SaslFinal { .. }
1554 | ServerAuthenticationAction::GssContinue(_) => {
1555 let _ = auth.into_transport();
1556 return Err(AcceptError::AuthenticationProtocol);
1557 }
1558 };
1559 context.identity = Some(identity);
1560 let (mut startup_ready, _authentication_ok) =
1561 auth.authentication_ok().map_err(AcceptError::Io)?;
1562 if let Some(final_frame) = final_frame {
1563 let final_frame = intercept_server_backend(handler, context, state, final_frame)
1564 .map_err(AcceptError::Io)?;
1565 startup_ready = push_or_abort(startup_ready, final_frame)?;
1566 }
1567 let authentication_ok = handler
1568 .backend(
1569 context,
1570 state,
1571 BackendMessage::Authentication(crate::codec::Authentication::Ok),
1572 )
1573 .to_frame()
1574 .map_err(AcceptError::Io)?;
1575 let startup_ready = push_or_abort(startup_ready, authentication_ok)?;
1576 let (ready, _ready_frame) = startup_ready.ready().map_err(AcceptError::Io)?;
1577 let ready = if defer_ready {
1578 ready
1579 } else {
1580 let ready_frame = handler
1581 .backend(
1582 context,
1583 state,
1584 BackendMessage::ReadyForQuery(crate::codec::TransactionStatus::Idle),
1585 )
1586 .to_frame()
1587 .map_err(AcceptError::Io)?;
1588 push_or_abort(ready, ready_frame)?
1589 };
1590 let ready = flush_or_abort(ready).await?;
1591 Ok(ready)
1592}
1593
1594async fn authenticate_sasl<I, Policy, Peer, TlsError, State, Handler>(
1595 auth: Conn<Buffered<I, Frontend>, crate::server_auth::ServerAuth>,
1596 mechanisms: Vec<Bytes>,
1597 policy: &mut Policy,
1598 request: ServerAuthenticationRequest<'_, Peer>,
1599 context: &ServerConnectionContext<Peer, Policy::Identity>,
1600 state: &mut State,
1601 handler: &mut Handler,
1602) -> Result<
1603 (
1604 Conn<Buffered<I, Frontend>, crate::server_auth::ServerAuth>,
1605 Policy::Identity,
1606 Option<crate::codec::Frame>,
1607 ),
1608 AcceptError<TlsError, Policy::Error>,
1609>
1610where
1611 I: AsyncRead + AsyncWrite + Unpin,
1612 Policy: ServerAuthentication<Peer>,
1613 Handler: crate::ServerMiddleware<State, ServerConnectionContext<Peer, Policy::Identity>>,
1614{
1615 if mechanisms.iter().any(|mechanism| mechanism.contains(&0)) {
1616 let _ = auth.into_transport();
1617 return Err(AcceptError::Io(io::Error::new(
1618 io::ErrorKind::InvalidInput,
1619 "SASL mechanism contains NUL",
1620 )));
1621 }
1622 let (initial, frame) = auth.request_sasl(mechanisms).map_err(AcceptError::Io)?;
1623 let frame =
1624 intercept_server_backend(handler, context, state, frame).map_err(AcceptError::Io)?;
1625 let initial = push_or_abort(initial, frame)?;
1626 let initial = flush_or_abort(initial).await?;
1627 let (initial, wire) = receive_frontend_or_abort(initial).await?;
1628 let wire = handler.frontend(context, state, wire);
1629 let (mut sasl, initial_response) = match initial.receive_initial(wire) {
1630 Ok(response) => response,
1631 Err(rejected) => {
1632 let (initial, _) = *rejected;
1633 let _ = initial.into_transport();
1634 return Err(AcceptError::AuthenticationProtocol);
1635 }
1636 };
1637 let mut action = match policy
1638 .respond(
1639 request,
1640 ServerAuthenticationResponse::SaslInitial {
1641 mechanism: initial_response.mechanism,
1642 response: initial_response.response,
1643 },
1644 )
1645 .await
1646 {
1647 Ok(action) => action,
1648 Err(error) => {
1649 let _ = sasl.into_transport();
1650 return Err(AcceptError::Authentication(error));
1651 }
1652 };
1653 loop {
1654 match action {
1655 ServerAuthenticationAction::SaslContinue(challenge) => {
1656 let (waiting, frame) = sasl.continue_with(challenge).map_err(AcceptError::Io)?;
1657 let frame = intercept_server_backend(handler, context, state, frame)
1658 .map_err(AcceptError::Io)?;
1659 let waiting = push_or_abort(waiting, frame)?;
1660 let waiting = flush_or_abort(waiting).await?;
1661 let (waiting, wire) = receive_frontend_or_abort(waiting).await?;
1662 let wire = handler.frontend(context, state, wire);
1663 let (next, response) = match waiting.receive_response(wire) {
1664 Ok(response) => response,
1665 Err(rejected) => {
1666 let (waiting, _) = *rejected;
1667 let _ = waiting.into_transport();
1668 return Err(AcceptError::AuthenticationProtocol);
1669 }
1670 };
1671 sasl = next;
1672 action = match policy
1673 .respond(request, ServerAuthenticationResponse::Sasl(response))
1674 .await
1675 {
1676 Ok(action) => action,
1677 Err(error) => {
1678 let _ = sasl.into_transport();
1679 return Err(AcceptError::Authentication(error));
1680 }
1681 };
1682 }
1683 ServerAuthenticationAction::SaslFinal {
1684 server_final,
1685 identity,
1686 } => {
1687 let (auth, frame) = sasl.finish(server_final).map_err(AcceptError::Io)?;
1688 return Ok((auth, identity, Some(frame)));
1689 }
1690 _ => {
1691 let _ = sasl.into_transport();
1692 return Err(AcceptError::AuthenticationProtocol);
1693 }
1694 }
1695 }
1696}
1697
1698async fn authenticate_token<I, Policy, Peer, TlsError, State, Handler>(
1699 auth: Conn<Buffered<I, Frontend>, crate::server_auth::ServerAuth>,
1700 initial_action: ServerAuthenticationAction<Policy::Identity>,
1701 policy: &mut Policy,
1702 request: ServerAuthenticationRequest<'_, Peer>,
1703 context: &ServerConnectionContext<Peer, Policy::Identity>,
1704 state: &mut State,
1705 handler: &mut Handler,
1706) -> Result<
1707 (
1708 Conn<Buffered<I, Frontend>, crate::server_auth::ServerAuth>,
1709 Policy::Identity,
1710 Option<crate::codec::Frame>,
1711 ),
1712 AcceptError<TlsError, Policy::Error>,
1713>
1714where
1715 I: AsyncRead + AsyncWrite + Unpin,
1716 Policy: ServerAuthentication<Peer>,
1717 Handler: crate::ServerMiddleware<State, ServerConnectionContext<Peer, Policy::Identity>>,
1718{
1719 let (waiting, frame) = match initial_action {
1720 ServerAuthenticationAction::KerberosV5 => auth.request_kerberos_v5(),
1721 ServerAuthenticationAction::Gss => auth.request_gss(),
1722 ServerAuthenticationAction::Sspi => auth.request_sspi(),
1723 _ => unreachable!("matched initial token action"),
1724 }
1725 .map_err(AcceptError::Io)?;
1726 let frame =
1727 intercept_server_backend(handler, context, state, frame).map_err(AcceptError::Io)?;
1728 let waiting = push_or_abort(waiting, frame)?;
1729 let mut waiting = flush_or_abort(waiting).await?;
1730 loop {
1731 let received = receive_frontend_or_abort(waiting).await?;
1732 waiting = received.0;
1733 let wire = handler.frontend(context, state, received.1);
1734 let (decision, token) = match waiting.receive_response(wire) {
1735 Ok(response) => response,
1736 Err(rejected) => {
1737 let (waiting, _) = *rejected;
1738 let _ = waiting.into_transport();
1739 return Err(AcceptError::AuthenticationProtocol);
1740 }
1741 };
1742 let action = match policy
1743 .respond(request, ServerAuthenticationResponse::Token(token))
1744 .await
1745 {
1746 Ok(action) => action,
1747 Err(error) => {
1748 let _ = decision.into_transport();
1749 return Err(AcceptError::Authentication(error));
1750 }
1751 };
1752 match action {
1753 ServerAuthenticationAction::Accept(identity) => {
1754 return Ok((decision.verified(), identity, None));
1755 }
1756 ServerAuthenticationAction::GssContinue(token) => {
1757 let (next, frame) = decision.continue_gss(token).map_err(AcceptError::Io)?;
1758 let frame = intercept_server_backend(handler, context, state, frame)
1759 .map_err(AcceptError::Io)?;
1760 let next = push_or_abort(next, frame)?;
1761 waiting = flush_or_abort(next).await?;
1762 }
1763 _ => {
1764 let _ = decision.into_transport();
1765 return Err(AcceptError::AuthenticationProtocol);
1766 }
1767 }
1768 }
1769}
1770
1771fn intercept_server_backend<State, Context, Handler>(
1772 handler: &mut Handler,
1773 context: &Context,
1774 state: &mut State,
1775 frame: crate::codec::Frame,
1776) -> io::Result<crate::codec::Frame>
1777where
1778 Handler: crate::ServerMiddleware<State, Context>,
1779{
1780 handler
1781 .backend(context, state, Backend::decode(frame)?)
1782 .to_frame()
1783}
1784
1785async fn flush_or_abort<I, D, Phase, TlsError, AuthenticationError>(
1786 mut conn: Conn<Buffered<I, D>, Phase>,
1787) -> Result<Conn<Buffered<I, D>, Phase>, AcceptError<TlsError, AuthenticationError>>
1788where
1789 I: AsyncWrite + Unpin,
1790{
1791 if let Err(error) = conn.flush().await {
1792 let _ = conn.into_transport();
1793 return Err(AcceptError::Io(error));
1794 }
1795 Ok(conn)
1796}
1797
1798fn push_or_abort<I, D, Phase, TlsError, AuthenticationError>(
1799 mut conn: Conn<Buffered<I, D>, Phase>,
1800 frame: crate::codec::Frame,
1801) -> Result<Conn<Buffered<I, D>, Phase>, AcceptError<TlsError, AuthenticationError>> {
1802 if let Err(error) = conn.push_frame(frame) {
1803 let _ = conn.into_transport();
1804 return Err(AcceptError::Io(error));
1805 }
1806 Ok(conn)
1807}
1808
1809async fn receive_frontend_or_abort<I, Phase, TlsError, AuthenticationError>(
1810 mut conn: Conn<Buffered<I, Frontend>, Phase>,
1811) -> Result<
1812 (Conn<Buffered<I, Frontend>, Phase>, FrontendMessage),
1813 AcceptError<TlsError, AuthenticationError>,
1814>
1815where
1816 I: AsyncRead + Unpin,
1817{
1818 match conn.receive_frontend_wire().await {
1819 Ok(message) => Ok((conn, message)),
1820 Err(error) => {
1821 let _ = conn.into_transport();
1822 Err(AcceptError::Io(error))
1823 }
1824 }
1825}