Your locally hosted lumina server for IDAPro
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

support delete command (#60)

* support delete command

authored by

Naim A and committed by
GitHub
b4398051 e2da794d

+72 -3
+1
common/src/config.rs
··· 13 13 pub use_tls: Option<bool>, 14 14 pub tls: Option<TlsIdentity>, 15 15 pub server_name: Option<String>, 16 + pub allow_deletes: Option<bool>, 16 17 } 17 18 18 19 #[derive(Deserialize)]
+15
common/src/db/mod.rs
··· 325 325 .collect(); 326 326 Ok(res) 327 327 } 328 + 329 + pub async fn delete_metadata(&self, req: &crate::rpc::DelHistory<'_>) -> Result<(), deadpool_postgres::PoolError> { 330 + let conn = self.pool.get().await?; 331 + let stmt = conn.prepare_cached("DELETE FROM funcs WHERE chksum = ANY($1)").await?; 332 + 333 + let chksums = req.funcs.iter() 334 + .map(|v| v.as_slice()) 335 + .collect::<Vec<_>>(); 336 + 337 + conn.execute(&stmt, &[ 338 + &chksums 339 + ]).await?; 340 + 341 + Ok(()) 342 + } 328 343 }
+1 -1
common/src/lib.rs
··· 22 22 const CHUNK_SIZE: usize = 32; 23 23 data.chunks(CHUNK_SIZE).for_each(|chunk| { 24 24 for &ch in chunk { 25 - let _ = write!(&mut output, "{:02x} ", ch); 25 + let _ = write!(&mut output, "{ch:02x} "); 26 26 } 27 27 let padding = CHUNK_SIZE - chunk.len(); 28 28 for _ in 0..padding {
+21
common/src/rpc/messages.rs
··· 84 84 // array of 0=exists, 1=NEW 85 85 pub status: Cow<'a, [u32]>, 86 86 } 87 + 88 + #[derive(Debug, Deserialize, Serialize)] 89 + pub struct DelHistory<'a> { 90 + pub unk0: u32, // =0x08 91 + pub unk1: Cow<'a, [Cow<'a, str>]>, 92 + pub unk2: Cow<'a, [[u64; 2]]>, 93 + pub unk3: Cow<'a, [[u64; 2]]>, 94 + pub unk4: Cow<'a, [Cow<'a, str>]>, 95 + pub unk5: Cow<'a, [Cow<'a, str>]>, 96 + pub unk6: Cow<'a, [Cow<'a, str>]>, 97 + pub unk7: Cow<'a, [Cow<'a, str>]>, 98 + pub unk8: Cow<'a, [Cow<'a, [u8; 16]>]>, 99 + pub funcs: Cow<'a, [Cow<'a, [u8; 16]>]>, 100 + pub unk10: Cow<'a, [[u64; 2]]>, 101 + pub unk11: u64, 102 + } 103 + 104 + #[derive(Deserialize, Serialize)] 105 + pub struct DelHistoryResult { 106 + pub deleted_mds: u32, 107 + }
+8
common/src/rpc/mod.rs
··· 116 116 PullMetadataResult(PullMetadataResult<'a>), 117 117 PushMetadata(PushMetadata<'a>), 118 118 PushMetadataResult(PushMetadataResult<'a>), 119 + DelHistory(DelHistory<'a>), 120 + DelHistoryResult(DelHistoryResult), 119 121 } 120 122 121 123 impl<'a> serde::Serialize for RpcMessage<'a> { ··· 137 139 RpcMessage::PullMetadataResult(msg) => tuple.serialize_element(msg)?, 138 140 RpcMessage::PushMetadata(msg) => tuple.serialize_element(msg)?, 139 141 RpcMessage::PushMetadataResult(msg) => tuple.serialize_element(msg)?, 142 + RpcMessage::DelHistory(msg) => tuple.serialize_element(msg)?, 143 + RpcMessage::DelHistoryResult(msg) => tuple.serialize_element(msg)?, 140 144 } 141 145 142 146 tuple.end() ··· 187 191 0x0f => RpcMessage::PullMetadataResult(Self::deserialize_check(payload)?), 188 192 0x10 => RpcMessage::PushMetadata(Self::deserialize_check(payload)?), 189 193 0x11 => RpcMessage::PushMetadataResult(Self::deserialize_check(payload)?), 194 + 0x18 => RpcMessage::DelHistory(Self::deserialize_check(payload)?), 195 + 0x19 => RpcMessage::DelHistoryResult(Self::deserialize_check(payload)?), 190 196 _ => { 191 197 trace!("got invalid message type '{:02x}'", msg_type); 192 198 return Err(Error::InvalidData); ··· 217 223 PullMetadataResult(_) => 0x0f, 218 224 PushMetadata(_) => 0x10, 219 225 PushMetadataResult(_) => 0x11, 226 + DelHistory(_) => 0x18, 227 + DelHistoryResult(_) => 0x19, 220 228 } 221 229 } 222 230 }
+1 -1
common/src/web/api.rs
··· 219 219 220 220 let stats = match state.db.get_stats().await { 221 221 Ok(stats) => DbStatus::Stats(stats), 222 - Err(err) => DbStatus::Error(format!("{}", err)), 222 + Err(err) => DbStatus::Error(format!("{err}")), 223 223 }; 224 224 225 225 Result::<_, Rejection>::Ok(warp::reply::json(&Response {
+3
config-example.toml
··· 6 6 # server display name; appears in IDA output window 7 7 server_name = "lumen" 8 8 9 + # Allow clients to delete metadata from the database? 10 + allow_deletes = false 11 + 9 12 # only required when `use_tls` is set to true. 10 13 [lumina.tls] 11 14 # Specify the server's certificate.
+22 -1
lumen/src/main.rs
··· 131 131 status: Cow::Owned(status), 132 132 }).async_write(&mut stream).await?; 133 133 }, 134 + RpcMessage::DelHistory(req) => { 135 + let is_delete_allowed = state.config.lumina.allow_deletes.unwrap_or(false); 136 + if !is_delete_allowed { 137 + RpcMessage::Fail(rpc::RpcFail { 138 + code: 2, 139 + message: &format!("{server_name}: Delete command is disabled on this server.") 140 + }).async_write(&mut stream).await?; 141 + } else { 142 + if let Err(err) = db.delete_metadata(&req).await { 143 + error!("delete failed. db: {err}"); 144 + RpcMessage::Fail(rpc::RpcFail { 145 + code: 3, 146 + message: &format!("{server_name}: db error, please try again later.") 147 + }).async_write(&mut stream).await?; 148 + return Ok(()); 149 + } 150 + RpcMessage::DelHistoryResult(rpc::DelHistoryResult { 151 + deleted_mds: req.funcs.len() as u32, 152 + }).async_write(&mut stream).await?; 153 + } 154 + }, 134 155 _ => { 135 156 RpcMessage::Fail(rpc::RpcFail{code: 0, message: &format!("{server_name}: invalid data.\n")}).async_write(&mut stream).await?; 136 157 } ··· 157 178 // send error 158 179 error!("got bad hello message"); 159 180 160 - let resp = rpc::RpcFail{ code: 0, message: &format!("{}: bad sequence.\n", server_name) }; 181 + let resp = rpc::RpcFail{ code: 0, message: &format!("{server_name}: bad sequence.") }; 161 182 let resp = rpc::RpcMessage::Fail(resp); 162 183 resp.async_write(&mut stream).await?; 163 184