1 /* $Id: test_resource_info.cpp 534857 2017-05-03 12:26:07Z ivanov $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Aleksey Grichenko
27 *
28 * File Description:
29 * Test for secure resources API
30 *
31 */
32
33 #include <ncbi_pch.hpp>
34 #include <corelib/ncbiapp.hpp>
35 #include <corelib/ncbiargs.hpp>
36 #include <corelib/ncbifile.hpp>
37 #include <corelib/resource_info.hpp>
38
39 #include <common/test_assert.h> /* This header must go last */
40
41 USING_NCBI_SCOPE;
42
43
44 //////////////////////////////////////////////////////////////////////////////
45 //
46 // Test application
47 //
48
49
50 class CResInfoTest : public CNcbiApplication
51 {
52 public:
53 void Init(void);
54 int Run(void);
55 };
56
57
Init(void)58 void CResInfoTest::Init(void)
59 {
60 unique_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
61 string prog_description = "Test for CNcbiResourceInfo\n";
62 arg_desc->SetUsageContext(GetArguments().GetProgramBasename(), prog_description, false);
63 SetupArgDescriptions(arg_desc.release());
64 }
65
66
67 const char* src_name = "resinfo_plain.txt";
68
69 const char* test1_res = "resource_info/some_user@some_server";
70 const char* test1_pwd = "resinfo_password";
71 const char* test1_val = "server_password";
72
73 const char* test2_res = "resource_info/some_user@some_server";
74 const char* test2_pwd = "resinfo_password2";
75 const char* test2_val = "server_password2";
76 const char* test2_ex = "username=anyone&server=server_name";
77
78 const char* test3_res = "resource_info2/another_user@another_server";
79 const char* test3_pwd = "resinfo_password";
80 const char* test3_val = "server_password";
81 const char* test3_ex = "username=onemore&server=server_name";
82
83 typedef CNcbiResourceInfo::TExtraValuesMap TExtraValuesMap;
84 typedef CNcbiResourceInfo::TExtraValues TExtraValues;
85
86
CheckExtra(const CNcbiResourceInfo & info,const string & ref)87 void CheckExtra(const CNcbiResourceInfo& info, const string& ref)
88 {
89 // The order of extra values is undefined
90 const TExtraValuesMap& info_ex = info.GetExtraValues().GetPairs();
91 TExtraValues ref_ex_pairs;
92 ref_ex_pairs.Parse(ref);
93 const TExtraValuesMap& ref_ex = ref_ex_pairs.GetPairs();
94 _ASSERT(info_ex.size() == ref_ex.size());
95 ITERATE(TExtraValuesMap, it, info_ex) {
96 TExtraValuesMap::const_iterator match = ref_ex.find(it->first);
97 _ASSERT(match != ref_ex.end());
98 _ASSERT(match->second == it->second);
99 }
100 }
101
102
Run(void)103 int CResInfoTest::Run(void)
104 {
105 string enc_name = CFile::GetTmpName();
106 _ASSERT(!enc_name.empty());
107 //CFileDeleteAtExit::Add(enc_name);
108
109 {{
110 // Encode and save the source plaintext file
111 CNcbiResourceInfoFile newfile(enc_name);
112 newfile.ParsePlainTextFile(src_name);
113 newfile.SaveFile();
114 }}
115
116 // Load the created file and get some resource info
117 CNcbiResourceInfoFile resfile(enc_name);
118
119 const CNcbiResourceInfo& info1 =
120 resfile.GetResourceInfo(test1_res, test1_pwd);
121 _ASSERT(info1); // success?
122 _ASSERT(info1.GetValue() == test1_val); // check main value
123 _ASSERT(info1.GetExtraValues().GetPairs().empty()); // no extra data
124
125 const CNcbiResourceInfo& info2 =
126 resfile.GetResourceInfo(test2_res, test2_pwd);
127 _ASSERT(info2); // success?
128 _ASSERT(info2.GetValue() == test2_val); // check main value
129 CheckExtra(info2, test2_ex);
130
131 const CNcbiResourceInfo& info3 =
132 resfile.GetResourceInfo(test3_res, test3_pwd);
133 _ASSERT(info3); // success?
134 _ASSERT(info3.GetValue() == test3_val); // check main value
135 CheckExtra(info3, test3_ex);
136
137 // Test string encryption/decrypton using an explicit password.
138 string data = "Test CNcbiEncrypt class";
139 string key = CNcbiEncrypt::GenerateKey("foobar");
140 _ASSERT(key == "2BCB50C9A5FC53A1608242FE827BAE228:0AA2C441A5F2F3DB7E9565E9349C18AB");
141 string encr = CNcbiEncrypt::Encrypt(data, "foobar");
142 string decr = CNcbiEncrypt::Decrypt(encr, "foobar");
143 _ASSERT(decr == data);
144 // Test v1 decryption
145 string v1_encr = "1BCB50C9A5FC53A1608242FE827BAE228:A8F7030E91CCF4E5FDF7C0F3F734BEBBDA2AAB8583729E9E5F438D1E569F2F21";
146 decr = CNcbiEncrypt::Decrypt(v1_encr, "foobar");
147 _ASSERT(decr == data);
148
149 // Test decryption using ncbi keys file, the key is a non-default one
150 // (not the first key in the file).
151 decr = CNcbiEncrypt::Decrypt(encr);
152 _ASSERT(decr == data);
153
154 // Test automatic key selection.
155 encr = CNcbiEncrypt::Encrypt(data);
156 decr = CNcbiEncrypt::Decrypt(encr);
157 _ASSERT(decr == data);
158 v1_encr = "1E5606B599D707645329ABE4E0E3F6AC9:52CE4D659462C9ABA48CF7588D8E1FD9D5CD52EFCE578B0A40AF9B4D1208CF9F";
159 decr = CNcbiEncrypt::Decrypt(v1_encr);
160 _ASSERT(decr == data);
161
162 // Test domain encryption.
163 encr = CNcbiEncrypt::EncryptForDomain(data, "domain");
164 // Automatic domain key selection.
165 decr = CNcbiEncrypt::Decrypt(encr);
166 _ASSERT(decr == data);
167 // Explicit domain
168 decr = CNcbiEncrypt::DecryptForDomain(encr, "domain");
169 _ASSERT(decr == data);
170 // Two domains
171 decr = CNcbiEncrypt::DecryptForDomain(encr, "domain2");
172 _ASSERT(decr == data);
173 v1_encr = "11BDF0BA7079A8C2BD6656D3CF2D79160:3F7930D402567001F058086D263539596792628CEEF15AFE9D7E84FCD9C7BC14/domain";
174 decr = CNcbiEncrypt::Decrypt(v1_encr);
175 _ASSERT(decr == data);
176
177 // Test IsEncrypted()
178 // Encrypted data
179 _ASSERT(CNcbiEncrypt::IsEncrypted("1E5606B599D707645329ABE4E0E3F6AC9:52CE4D659462C9ABA48CF7588D8E1FD9D5CD52EFCE578B0A40AF9B4D1208CF9F"));
180 // Encrypted data with domain
181 _ASSERT(CNcbiEncrypt::IsEncrypted("11BDF0BA7079A8C2BD6656D3CF2D79160:3F7930D402567001F058086D263539596792628CEEF15AFE9D7E84FCD9C7BC14/domain"));
182 // False-positive - the format is correct, but the string contains garbage.
183 _ASSERT(CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEF:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"));
184 // False-positive - the format is correct (with domain), but the string contains garbage.
185 _ASSERT(CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEF:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF/not an actual domain"));
186 // Empty domain
187 _ASSERT(!CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEF:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF/"));
188 // Missing version
189 _ASSERT(!CNcbiEncrypt::IsEncrypted("0123456789ABCDEF0123456789ABCDEF:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"));
190 // Invalid version
191 _ASSERT(!CNcbiEncrypt::IsEncrypted("00123456789ABCDEF0123456789ABCDEF:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"));
192 // Wrong checksum length
193 _ASSERT(!CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDE:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"));
194 _ASSERT(!CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEFF:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"));
195 // Checksum is not a HEX value
196 _ASSERT(!CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEz:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"));
197 // Missing checksum separator
198 _ASSERT(!CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"));
199 // Empty encrypted part
200 _ASSERT(!CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEF:"));
201 // Data has wrong length
202 _ASSERT(!CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEF:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE"));
203 _ASSERT(!CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEF:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEFF"));
204 // Data is not a HEX string
205 _ASSERT(!CNcbiEncrypt::IsEncrypted("10123456789ABCDEF0123456789ABCDEF:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEz"));
206
207 // Test registry glue
208 bool caught_exception = false;
209 const CNcbiRegistry& reg = GetConfig();
210 string s = reg.GetEncryptedString("NCBI_KEY", "Paths",
211 IRegistry::fPlaintextAllowed);
212 _ASSERT(s == ".");
213 try {
214 reg.GetEncryptedString("NCBI_KEY", "Paths");
215 } catch (CRegistryException&) {
216 caught_exception = true;
217 }
218 _ASSERT(caught_exception);
219
220 s = reg.GetEncryptedString("sect", "val1", 0, "foobar");
221 _ASSERT(s == data);
222 try {
223 caught_exception = false;
224 reg.GetEncryptedString("sect", "val1", 0, "baz");
225 } catch (CRegistryException&) {
226 caught_exception = true;
227 }
228 _ASSERT(caught_exception);
229 // Decrypt with the default key
230 s = reg.GetEncryptedString("sect", "val1");
231 _ASSERT(s == data);
232 // Decrypt with a non-default key
233 s = reg.GetEncryptedString("sect", "val2");
234 _ASSERT(s == data);
235 // Decryt with a domain key
236 s = reg.GetEncryptedString("sect", "val3");
237 _ASSERT(s == data);
238
239 cout << "All tests passed" << endl;
240 return 0;
241 }
242
243
244 /////////////////////////////////////////////////////////////////////////////
245 // MAIN
246
main(int argc,const char * argv[])247 int main(int argc, const char* argv[])
248 {
249 return CResInfoTest().AppMain(argc, argv);
250 }
251