Skip to content

Commit

Permalink
fix(apns): proper handling of the wrong CA in APNS certificate (#343)
Browse files Browse the repository at this point in the history
  • Loading branch information
geekbrother authored Jun 21, 2024
1 parent 5d201d8 commit fc38254
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ pub enum Error {
#[error("Expired APNs certificate")]
ApnsCertificateExpired,

#[error("Unknown CA of APNs certificate")]
ApnsCertificateUnknownCA,

#[error("client deleted due to invalid device token")]
ClientDeleted,

Expand Down
17 changes: 17 additions & 0 deletions src/handlers/push_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,23 @@ pub async fn handler_internal(
);
Err(Error::TenantSuspended)
}
Error::ApnsCertificateUnknownCA => {
let reason = "Unknown APNs certificate's CA";
state
.tenant_store
.suspend_tenant(&tenant_id, reason)
.await
.map_err(|e| (e, analytics.clone()))?;
increment_counter!(state.metrics, tenant_suspensions);
warn!(
%tenant_id,
client_id = %client_id,
notification_id = %notification.id,
push_type = client.push_type.as_str(),
"tenant has been suspended due to: {reason}"
);
Err(Error::TenantSuspended)
}
Error::BadFcmApiKey => {
state
.tenant_store
Expand Down
27 changes: 17 additions & 10 deletions src/providers/apns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,23 @@ impl PushProvider for ApnsProvider {
a2::Error::ConnectionError(ref hyper_error) => {
let dbg = format!("{hyper_error:?}");
// e.g. Apns(ConnectionError(hyper::Error(Io, Custom { kind: InvalidData, error: "received fatal alert: CertificateExpired" })))
if dbg.contains("received fatal alert: CertificateExpired") {
// Checking if debug fmt contains something is strange.
// Logging stuff here temporarily so we can determine better
// ways to detect this error (e.g. display). Ideally we can extract
// the error field directly and check if exactly equal to the above
// rather than using contains()
info!("APNs certificate expired: debug:{dbg}, display: {hyper_error}");
Err(Error::ApnsCertificateExpired)
} else {
Err(Error::Apns(e))
// Checking if debug fmt contains something is strange.
// Logging stuff here temporarily so we can determine better
// ways to detect this error (e.g. display). Ideally we can extract
// the error field directly and check if exactly equal to the above
// rather than using contains()
match dbg {
dbg if dbg.contains("received fatal alert: CertificateExpired") => {
info!("APNs certificate expired: debug:{dbg}, display: {hyper_error}");
Err(Error::ApnsCertificateExpired)
}
dbg if dbg.contains("received fatal alert: UnknownCA") => {
info!(
"APNs certificate unknown CA: debug:{dbg}, display: {hyper_error}"
);
Err(Error::ApnsCertificateUnknownCA)
}
_ => Err(Error::Apns(e)),
}
}
e => Err(Error::Apns(e)),
Expand Down

0 comments on commit fc38254

Please sign in to comment.