CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DecodingKey.cc
Go to the documentation of this file.
5 //
6 #include <sstream>
7 #include <string.h>
8 #include <fstream>
9 #include <vector>
10 #include <pwd.h>
11 #include <ctime>
12 
15 
16 // character set same as base64, except for last two (missing are + and / )
17 static const char* b64str =
18  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
19 
20 static const std::string KEY_HEADER("Cond_Authentication_Key");
21 
22 static const std::string NAMEPREFIX("N=");
23 static const std::string KEYPREFIX("K=");
24 static const std::string OWNERPREFIX("O=");
25 
26 static const std::string DATEPREFIX("D=");
27 
28 static const std::string SERVICEPREFIX("S=");
29 static const std::string CONNECTIONPREFIX("C=");
30 static const std::string USERPREFIX("U=");
31 static const std::string PASSWORDPREFIX("P=");
32 
33 static const std::string DEFAULT_SERVICE("Cond_Default_Service");
34 
35 namespace cond {
36  char randomChar(){
37  int irand = ::rand()%(::strlen(b64str));
38  return b64str[irand];
39  }
40 
41  std::string getLoginName(){
42  std::string loginName("");
43  struct passwd* userp = ::getpwuid(::getuid());
44  if(userp) {
45  char* uName = userp->pw_name;
46  if(uName){
47  loginName += uName;
48  }
49  }
50  if(loginName.empty()){
51  std::string msg("Cannot determine login name.");
52  throwException(msg,"DecodingKey::getLoginName");
53  }
54  return loginName;
55  }
56 
57  void parseLineForNamedParams( const std::string& line, std::map<std::string,std::string>& params ){
58  std::stringstream str( line );
59  std::string paramName("");
60  std::string paramValue("");
61  while( str.good() ){
62  std::string item("");
63  getline( str, item, ItemSeparator);
64  if( item.size()>3 ){
65  paramName = item.substr(0,2);
66  paramValue = item.substr(2);
67  params.insert( std::make_pair( paramName, paramValue ) );
68  }
69  }
70  }
71 
72 }
73 
74 std::string cond::KeyGenerator::make( size_t keySize ){
75  ::srand( m_iteration+2 );
76  int rseed = ::rand();
77  int seed = ::time( NULL)%10 + rseed;
78  ::srand( seed );
79  std::string ret("");
80  for( size_t i=0;i<keySize; i++ ){
81  ret += randomChar();
82  }
83  m_iteration++;
84  return ret;
85 }
86 
88  ::srand( m_iteration+2 );
89  int rseed = ::rand();
90  int seed = ::time( NULL)%10 + rseed;
91  ::srand( seed );
92  size_t sz = rand()%maxSize;
93  return make( sz );
94 }
95 
96 const std::string cond::DecodingKey::FILE_NAME("db.key");
97 const std::string cond::DecodingKey::FILE_PATH(".cms_cond/"+FILE_NAME);
98 
100  std::stringstream s;
101  s<<NAMEPREFIX<<"<principal_name>"<<std::endl;
102  s<<OWNERPREFIX<<"<owner_name, optional>"<<std::endl;
103  s<<KEYPREFIX<<"<key, leave empty if generated>"<<std::endl;
104  //s<<DATEPREFIX<<"<expiring date, optional>"<<std::endl;
105  s<<SERVICEPREFIX<<"<service_name0>;"<<CONNECTIONPREFIX<<"<service0_connection_string>;"<<USERPREFIX<<"<user0_name>;"<<PASSWORDPREFIX<<"<password0>;"<<std::endl;
106  s<<SERVICEPREFIX<<"<service_name1>;"<<CONNECTIONPREFIX<<"<service1_connection_string>;"<<USERPREFIX<<"<user1_name>;"<<PASSWORDPREFIX<<"<password1>;"<<std::endl;
107  s<<SERVICEPREFIX<<"<service_name2>;"<<CONNECTIONPREFIX<<"<service2_connection_string>;"<<USERPREFIX<<"<user2_name>;"<<PASSWORDPREFIX<<"<password2>;"<<std::endl;
108  return s.str();
109 }
110 
111 size_t cond::DecodingKey::init( const std::string& keyFileName, const std::string& password, bool readMode ){
112  if(keyFileName.empty()){
113  std::string msg("Provided key file name is empty.");
114  throwException(msg,"DecodingKey::init");
115  }
116  m_fileName = keyFileName;
117  m_pwd = password;
118  m_mode = readMode;
119  m_principalName.clear();
120  m_principalKey.clear();
121  m_owner.clear();
122  m_services.clear();
123  size_t nelem = 0;
124  if( m_mode ){
125  std::ifstream keyFile (m_fileName.c_str(),std::ios::in|std::ios::binary|std::ios::ate);
126  if (keyFile.is_open()){
127  size_t fsize = keyFile.tellg();
128  unsigned char* buff = (unsigned char*)malloc( fsize );
129  keyFile.seekg (0, std::ios::beg);
130  keyFile.read (reinterpret_cast<char*>(buff), fsize);
131  Cipher cipher( m_pwd );
132  std::string content = cipher.decrypt( buff, fsize );
133  free ( buff );
134  // skip the header + line separator
135  if( content.substr( 0, KEY_HEADER.size() )!=KEY_HEADER ){
136  std::string msg("Provided key content is invalid.");
137  throwException(msg,"DecodingKey::init");
138  }
139  std::stringstream str( content.substr( KEY_HEADER.size()+1) );
140  while( str.good() ){
141  std::string line;
142  getline ( str, line,LineSeparator );
143  if(line.size()>3 ){
144  if( line.substr(0,2)==NAMEPREFIX ){
145  m_principalName = line.substr(2);
146  } else if ( line.substr(0,2)== KEYPREFIX ){
147  m_principalKey = line.substr(2);
148  } else if ( line.substr(0,2)== OWNERPREFIX ){
149  m_owner = line.substr(2);
150  } else if ( line.substr(0,2)== SERVICEPREFIX ){
151  std::stringstream serviceStr( line.substr(2) );
152  std::vector<std::string> sdata;
153  while( serviceStr.good() ){
154  sdata.push_back( std::string("") );
155  getline( serviceStr, sdata.back(), ItemSeparator);
156  }
157  std::map< std::string, ServiceCredentials >::iterator iS = m_services.insert( std::make_pair( sdata[0], ServiceCredentials() ) ).first;
158  iS->second.connectionString = sdata[1];
159  iS->second.userName = sdata[2];
160  iS->second.password = sdata[3];
161  nelem++;
162  }
163  }
164  }
165  keyFile.close();
166  if( m_principalName.empty() || m_principalKey.empty() ){
167  std::string msg = "Provided key is invalid.";
168  throwException(msg,"DecodingKey::init");
169  }
170  if( !m_owner.empty() ){
171  std::string currentUser = getLoginName();
172  if(m_owner != currentUser ){
173  m_principalName.clear();
174  m_principalKey.clear();
175  m_owner.clear();
176  m_services.clear();
177  std::string msg = "Provided key is invalid for user=" + currentUser;
178  throwException(msg,"DecodingKey::init");
179  }
180  }
181  } else {
182  std::string msg = "Provided Key File \""+m_fileName+"\" is invalid.";
183  throwException(msg,"DecodingKey::init");
184  }
185  }
186  return nelem;
187 }
188 
189 size_t cond::DecodingKey::createFromInputFile( const std::string& inputFileName, size_t generatedKeySize ){
190  size_t nelem = 0;
191  if(inputFileName.empty()){
192  std::string msg("Provided input file name is empty.");
193  throwException(msg,"DecodingKey::readFromInputFile");
194  }
195  m_principalName.clear();
196  m_principalKey.clear();
197  m_owner.clear();
198  m_services.clear();
199  std::ifstream inputFile (inputFileName.c_str());
200  if (inputFile.is_open()){
201  std::map<std::string,std::string> params;
202  while ( inputFile.good() ){
203  std::string line;
204  getline (inputFile, line);
205  params.clear();
206  if(line.size()>3 ){
207  if( line.substr(0,2)==NAMEPREFIX ){
208  m_principalName = line.substr(2);
209  } else if ( line.substr(0,2)== KEYPREFIX ){
210  m_principalKey = line.substr(2);
211  } else if ( line.substr(0,2)== OWNERPREFIX ){
212  m_owner = line.substr(2);
213  } else if ( line.substr(0,2)== SERVICEPREFIX ){
214  parseLineForNamedParams( line, params );
215  std::string& serviceName = params[ SERVICEPREFIX ];
216  ServiceCredentials creds;
217  creds.connectionString = params[ CONNECTIONPREFIX ];
218  creds.userName = params[ USERPREFIX ];
219  creds.password = params[ PASSWORDPREFIX ];
220  m_services.insert( std::make_pair( serviceName, creds ) );
221  nelem++;
222  }
223  }
224  }
225  inputFile.close();
226  if( m_principalKey.empty() && generatedKeySize){
228  m_principalKey = gen.make( generatedKeySize );
229  }
230 
231  } else {
232  std::string msg = "Provided Input File \""+inputFileName+"\n is invalid.";
233  throwException(msg,"DecodingKey::readFromInputFile");
234  }
235  return nelem;
236 }
237 
238 void cond::DecodingKey::list( std::ostream& out ){
239  out <<NAMEPREFIX<<m_principalName<<std::endl;
240  out <<KEYPREFIX<<m_principalKey<<std::endl;
241  out <<OWNERPREFIX<<m_owner<<std::endl;
242  for( std::map< std::string, ServiceCredentials >::const_iterator iS = m_services.begin();
243  iS != m_services.end(); iS++ ){
244  out <<SERVICEPREFIX<<iS->first<<";";
245  out <<CONNECTIONPREFIX<<iS->second.connectionString<<";";
246  out <<USERPREFIX<<iS->second.userName<<";";
247  out <<PASSWORDPREFIX<<iS->second.password<<";"<<std::endl;
248  }
249 }
250 
252  std::ofstream outFile ( m_fileName.c_str(),std::ios::binary);
253  if (outFile.is_open()){
254  std::stringstream content;
255  content << KEY_HEADER << LineSeparator;
256  if( !m_principalName.empty() ){
257  content << NAMEPREFIX << m_principalName << LineSeparator;
258  }
259  if( !m_principalKey.empty() ){
260  content << KEYPREFIX << m_principalKey << LineSeparator;
261  }
262  if( !m_owner.empty() ){
263  content << OWNERPREFIX << m_owner << LineSeparator;
264  }
265  for( std::map< std::string, ServiceCredentials >::const_iterator iD = m_services.begin();
266  iD != m_services.end(); ++iD ){
267  content << SERVICEPREFIX << iD->first << ItemSeparator;
268  content << iD->second.connectionString << ItemSeparator;
269  content << iD->second.userName << ItemSeparator;
270  content << iD->second.password << ItemSeparator;
271  content << LineSeparator;
272  }
273  Cipher cipher( m_pwd );
274  unsigned char* out;
275  size_t outSize = cipher.encrypt( content.str(), out );
276  outFile.write( reinterpret_cast<char*>(out),outSize);
277  free (out );
278  } else {
279  std::string msg("");
280  msg += "Provided Key File \""+m_fileName+"\n is invalid.";
281  throwException(msg,"DecodingKey::flush");
282  }
283  outFile.close();
284 }
285 
286 void cond::DecodingKey::addDefaultService( const std::string& connectionString ){
287  addService( DEFAULT_SERVICE, connectionString, "", "" );
288 }
289 
290 void cond::DecodingKey::addService( const std::string& serviceName,
291  const std::string& connectionString,
292  const std::string& userName,
293  const std::string& password ){
294  std::map< std::string, ServiceCredentials >::iterator iK = m_services.find( serviceName );
295  if( iK == m_services.end() ){
296  iK = m_services.insert( std::make_pair( serviceName, ServiceCredentials() ) ).first;
297  }
298  iK->second.connectionString = connectionString;
299  iK->second.userName = userName;
300  iK->second.password = password;
301 }
302 
static const std::string FILE_PATH
Definition: DecodingKey.h:37
int i
Definition: DBlmapReader.cc:9
void addService(const std::string &serviceName, const std::string &connectionString, const std::string &userName, const std::string &password)
Definition: DecodingKey.cc:290
static const std::string KEYPREFIX("K=")
std::string makeWithRandomSize(size_t maxSize)
Definition: DecodingKey.cc:87
static std::string templateFile()
Definition: DecodingKey.cc:99
std::string connectionString
Definition: DecodingKey.h:13
void addDefaultService(const std::string &connectionString)
Definition: DecodingKey.cc:286
void parseLineForNamedParams(const std::string &line, std::map< std::string, std::string > &params)
Definition: DecodingKey.cc:57
S make(const edm::ParameterSet &cfg)
std::string getLoginName()
Definition: DecodingKey.cc:41
#define NULL
Definition: scimark2.h:8
static const std::string USERPREFIX("U=")
std::string decrypt(const unsigned char *input, size_t inputSize)
Definition: Cipher.cc:66
static const std::string serviceName
static const std::string SERVICEPREFIX("S=")
static const std::string DATEPREFIX("D=")
static const char * b64str
Definition: DecodingKey.cc:17
static const std::string KEY_HEADER("Cond_Authentication_Key")
constexpr char LineSeparator
Definition: DecodingKey.cc:14
static const std::string DEFAULT_SERVICE("Cond_Default_Service")
tuple maxSize
&#39;/store/data/Commissioning08/BeamHalo/RECO/StuffAlmostToP5_v1/000/061/642/10A0FE34-A67D-DD11-AD05-000...
size_t encrypt(const std::string &input, unsigned char *&output)
Definition: Cipher.cc:62
size_t createFromInputFile(const std::string &inputFileName, size_t generatedKeySize=0)
Definition: DecodingKey.cc:189
void list(std::ostream &out)
Definition: DecodingKey.cc:238
constexpr char ItemSeparator
Definition: DecodingKey.cc:13
tuple out
Definition: dbtoconf.py:99
static const std::string PASSWORDPREFIX("P=")
size_t init(const std::string &keyFileName, const std::string &password, bool readMode=true)
Definition: DecodingKey.cc:111
void throwException(std::string const &message, std::string const &methodName)
Definition: Exception.cc:17
static const std::string OWNERPREFIX("O=")
std::string make(size_t keySize)
Definition: DecodingKey.cc:74
static const std::string CONNECTIONPREFIX("C=")
static const std::string NAMEPREFIX("N=")
static const std::string keyFile("/nfshome0/hcalsw/.ReadOMDSKey")
Signal rand(Signal arg)
Definition: vlib.cc:442
char randomChar()
Definition: DecodingKey.cc:36
static const std::string FILE_NAME
Definition: DecodingKey.h:36
#define constexpr