feat: clipboard files, audit (#12730)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -2257,7 +2257,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
}
|
||||
#[cfg(feature = "unix-file-copy-paste")]
|
||||
if crate::is_support_file_copy_paste_num(self.handler.lc.read().unwrap().version) {
|
||||
let mut out_msg = None;
|
||||
let mut out_msgs = vec![];
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
if clipboard::platform::unix::macos::should_handle_msg(&clip) {
|
||||
@@ -2269,7 +2269,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
log::error!("failed to handle cliprdr msg: {}", e);
|
||||
}
|
||||
} else {
|
||||
out_msg = unix_file_clip::serve_clip_messages(
|
||||
out_msgs = unix_file_clip::serve_clip_messages(
|
||||
ClipboardSide::Client,
|
||||
clip,
|
||||
self.client_conn_id,
|
||||
@@ -2278,14 +2278,14 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
out_msg = unix_file_clip::serve_clip_messages(
|
||||
out_msgs = unix_file_clip::serve_clip_messages(
|
||||
ClipboardSide::Client,
|
||||
clip,
|
||||
self.client_conn_id,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(msg) = out_msg {
|
||||
for msg in out_msgs.into_iter() {
|
||||
allow_err!(_peer.send(&msg).await);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +143,40 @@ pub fn clip_2_msg(clip: ClipboardFile) -> Message {
|
||||
})),
|
||||
..Default::default()
|
||||
},
|
||||
ClipboardFile::Files { files } => {
|
||||
let files = files
|
||||
.iter()
|
||||
.filter_map(|(f, s)| {
|
||||
if *s == 0 {
|
||||
if let Ok(meta) = std::fs::metadata(f) {
|
||||
Some(CliprdrFile {
|
||||
name: f.to_owned(),
|
||||
size: meta.len(),
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
Some(CliprdrFile {
|
||||
name: f.to_owned(),
|
||||
size: *s,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
Message {
|
||||
union: Some(message::Union::Cliprdr(Cliprdr {
|
||||
union: Some(cliprdr::Union::Files(CliprdrFiles {
|
||||
files,
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
})),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +277,7 @@ pub mod unix_file_clip {
|
||||
side: ClipboardSide,
|
||||
clip: ClipboardFile,
|
||||
conn_id: i32,
|
||||
) -> Option<Message> {
|
||||
) -> Vec<Message> {
|
||||
log::debug!("got clipfile from client peer");
|
||||
match clip {
|
||||
ClipboardFile::MonitorReady => {
|
||||
@@ -257,7 +291,7 @@ pub mod unix_file_clip {
|
||||
.is_some()
|
||||
{
|
||||
log::error!("no file contents format found");
|
||||
return None;
|
||||
return vec![];
|
||||
};
|
||||
let Some(file_descriptor_id) = format_list
|
||||
.iter()
|
||||
@@ -265,13 +299,13 @@ pub mod unix_file_clip {
|
||||
.map(|(id, _)| *id)
|
||||
else {
|
||||
log::error!("no file descriptor format found");
|
||||
return None;
|
||||
return vec![];
|
||||
};
|
||||
// sync file system from peer
|
||||
let data = ClipboardFile::FormatDataRequest {
|
||||
requested_format_id: file_descriptor_id,
|
||||
};
|
||||
return Some(clip_2_msg(data));
|
||||
return vec![clip_2_msg(data)];
|
||||
}
|
||||
ClipboardFile::FormatListResponse {
|
||||
msg_flags: _msg_flags,
|
||||
@@ -282,13 +316,13 @@ pub mod unix_file_clip {
|
||||
log::debug!("requested format id: {}", _requested_format_id);
|
||||
let format_data = serv_files::get_file_list_pdu();
|
||||
if !format_data.is_empty() {
|
||||
return Some(clip_2_msg(ClipboardFile::FormatDataResponse {
|
||||
return vec![clip_2_msg(ClipboardFile::FormatDataResponse {
|
||||
msg_flags: 1,
|
||||
format_data,
|
||||
}));
|
||||
})];
|
||||
}
|
||||
// empty file list, send failure message
|
||||
return Some(msg_resp_format_data_failure());
|
||||
return vec![msg_resp_format_data_failure()];
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
ClipboardFile::FormatDataResponse {
|
||||
@@ -329,7 +363,7 @@ pub mod unix_file_clip {
|
||||
..
|
||||
} => {
|
||||
log::debug!("file contents request: stream_id: {}, list_index: {}, dw_flags: {}, n_position_low: {}, n_position_high: {}, cb_requested: {}", stream_id, list_index, dw_flags, n_position_low, n_position_high, cb_requested);
|
||||
match serv_files::read_file_contents(
|
||||
return serv_files::read_file_contents(
|
||||
conn_id,
|
||||
stream_id,
|
||||
list_index,
|
||||
@@ -337,15 +371,16 @@ pub mod unix_file_clip {
|
||||
n_position_low,
|
||||
n_position_high,
|
||||
cb_requested,
|
||||
) {
|
||||
Ok(data) => {
|
||||
return Some(clip_2_msg(data));
|
||||
}
|
||||
)
|
||||
.into_iter()
|
||||
.map(|res| match res {
|
||||
Ok(data) => clip_2_msg(data),
|
||||
Err(e) => {
|
||||
log::error!("failed to read file contents: {:?}", e);
|
||||
return Some(resp_file_contents_fail(stream_id));
|
||||
resp_file_contents_fail(stream_id)
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect::<_>();
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
ClipboardFile::FileContentsResponse {
|
||||
@@ -387,6 +422,6 @@ pub mod unix_file_clip {
|
||||
log::error!("unsupported clipboard file type");
|
||||
}
|
||||
}
|
||||
None
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,7 +633,22 @@ impl Connection {
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
ipc::Data::ClipboardFile(clip) => {
|
||||
allow_err!(conn.stream.send(&clip_2_msg(clip)).await);
|
||||
match clip {
|
||||
clipboard::ClipboardFile::Files { files } => {
|
||||
let files = files.into_iter().map(|(f, s)| {
|
||||
(f, s as i64)
|
||||
}).collect::<Vec<_>>();
|
||||
conn.post_file_audit(
|
||||
FileAuditType::RemoteSend,
|
||||
"",
|
||||
files,
|
||||
json!({}),
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
allow_err!(conn.stream.send(&clip_2_msg(clip)).await);
|
||||
}
|
||||
}
|
||||
}
|
||||
ipc::Data::PrivacyModeState((_, state, impl_key)) => {
|
||||
let msg_out = match state {
|
||||
@@ -2463,14 +2478,25 @@ impl Connection {
|
||||
}
|
||||
#[cfg(any(target_os = "windows", feature = "unix-file-copy-paste"))]
|
||||
Some(message::Union::Cliprdr(clip)) => {
|
||||
if let Some(clip) = msg_2_clip(clip) {
|
||||
if let Some(cliprdr::Union::Files(files)) = &clip.union {
|
||||
self.post_file_audit(
|
||||
FileAuditType::RemoteReceive,
|
||||
"",
|
||||
files
|
||||
.files
|
||||
.iter()
|
||||
.map(|f| (f.name.clone(), f.size as i64))
|
||||
.collect::<Vec<(String, i64)>>(),
|
||||
json!({}),
|
||||
);
|
||||
} else if let Some(clip) = msg_2_clip(clip) {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
self.send_to_cm(ipc::Data::ClipboardFile(clip));
|
||||
}
|
||||
#[cfg(feature = "unix-file-copy-paste")]
|
||||
if crate::is_support_file_copy_paste(&self.lr.version) {
|
||||
let mut out_msg = None;
|
||||
let mut out_msgs = vec![];
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
if clipboard::platform::unix::macos::should_handle_msg(&clip) {
|
||||
@@ -2485,7 +2511,7 @@ impl Connection {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
out_msg = unix_file_clip::serve_clip_messages(
|
||||
out_msgs = unix_file_clip::serve_clip_messages(
|
||||
ClipboardSide::Host,
|
||||
clip,
|
||||
self.inner.id(),
|
||||
@@ -2494,14 +2520,31 @@ impl Connection {
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
out_msg = unix_file_clip::serve_clip_messages(
|
||||
out_msgs = unix_file_clip::serve_clip_messages(
|
||||
ClipboardSide::Host,
|
||||
clip,
|
||||
self.inner.id(),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(msg) = out_msg {
|
||||
for msg in out_msgs.into_iter() {
|
||||
if let Some(message::Union::Cliprdr(cliprdr)) = msg.union.as_ref() {
|
||||
if let Some(cliprdr::Union::Files(files)) =
|
||||
cliprdr.union.as_ref()
|
||||
{
|
||||
self.post_file_audit(
|
||||
FileAuditType::RemoteSend,
|
||||
"",
|
||||
files
|
||||
.files
|
||||
.iter()
|
||||
.map(|f| (f.name.clone(), f.size as i64))
|
||||
.collect::<Vec<(String, i64)>>(),
|
||||
json!({}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
self.send(msg).await;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user