]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
nfs: log more rpc
authorVictor Julien <victor@inliniac.net>
Wed, 14 Jun 2017 10:41:49 +0000 (12:41 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 16 Jun 2017 11:11:36 +0000 (13:11 +0200)
rust/src/nfs/log.rs
rust/src/nfs/nfs3.rs
rust/src/nfs/rpc_records.rs
rust/src/nfs/types.rs
src/output-json-nfs3.c

index fd8335e8c361b9d36ef0f86dbcc289c4fee494e5..28e5a9249fd0459103ddd1a2e4259db98fb568a3 100644 (file)
@@ -80,7 +80,6 @@ fn nfs3_file_object(tx: &NFS3Transaction) -> Json
 fn nfs3_common_header(tx: &NFS3Transaction) -> Json
 {
     let js = Json::object();
-    js.set_integer("xid", tx.xid as u64);
     js.set_string("procedure", &nfs3_procedure_string(tx.procedure));
     let file_name = String::from_utf8_lossy(&tx.file_name);
     js.set_string("filename", &file_name);
@@ -103,12 +102,7 @@ pub extern "C" fn rs_nfs3_log_json_response(tx: &mut NFS3Transaction) -> *mut Js
     let js = nfs3_common_header(tx);
     js.set_string("type", "response");
 
-    js.set_string("status", &nfs3_status_string(tx.response_status));
-
-    if tx.has_creds {
-        let creds_js = nfs3_creds_object(tx);
-        js.set("creds", creds_js);
-    }
+    js.set_string("status", &nfs3_status_string(tx.nfs_response_status));
 
     if tx.procedure == NFSPROC3_READ {
         let read_js = nfs3_file_object(tx);
@@ -123,3 +117,19 @@ pub extern "C" fn rs_nfs3_log_json_response(tx: &mut NFS3Transaction) -> *mut Js
 
     return js.unwrap();
 }
+
+
+#[no_mangle]
+pub extern "C" fn rs_rpc_log_json_response(tx: &mut NFS3Transaction) -> *mut JsonT
+{
+    let js = Json::object();
+    js.set_integer("xid", tx.xid as u64);
+    js.set_string("status", &rpc_status_string(tx.rpc_response_status));
+    js.set_string("auth_type", &rpc_auth_type_string(tx.auth_type));
+    if tx.auth_type == RPCAUTH_UNIX {
+        let creds_js = nfs3_creds_object(tx);
+        js.set("creds", creds_js);
+    }
+
+    return js.unwrap();
+}
index edfc719d49f98d97840622fde4705cee3d2dc036..de5be914b6c154a77b43f9b752c73ca8fe372e2a 100644 (file)
@@ -132,13 +132,14 @@ pub struct NFS3Transaction {
     /// this is the 'from' or original name.
     pub file_name: Vec<u8>,
 
+    pub auth_type: u32,
     pub request_machine_name: Vec<u8>,
     pub request_uid: u32,
     pub request_gid: u32,
 
-    pub response_status: u32,
+    pub rpc_response_status: u32,
+    pub nfs_response_status: u32,
 
-    pub has_creds: bool,
     pub is_first: bool,
     pub is_last: bool,
 
@@ -174,8 +175,9 @@ impl NFS3Transaction {
             request_machine_name:Vec::new(),
             request_uid:0,
             request_gid:0,
-            response_status:0,
-            has_creds: false,
+            rpc_response_status:0,
+            nfs_response_status:0,
+            auth_type: 0,
             is_first: false,
             is_last: false,
             request_done: false,
@@ -399,12 +401,13 @@ impl NFS3State {
     }
 
     // TODO maybe not enough users to justify a func
-    fn mark_response_tx_done(&mut self, xid: u32, status: u32)
+    fn mark_response_tx_done(&mut self, xid: u32, rpc_status: u32, nfs_status: u32)
     {
         match self.get_tx_by_xid(xid) {
             Some(mut mytx) => {
                 mytx.response_done = true;
-                mytx.response_status = status;
+                mytx.rpc_response_status = rpc_status;
+                mytx.nfs_response_status = nfs_status;
 
                 SCLogDebug!("process_reply_record: tx ID {} XID {} REQUEST {} RESPONSE {}",
                         mytx.id, mytx.xid, mytx.request_done, mytx.response_done);
@@ -577,12 +580,12 @@ impl NFS3State {
                 tx.type_data = Some(NFS3TransactionTypeData::RENAME(aux_file_name));
             }
 
+            tx.auth_type = r.creds_flavor;
             match &r.creds_unix {
                 &Some(ref u) => {
                     tx.request_machine_name = u.machine_name_buf.to_vec();
                     tx.request_uid = u.uid;
                     tx.request_gid = u.gid;
-                    tx.has_creds = true;
                 },
                 _ => { },
             }
@@ -639,12 +642,12 @@ impl NFS3State {
                 tx.type_data = Some(NFS3TransactionTypeData::RENAME(aux_file_name));
             }
 
+            tx.auth_type = r.creds_flavor;
             match &r.creds_unix {
                 &Some(ref u) => {
                     tx.request_machine_name = u.machine_name_buf.to_vec();
                     tx.request_uid = u.uid;
                     tx.request_gid = u.gid;
-                    tx.has_creds = true;
                 },
                 _ => { },
             }
@@ -781,7 +784,7 @@ impl NFS3State {
     }
 
     fn process_reply_record_v3<'b>(&mut self, r: &RpcReplyPacket<'b>, xidmap: &mut NFS3RequestXidMap) -> u32 {
-        let status;
+        let nfs_status;
 
         if xidmap.procedure == NFSPROC3_LOOKUP {
             match parse_nfs3_response_lookup(r.prog_data) {
@@ -789,7 +792,7 @@ impl NFS3State {
                     SCLogDebug!("LOOKUP: {:?}", lookup);
                     SCLogDebug!("RESPONSE LOOKUP file_name {:?}", xidmap.file_name);
 
-                    status = lookup.status;
+                    nfs_status = lookup.status;
 
                     SCLogDebug!("LOOKUP handle {:?}", lookup.handle);
                     self.namemap.insert(lookup.handle.value.to_vec(), xidmap.file_name.to_vec());
@@ -803,7 +806,7 @@ impl NFS3State {
                     SCLogDebug!("nfs3_create_record: {:?}", nfs3_create_record);
 
                     SCLogDebug!("RESPONSE CREATE file_name {:?}", xidmap.file_name);
-                    status = nfs3_create_record.status;
+                    nfs_status = nfs3_create_record.status;
 
                     match nfs3_create_record.handle {
                         Some(h) => {
@@ -821,7 +824,7 @@ impl NFS3State {
             match parse_nfs3_reply_read(r.prog_data) {
                 IResult::Done(_, ref reply) => {
                     self.process_read_record(r, reply, Some(&xidmap));
-                    status = reply.status;
+                    nfs_status = reply.status;
                 },
                 IResult::Incomplete(_) => { panic!("Incomplete!"); },
                 IResult::Error(e) => { panic!("Parsing failed: {:?}",e); },
@@ -831,7 +834,7 @@ impl NFS3State {
                 IResult::Done(_, ref reply) => {
                     //SCLogDebug!("READDIRPLUS reply {:?}", reply);
 
-                    status = reply.status;
+                    nfs_status = reply.status;
 
                     // cut off final eof field
                     let d = &reply.data[..reply.data.len()-4 as usize];
@@ -874,27 +877,27 @@ impl NFS3State {
                 }
                 _ => 0 as u32
             };
-            status = stat;
+            nfs_status = stat;
         }
         SCLogDebug!("REPLY {} to procedure {} blob size {}",
                 r.hdr.xid, xidmap.procedure, r.prog_data.len());
 
         if xidmap.procedure != NFSPROC3_READ {
-            self.mark_response_tx_done(r.hdr.xid, status);
+            self.mark_response_tx_done(r.hdr.xid, r.reply_state, nfs_status);
         }
 
         0
     }
 
     fn process_reply_record_v2<'b>(&mut self, r: &RpcReplyPacket<'b>, xidmap: &NFS3RequestXidMap) -> u32 {
-        let status;
+        let nfs_status;
 
         if xidmap.procedure == NFSPROC3_READ {
             match parse_nfs2_reply_read(r.prog_data) {
                 IResult::Done(_, ref reply) => {
                     SCLogDebug!("NFSv2 READ reply record");
                     self.process_read_record(r, reply, Some(&xidmap));
-                    status = reply.status;
+                    nfs_status = reply.status;
                 },
                 IResult::Incomplete(_) => { panic!("Incomplete!"); },
                 IResult::Error(e) => { panic!("Parsing failed: {:?}",e); },
@@ -906,12 +909,12 @@ impl NFS3State {
                 }
                 _ => 0 as u32
             };
-            status = stat;
+            nfs_status = stat;
         }
         SCLogDebug!("REPLY {} to procedure {} blob size {}",
                 r.hdr.xid, xidmap.procedure, r.prog_data.len());
 
-        self.mark_response_tx_done(r.hdr.xid, status);
+        self.mark_response_tx_done(r.hdr.xid, r.reply_state, nfs_status);
 
         0
     }
@@ -1102,7 +1105,8 @@ impl NFS3State {
                         reply.count, fill_bytes as u8, reply.eof, &r.hdr.xid);
                 if is_last {
                     tdf.file_last_xid = r.hdr.xid;
-                    tx.response_status = reply.status;
+                    tx.rpc_response_status = r.reply_state;
+                    tx.nfs_response_status = reply.status;
                     tx.is_last = true;
                     tx.response_done = true;
                 }
@@ -1124,7 +1128,8 @@ impl NFS3State {
             tx.is_first = true;
             if is_last {
                 tdf.file_last_xid = r.hdr.xid;
-                tx.response_status = reply.status;
+                tx.rpc_response_status = r.reply_state;
+                tx.nfs_response_status = reply.status;
                 tx.is_last = true;
                 tx.response_done = true;
             }
index 361d5c0de0bcc5c5071551bf2309eba22acd22b0..d1958f6a48c02f8830f3cac1d59bc2c835dc8514 100644 (file)
@@ -17,7 +17,7 @@
 
 //! Nom parsers for RPC & NFSv3
 
-use nom::{be_u32, be_u64, rest};
+use nom::{be_u32, rest};
 
 #[derive(Debug,PartialEq)]
 pub struct RpcRequestCredsUnix<'a> {
index 9e8c00ec589673c9daf2a756b6145c89e49af709..b0a0f88db96aeb96bacc1a9860faad048cf64105 100644 (file)
@@ -136,3 +136,91 @@ pub fn nfs3_status_string(status: u32) -> String {
         },
     }.to_string()
 }
+
+pub const RPCMSG_ACCEPTED:  u32 = 0;
+pub const RPCMSG_DENIED:    u32 = 1;
+
+pub fn rpc_status_string(status: u32) -> String {
+    match status {
+        RPCMSG_ACCEPTED => "ACCEPTED",
+        RPCMSG_DENIED   => "DENIED",
+        _ => {
+            return (status).to_string();
+        },
+    }.to_string()
+}
+
+/* http://www.iana.org/assignments/rpc-authentication-numbers/rpc-authentication-numbers.xhtml */
+/* RFC 1057 Section 7.2 */
+/* RFC 2203 Section 3 */
+
+pub const RPCAUTH_NULL:         u32 = 0;
+pub const RPCAUTH_UNIX:         u32 = 1;
+pub const RPCAUTH_SHORT:        u32 = 2;
+pub const RPCAUTH_DH:           u32 = 3;
+pub const RPCAUTH_KERB:         u32 = 4;
+pub const RPCAUTH_RSA:          u32 = 5;
+pub const RPCAUTH_GSS:          u32 = 6;
+
+pub fn rpc_auth_type_string(auth_type: u32) -> String {
+    match auth_type {
+        RPCAUTH_NULL    => "NULL",
+        RPCAUTH_UNIX    => "UNIX",
+        RPCAUTH_SHORT   => "SHORT",
+        RPCAUTH_DH      => "DH",
+        RPCAUTH_KERB    => "KERB",
+        RPCAUTH_RSA     => "RSA",
+        RPCAUTH_GSS     => "GSS",
+        _ => {
+            return (auth_type).to_string();
+        },
+    }.to_string()
+}
+
+/* http://www.iana.org/assignments/rpc-authentication-numbers/rpc-authentication-numbers.xhtml */
+pub const RPCAUTH_OK:                   u32 = 0;  // success/failed at remote end    [RFC5531]
+pub const RPCAUTH_BADCRED:              u32 = 1;  // bad credential (seal broken)    [RFC5531]
+pub const RPCAUTH_REJECTEDCRED:         u32 = 2;  // client must begin new session   [RFC5531]
+pub const RPCAUTH_BADVERF:              u32 = 3;  // bad verifier (seal broken)  [RFC5531]
+pub const RPCAUTH_REJECTEDVERF:         u32 = 4;  // verifier expired or replayed    [RFC5531]
+pub const RPCAUTH_TOOWEAK:              u32 = 5;  // rejected for security reasons/failed locally    [RFC5531]
+pub const RPCAUTH_INVALIDRESP:          u32 = 6;  // bogus response verifier     [RFC5531]
+pub const RPCAUTH_FAILED:               u32 = 7;  // reason unknown/AUTH_KERB errors; deprecated. See [RFC2695]  [RFC5531]
+pub const RPCAUTH_KERB_GENERIC:         u32 = 8;  // kerberos generic error  [RFC5531]
+pub const RPCAUTH_TIMEEXPIRE:           u32 = 9;  // time of credential expired  [RFC5531]
+pub const RPCAUTH_TKT_FILE:             u32 = 10; // problem with ticket file    [RFC5531]
+pub const RPCAUTH_DECODE:               u32 = 11; // can't decode authenticator  [RFC5531]
+pub const RPCAUTH_NET_ADDR:             u32 = 12; // wrong net address in ticket/RPCSEC_GSS GSS related errors   [RFC5531]
+pub const RPCSEC_GSS_CREDPROBLEM:       u32 = 13; // no credentials for user     [RFC5531]
+pub const RPCSEC_GSS_CTXPROBLEM:        u32 = 14; // problem with context    [RFC5531]
+pub const RPCSEC_GSS_INNER_CREDPROBLEM: u32 = 15; // No credentials for multi-principal assertion inner context user     [RFC7861]
+pub const RPCSEC_GSS_LABEL_PROBLEM:     u32 = 16; // Problem with label assertion    [RFC7861]
+pub const RPCSEC_GSS_PRIVILEGE_PROBLEM: u32 = 17; // Problem with structured privilege assertion     [RFC7861]
+pub const RPCSEC_GSS_UNKNOWN_MESSAGE:   u32 = 18; // Unknown structured privilege assertion  [RFC7861]
+
+pub fn rpc_auth_status_string(auth_status: u32) -> String {
+    match auth_status {
+        RPCAUTH_OK                      => "OK",
+        RPCAUTH_BADCRED                 => "BADCRED",
+        RPCAUTH_REJECTEDCRED            => "REJECTEDCRED",
+        RPCAUTH_BADVERF                 => "BADVERF",
+        RPCAUTH_REJECTEDVERF            => "REJECTEDVERF",
+        RPCAUTH_TOOWEAK                 => "TOOWEAK",
+        RPCAUTH_INVALIDRESP             => "NVALIDRESP",
+        RPCAUTH_FAILED                  => "FAILED",
+        RPCAUTH_KERB_GENERIC            => "KERB_GENERIC",
+        RPCAUTH_TIMEEXPIRE              => "TIMEEXPIRE",
+        RPCAUTH_TKT_FILE                => "TKT_FILE",
+        RPCAUTH_DECODE                  => "DECODE",
+        RPCAUTH_NET_ADDR                => "NET_ADDR",
+        RPCSEC_GSS_CREDPROBLEM          => "GSS_CREDPROBLEM",
+        RPCSEC_GSS_CTXPROBLEM           => "GSS_CTXPROBLEM",
+        RPCSEC_GSS_INNER_CREDPROBLEM    => "GSS_INNER_CREDPROBLEM",
+        RPCSEC_GSS_LABEL_PROBLEM        => "GSS_LABEL_PROBLEM",
+        RPCSEC_GSS_PRIVILEGE_PROBLEM    => "GSS_PRIVILEGE_PROBLEM",
+        RPCSEC_GSS_UNKNOWN_MESSAGE      => "GSS_UNKNOWN_MESSAGE",
+        _ => {
+            return (auth_status).to_string();
+        },
+    }.to_string()
+}
index c2d5d04ac5c25df8f0703d1cd340fcb9746cacc3..52eb711687c1ca55c8da2bb3a5916cb35d2f0223 100644 (file)
@@ -84,11 +84,16 @@ static int JsonNFS3Logger(ThreadVars *tv, void *thread_data,
         return TM_ECODE_FAILED;
     }
 
+    json_t *rpcjs = rs_rpc_log_json_response(tx);
+    if (unlikely(rpcjs == NULL)) {
+        goto error;
+    }
+    json_object_set_new(js, "rpc", rpcjs);
+
     nfs3js = rs_nfs3_log_json_response(tx);
     if (unlikely(nfs3js == NULL)) {
         goto error;
     }
-
     json_object_set_new(js, "nfs3", nfs3js);
 
     MemBufferReset(thread->buffer);