1 /* Copyright (C) 2020 Open Information Security Foundation
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
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.
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
18 // Author: Frank Honza <frank.honza@dcso.de>
21 use std::ffi::CString;
22 use std::mem::transmute;
23 use crate::core::{self, ALPROTO_UNKNOWN, AppProto, Flow, IPPROTO_TCP};
26 use crate::applayer::*;
30 static mut ALPROTO_RFB: AppProto = ALPROTO_UNKNOWN;
32 pub struct RFBTransaction {
35 pub chosen_security_type: Option<u32>,
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>,
50 de_state: Option<*mut core::DetectEngineState>,
51 events: *mut core::AppLayerDecoderEvents,
52 detect_flags: applayer::TxDetectFlags,
56 pub fn new() -> RFBTransaction {
60 chosen_security_type: None,
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,
70 tc_security_result: None,
71 tc_failure_reason: None,
74 logged: LoggerFlags::new(),
76 events: std::ptr::null_mut(),
77 detect_flags: applayer::TxDetectFlags::default(),
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);
85 if let Some(state) = self.de_state {
86 core::sc_detect_engine_state_free(state);
91 impl Drop for RFBTransaction {
99 transactions: Vec<RFBTransaction>,
100 state: parser::RFBGlobalState
104 pub fn new() -> Self {
107 transactions: Vec::new(),
108 state: parser::RFBGlobalState::TCServerProtocolVersion
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;
118 let tx = &self.transactions[i];
119 if tx.tx_id == tx_id + 1 {
126 self.transactions.remove(index);
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 {
139 fn new_tx(&mut self) -> RFBTransaction {
140 let mut tx = RFBTransaction::new();
142 tx.tx_id = self.tx_id;
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 {
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();
161 let mut current = input;
162 let mut consumed = 0;
163 SCLogDebug!("request_state {}, input_len {}", self.state, input.len());
165 if current.len() == 0 {
166 return AppLayerResult::ok();
169 parser::RFBGlobalState::TSClientProtocolVersion => {
170 match parser::parse_protocol_version(current) {
171 Ok((rem, request)) => {
172 consumed += current.len() - rem.len();
175 if request.major == "003" && request.minor == "003" {
176 // in version 3.3 the server decided security type
177 self.state = parser::RFBGlobalState::TCServerSecurityType;
179 self.state = parser::RFBGlobalState::TCSupportedSecurityTypes;
182 if let Some(current_transaction) = self.get_current_tx() {
183 current_transaction.ts_client_protocol_version = Some(request);
185 return AppLayerResult::err();
188 Err(nom::Err::Incomplete(_)) => {
189 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
192 return AppLayerResult::err();
196 parser::RFBGlobalState::TSSecurityTypeSelection => {
197 match parser::parse_security_type_selection(current) {
198 Ok((rem, request)) => {
199 consumed += current.len() - rem.len();
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(),
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);
213 return AppLayerResult::err();
216 Err(nom::Err::Incomplete(_)) => {
217 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
220 return AppLayerResult::err();
224 parser::RFBGlobalState::TSVncResponse => {
225 match parser::parse_vnc_auth(current) {
226 Ok((rem, request)) => {
227 consumed += current.len() - rem.len();
230 self.state = parser::RFBGlobalState::TCSecurityResult;
232 if let Some(current_transaction) = self.get_current_tx() {
233 current_transaction.ts_vnc_response = Some(request);
235 return AppLayerResult::err();
238 Err(nom::Err::Incomplete(_)) => {
239 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
242 return AppLayerResult::err();
246 parser::RFBGlobalState::TSClientInit => {
247 match parser::parse_client_init(current) {
248 Ok((rem, request)) => {
249 consumed += current.len() - rem.len();
252 self.state = parser::RFBGlobalState::TCServerInit;
254 if let Some(current_transaction) = self.get_current_tx() {
255 current_transaction.ts_client_init = Some(request);
257 return AppLayerResult::err();
260 Err(nom::Err::Incomplete(_)) => {
261 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
264 return AppLayerResult::err();
268 parser::RFBGlobalState::Message => {
269 //todo implement RFB messages, for now we stop here
270 return AppLayerResult::err();
272 parser::RFBGlobalState::TCServerProtocolVersion => {
273 SCLogDebug!("Reversed traffic, expected response.");
274 return AppLayerResult::err();
277 SCLogDebug!("Invalid state for request {}", self.state);
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();
290 let mut current = input;
291 let mut consumed = 0;
292 SCLogDebug!("response_state {}, response_len {}", self.state, input.len());
294 if current.len() == 0 {
295 return AppLayerResult::ok();
298 parser::RFBGlobalState::TCServerProtocolVersion => {
299 match parser::parse_protocol_version(current) {
300 Ok((rem, request)) => {
301 consumed += current.len() - rem.len();
304 self.state = parser::RFBGlobalState::TSClientProtocolVersion;
305 let tx = self.new_tx();
306 self.transactions.push(tx);
308 if let Some(current_transaction) = self.get_current_tx() {
309 current_transaction.tc_server_protocol_version = Some(request);
311 return AppLayerResult::err();
314 Err(nom::Err::Incomplete(_)) => {
315 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
318 return AppLayerResult::err();
322 parser::RFBGlobalState::TCSupportedSecurityTypes => {
323 match parser::parse_supported_security_types(current) {
324 Ok((rem, request)) => {
325 consumed += current.len() - rem.len();
329 "supported_security_types: {}, types: {}", request.number_of_types,
330 request.types.iter().map(ToString::to_string).map(|v| v + " ").collect::<String>()
333 self.state = parser::RFBGlobalState::TSSecurityTypeSelection;
334 if request.number_of_types == 0 {
335 self.state = parser::RFBGlobalState::TCFailureReason;
338 if let Some(current_transaction) = self.get_current_tx() {
339 current_transaction.tc_supported_security_types = Some(request);
341 return AppLayerResult::err();
344 Err(nom::Err::Incomplete(_)) => {
345 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
348 return AppLayerResult::err();
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)) => {
356 consumed += current.len() - rem.len();
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,
366 // TODO Event unknown security type
367 return AppLayerResult::err();
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);
375 return AppLayerResult::err();
378 Err(nom::Err::Incomplete(_)) => {
379 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
382 return AppLayerResult::err();
386 parser::RFBGlobalState::TCVncChallenge => {
387 match parser::parse_vnc_auth(current) {
388 Ok((rem, request)) => {
389 consumed += current.len() - rem.len();
392 self.state = parser::RFBGlobalState::TSVncResponse;
394 if let Some(current_transaction) = self.get_current_tx() {
395 current_transaction.tc_vnc_challenge = Some(request);
397 return AppLayerResult::err();
400 Err(nom::Err::Incomplete(_)) => {
401 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
404 return AppLayerResult::err();
408 parser::RFBGlobalState::TCSecurityResult => {
409 match parser::parse_security_result(current) {
410 Ok((rem, request)) => {
411 consumed += current.len() - rem.len();
414 if request.status == 0 {
415 self.state = parser::RFBGlobalState::TSClientInit;
417 if let Some(current_transaction) = self.get_current_tx() {
418 current_transaction.tc_security_result = Some(request);
420 return AppLayerResult::err();
422 } else if request.status == 1 {
423 self.state = parser::RFBGlobalState::TCFailureReason;
425 // TODO: Event: unknown security result value
428 Err(nom::Err::Incomplete(_)) => {
429 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
432 return AppLayerResult::err();
436 parser::RFBGlobalState::TCFailureReason => {
437 match parser::parse_failure_reason(current) {
438 Ok((_rem, request)) => {
439 if let Some(current_transaction) = self.get_current_tx() {
440 current_transaction.tc_failure_reason = Some(request);
442 return AppLayerResult::err();
444 return AppLayerResult::err();
446 Err(nom::Err::Incomplete(_)) => {
447 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
450 return AppLayerResult::err();
454 parser::RFBGlobalState::TCServerInit => {
455 match parser::parse_server_init(current) {
456 Ok((rem, request)) => {
457 consumed += current.len() - rem.len();
460 self.state = parser::RFBGlobalState::Message;
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;
467 return AppLayerResult::err();
470 Err(nom::Err::Incomplete(_)) => {
471 return AppLayerResult::incomplete(consumed as u32, (current.len() + 1) as u32);
474 return AppLayerResult::err();
478 parser::RFBGlobalState::Message => {
479 //todo implement RFB messages, for now we stop here
480 return AppLayerResult::err();
483 SCLogDebug!("Invalid state for response");
484 return AppLayerResult::err();
494 ) -> Option<(&RFBTransaction, u64, bool)> {
495 let mut index = *state as usize;
496 let len = self.transactions.len();
499 let tx = &self.transactions[index];
500 if tx.tx_id < min_tx_id + 1 {
504 *state = index as u64;
505 return Some((tx, tx.tx_id - 1, (len - index) > 1));
514 export_tx_get_detect_state!(
515 rs_rfb_tx_get_detect_state,
518 export_tx_set_detect_state!(
519 rs_rfb_tx_set_detect_state,
524 pub 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) };
531 pub extern "C" fn rs_rfb_state_free(state: *mut std::os::raw::c_void) {
533 let _drop: Box<RFBState> = unsafe { transmute(state) };
537 pub extern "C" fn rs_rfb_state_tx_free(
538 state: *mut std::os::raw::c_void,
541 let state = cast_pointer!(state, RFBState);
542 state.free_tx(tx_id);
546 pub extern "C" fn rs_rfb_parse_request(
548 state: *mut std::os::raw::c_void,
549 _pstate: *mut std::os::raw::c_void,
552 _data: *const std::os::raw::c_void,
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);
561 pub extern "C" fn rs_rfb_parse_response(
563 state: *mut std::os::raw::c_void,
564 _pstate: *mut std::os::raw::c_void,
567 _data: *const std::os::raw::c_void,
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);
576 pub extern "C" fn rs_rfb_state_get_tx(
577 state: *mut std::os::raw::c_void,
579 ) -> *mut std::os::raw::c_void {
580 let state = cast_pointer!(state, RFBState);
581 match state.get_tx(tx_id) {
583 return unsafe { transmute(tx) };
586 return std::ptr::null_mut();
592 pub extern "C" fn rs_rfb_state_get_tx_count(
593 state: *mut std::os::raw::c_void,
595 let state = cast_pointer!(state, RFBState);
600 pub extern "C" fn rs_rfb_state_progress_completion_status(
602 ) -> std::os::raw::c_int {
603 // This parser uses 1 to signal transaction completion status.
608 pub extern "C" fn rs_rfb_tx_get_alstate_progress(
609 tx: *mut std::os::raw::c_void,
611 ) -> std::os::raw::c_int {
612 let tx = cast_pointer!(tx, RFBTransaction);
620 pub extern "C" fn rs_rfb_tx_get_logged(
621 _state: *mut std::os::raw::c_void,
622 tx: *mut std::os::raw::c_void,
624 let tx = cast_pointer!(tx, RFBTransaction);
625 return tx.logged.get();
629 pub extern "C" fn rs_rfb_tx_set_logged(
630 _state: *mut std::os::raw::c_void,
631 tx: *mut std::os::raw::c_void,
634 let tx = cast_pointer!(tx, RFBTransaction);
635 tx.logged.set(logged);
639 pub 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);
647 pub 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 {
656 pub 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
663 pub extern "C" fn rs_rfb_state_get_tx_iterator(
666 state: *mut std::os::raw::c_void,
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(
683 return applayer::AppLayerGetTxIterTuple::not_found();
688 // Parser name as a C style string.
689 const PARSER_NAME: &'static [u8] = b"rfb\0";
691 export_tx_detect_flags_set!(rs_rfb_set_tx_detect_flags, RFBTransaction);
692 export_tx_detect_flags_get!(rs_rfb_get_tx_detect_flags, RFBTransaction);
695 pub 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,
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,
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),
728 apply_tx_config: None,
731 let ip_proto_str = CString::new("tcp").unwrap();
733 if AppLayerProtoDetectConfProtoDetectionEnabled(
734 ip_proto_str.as_ptr(),
738 let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
739 ALPROTO_RFB = alproto;
740 if AppLayerParserConfParserEnabled(
741 ip_proto_str.as_ptr(),
745 let _ = AppLayerRegisterParser(&parser, alproto);
747 SCLogDebug!("Rust rfb parser registered.");
749 SCLogDebug!("Protocol detector and parser disabled for RFB.");