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