Skip to content

Commit

Permalink
nostr: allow client and relays messages to be longer than expecte…
Browse files Browse the repository at this point in the history
…d during deserialization

A relay is sending a 3rd argument in `EOSE` message causing issues with deserialization. Checking if the message array len is `>= X` fix this and potentially others issues in the future.
  • Loading branch information
yukibtc committed Jan 14, 2024
1 parent a67cd2a commit 30d24b2
Showing 2 changed files with 98 additions and 93 deletions.
72 changes: 38 additions & 34 deletions crates/nostr/src/message/client.rs
Original file line number Diff line number Diff line change
@@ -223,11 +223,12 @@ impl ClientMessage {
// Event
// ["EVENT", <event JSON>]
if v[0] == "EVENT" {
if v_len != 2 {
if v_len >= 2 {
let event = Event::from_value(v[1].clone())?;
return Ok(Self::new_event(event));
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}
let event = Event::from_value(v[1].clone())?;
return Ok(Self::new_event(event));
}

// Req
@@ -262,67 +263,70 @@ impl ClientMessage {
// Close
// ["CLOSE", <subscription_id>]
if v[0] == "CLOSE" {
if v_len != 2 {
if v_len >= 2 {
let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?;
return Ok(Self::close(subscription_id));
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}

let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?;

return Ok(Self::close(subscription_id));
}

// Auth
// ["AUTH", <event JSON>]
if v[0] == "AUTH" {
if v_len != 2 {
if v_len >= 2 {
let event = Event::from_value(v[1].clone())?;
return Ok(Self::new_auth(event));
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}
let event = Event::from_value(v[1].clone())?;
return Ok(Self::new_auth(event));
}

// Negentropy Open
// ["NEG-OPEN", <subscription ID string>, <filter>, <idSize>, <initialMessage, lowercase hex-encoded>]
if v[0] == "NEG-OPEN" {
if v_len != 5 {
if v_len >= 5 {
let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?;
let filter: Filter = Filter::from_json(v[2].to_string())?;
let id_size: u8 =
v[3].as_u64()
.ok_or(MessageHandleError::InvalidMessageFormat)? as u8;
let initial_message: String = serde_json::from_value(v[4].clone())?;
return Ok(Self::NegOpen {
subscription_id,
filter: Box::new(filter),
id_size,
initial_message,
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}
let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?;
let filter: Filter = Filter::from_json(v[2].to_string())?;
let id_size: u8 =
v[3].as_u64()
.ok_or(MessageHandleError::InvalidMessageFormat)? as u8;
let initial_message: String = serde_json::from_value(v[4].clone())?;
return Ok(Self::NegOpen {
subscription_id,
filter: Box::new(filter),
id_size,
initial_message,
});
}

// Negentropy Message
// ["NEG-MSG", <subscription ID string>, <message, lowercase hex-encoded>]
if v[0] == "NEG-MSG" {
if v_len != 3 {
if v_len >= 3 {
let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?;
let message: String = serde_json::from_value(v[2].clone())?;
return Ok(Self::NegMsg {
subscription_id,
message,
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}
let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?;
let message: String = serde_json::from_value(v[2].clone())?;
return Ok(Self::NegMsg {
subscription_id,
message,
});
}

// Negentropy Close
// ["NEG-CLOSE", <subscription ID string>]
if v[0] == "NEG-CLOSE" {
if v_len != 2 {
if v_len >= 2 {
let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?;
return Ok(Self::NegClose { subscription_id });
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}
let subscription_id: SubscriptionId = serde_json::from_value(v[1].clone())?;
return Ok(Self::NegClose { subscription_id });
}

Err(MessageHandleError::InvalidMessageFormat)
119 changes: 60 additions & 59 deletions crates/nostr/src/message/relay/raw.rs
Original file line number Diff line number Diff line change
@@ -87,122 +87,123 @@ impl RawRelayMessage {
// Notice
// Relay response format: ["NOTICE", <message>]
if v[0] == "NOTICE" {
if v_len != 2 {
if v_len >= 2 {
return Ok(Self::Notice {
message: serde_json::from_value(v[1].clone())?,
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}
return Ok(Self::Notice {
message: serde_json::from_value(v[1].clone())?,
});
}

// Closed
// Relay response format: ["CLOSED", <subscription_id>, <message>]
if v[0] == "CLOSED" {
if v_len != 3 {
if v_len >= 3 {
return Ok(Self::Closed {
subscription_id: serde_json::from_value(v[1].clone())?,
message: serde_json::from_value(v[2].clone())?,
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}

return Ok(Self::Closed {
subscription_id: serde_json::from_value(v[1].clone())?,
message: serde_json::from_value(v[2].clone())?,
});
}

// Event
// Relay response format: ["EVENT", <subscription id>, <event JSON>]
if v[0] == "EVENT" {
if v_len != 3 {
if v_len >= 3 {
return Ok(Self::Event {
subscription_id: serde_json::from_value(v[1].clone())?,
event: v[2].clone(),
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}

return Ok(Self::Event {
subscription_id: serde_json::from_value(v[1].clone())?,
event: v[2].clone(),
});
}

// EOSE (NIP-15)
// Relay response format: ["EOSE", <subscription_id>]
if v[0] == "EOSE" {
if v_len != 2 {
if v_len >= 2 {
let subscription_id: String = serde_json::from_value(v[1].clone())?;
return Ok(Self::EndOfStoredEvents(subscription_id));
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}

let subscription_id: String = serde_json::from_value(v[1].clone())?;
return Ok(Self::EndOfStoredEvents(subscription_id));
}

// OK (NIP-20)
// Relay response format: ["OK", <event_id>, <true|false>, <message>]
if v[0] == "OK" {
if v_len != 4 {
if v_len >= 4 {
return Ok(Self::Ok {
event_id: serde_json::from_value(v[1].clone())?,
status: serde_json::from_value(v[2].clone())?,
message: serde_json::from_value(v[3].clone())?,
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}

return Ok(Self::Ok {
event_id: serde_json::from_value(v[1].clone())?,
status: serde_json::from_value(v[2].clone())?,
message: serde_json::from_value(v[3].clone())?,
});
}

// OK (NIP-42)
// Relay response format: ["AUTH", <challenge>]
if v[0] == "AUTH" {
if v_len != 2 {
if v_len >= 2 {
return Ok(Self::Auth {
challenge: serde_json::from_value(v[1].clone())?,
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}

return Ok(Self::Auth {
challenge: serde_json::from_value(v[1].clone())?,
});
}

// Relay response format: ["EVENT", <subscription id>, <event JSON>]
if v[0] == "COUNT" {
if v_len != 3 {
if v_len >= 3 {
let map = v[2]
.as_object()
.ok_or(MessageHandleError::InvalidMessageFormat)?;
let count: Value = map
.get("count")
.ok_or(MessageHandleError::InvalidMessageFormat)?
.clone();
let count: usize = serde_json::from_value(count)?;

return Ok(Self::Count {
subscription_id: serde_json::from_value(v[1].clone())?,
count,
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}

let map = v[2]
.as_object()
.ok_or(MessageHandleError::InvalidMessageFormat)?;
let count: Value = map
.get("count")
.ok_or(MessageHandleError::InvalidMessageFormat)?
.clone();
let count: usize = serde_json::from_value(count)?;

return Ok(Self::Count {
subscription_id: serde_json::from_value(v[1].clone())?,
count,
});
}

// Negentropy Message
// ["NEG-MSG", <subscription ID string>, <message, lowercase hex-encoded>]
if v[0] == "NEG-MSG" {
if v_len != 3 {
if v_len >= 3 {
return Ok(Self::NegMsg {
subscription_id: serde_json::from_value(v[1].clone())?,
message: serde_json::from_value(v[2].clone())?,
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}

return Ok(Self::NegMsg {
subscription_id: serde_json::from_value(v[1].clone())?,
message: serde_json::from_value(v[2].clone())?,
});
}

// Negentropy Error
// ["NEG-ERR", <subscription ID string>, <reason-code>]
if v[0] == "NEG-ERR" {
if v_len != 3 {
if v_len >= 3 {
return Ok(Self::NegErr {
subscription_id: serde_json::from_value(v[1].clone())?,
code: serde_json::from_value(v[2].clone())?,
});
} else {
return Err(MessageHandleError::InvalidMessageFormat);
}

return Ok(Self::NegErr {
subscription_id: serde_json::from_value(v[1].clone())?,
code: serde_json::from_value(v[2].clone())?,
});
}

Err(MessageHandleError::InvalidMessageFormat)

0 comments on commit 30d24b2

Please sign in to comment.