OpenVPN 3 Core Library
Loading...
Searching...
No Matches
test_acc.cpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12
13
14#include "test_common.hpp"
16#include <regex>
17
18using namespace openvpn;
19
20// This message has 215 bytes
21const std::string messagetext = "OpenVPN -- An application to securely tunnel IP networks\n"
22 "over a single port, with support for SSL/TLS-based\n"
23 "session authentication and key exchange,\n"
24 "packet encryption, packet authentication, and\n"
25 "packet compression.";
26
28{
30
31 acmc.supported_protocols = {"foo", "flower"};
32 acmc.max_msg_size = 140;
33 acmc.encoding_base64 = true;
34 acmc.encoding_text = true;
35 return acmc;
36}
37
38TEST(customcontrolchannel, msgroundtrip)
39{
40 auto acmc = genACMC();
41
42 auto controlmsg = acmc.format_message("flower", messagetext);
43 // \n forces base64 and should trigger three messages
44 EXPECT_EQ(controlmsg.size(), 3);
45
46 bool received;
47
49 for (const auto &cmsg : controlmsg)
50 {
51 ASSERT_LE(cmsg.size(), 140);
52 received = accrecv.receive_message(cmsg);
53 }
54
55 ASSERT_TRUE(received);
56
57 auto [recv_proto, received_message] = accrecv.get_message();
58 ASSERT_EQ(received_message, messagetext);
59 ASSERT_EQ(recv_proto, "flower");
60}
61
62TEST(customcontrolchannel, msgroundtripascii)
63{
64 auto acmc = genACMC();
65
66 // Remove special chars
67 auto messagetextNoCR = std::regex_replace(messagetext, std::regex{"\n"}, "");
68 auto controlmsg = acmc.format_message("flower", messagetextNoCR);
69
70 // Should be text encoding
71 EXPECT_EQ(controlmsg.size(), 2);
72
73 bool received;
75
76 for (const auto &cmsg : controlmsg)
77 {
78 ASSERT_LE(cmsg.size(), 140);
79 received = accrecv.receive_message(cmsg);
80 }
81
82 ASSERT_TRUE(received);
83 auto [recv_proto, received_message] = accrecv.get_message();
84 ASSERT_EQ(received_message, messagetextNoCR);
85 ASSERT_EQ(recv_proto, "flower");
86}
87
88TEST(customcontrolchannel, msgroundtriponepacket)
89{
90 auto acmc = genACMC();
91
92 acmc.max_msg_size = 2000;
93 auto controlmsg = acmc.format_message("flower", messagetext);
94
95 /* Should fit the whole message */
96 EXPECT_EQ(controlmsg.size(), 1);
97
98 bool received;
100
101 received = accrecv.receive_message(controlmsg.at(0));
102
103 ASSERT_TRUE(received);
104 auto [recv_proto, received_message] = accrecv.get_message();
105 ASSERT_EQ(received_message, messagetext);
106 ASSERT_EQ(recv_proto, "flower");
107}
108
109TEST(customcontrolchannel, tinymessage)
110{
111 std::string request{"I want a cookie!"};
112 auto acmc = genACMC();
113 acmc.supported_protocols.push_back("fortune");
114 auto cmsgs = acmc.format_message("fortune", request);
115 EXPECT_EQ(cmsgs.size(), 1);
116
117 EXPECT_EQ(cmsgs.at(0), std::string("ACC,fortune,16,A,I want a cookie!"));
118}
119
120TEST(customcontrolchannel, acctostr)
121{
122 auto acmc = genACMC();
123
124 auto desc = acmc.str();
125 EXPECT_EQ(desc, "protocols foo flower, msg_size 140, encoding ascii base64");
126}
127
128TEST(customcontrolchannel, recv_with_nul)
129{
130 std::string control_msg{"ACC,fortune,64,6,InsgIm1lIjogImZyb2ciLCAAeGZm/SJtc2ciOiAiSSBhbSAAS2VybWl0IiB9Ig=="};
131
132 bool received = false;
134
135
136 received = accrecv.receive_message(control_msg);
137
138 char data[] = "\"{ \"me\": \"frog\", \0xff\xfd\"msg\": \"I am \0Kermit\" }\"";
139 const std::string expected_string{data, sizeof(data) - 1};
140
141 ASSERT_TRUE(received);
142 auto [recv_proto, received_message] = accrecv.get_message();
143 ASSERT_EQ(46, received_message.length());
144 ASSERT_EQ(received_message, expected_string);
145 ASSERT_EQ(recv_proto, "fortune");
146}
147
148TEST(customcontrolchannel, send_with_nul)
149{
150 auto acmc = genACMC();
151 acmc.supported_protocols.push_back("fortune");
152
153
154 char data[] = "\"{ \"me\": \"frog\", \0xff\xfd\"msg\": \"I am \0Kermit\" }\"";
155 const std::string string_with_nul{data, sizeof(data) - 1};
156
157 const auto cmsgs = acmc.format_message("fortune", string_with_nul);
158
159 const std::string expected_control_msg{"ACC,fortune,64,6,InsgIm1lIjogImZyb2ciLCAAeGZm/SJtc2ciOiAiSSBhbSAAS2VybWl0IiB9Ig=="};
160
161 EXPECT_EQ(cmsgs.size(), 1);
162 EXPECT_EQ(cmsgs[0], expected_control_msg);
163}
164
165TEST(customcontrolchannel, test_incorrect_len)
166{
167 std::string control_msg{"ACC,fortune,62,6,InsgIm1lIjogImZyb2ciLCAAeGZm/SJtc2ciOiAiSSBhbSAAS2VybWl0IiB9Ig=="};
168
170
171 EXPECT_THROW(
172 accrecv.receive_message(control_msg),
173 parse_acc_message);
174}
175
176TEST(customcontrolchannel, test_wrong_header)
177{
178 std::string control_msg{"ABC,fortune,64,6,InsgIm1lIjogImZyb2ciLCAAeGZm/SJtc2ciOiAiSSBhbSAAS2VybWl0IiB9Ig=="};
179
181
182 EXPECT_THROW(
183 accrecv.receive_message(control_msg),
184 parse_acc_message);
185}
186
187TEST(customcontrolchannel, test_unsupported_encoding)
188{
189 std::string control_msg{"ACC,fortune,64,Q,InsgIm1lIjogImZyb2ciLCAAeGZm/SJtc2ciOiAiSSBhbSAAS2VybWl0IiB9Ig=="};
190
192
193 EXPECT_THROW(
194 accrecv.receive_message(control_msg),
195 parse_acc_message);
196}
197
198TEST(customcontrolchannel, test_missing_message)
199{
200 std::string control_msg{"ABC,fortune,64,6"};
201
203
204 EXPECT_THROW(
205 accrecv.receive_message(control_msg),
206 parse_acc_message);
207}
bool receive_message(const std::string &msg)
std::pair< std::string, std::string > get_message()
std::vector< std::string > supported_protocols
List of supported protocols.
int max_msg_size
Maximum size of each individual message/message fragment.
bool encoding_base64
Supports sending/receiving messages as base64 encoded binary.
TEST(customcontrolchannel, msgroundtrip)
Definition test_acc.cpp:38
const std::string messagetext
Definition test_acc.cpp:21
static AppControlMessageConfig genACMC()
Definition test_acc.cpp:27