/src/suricata7/rust/src/nfs/log.rs
Line | Count | Source |
1 | | /* Copyright (C) 2017-2020 Open Information Security Foundation |
2 | | * |
3 | | * You can copy, redistribute or modify this Program under the terms of |
4 | | * the GNU General Public License version 2 as published by the Free |
5 | | * Software Foundation. |
6 | | * |
7 | | * This program is distributed in the hope that it will be useful, |
8 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | | * GNU General Public License for more details. |
11 | | * |
12 | | * You should have received a copy of the GNU General Public License |
13 | | * version 2 along with this program; if not, write to the Free Software |
14 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
15 | | * 02110-1301, USA. |
16 | | */ |
17 | | |
18 | | use std::string::String; |
19 | | use crate::jsonbuilder::{JsonBuilder, JsonError}; |
20 | | use crate::nfs::types::*; |
21 | | use crate::nfs::nfs::*; |
22 | | use crc::crc32; |
23 | | |
24 | | #[no_mangle] |
25 | 5.61k | pub extern "C" fn rs_nfs_tx_logging_is_filtered(state: &mut NFSState, |
26 | 5.61k | tx: &mut NFSTransaction) |
27 | 5.61k | -> u8 |
28 | | { |
29 | | // TODO probably best to make this configurable |
30 | | |
31 | 5.61k | if state.nfs_version <= 3 && tx.procedure == NFSPROC3_GETATTR { |
32 | 1.11k | return 1; |
33 | 4.49k | } |
34 | | |
35 | 4.49k | return 0; |
36 | 5.61k | } |
37 | | |
38 | 80 | fn nfs_rename_object(tx: &NFSTransaction, js: &mut JsonBuilder) |
39 | 80 | -> Result<(), JsonError> |
40 | | { |
41 | 80 | let from_str = String::from_utf8_lossy(&tx.file_name); |
42 | 80 | js.set_string("from", &from_str)?; |
43 | | |
44 | 80 | let to_vec = match tx.type_data { |
45 | 80 | Some(NFSTransactionTypeData::RENAME(ref x)) => { x.to_vec() }, |
46 | 0 | _ => { Vec::new() } |
47 | | }; |
48 | | |
49 | 80 | let to_str = String::from_utf8_lossy(&to_vec); |
50 | 80 | js.set_string("to", &to_str)?; |
51 | 80 | Ok(()) |
52 | 80 | } |
53 | | |
54 | 6.87k | fn nfs_creds_object(tx: &NFSTransaction, js: &mut JsonBuilder) |
55 | 6.87k | -> Result<(), JsonError> |
56 | | { |
57 | 6.87k | let mach_name = String::from_utf8_lossy(&tx.request_machine_name); |
58 | 6.87k | js.set_string("machine_name", &mach_name)?; |
59 | 6.87k | js.set_uint("uid", tx.request_uid as u64)?; |
60 | 6.87k | js.set_uint("gid", tx.request_gid as u64)?; |
61 | 6.87k | Ok(()) |
62 | 6.87k | } |
63 | | |
64 | 834 | fn nfs_file_object(tx: &NFSTransaction, js: &mut JsonBuilder) |
65 | 834 | -> Result<(), JsonError> |
66 | | { |
67 | 834 | js.set_bool("first", tx.is_first)?; |
68 | 834 | js.set_bool("last", tx.is_last)?; |
69 | | |
70 | 834 | if let Some(NFSTransactionTypeData::FILE(ref tdf)) = tx.type_data { |
71 | 834 | js.set_uint("last_xid", tdf.file_last_xid as u64)?; |
72 | 834 | js.set_uint("chunks", tdf.chunk_count as u64)?; |
73 | 0 | } |
74 | 834 | Ok(()) |
75 | 834 | } |
76 | | /* |
77 | | fn nfs_handle2hex(bytes: &Vec<u8>) -> String { |
78 | | let strings: Vec<String> = bytes.iter() |
79 | | .map(|b| format!("{:02x}", b)) |
80 | | .collect(); |
81 | | strings.join("") |
82 | | } |
83 | | */ |
84 | 2.81k | fn nfs_handle2crc(bytes: &[u8]) -> u32 { |
85 | 2.81k | let c = crc32::checksum_ieee(bytes); |
86 | 2.81k | c |
87 | 2.81k | } |
88 | | |
89 | 7.37k | fn nfs_common_header(state: &NFSState, tx: &NFSTransaction, js: &mut JsonBuilder) |
90 | 7.37k | -> Result<(), JsonError> |
91 | | { |
92 | 7.37k | js.set_uint("version", state.nfs_version as u64)?; |
93 | 7.37k | let proc_string = if state.nfs_version < 4 { |
94 | 7.35k | nfs3_procedure_string(tx.procedure) |
95 | | } else { |
96 | 17 | nfs4_procedure_string(tx.procedure) |
97 | | }; |
98 | 7.37k | js.set_string("procedure", &proc_string)?; |
99 | 7.37k | let file_name = String::from_utf8_lossy(&tx.file_name); |
100 | 7.37k | js.set_string("filename", &file_name)?; |
101 | | |
102 | 7.37k | if !tx.file_handle.is_empty() { |
103 | | //js.set_string("handle", &nfs_handle2hex(&tx.file_handle)); |
104 | 2.81k | let c = nfs_handle2crc(&tx.file_handle); |
105 | 2.81k | let s = format!("{:x}", c); |
106 | 2.81k | js.set_string("hhash", &s)?; |
107 | 4.55k | } |
108 | 7.37k | js.set_uint("id", tx.id)?; |
109 | 7.37k | js.set_bool("file_tx", tx.is_file_tx)?; |
110 | 7.37k | Ok(()) |
111 | 7.37k | } |
112 | | |
113 | 0 | fn nfs_log_request(state: &NFSState, tx: &NFSTransaction, js: &mut JsonBuilder) |
114 | 0 | -> Result<(), JsonError> |
115 | | { |
116 | 0 | nfs_common_header(state, tx, js)?; |
117 | 0 | js.set_string("type", "request")?; |
118 | 0 | Ok(()) |
119 | 0 | } |
120 | | |
121 | | #[no_mangle] |
122 | 0 | pub extern "C" fn rs_nfs_log_json_request(state: &mut NFSState, tx: &mut NFSTransaction, |
123 | 0 | js: &mut JsonBuilder) -> bool |
124 | | { |
125 | 0 | nfs_log_request(state, tx, js).is_ok() |
126 | 0 | } |
127 | | |
128 | 7.37k | fn nfs_log_response(state: &NFSState, tx: &NFSTransaction, js: &mut JsonBuilder) |
129 | 7.37k | -> Result<(), JsonError> |
130 | | { |
131 | 7.37k | nfs_common_header(state, tx, js)?; |
132 | 7.37k | js.set_string("type", "response")?; |
133 | | |
134 | 7.37k | js.set_string("status", &nfs3_status_string(tx.nfs_response_status))?; |
135 | | |
136 | 7.37k | if state.nfs_version <= 3 { |
137 | 7.35k | if tx.procedure == NFSPROC3_READ { |
138 | 770 | js.open_object("read")?; |
139 | 770 | nfs_file_object(tx, js)?; |
140 | 770 | js.close()?; |
141 | 6.58k | } else if tx.procedure == NFSPROC3_WRITE { |
142 | 64 | js.open_object("write")?; |
143 | 64 | nfs_file_object(tx, js)?; |
144 | 64 | js.close()?; |
145 | 6.52k | } else if tx.procedure == NFSPROC3_RENAME { |
146 | 80 | js.open_object("rename")?; |
147 | 80 | nfs_rename_object(tx, js)?; |
148 | 80 | js.close()?; |
149 | 6.44k | } |
150 | 17 | } |
151 | 7.37k | Ok(()) |
152 | 7.37k | } |
153 | | |
154 | | #[no_mangle] |
155 | 7.37k | pub extern "C" fn rs_nfs_log_json_response(state: &mut NFSState, tx: &mut NFSTransaction, |
156 | 7.37k | js: &mut JsonBuilder) -> bool |
157 | | { |
158 | 7.37k | nfs_log_response(state, tx, js).is_ok() |
159 | 7.37k | } |
160 | | |
161 | 7.37k | fn rpc_log_response(tx: &NFSTransaction, js: &mut JsonBuilder) |
162 | 7.37k | -> Result<(), JsonError> |
163 | | { |
164 | 7.37k | js.set_uint("xid", tx.xid as u64)?; |
165 | 7.37k | js.set_string("status", &rpc_status_string(tx.rpc_response_status))?; |
166 | 7.37k | js.set_string("auth_type", &rpc_auth_type_string(tx.auth_type))?; |
167 | 7.37k | if tx.auth_type == RPCAUTH_UNIX { |
168 | 6.87k | js.open_object("creds")?; |
169 | 6.87k | nfs_creds_object(tx, js)?; |
170 | 6.87k | js.close()?; |
171 | 498 | } |
172 | 7.37k | Ok(()) |
173 | 7.37k | } |
174 | | |
175 | | #[no_mangle] |
176 | 7.37k | pub extern "C" fn rs_rpc_log_json_response(tx: &mut NFSTransaction, |
177 | 7.37k | js: &mut JsonBuilder) -> bool |
178 | | { |
179 | 7.37k | rpc_log_response(tx, js).is_ok() |
180 | 7.37k | } |