1 /**
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2018-2020 Bareos GmbH & Co. KG
5 
6    This program is Free Software; you can redistribute it and/or
7    modify it under the terms of version three of the GNU Affero General Public
8    License as published by the Free Software Foundation and included
9    in the file LICENSE.
10 
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14    Affero General Public License for more details.
15 
16    You should have received a copy of the GNU Affero General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19    02110-1301, USA.
20 */
21 #if defined(HAVE_MINGW)
22 #  include "include/bareos.h"
23 #  include "gtest/gtest.h"
24 #else
25 #  include "gtest/gtest.h"
26 #  include "include/bareos.h"
27 #endif
28 
29 #include "include/version_numbers.h"
30 #define BAREOS_TEST_LIB
31 #include "lib/bnet.h"
32 #include "lib/bstringlist.h"
33 #include "lib/ascii_control_characters.h"
34 #include "lib/util.h"
35 
TEST(BStringList,ConstructorsTest)36 TEST(BStringList, ConstructorsTest)
37 {
38   BStringList list1;
39   EXPECT_TRUE(list1.empty());
40 
41   list1.emplace_back(std::string("Test123"));
42   EXPECT_EQ(0, list1.at(0).compare(std::string("Test123")));
43 
44   BStringList list2(list1);
45   EXPECT_EQ(1, list2.size());
46   EXPECT_EQ(0, list2.front().compare(std::string("Test123")));
47 }
48 
TEST(BStringList,AppendTest)49 TEST(BStringList, AppendTest)
50 {
51   BStringList list1;
52   std::vector<std::string> list{"T", "est", "123"};
53   list1.Append(list);
54   EXPECT_EQ(0, list1.front().compare(std::string("T")));
55   list1.erase(list1.begin());
56   EXPECT_EQ(0, list1.front().compare(std::string("est")));
57   list1.erase(list1.begin());
58   EXPECT_EQ(0, list1.front().compare(std::string("123")));
59 
60   BStringList list2;
61   list2.Append('T');
62   list2.Append('e');
63   EXPECT_EQ(0, list2.front().compare(std::string("T")));
64   list2.erase(list2.begin());
65   EXPECT_EQ(0, list2.front().compare(std::string("e")));
66 }
67 
TEST(BStringList,JoinTest)68 TEST(BStringList, JoinTest)
69 {
70   BStringList list1;
71   list1 << "Test";
72   list1 << 1 << 23;
73   EXPECT_EQ(3, list1.size());
74   EXPECT_STREQ(list1.Join().c_str(), "Test123");
75   EXPECT_STREQ(list1.Join(' ').c_str(), "Test 1 23");
76 
77   BStringList list2;
78   list2.Append("Test");
79   list2.Append("123");
80 
81   std::string s = list2.Join(AsciiControlCharacters::RecordSeparator());
82   EXPECT_EQ(8, s.size());
83 
84   std::string test{"Test"};
85   test += AsciiControlCharacters::RecordSeparator();  // 0x1e
86   test += "123";
87 
88   EXPECT_STREQ(s.c_str(), test.c_str());
89 }
90 
TEST(BStringList,SplitStringTest)91 TEST(BStringList, SplitStringTest)
92 {
93   std::string test{"Test@123@String"};
94   BStringList list1(test, '@');
95   EXPECT_EQ(3, list1.size());
96 
97   EXPECT_STREQ("Test", list1.front().c_str());
98   list1.erase(list1.begin());
99   EXPECT_STREQ("123", list1.front().c_str());
100   list1.erase(list1.begin());
101   EXPECT_STREQ("String", list1.front().c_str());
102 }
103 
TEST(BStringList,SplitStringTestStringSeparator)104 TEST(BStringList, SplitStringTestStringSeparator)
105 {
106   std::string test{"Test::123::String::::"};
107   BStringList list1(test, "::");
108   EXPECT_EQ(5, list1.size());
109 
110   EXPECT_STREQ("Test", list1.front().c_str());
111   list1.erase(list1.begin());
112   EXPECT_STREQ("123", list1.front().c_str());
113   list1.erase(list1.begin());
114   EXPECT_STREQ("String", list1.front().c_str());
115 }
116 
TEST(BNet,ReadoutCommandIdFromStringTest)117 TEST(BNet, ReadoutCommandIdFromStringTest)
118 {
119   bool ok;
120   uint32_t id;
121 
122   std::string message1 = "1000";
123   message1 += 0x1e;
124   message1 += "OK: <director-name> Version: <version>";
125   BStringList list_of_arguments1(message1, 0x1e);
126   ok = ReadoutCommandIdFromMessage(list_of_arguments1, id);
127   EXPECT_EQ(id, kMessageIdOk);
128   EXPECT_EQ(ok, true);
129 
130   std::string message2 = "1001";
131   message2 += 0x1e;
132   message2 += "OK: <director-name> Version: <version>";
133   BStringList list_of_arguments2(message2, 0x1e);
134   ok = ReadoutCommandIdFromMessage(list_of_arguments2, id);
135   EXPECT_NE(id, kMessageIdOk);
136   EXPECT_EQ(ok, true);
137 }
138 
TEST(BNet,EvaluateResponseMessage_Wrong_Id)139 TEST(BNet, EvaluateResponseMessage_Wrong_Id)
140 {
141   bool ok;
142 
143   std::string message3 = "A1001";
144   message3 += 0x1e;
145   message3 += "OK: <director-name> Version: <version>";
146 
147   uint32_t id = kMessageIdUnknown;
148   BStringList args;
149   ok = EvaluateResponseMessageId(message3, id, args);
150 
151   EXPECT_EQ(id, kMessageIdUnknown);
152   EXPECT_EQ(ok, false);
153 
154   const char* m3{"A1001 OK: <director-name> Version: <version>"};
155   EXPECT_STREQ(args.JoinReadable().c_str(), m3);
156 }
157 
TEST(BNet,EvaluateResponseMessage_Correct_Id)158 TEST(BNet, EvaluateResponseMessage_Correct_Id)
159 {
160   bool ok;
161   uint32_t id;
162 
163   std::string message4 = "1001";
164   message4 += 0x1e;
165   message4 += "OK: <director-name> Version: <version>";
166 
167   BStringList args;
168   ok = EvaluateResponseMessageId(message4, id, args);
169 
170   EXPECT_EQ(id, kMessageIdPamRequired);
171   EXPECT_EQ(ok, true);
172 
173   const char* m3{"1001 OK: <director-name> Version: <version>"};
174   EXPECT_STREQ(args.JoinReadable().c_str(), m3);
175 }
176 
177 enum
178 {
179   R_DIRECTOR = 1,
180   R_CLIENT,
181   R_JOB,
182   R_STORAGE,
183   R_CONSOLE
184 };
185 
186 #include "lib/qualified_resource_name_type_converter.h"
187 
do_get_name_from_hello_test(const char * client_string_fmt,const char * client_name,const std::string & r_type_test,const BareosVersionNumber & version_test)188 static void do_get_name_from_hello_test(const char* client_string_fmt,
189                                         const char* client_name,
190                                         const std::string& r_type_test,
191                                         const BareosVersionNumber& version_test)
192 {
193   char bashed_client_name[20];
194   assert(strlen(client_name) <= 20);
195   strncpy(bashed_client_name, client_name, 20);
196   BashSpaces(bashed_client_name);
197 
198   char output_text[64];
199   sprintf(output_text, client_string_fmt, bashed_client_name);
200 
201   std::string name;
202   std::string r_type_str;
203   BareosVersionNumber version = BareosVersionNumber::kUndefined;
204 
205   bool ok = GetNameAndResourceTypeAndVersionFromHello(output_text, name,
206                                                       r_type_str, version);
207 
208   EXPECT_TRUE(ok);
209   EXPECT_STREQ(name.c_str(), client_name);
210   EXPECT_STREQ(r_type_str.c_str(), r_type_test.c_str());
211   EXPECT_EQ(version, version_test);
212 }
213 
TEST(Util,get_name_from_hello_test)214 TEST(Util, get_name_from_hello_test)
215 {
216   // clang-format off
217   do_get_name_from_hello_test("Hello Client %s calling",
218                               "Test Client",        "R_CLIENT",   BareosVersionNumber::kUndefined);
219   do_get_name_from_hello_test("Hello Storage calling Start Job %s",
220                               "Test Client",        "R_JOB",      BareosVersionNumber::kUndefined);
221   do_get_name_from_hello_test("Hello %s",
222                               "Console Name",       "R_CONSOLE",  BareosVersionNumber::kUndefined);
223   do_get_name_from_hello_test("Hello %s",
224                               "*UserAgent*",        "R_CONSOLE",  BareosVersionNumber::kUndefined);
225   do_get_name_from_hello_test("Hello %s",
226                               "*UserAgent*",        "R_CONSOLE",  BareosVersionNumber::kUndefined);
227   do_get_name_from_hello_test("Hello %s calling version 18.2.4rc2",
228                               "Console",            "R_CONSOLE",  BareosVersionNumber::kRelease_18_2);
229   do_get_name_from_hello_test("Hello Director %s calling\n",
230                               "bareos dir",         "R_DIRECTOR", BareosVersionNumber::kUndefined);
231   do_get_name_from_hello_test("Hello Start Storage Job %s",
232                               "Test Job",           "R_JOB",      BareosVersionNumber::kUndefined);
233   do_get_name_from_hello_test("Hello Client %s FdProtocolVersion=123 calling\n",
234                               "Test Client again",  "R_CLIENT",    BareosVersionNumber::kUndefined);
235   // clang-format on
236 }
237 
TEST(Util,version_number_test)238 TEST(Util, version_number_test)
239 {
240   EXPECT_EQ(BareosVersionNumber::kRelease_18_2,
241             static_cast<BareosVersionNumber>(1802));
242   EXPECT_EQ(BareosVersionNumber::kUndefined,
243             static_cast<BareosVersionNumber>(1));
244   EXPECT_NE(BareosVersionNumber::kRelease_18_2,
245             static_cast<BareosVersionNumber>(1702));
246   EXPECT_GT(BareosVersionNumber::kRelease_18_2,
247             BareosVersionNumber::kUndefined);
248 }
249 
TEST(Util,version_number_major_minor)250 TEST(Util, version_number_major_minor)
251 {
252   BareosVersionNumber version = BareosVersionNumber::kRelease_18_2;
253   BareosVersionToMajorMinor v(version);
254   EXPECT_EQ(v.major, 18);
255   EXPECT_EQ(v.minor, 2);
256 }
257 
258 #include "filed/evaluate_job_command.h"
259 
TEST(Filedaemon,evaluate_jobcommand_from_18_2_test)260 TEST(Filedaemon, evaluate_jobcommand_from_18_2_test)
261 {
262   /* command with ssl argument */
263   static const char jobcmd_kVersionFrom_18_2[]
264       = "JobId=111 Job=FirstJob SDid=222 SDtime=333 Authorization=SecretOne "
265         "ssl=4\n";
266 
267   filedaemon::JobCommand eval(jobcmd_kVersionFrom_18_2);
268 
269   EXPECT_TRUE(eval.EvaluationSuccesful());
270   EXPECT_EQ(eval.protocol_version_,
271             filedaemon::JobCommand::ProtocolVersion::kVersionFrom_18_2);
272   EXPECT_EQ(eval.job_id_, 111);
273   EXPECT_STREQ(eval.job_, "FirstJob");
274   EXPECT_EQ(eval.vol_session_id_, 222);
275   EXPECT_EQ(eval.vol_session_time_, 333);
276   EXPECT_STREQ(eval.sd_auth_key_, "SecretOne");
277   EXPECT_EQ(eval.tls_policy_, 4);
278 }
279 
TEST(Filedaemon,evaluate_jobcommand_before_18_2_test)280 TEST(Filedaemon, evaluate_jobcommand_before_18_2_test)
281 {
282   /* command without ssl argument */
283   static char jobcmdssl_KVersionBefore_18_2[]
284       = "JobId=123 Job=SecondJob SDid=456 SDtime=789 Authorization=SecretTwo";
285 
286   filedaemon::JobCommand eval(jobcmdssl_KVersionBefore_18_2);
287 
288   EXPECT_TRUE(eval.EvaluationSuccesful());
289   EXPECT_EQ(eval.protocol_version_,
290             filedaemon::JobCommand::ProtocolVersion::KVersionBefore_18_2);
291   EXPECT_EQ(eval.job_id_, 123);
292   EXPECT_STREQ(eval.job_, "SecondJob");
293   EXPECT_EQ(eval.vol_session_id_, 456);
294   EXPECT_EQ(eval.vol_session_time_, 789);
295   EXPECT_STREQ(eval.sd_auth_key_, "SecretTwo");
296 }
297 
TEST(Filedaemon,evaluate_jobcommand_wrong_format_test)298 TEST(Filedaemon, evaluate_jobcommand_wrong_format_test)
299 {
300   /* malformed command  */
301   static char jobcmdssl_KVersionBefore_18_2[] = "JobId=123 Job=Foo";
302 
303   filedaemon::JobCommand eval(jobcmdssl_KVersionBefore_18_2);
304 
305   EXPECT_FALSE(eval.EvaluationSuccesful());
306   EXPECT_EQ(eval.protocol_version_,
307             filedaemon::JobCommand::ProtocolVersion::kVersionUndefinded);
308 }
309