Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/app-layer-rfb.c
Line
Count
Source
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
/**
19
 * \file
20
 *
21
 * \author Sascha Steinbiss <sascha.steinbiss@dcso.de>
22
 *
23
 * RFB (VNC) application layer detector and parser.
24
 *
25
 */
26
27
#include "suricata-common.h"
28
29
#include "util-unittest.h"
30
31
#include "app-layer-detect-proto.h"
32
#include "app-layer-parser.h"
33
#include "app-layer-rfb.h"
34
35
#include "rust.h"
36
37
static int RFBRegisterPatternsForProtocolDetection(void)
38
34
{
39
34
    if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_RFB,
40
34
                                               "RFB ", 4, 0, STREAM_TOCLIENT) < 0)
41
0
    {
42
0
        return -1;
43
0
    }
44
34
    if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_RFB,
45
34
                                               "RFB ", 4, 0, STREAM_TOSERVER) < 0)
46
0
    {
47
0
        return -1;
48
0
    }
49
34
    return 0;
50
34
}
51
52
void RFBParserRegisterTests(void);
53
54
void RegisterRFBParsers(void)
55
34
{
56
34
    rs_rfb_register_parser();
57
34
    if (RFBRegisterPatternsForProtocolDetection() < 0 )
58
0
            return;
59
#ifdef UNITTESTS
60
    AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_RFB,
61
        RFBParserRegisterTests);
62
#endif
63
34
}
64
65
66
#ifdef UNITTESTS
67
68
#include "stream-tcp.h"
69
#include "util-unittest-helper.h"
70
71
static int RFBParserTest(void)
72
{
73
    uint64_t ret[4];
74
    AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
75
    FAIL_IF_NULL(alp_tctx);
76
77
    StreamTcpInitConfig(true);
78
    TcpSession ssn;
79
    memset(&ssn, 0, sizeof(ssn));
80
81
    Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 59001, 5900);
82
    FAIL_IF_NULL(f);
83
    f->protoctx = &ssn;
84
    f->proto = IPPROTO_TCP;
85
    f->alproto = ALPROTO_RFB;
86
    f->flags |= FLOW_SGH_TOCLIENT | FLOW_SGH_TOSERVER;
87
88
    static const unsigned char rfb_version_str[12] = {
89
            0x52, 0x46, 0x42, 0x20, 0x30, 0x30, 0x33, 0x2e, 0x30, 0x30, 0x37, 0x0a
90
    };
91
92
    // the RFB server sending the first handshake message
93
    int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_RFB, STREAM_TOCLIENT | STREAM_START,
94
            (uint8_t *)rfb_version_str, sizeof(rfb_version_str));
95
    FAIL_IF_NOT(r == 0);
96
97
    r = AppLayerParserParse(
98
            NULL, alp_tctx, f, ALPROTO_RFB, STREAM_TOSERVER, (uint8_t *)rfb_version_str, sizeof(rfb_version_str));
99
    FAIL_IF_NOT(r == 0);
100
101
    static const unsigned char security_types[3] = {
102
            0x02, 0x01, 0x02
103
    };
104
    r = AppLayerParserParse(
105
            NULL, alp_tctx, f, ALPROTO_RFB, STREAM_TOCLIENT, (uint8_t *)security_types, sizeof(security_types));
106
    FAIL_IF_NOT(r == 0);
107
108
    static const unsigned char type_selection[1] = {
109
            0x01
110
    };
111
    r = AppLayerParserParse(
112
            NULL, alp_tctx, f, ALPROTO_RFB, STREAM_TOSERVER, (uint8_t *)type_selection, sizeof(type_selection));
113
    FAIL_IF_NOT(r == 0);
114
115
    static const unsigned char client_init[1] = {
116
            0x01
117
    };
118
    r = AppLayerParserParse(
119
            NULL, alp_tctx, f, ALPROTO_RFB, STREAM_TOSERVER, (uint8_t *)client_init, sizeof(client_init));
120
    FAIL_IF_NOT(r == 0);
121
122
    static const unsigned char server_init[] = {
123
          0x05, 0x00, 0x03, 0x20, 0x20, 0x18, 0x00, 0x01,
124
          0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x10, 0x08,
125
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
126
          0x61, 0x6e, 0x65, 0x61, 0x67, 0x6c, 0x65, 0x73,
127
          0x40, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
128
          0x73, 0x74, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
129
          0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e
130
    };
131
132
    r = AppLayerParserParse(
133
            NULL, alp_tctx, f, ALPROTO_RFB, STREAM_TOCLIENT, (uint8_t *)server_init, sizeof(server_init));
134
    FAIL_IF_NOT(r == 0);
135
136
    AppLayerParserTransactionsCleanup(f, STREAM_TOCLIENT);
137
    UTHAppLayerParserStateGetIds(f->alparser, &ret[0], &ret[1], &ret[2], &ret[3]);
138
    FAIL_IF_NOT(ret[0] == 1); // inspect_id[0]
139
    FAIL_IF_NOT(ret[1] == 1); // inspect_id[1]
140
    FAIL_IF_NOT(ret[2] == 1); // log_id
141
    FAIL_IF_NOT(ret[3] == 1); // min_id
142
143
    AppLayerParserTransactionsCleanup(f, STREAM_TOCLIENT);
144
    AppLayerParserThreadCtxFree(alp_tctx);
145
    StreamTcpFreeConfig(true);
146
    UTHFreeFlow(f);
147
148
    PASS;
149
}
150
151
void RFBParserRegisterTests(void)
152
{
153
    UtRegisterTest("RFBParserTest", RFBParserTest);
154
}
155
156
#endif