NCBI C++ ToolKit
resource_info.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CORELIB___RESOURCE_INFO__HPP
2 #define CORELIB___RESOURCE_INFO__HPP
3 
4 /* $Id: resource_info.hpp 84598 2018-11-20 20:23:54Z ucko $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Author: Aleksey Grichenko
30  *
31  * File Description:
32  * NCBI C++ secure resources API
33  *
34  */
35 
36 /// @file resource_info.hpp
37 ///
38 /// Defines NCBI C++ secure resources API.
39 
40 
41 #include <corelib/ncbitype.h>
42 #include <corelib/ncbistr.hpp>
43 #include <corelib/ncbiexpt.hpp>
44 #include <corelib/ncbiobj.hpp>
46 
47 
49 
50 
51 /// Class for storing encrypted resource information.
53 {
54 public:
55  /// Get resource name.
56  const string& GetName(void) const { return m_Name; }
57 
58  /// Get main value associated with the requested resource.
59  const string& GetValue(void) const { return m_Value; }
60 
61  /// Set new main value for the resource.
62  void SetValue(const string& new_value) { m_Value = new_value; }
63 
64  /// Types to access extra values
67 
68  /// Get read-only set of extra values associated with the resource.
69  const TExtraValues& GetExtraValues(void) const { return m_Extra; }
70 
71  /// Get non-const set of extra values associated with the resource.
72  TExtraValues& GetExtraValues_NC(void) { return m_Extra; }
73 
74  /// Check if the object is initialized
75  operator bool(void) const { return !x_IsEmpty(); }
76 
77 private:
78  // Prohibit copy operations
81 
82  friend class CNcbiResourceInfoFile;
84 
85  /// Create a new empty resource info.
86  CNcbiResourceInfo(void);
87 
88  // Initialize resource info. Decode the data, store the
89  // password for firther encoding.
90  CNcbiResourceInfo(const string& res_name,
91  const string& pwd,
92  const string& enc);
93 
94  static CNcbiResourceInfo& GetEmptyResInfo(void);
95 
96  // Check if the object has not been initialized
97  bool x_IsEmpty(void) const { return m_Name.empty(); }
98 
99  // Get encoded value string. If not initialized, return an empty string.
100  string x_GetEncoded(void) const;
101 
102  string m_Name; // plaintext resource name
103  mutable string m_Password;
104  mutable string m_Value;
106 };
107 
108 
109 /// Class for handling resource info files
111 {
112 public:
113  /// Get default resource info file location (/etc/ncbi/.info).
114  static string GetDefaultFileName(void);
115 
116  /// Load resource-info file. If the file does not exist or can not
117  /// be read, an empty object is created.
118  CNcbiResourceInfoFile(const string& filename);
119 
120  /// Save data to file. If new_name is empty, overwrite the original
121  /// file.
122  void SaveFile(const string& new_name = kEmptyStr);
123 
124  /// Get read-only resource info for the given name. Returns empty
125  /// object if the resource does not exist.
126  const CNcbiResourceInfo& GetResourceInfo(const string& res_name,
127  const string& pwd) const;
128  /// Get (or create) non-const resource info for the given name
129  CNcbiResourceInfo& GetResourceInfo_NC(const string& res_name,
130  const string& pwd);
131 
132  /// Delete resource associated with the name
133  void DeleteResourceInfo(const string& res_name,
134  const string& pwd);
135 
136  /// Create new resource info from the string and return reference to
137  /// the new CNcbiResourceInfo object or an empty object if the string
138  /// format is invalid.
139  /// String format is (tabs or spaces can be used as separators):
140  /// <password> <resource name> <main value> <extra values>
141  /// where password, resource name and main value are URL-encoded
142  /// and extra values are formatted like a CGI query string (individual
143  /// values are URL-encoded). The password is used to encode all other
144  /// information.
145  /// Example:
146  /// my%20pass%21 db%22name dbpa%24%24word ex1=val%201&ex2=val_2
147  CNcbiResourceInfo& AddResourceInfo(const string& plain_text);
148 
149  /// Parse file containing source plaintext data, add (replace) all
150  /// resources to the current file.
151  void ParsePlainTextFile(const string& filename);
152 
153 private:
154  // Generate password for resource data using it's name and
155  // user provided password.
156  string x_GetDataPassword(const string& name_pwd,
157  const string& res_name) const;
158 
159  // Structure to cache decoded resource info
160  struct SResInfoCache {
161  string encoded; // Original encoded values
162  CRef<CNcbiResourceInfo> info; // Decoded data
163  };
164 
166 
167  string m_FileName;
168  mutable TCache m_Cache;
169 };
170 
171 
172 /// "NCBI keys file" -- contains a set of encryption keys, one key per line.
173 /// These files are supposed to be readable only by selected accounts that
174 /// require the use of keys (through CNcbiEncrypt API).
175 ///
176 /// By default, the key file is ".ncbi_keys" in the user's home directory.
177 /// This can be changed via env variable $NCBI_KEY_FILES. There can be more
178 /// than one key file, e.g. $NCBI_KEY_FILES="/foo/.bar:/bar/.foo"
179 ///
181 {
182 public:
183  /// Encrypt a string using key from the 1st line of the 1st NCBI keys file.
184  /// @note The key must be generated using GenerateKey() method.
185  /// @param original_string
186  /// The string to encrypt
187  /// @return
188  /// Encrypted string
189  static string Encrypt(const string& original_string);
190 
191  /// Decrypt a string using the matching key found in the NCBI keys files.
192  /// @note It looks up for the matching key (using key checksum stored
193  /// in the "encrypted_string") in all NCBI keys files.
194  ///
195  /// @note The key must be generated using GenerateKey() method.
196  /// @param encrypted_string
197  /// The string to decrypt. The string may contain domain suffix,
198  /// separated by slash ("<encrypted data>/<domain>"). In this case
199  /// the function will try to find the decryption key for the specified
200  /// domain rather than use the usual set of keys.
201  /// @return
202  /// Decrypted string
203  /// @sa DecryptForDomain
204  static string Decrypt(const string& encrypted_string);
205 
206  /// Re-read key file locations and domain paths, reload encryption keys.
207  static void Reload(void);
208 
209  /// Generate an encryption key from the password, encrypt the string
210  /// using the key.
211  /// @param original_string
212  /// The string to encrypt
213  /// @param password
214  /// The password used to generate the encryption key.
215  /// @return
216  /// Encrypted string
217  static string Encrypt(const string& original_string,
218  const string& password);
219 
220  /// Generate a decryption key from the password, decrypt the string
221  /// using the key.
222  /// @param encrypted_string
223  /// The string to decrypt
224  /// @param password
225  /// The password used to generate the decryption key.
226  /// @return
227  /// Decrypted string
228  static string Decrypt(const string& encrypted_string,
229  const string& password);
230 
231  /// Encrypt data using domain key. Search NCBI_KEY_PATHS for a
232  /// keys file for the specified domain, load the first key from
233  /// the file and use it for encryption. If no domain file is found
234  /// in the paths, throw exception.
235  /// @param original_string
236  /// The string to encrypt
237  /// @param domain
238  /// Keys domain. The corresponding keys file name is ".ncbi_keys.<domain>".
239  /// @return
240  /// Data encrypted using the first key from the first available domain file.
241  /// The encrypted data include domain suffix which can be used for automatic
242  /// decryption.
243  static string EncryptForDomain(const string& original_string,
244  const string& domain);
245 
246  /// Decrypt data using domain key. Search NCBI_KEY_PATHS for a
247  /// keys file for the specified domain, find a key for the
248  /// checksum (stored in the encrypted string), use it for
249  /// decryption. If no domain file is found, throw exception.
250  /// @param encrypted_string
251  /// The string to decrypt. If the string includes domain suffix, it is
252  /// checked as well as the domain passed as the second argument.
253  /// @param domain
254  /// Keys domain. The corresponding keys file name is ".ncbi_keys.<domain>".
255  /// @return
256  /// Decrypted string.
257  static string DecryptForDomain(const string& encrypted_string,
258  const string& domain);
259 
260  /// Generate an encryption/decryption key from the seed string.
261  /// @param seed
262  /// String to be used as a seed for the key. This can be a random
263  /// set of characters, a password provided by user input, or
264  /// anything else.
265  /// @return
266  /// Hexadecimal string representation of the key.
267  static string GenerateKey(const string& seed);
268 
269  /// Check if the string contains valid encrypted data.
270  /// No actual decryption is performed, so some false-positives
271  /// are possible if the string format matches that of the encrypted
272  /// data.
273  /// @param data
274  /// The string to check.
275  /// @return
276  /// True if the string contains data encrypted with CNcbiEncrypt,
277  /// false otherwise.
278  static bool IsEncrypted(const string& data);
279 
280  /// Get encryption API version.
281  static const char* GetVersion(void);
282 
283 private:
284  // Encryption key info
286  {
288  : m_Severity(eDiag_Trace), m_Line(0), m_Version(0)
289  {}
290 
291  SEncryptionKeyInfo(const string& key,
292  EDiagSev sev,
293  const string& file,
294  size_t line,
295  char ver)
296  : m_Key(key),
297  m_Severity(sev),
298  m_File(file),
299  m_Line(line),
300  m_Version(ver)
301  {}
302 
303  string m_Key;
305  string m_File;
306  size_t m_Line;
307  char m_Version; // API version
308  };
309 
310  // Key storage
312 
313  // Load (if not yet loaded) and return key map.
314  static void sx_InitKeyMap(void);
315  // Calculate checksum for a binary (not printable hexadecimal) key.
316  static string x_GetBinKeyChecksum(const string& key);
317  // Load keys from the file, put them in the map. Return the first key
318  // found in the file (or empty string if there are no valid keys).
319  static string x_LoadKeys(const string& filename, TKeyMap* keys);
320  // Load keys from the domain (search NCBI_KEY_PATHS for the domain
321  // file). Return the first key.
322  static string x_GetDomainKeys(const string& domain, TKeyMap* keys);
323  // Encrypt data using the provided binary key.
324  static string x_Encrypt(const string& data, const string& key);
325  // Find a matching key and decrypt data.
326  static string x_Decrypt(const string& data, const TKeyMap& keys);
327 
328  // Salt handling - used starting API version 2.
329  static string x_AddSalt(const string& data, char version);
330  static string x_RemoveSalt(const string& data, char version);
331 
334  static volatile bool s_KeysInitialized;
335 };
336 
337 
338 /// Exception thrown by resource info classes
341 {
342 public:
343  enum EErrCode {
344  eFileSave, //< Failed to save file
345  eParser, //< Error while parsing data
346  eDecrypt //< Error decrypting value
347  };
348 
349  virtual const char* GetErrCodeString(void) const override
350  {
351  switch ( GetErrCode() ) {
352  case eFileSave: return "eFileSave";
353  case eParser: return "eParser";
354  case eDecrypt: return "eDecrypt";
355  default: return CException::GetErrCodeString();
356  }
357  }
358 
360 };
361 
362 
363 /// Exception thrown by encryption classes
366 {
367 public:
368  enum EErrCode {
369  eMissingKey, //< No keys found
370  eBadPassword, //< Bad password string (empty password).
371  eBadFormat, //< Invalid encrypted string format
372  eBadDomain, //< Bad keys domain provided.
373  eBadVersion //< Bad API version in the data.
374  };
375 
376  virtual const char* GetErrCodeString(void) const override
377  {
378  switch ( GetErrCode() ) {
379  case eMissingKey: return "eMissingKey";
380  case eBadPassword: return "eBadPassword";
381  case eBadFormat: return "eBadFormat";
382  case eBadDomain: return "eBadDomain";
383  case eBadVersion: return "eBadVersion";
384  default: return CException::GetErrCodeString();
385  }
386  }
387 
389 };
390 
391 
393 
394 
395 #endif /* CORELIB___RESOURCE_INFO__HPP */
#define bool
Definition: bool.h:34
Exception thrown by encryption classes.
virtual const char * GetErrCodeString(void) const override
NCBI_EXCEPTION_DEFAULT(CNcbiEncryptException, CException)
"NCBI keys file" – contains a set of encryption keys, one key per line.
static CSafeStatic< CNcbiEncrypt::TKeyMap > s_KeyMap
static CSafeStatic< string > s_DefaultKey
map< string, SEncryptionKeyInfo > TKeyMap
static volatile bool s_KeysInitialized
Exception thrown by resource info classes.
NCBI_EXCEPTION_DEFAULT(CNcbiResourceInfoException, CException)
virtual const char * GetErrCodeString(void) const override
Class for handling resource info files.
map< string, SResInfoCache > TCache
Class for storing encrypted resource information.
multimap< string, string > TExtraValuesMap
Types to access extra values.
CStringPairs< TExtraValuesMap > TExtraValues
void SetValue(const string &new_value)
Set new main value for the resource.
CNcbiResourceInfo(const CNcbiResourceInfo &)
bool x_IsEmpty(void) const
const string & GetName(void) const
Get resource name.
TExtraValues & GetExtraValues_NC(void)
Get non-const set of extra values associated with the resource.
const TExtraValues & GetExtraValues(void) const
Get read-only set of extra values associated with the resource.
CNcbiResourceInfo & operator=(const CNcbiResourceInfo &)
TExtraValues m_Extra
const string & GetValue(void) const
Get main value associated with the requested resource.
CObject –.
Definition: ncbiobj.hpp:180
Helper class for object allocation/deallocation.
CSafeStatic<>::
The NCBI C++ standard methods for dealing with std::string.
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
@ eDiag_Trace
Trace message.
Definition: ncbidiag.hpp:657
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
Definition: ncbiexpt.cpp:444
#define EXCEPTION_VIRTUAL_BASE
Do not use virtual base classes in exception declaration at all, because in this case derived class s...
Definition: ncbiexpt.hpp:1388
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
#define NCBI_XNCBI_EXPORT
Definition: ncbi_export.h:1283
FILE * file
static int version
Definition: mdb_load.c:29
const struct ncbi::grid::netcache::search::fields::KEY key
Static variables safety - create on demand, destroy on application termination.
Defines NCBI C++ exception handling.
Portable reference counted smart and weak pointers using CWeakRef, CRef, CObject and CObjectEx.
Defines Limits for the types used in NCBI C/C++ toolkit.
SEncryptionKeyInfo(const string &key, EDiagSev sev, const string &file, size_t line, char ver)
CRef< CNcbiResourceInfo > info
static int seed
Definition: test_table.cpp:132
Modified on Thu Nov 30 04:54:32 2023 by modify_doxy.py rev. 669887