]> git.ipfire.org Git - people/ms/suricata.git/blame - rust/src/rfb/rfb.rs
krb5: support AppLayerTxData
[people/ms/suricata.git] / rust / src / rfb / rfb.rs
CommitLineData
1c8943de
FH
1/* Copyright (C) 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// Author: Frank Honza <frank.honza@dcso.de>
19
20use std;
21use std::ffi::CString;
22use std::mem::transmute;
23use crate::core::{self, ALPROTO_UNKNOWN, AppProto, Flow, IPPROTO_TCP};
24use crate::log::*;
25use crate::applayer;
26use crate::applayer::*;
27use nom;
28use super::parser;
29
30static mut ALPROTO_RFB: AppProto = ALPROTO_UNKNOWN;
31
32pub struct RFBTransaction {
33 tx_id: u64,
34 pub complete: bool,
35 pub chosen_security_type: Option<u32>,
36
37 pub tc_server_protocol_version: Option<parser::ProtocolVersion>,
38 pub ts_client_protocol_version: Option<parser::ProtocolVersion>,
39 pub tc_supported_security_types: Option<parser::SupportedSecurityTypes>,
40 pub ts_security_type_selection: Option<parser::SecurityTypeSelection>,
41 pub tc_server_security_type: Option<parser::ServerSecurityType>,
42 pub tc_vnc_challenge: Option<parser::VncAuth>,
43 pub ts_vnc_response: Option<parser::VncAuth>,
44 pub ts_client_init: Option<parser::ClientInit>,
45 pub tc_security_result: Option<parser::SecurityResult>,
46 pub tc_failure_reason: Option<parser::FailureReason>,
47 pub tc_server_init: Option<parser::ServerInit>,
48
49 logged: LoggerFlags,
50 de_state: Option<*mut core::DetectEngineState>,
51 events: *mut core::AppLayerDecoderEvents,
52 detect_flags: applayer::TxDetectFlags,
53}
54
55impl RFBTransaction {
56 pub fn new() -> RFBTransaction {
57 RFBTransaction {
58 tx_id: 0,
59 complete: false,
60 chosen_security_type: None,
61
62 tc_server_protocol_version: None,
63 ts_client_protocol_version: None,
64 tc_supported_security_types: None,
65 ts_security_type_selection: None,
66 tc_server_security_type: None,
67 tc_vnc_challenge: None,
68 ts_vnc_response: None,
69 ts_client_init: None,
70 tc_security_result: None,
71 tc_failure_reason: None,
72 tc_server_init: None,
73
74 logged: LoggerFlags::new(),
75 de_state: None,
76 events: std::ptr::null_mut(),
77 detect_flags: applayer::TxDetectFlags::default(),
78 }
79 }
80
81 pub fn free(&mut self) {
82 if self.events != std::ptr::null_mut() {
83 core::sc_app_layer_decoder_events_free_events(&mut self.events);
84 }
85 if let Some(state) = self.de_state {
86 core::sc_detect_engine_state_free(state);
87 }
88 }
89}
90
91impl Drop for RFBTransaction {
92 fn drop(&mut self) {
93 self.free();
94 }
95}
96
97pub struct RFBState {
98 tx_id: u64,
99 transactions: Vec<RFBTransaction>,
100 state: parser::RFBGlobalState
101}
102
103impl RFBState {
104 pub fn new() -> Self {
105 Self {
106 tx_id: 0,
107 transactions: Vec::new(),
108 state: parser::RFBGlobalState::TCServerProtocolVersion
109 }
110 }
111
112 // Free a transaction by ID.
113 fn free_tx(&mut self, tx_id: u64) {
114 let len = self.transactions.len();
115 let mut found = false;
116 let mut index = 0;
117 for i in 0..len {
118 let tx = &self.transactions[i];
119 if tx.tx_id == tx_id + 1 {
120 found = true;
121 index = i;
122 break;
123 }
124 }
125 if found {
126 self.transactions.remove(index);
127 }
128 }
129
130 pub fn get_tx(&mut self, tx_id: u64) -> Option<&RFBTransaction> {
131 for tx in &mut self.transactions {
132 if tx.tx_id == tx_id + 1 {
133 return Some(tx);
134 }
135 }
136 return None;
137 }
138
139 fn new_tx(&mut self) -> RFBTransaction {
140 let mut tx = RFBTransaction::new();
141 self.tx_id += 1;
142 tx.tx_id = self.tx_id;
143 return tx;
144 }
145
146 fn get_current_tx(&mut self) -> Option<&mut RFBTransaction> {
147 for tx in &mut self.transactions {
148 if tx.tx_id == self.tx_id {
149 return Some(tx);
150 }
151 }
152 return None;
153 }
154
155 fn parse_request(&mut self, input: &[u8]) -> AppLayerResult {
156 // We're not interested in empty requests.
157 if input.len() == 0 {
158 return AppLayerResult::ok();
159 }
160
161 let mut current = input;
bbe9137f 162 let mut consumed = 0;
1c8943de
FH
163 SCLogDebug!("request_state {}, input_len {}", self.state, input.len());
164 loop {
165 if current.len() == 0 {
166 return AppLayerResult::ok();
167 }
168 match self.state {
169 parser::RFBGlobalState::TSClientProtocolVersion => {
170 match parser::parse_protocol_version(current) {
171 Ok((rem, request)) => {
bbe9137f 172 consumed += current.len() - rem.len();
1c8943de 173 current = rem;
bbe9137f 174
1c8943de
FH
175 if request.major == "003" && request.minor == "003" {
176 // in version 3.3 the server decided security type
177 self.state = parser::RFBGlobalState::TCServerSecurityType;
178 } else {
179 self.state = parser::RFBGlobalState::TCSupportedSecurityTypes;
180 }
181
26123e05
SS
182 if let Some(current_transaction) = self.get_current_tx() {
183 current_transaction.ts_client_protocol_version = Some(request);
184 } else {
185 return AppLayerResult::err();
1c8943de
FH
186 }
187 }
bbe9137f 188 Err(nom::Err::Incomplete(_)) => {
189 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
190 }
191 Err(_) => {
192 return AppLayerResult::err();
193 }
194 }
195 }
196 parser::RFBGlobalState::TSSecurityTypeSelection => {
197 match parser::parse_security_type_selection(current) {
198 Ok((rem, request)) => {
bbe9137f 199 consumed += current.len() - rem.len();
1c8943de
FH
200 current = rem;
201
202 let chosen_security_type = request.security_type;
203 match chosen_security_type {
204 2 => self.state = parser::RFBGlobalState::TCVncChallenge,
205 1 => self.state = parser::RFBGlobalState::TSClientInit,
206 _ => return AppLayerResult::err(),
207 }
208
26123e05
SS
209 if let Some(current_transaction) = self.get_current_tx() {
210 current_transaction.ts_security_type_selection = Some(request);
211 current_transaction.chosen_security_type = Some(chosen_security_type as u32);
212 } else {
213 return AppLayerResult::err();
1c8943de
FH
214 }
215 }
bbe9137f 216 Err(nom::Err::Incomplete(_)) => {
217 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
218 }
219 Err(_) => {
220 return AppLayerResult::err();
221 }
222 }
223 }
224 parser::RFBGlobalState::TSVncResponse => {
225 match parser::parse_vnc_auth(current) {
226 Ok((rem, request)) => {
bbe9137f 227 consumed += current.len() - rem.len();
1c8943de
FH
228 current = rem;
229
230 self.state = parser::RFBGlobalState::TCSecurityResult;
231
26123e05
SS
232 if let Some(current_transaction) = self.get_current_tx() {
233 current_transaction.ts_vnc_response = Some(request);
234 } else {
235 return AppLayerResult::err();
1c8943de
FH
236 }
237 }
bbe9137f 238 Err(nom::Err::Incomplete(_)) => {
239 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
240 }
241 Err(_) => {
242 return AppLayerResult::err();
243 }
244 }
245 }
246 parser::RFBGlobalState::TSClientInit => {
247 match parser::parse_client_init(current) {
248 Ok((rem, request)) => {
bbe9137f 249 consumed += current.len() - rem.len();
1c8943de 250 current = rem;
bbe9137f 251
1c8943de
FH
252 self.state = parser::RFBGlobalState::TCServerInit;
253
26123e05
SS
254 if let Some(current_transaction) = self.get_current_tx() {
255 current_transaction.ts_client_init = Some(request);
256 } else {
257 return AppLayerResult::err();
1c8943de
FH
258 }
259 }
bbe9137f 260 Err(nom::Err::Incomplete(_)) => {
261 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
262 }
263 Err(_) => {
264 return AppLayerResult::err();
265 }
266 }
267 }
268 parser::RFBGlobalState::Message => {
269 //todo implement RFB messages, for now we stop here
270 return AppLayerResult::err();
271 }
272 parser::RFBGlobalState::TCServerProtocolVersion => {
273 SCLogDebug!("Reversed traffic, expected response.");
274 return AppLayerResult::err();
275 }
276 _ => {
277 SCLogDebug!("Invalid state for request {}", self.state);
278 current = b"";
279 }
280 }
281 }
282 }
283
284 fn parse_response(&mut self, input: &[u8]) -> AppLayerResult {
285 // We're not interested in empty responses.
286 if input.len() == 0 {
287 return AppLayerResult::ok();
288 }
289
290 let mut current = input;
bbe9137f 291 let mut consumed = 0;
1c8943de
FH
292 SCLogDebug!("response_state {}, response_len {}", self.state, input.len());
293 loop {
294 if current.len() == 0 {
295 return AppLayerResult::ok();
296 }
297 match self.state {
298 parser::RFBGlobalState::TCServerProtocolVersion => {
299 match parser::parse_protocol_version(current) {
300 Ok((rem, request)) => {
bbe9137f 301 consumed += current.len() - rem.len();
1c8943de 302 current = rem;
bbe9137f 303
1c8943de
FH
304 self.state = parser::RFBGlobalState::TSClientProtocolVersion;
305 let tx = self.new_tx();
306 self.transactions.push(tx);
307
26123e05
SS
308 if let Some(current_transaction) = self.get_current_tx() {
309 current_transaction.tc_server_protocol_version = Some(request);
310 } else {
311 return AppLayerResult::err();
1c8943de
FH
312 }
313 }
bbe9137f 314 Err(nom::Err::Incomplete(_)) => {
315 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
316 }
317 Err(_) => {
318 return AppLayerResult::err();
319 }
320 }
321 }
322 parser::RFBGlobalState::TCSupportedSecurityTypes => {
323 match parser::parse_supported_security_types(current) {
324 Ok((rem, request)) => {
bbe9137f 325 consumed += current.len() - rem.len();
1c8943de 326 current = rem;
bbe9137f 327
1c8943de
FH
328 SCLogDebug!(
329 "supported_security_types: {}, types: {}", request.number_of_types,
330 request.types.iter().map(ToString::to_string).map(|v| v + " ").collect::<String>()
331 );
332
333 self.state = parser::RFBGlobalState::TSSecurityTypeSelection;
334 if request.number_of_types == 0 {
335 self.state = parser::RFBGlobalState::TCFailureReason;
336 }
337
26123e05
SS
338 if let Some(current_transaction) = self.get_current_tx() {
339 current_transaction.tc_supported_security_types = Some(request);
340 } else {
341 return AppLayerResult::err();
1c8943de
FH
342 }
343 }
bbe9137f 344 Err(nom::Err::Incomplete(_)) => {
345 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
346 }
347 Err(_) => {
348 return AppLayerResult::err();
349 }
350 }
351 }
352 parser::RFBGlobalState::TCServerSecurityType => {
353 // In RFB 3.3, the server decides the authentication type
354 match parser::parse_server_security_type(current) {
355 Ok((rem, request)) => {
bbe9137f 356 consumed += current.len() - rem.len();
1c8943de 357 current = rem;
bbe9137f 358
1c8943de
FH
359 let chosen_security_type = request.security_type;
360 SCLogDebug!("chosen_security_type: {}", chosen_security_type);
361 match chosen_security_type {
362 0 => self.state = parser::RFBGlobalState::TCFailureReason,
363 1 => self.state = parser::RFBGlobalState::TSClientInit,
364 2 => self.state = parser::RFBGlobalState::TCVncChallenge,
365 _ => {
366 // TODO Event unknown security type
367 return AppLayerResult::err();
368 }
369 }
370
26123e05
SS
371 if let Some(current_transaction) = self.get_current_tx() {
372 current_transaction.tc_server_security_type = Some(request);
373 current_transaction.chosen_security_type = Some(chosen_security_type);
374 } else {
375 return AppLayerResult::err();
1c8943de
FH
376 }
377 }
bbe9137f 378 Err(nom::Err::Incomplete(_)) => {
379 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
380 }
381 Err(_) => {
382 return AppLayerResult::err();
383 }
384 }
385 }
386 parser::RFBGlobalState::TCVncChallenge => {
387 match parser::parse_vnc_auth(current) {
388 Ok((rem, request)) => {
bbe9137f 389 consumed += current.len() - rem.len();
1c8943de
FH
390 current = rem;
391
392 self.state = parser::RFBGlobalState::TSVncResponse;
393
26123e05
SS
394 if let Some(current_transaction) = self.get_current_tx() {
395 current_transaction.tc_vnc_challenge = Some(request);
396 } else {
397 return AppLayerResult::err();
1c8943de
FH
398 }
399 }
bbe9137f 400 Err(nom::Err::Incomplete(_)) => {
401 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
402 }
403 Err(_) => {
404 return AppLayerResult::err();
405 }
406 }
407 }
408 parser::RFBGlobalState::TCSecurityResult => {
409 match parser::parse_security_result(current) {
410 Ok((rem, request)) => {
bbe9137f 411 consumed += current.len() - rem.len();
1c8943de
FH
412 current = rem;
413
414 if request.status == 0 {
415 self.state = parser::RFBGlobalState::TSClientInit;
416
26123e05
SS
417 if let Some(current_transaction) = self.get_current_tx() {
418 current_transaction.tc_security_result = Some(request);
419 } else {
420 return AppLayerResult::err();
1c8943de
FH
421 }
422 } else if request.status == 1 {
423 self.state = parser::RFBGlobalState::TCFailureReason;
424 } else {
425 // TODO: Event: unknown security result value
426 }
427 }
bbe9137f 428 Err(nom::Err::Incomplete(_)) => {
429 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
430 }
431 Err(_) => {
432 return AppLayerResult::err();
433 }
434 }
435 }
436 parser::RFBGlobalState::TCFailureReason => {
437 match parser::parse_failure_reason(current) {
438 Ok((_rem, request)) => {
26123e05
SS
439 if let Some(current_transaction) = self.get_current_tx() {
440 current_transaction.tc_failure_reason = Some(request);
441 } else {
442 return AppLayerResult::err();
1c8943de
FH
443 }
444 return AppLayerResult::err();
445 }
bbe9137f 446 Err(nom::Err::Incomplete(_)) => {
447 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
448 }
449 Err(_) => {
450 return AppLayerResult::err();
451 }
452 }
453 }
454 parser::RFBGlobalState::TCServerInit => {
455 match parser::parse_server_init(current) {
456 Ok((rem, request)) => {
bbe9137f 457 consumed += current.len() - rem.len();
1c8943de 458 current = rem;
bbe9137f 459
1c8943de
FH
460 self.state = parser::RFBGlobalState::Message;
461
26123e05
SS
462 if let Some(current_transaction) = self.get_current_tx() {
463 current_transaction.tc_server_init = Some(request);
464 // connection initialization is complete and parsed
465 current_transaction.complete = true;
466 } else {
467 return AppLayerResult::err();
1c8943de
FH
468 }
469 }
bbe9137f 470 Err(nom::Err::Incomplete(_)) => {
471 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
1c8943de
FH
472 }
473 Err(_) => {
474 return AppLayerResult::err();
475 }
476 }
477 }
478 parser::RFBGlobalState::Message => {
479 //todo implement RFB messages, for now we stop here
480 return AppLayerResult::err();
481 }
482 _ => {
483 SCLogDebug!("Invalid state for response");
484 return AppLayerResult::err();
485 }
486 }
487 }
488 }
489
490 fn tx_iterator(
491 &mut self,
492 min_tx_id: u64,
493 state: &mut u64,
494 ) -> Option<(&RFBTransaction, u64, bool)> {
495 let mut index = *state as usize;
496 let len = self.transactions.len();
497
498 while index < len {
499 let tx = &self.transactions[index];
500 if tx.tx_id < min_tx_id + 1 {
501 index += 1;
502 continue;
503 }
504 *state = index as u64;
505 return Some((tx, tx.tx_id - 1, (len - index) > 1));
506 }
507
508 return None;
509 }
510}
511
512// C exports.
513
514export_tx_get_detect_state!(
515 rs_rfb_tx_get_detect_state,
516 RFBTransaction
517);
518export_tx_set_detect_state!(
519 rs_rfb_tx_set_detect_state,
520 RFBTransaction
521);
522
523#[no_mangle]
524pub extern "C" fn rs_rfb_state_new() -> *mut std::os::raw::c_void {
525 let state = RFBState::new();
526 let boxed = Box::new(state);
527 return unsafe { transmute(boxed) };
528}
529
530#[no_mangle]
531pub extern "C" fn rs_rfb_state_free(state: *mut std::os::raw::c_void) {
532 // Just unbox...
533 let _drop: Box<RFBState> = unsafe { transmute(state) };
534}
535
536#[no_mangle]
537pub extern "C" fn rs_rfb_state_tx_free(
538 state: *mut std::os::raw::c_void,
539 tx_id: u64,
540) {
541 let state = cast_pointer!(state, RFBState);
542 state.free_tx(tx_id);
543}
544
545#[no_mangle]
546pub extern "C" fn rs_rfb_parse_request(
547 _flow: *const Flow,
548 state: *mut std::os::raw::c_void,
549 _pstate: *mut std::os::raw::c_void,
550 input: *const u8,
551 input_len: u32,
552 _data: *const std::os::raw::c_void,
553 _flags: u8,
554) -> AppLayerResult {
555 let state = cast_pointer!(state, RFBState);
556 let buf = build_slice!(input, input_len as usize);
557 return state.parse_request(buf);
558}
559
560#[no_mangle]
561pub extern "C" fn rs_rfb_parse_response(
562 _flow: *const Flow,
563 state: *mut std::os::raw::c_void,
564 _pstate: *mut std::os::raw::c_void,
565 input: *const u8,
566 input_len: u32,
567 _data: *const std::os::raw::c_void,
568 _flags: u8,
569) -> AppLayerResult {
570 let state = cast_pointer!(state, RFBState);
571 let buf = build_slice!(input, input_len as usize);
572 return state.parse_response(buf);
573}
574
575#[no_mangle]
576pub extern "C" fn rs_rfb_state_get_tx(
577 state: *mut std::os::raw::c_void,
578 tx_id: u64,
579) -> *mut std::os::raw::c_void {
580 let state = cast_pointer!(state, RFBState);
581 match state.get_tx(tx_id) {
582 Some(tx) => {
583 return unsafe { transmute(tx) };
584 }
585 None => {
586 return std::ptr::null_mut();
587 }
588 }
589}
590
591#[no_mangle]
592pub extern "C" fn rs_rfb_state_get_tx_count(
593 state: *mut std::os::raw::c_void,
594) -> u64 {
595 let state = cast_pointer!(state, RFBState);
596 return state.tx_id;
597}
598
599#[no_mangle]
600pub extern "C" fn rs_rfb_state_progress_completion_status(
601 _direction: u8,
602) -> std::os::raw::c_int {
603 // This parser uses 1 to signal transaction completion status.
604 return 1;
605}
606
607#[no_mangle]
608pub extern "C" fn rs_rfb_tx_get_alstate_progress(
609 tx: *mut std::os::raw::c_void,
610 _direction: u8,
611) -> std::os::raw::c_int {
612 let tx = cast_pointer!(tx, RFBTransaction);
613 if tx.complete {
614 return 1;
615 }
616 return 0;
617}
618
619#[no_mangle]
620pub extern "C" fn rs_rfb_tx_get_logged(
621 _state: *mut std::os::raw::c_void,
622 tx: *mut std::os::raw::c_void,
623) -> u32 {
624 let tx = cast_pointer!(tx, RFBTransaction);
625 return tx.logged.get();
626}
627
628#[no_mangle]
629pub extern "C" fn rs_rfb_tx_set_logged(
630 _state: *mut std::os::raw::c_void,
631 tx: *mut std::os::raw::c_void,
632 logged: u32,
633) {
634 let tx = cast_pointer!(tx, RFBTransaction);
635 tx.logged.set(logged);
636}
637
638#[no_mangle]
639pub extern "C" fn rs_rfb_state_get_events(
640 tx: *mut std::os::raw::c_void
641) -> *mut core::AppLayerDecoderEvents {
642 let tx = cast_pointer!(tx, RFBTransaction);
643 return tx.events;
644}
645
646#[no_mangle]
647pub extern "C" fn rs_rfb_state_get_event_info(
648 _event_name: *const std::os::raw::c_char,
649 _event_id: *mut std::os::raw::c_int,
650 _event_type: *mut core::AppLayerEventType,
651) -> std::os::raw::c_int {
652 return -1;
653}
654
655#[no_mangle]
656pub extern "C" fn rs_rfb_state_get_event_info_by_id(_event_id: std::os::raw::c_int,
657 _event_name: *mut *const std::os::raw::c_char,
658 _event_type: *mut core::AppLayerEventType
659) -> i8 {
660 return -1;
661}
662#[no_mangle]
663pub extern "C" fn rs_rfb_state_get_tx_iterator(
664 _ipproto: u8,
665 _alproto: AppProto,
666 state: *mut std::os::raw::c_void,
667 min_tx_id: u64,
668 _max_tx_id: u64,
669 istate: &mut u64,
670) -> applayer::AppLayerGetTxIterTuple {
671 let state = cast_pointer!(state, RFBState);
672 match state.tx_iterator(min_tx_id, istate) {
673 Some((tx, out_tx_id, has_next)) => {
674 let c_tx = unsafe { transmute(tx) };
675 let ires = applayer::AppLayerGetTxIterTuple::with_values(
676 c_tx,
677 out_tx_id,
678 has_next,
679 );
680 return ires;
681 }
682 None => {
683 return applayer::AppLayerGetTxIterTuple::not_found();
684 }
685 }
686}
687
688// Parser name as a C style string.
689const PARSER_NAME: &'static [u8] = b"rfb\0";
690
691export_tx_detect_flags_set!(rs_rfb_set_tx_detect_flags, RFBTransaction);
692export_tx_detect_flags_get!(rs_rfb_get_tx_detect_flags, RFBTransaction);
693
694#[no_mangle]
695pub unsafe extern "C" fn rs_rfb_register_parser() {
696 let default_port = CString::new("[5900]").unwrap();
697 let parser = RustParser {
698 name: PARSER_NAME.as_ptr() as *const std::os::raw::c_char,
699 default_port: default_port.as_ptr(),
700 ipproto: IPPROTO_TCP,
701 probe_ts: None,
702 probe_tc: None,
703 min_depth: 0,
704 max_depth: 16,
705 state_new: rs_rfb_state_new,
706 state_free: rs_rfb_state_free,
707 tx_free: rs_rfb_state_tx_free,
708 parse_ts: rs_rfb_parse_request,
709 parse_tc: rs_rfb_parse_response,
710 get_tx_count: rs_rfb_state_get_tx_count,
711 get_tx: rs_rfb_state_get_tx,
712 tx_get_comp_st: rs_rfb_state_progress_completion_status,
713 tx_get_progress: rs_rfb_tx_get_alstate_progress,
714 get_tx_logged: Some(rs_rfb_tx_get_logged),
715 set_tx_logged: Some(rs_rfb_tx_set_logged),
716 get_de_state: rs_rfb_tx_get_detect_state,
717 set_de_state: rs_rfb_tx_set_detect_state,
718 get_events: Some(rs_rfb_state_get_events),
719 get_eventinfo: Some(rs_rfb_state_get_event_info),
720 get_eventinfo_byid : Some(rs_rfb_state_get_event_info_by_id),
721 localstorage_new: None,
722 localstorage_free: None,
1c8943de
FH
723 get_files: None,
724 get_tx_iterator: Some(rs_rfb_state_get_tx_iterator),
725 get_tx_detect_flags: Some(rs_rfb_get_tx_detect_flags),
726 set_tx_detect_flags: Some(rs_rfb_set_tx_detect_flags),
411f428a 727 get_tx_data: None,
5665fc83 728 apply_tx_config: None,
1c8943de
FH
729 };
730
731 let ip_proto_str = CString::new("tcp").unwrap();
732
733 if AppLayerProtoDetectConfProtoDetectionEnabled(
734 ip_proto_str.as_ptr(),
735 parser.name,
736 ) != 0
737 {
738 let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
739 ALPROTO_RFB = alproto;
740 if AppLayerParserConfParserEnabled(
741 ip_proto_str.as_ptr(),
742 parser.name,
743 ) != 0
744 {
745 let _ = AppLayerRegisterParser(&parser, alproto);
746 }
747 SCLogDebug!("Rust rfb parser registered.");
748 } else {
749 SCLogDebug!("Protocol detector and parser disabled for RFB.");
750 }
751}