gardesk/garwarp / c0fb997

Browse files

reject unknown request fields

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
c0fb9974f7fe7f893b6dbeda8813a51e59a26d7b
Parents
01cdf42
Tree
50e1ab1

2 changed files

StatusFile+-
M garwarp-ipc/src/lib.rs 21 0
M garwarp/src/daemon.rs 29 0
garwarp-ipc/src/lib.rsmodified
@@ -150,11 +150,17 @@ impl ControlRequest {
150150
         match parts.next() {
151151
             Some("inspect") => {
152152
                 let fields = parse_fields(parts)?;
153
+                if !fields_only(&fields, &["id"]) {
154
+                    return None;
155
+                }
153156
                 let id = fields.get("id")?.clone();
154157
                 Some(Self::InspectRequest { id })
155158
             }
156159
             Some("begin") => {
157160
                 let fields = parse_fields(parts)?;
161
+                if !fields_only(&fields, &["id", "sender", "app_id", "parent"]) {
162
+                    return None;
163
+                }
158164
                 let id = fields.get("id")?.clone();
159165
                 let sender = fields.get("sender")?.clone();
160166
                 let app_id = fields.get("app_id").cloned();
@@ -168,6 +174,9 @@ impl ControlRequest {
168174
             }
169175
             Some("transition") => {
170176
                 let fields = parse_fields(parts)?;
177
+                if !fields_only(&fields, &["id", "sender", "state", "app_id"]) {
178
+                    return None;
179
+                }
171180
                 let id = fields.get("id")?.clone();
172181
                 let sender = fields.get("sender")?.clone();
173182
                 let app_id = fields.get("app_id").cloned();
@@ -471,6 +480,12 @@ where
471480
     Some(fields)
472481
 }
473482
 
483
+fn fields_only(fields: &std::collections::HashMap<String, String>, allowed: &[&str]) -> bool {
484
+    fields
485
+        .keys()
486
+        .all(|key| allowed.iter().any(|allowed| key == allowed))
487
+}
488
+
474489
 #[cfg(test)]
475490
 mod tests {
476491
     use super::{
@@ -567,4 +582,10 @@ mod tests {
567582
         let parsed = ControlRequest::parse_line("inspect id=req-1 id=req-2");
568583
         assert_eq!(parsed, None);
569584
     }
585
+
586
+    #[test]
587
+    fn request_parse_rejects_unknown_fields() {
588
+        let parsed = ControlRequest::parse_line("inspect id=req-1 bogus=1");
589
+        assert_eq!(parsed, None);
590
+    }
570591
 }
garwarp/src/daemon.rsmodified
@@ -524,6 +524,35 @@ mod tests {
524524
         );
525525
     }
526526
 
527
+    #[test]
528
+    fn unknown_request_fields_map_to_invalid_request() {
529
+        let (mut client, server) = UnixStream::pair().expect("pair should be created");
530
+        client
531
+            .write_all(b"begin id=req-1 sender=:1.2 bogus=1\n")
532
+            .expect("begin request should be written");
533
+
534
+        let mut state = DaemonState {
535
+            health: HealthStatus::Healthy,
536
+            requests: RequestRegistry::new(Duration::from_secs(5)),
537
+            running: true,
538
+        };
539
+        handle_connection(server, &mut state).expect("request should be handled");
540
+
541
+        let mut response_line = String::new();
542
+        let mut reader = BufReader::new(client);
543
+        reader
544
+            .read_line(&mut response_line)
545
+            .expect("response should be readable");
546
+        let response = ControlResponse::parse_line(&response_line).expect("response should parse");
547
+        assert_eq!(
548
+            response,
549
+            ControlResponse::Error {
550
+                code: 2,
551
+                reason: "invalid_request".to_string(),
552
+            }
553
+        );
554
+    }
555
+
527556
     #[test]
528557
     fn begin_request_tracks_parent_window_context() {
529558
         let (mut client, server) = UnixStream::pair().expect("pair should be created");