(file) Return to LocalAuthFile.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Security / Authentication

  1 martin 1.29 //%LICENSE////////////////////////////////////////////////////////////////
  2 martin 1.30 //
  3 martin 1.29 // Licensed to The Open Group (TOG) under one or more contributor license
  4             // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
  5             // this work for additional information regarding copyright ownership.
  6             // Each contributor licenses this file to you under the OpenPegasus Open
  7             // Source License; you may not use this file except in compliance with the
  8             // License.
  9 martin 1.30 //
 10 martin 1.29 // Permission is hereby granted, free of charge, to any person obtaining a
 11             // copy of this software and associated documentation files (the "Software"),
 12             // to deal in the Software without restriction, including without limitation
 13             // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 14             // and/or sell copies of the Software, and to permit persons to whom the
 15             // Software is furnished to do so, subject to the following conditions:
 16 martin 1.30 //
 17 martin 1.29 // The above copyright notice and this permission notice shall be included
 18             // in all copies or substantial portions of the Software.
 19 martin 1.30 //
 20 martin 1.29 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21 martin 1.30 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22 martin 1.29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 23             // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24             // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 25             // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 26             // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27 martin 1.30 //
 28 martin 1.29 //////////////////////////////////////////////////////////////////////////
 29 mike   1.2  //
 30             //%/////////////////////////////////////////////////////////////////////////////
 31             
 32             #include "LocalAuthFile.h"
 33             
 34 tony   1.5  #include <fstream>
 35             #include <errno.h>
 36             #include <sys/stat.h>
 37             #include <sys/types.h>
 38             #ifndef PEGASUS_OS_TYPE_WINDOWS
 39 kumpf  1.25 # include <sys/time.h>
 40             # include <unistd.h>
 41 tony   1.5  #endif
 42             
 43             #include <Pegasus/Common/System.h>
 44             #include <Pegasus/Common/FileSystem.h>
 45             #include <Pegasus/Common/Tracer.h>
 46 mike   1.18 #include <Pegasus/Common/Mutex.h>
 47 tony   1.5  #include <Pegasus/Config/ConfigManager.h>
 48             
 49             #include "LocalAuthFile.h"
 50             
 51 ouyang.jian 1.24 #if defined(PEGASUS_OS_TYPE_WINDOWS)
 52 kumpf       1.25 // srandom() and random() are srand() and rand() on OS/400 and windows
 53                  # define srandom(x) srand(x)
 54                  # define random() rand()
 55 tony        1.5  #endif
 56                  
 57                  
 58                  PEGASUS_USING_STD;
 59                  
 60                  PEGASUS_NAMESPACE_BEGIN
 61                  
 62                  //
 63                  // Constant representing the random seed for srandom function
 64                  //
 65                  const Uint32 RANDOM_SEED     =  100;
 66                  
 67                  //
 68                  // File path used to create temporary random file
 69                  //
 70                  const char TMP_AUTH_FILE_NAME []  =  "/cimclient_";
 71                  
 72                  //
 73                  // Constant representing the int buffer size
 74                  //
 75                  const Uint32 INT_BUFFER_SIZE = 16;
 76 tony        1.5  
 77                  //
 78                  // Constant representing the random device name
 79                  //
 80                  const char DEV_URANDOM []    =  "/dev/urandom";
 81                  
 82                  //
 83 kumpf       1.25 // Constant representing the size of random entropy needed.
 84                  // Require minimum 160 bits = 20 bytes of randomness.
 85 tony        1.5  //
 86 kumpf       1.25 const Uint32 RANDOM_BYTES_NEEDED = 20;
 87 tony        1.5  
 88                  //
 89                  // A unique sequence number used in random file name creation.
 90                  //
 91                  static Uint32 sequenceCount = 1;
 92                  static Mutex sequenceCountLock;
 93                  
 94                  
 95                  
 96                  LocalAuthFile::LocalAuthFile(const String& userName)
 97 sushma.fernandes 1.23     : _userName(userName)
 98 tony             1.5  {
 99                           PEG_METHOD_ENTER(TRC_AUTHENTICATION, "LocalAuthFile::LocalAuthFile()");
100                       
101                           srandom(RANDOM_SEED);
102                       
103                           //
104                           // get the configured temporary authentication file path
105                           //
106 h.sterling       1.12     _authFilePath = PEGASUS_LOCAL_AUTH_DIR;
107 tony             1.5  
108 mike             1.2  #if defined(PEGASUS_OS_TYPE_WINDOWS)
109 tony             1.5      System::makeDirectory((const char *)_authFilePath.getCString());
110                       #endif
111                           _authFilePath.append(TMP_AUTH_FILE_NAME);
112                       
113                           PEG_METHOD_EXIT();
114                       }
115                       
116 kumpf            1.25 LocalAuthFile::~LocalAuthFile()
117                       {
118 tony             1.5      PEG_METHOD_ENTER(TRC_AUTHENTICATION, "LocalAuthFile::~LocalAuthFile()");
119                       
120                           PEG_METHOD_EXIT();
121                       }
122                       
123                       //
124                       // create a file and make a random token data entry to it.
125                       // send the file name back to caller
126                       //
127                       String LocalAuthFile::create()
128                       {
129                           PEG_METHOD_ENTER(TRC_AUTHENTICATION, "LocalAuthFile::create()");
130                       
131                           Uint32 secs, milliSecs;
132                           Uint32 mySequenceNumber;
133                       
134                           System::getCurrentTime(secs, milliSecs);
135                       
136                           //
137                           // extension size is username plus the sequence count
138                           //
139 a.arora          1.6      {
140 kumpf            1.25         AutoMutex autoMut(sequenceCountLock);
141                               mySequenceNumber = sequenceCount++;
142 a.arora          1.6      } // mutex unlocks here
143 tony             1.5  
144                           char extension[2*INT_BUFFER_SIZE];
145                           sprintf(extension,"_%u_%u", mySequenceNumber, milliSecs);
146                           extension[strlen(extension)] = 0;
147                       
148 sushma.fernandes 1.23     String filePath;
149 tony             1.5  
150 kumpf            1.25     // Check to see whether a domain was specified. If so, strip the domain
151                           // from the local auth file name, since the backslash and '@' are invalid
152                           // filename characters.  Store this in another variable, since we need to
153                           // keep the domain around for the rest of the operations.
154                           String fileUserName = _userName;
155                           Uint32 index = _userName.find('\\');
156                           if (index != PEG_NOT_FOUND)
157                           {
158                               fileUserName = _userName.subString(index + 1);
159                           }
160                           else
161                           {
162                               index = _userName.find('@');
163                               if (index != PEG_NOT_FOUND)
164                               {
165                                   fileUserName = _userName.subString(0, index);
166                               }
167                           }
168 h.sterling       1.10 
169 tony             1.5      filePath.append(_authFilePath);
170 h.sterling       1.10     filePath.append(fileUserName);//_userName);
171 tony             1.5      filePath.append(extension);
172                           CString filePathCString = filePath.getCString();
173                       
174                           //
175                           // 1. Create a file name for authentication.
176                           //
177                           ofstream outfs(filePathCString);
178 ouyang.jian      1.24 
179 tony             1.5      if (!outfs)
180                           {
181                               // unable to create file
182 yi.zhou          1.21         Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
183 kumpf            1.28             MessageLoaderParms(
184                                       "Security.Authentication.LocalAuthFile.NO_CREATE",
185                                       "Creation of the local authentication security file"
186                                           " $0 failed: $1",
187                                       filePath, strerror(errno)));
188 tony             1.5          PEG_METHOD_EXIT();
189                               throw CannotOpenFile (filePath);
190                           }
191                           outfs.clear();
192                       
193                           //
194 thilo.boehm      1.13     // 2. Set file permission to read/write by the owner only.
195 tony             1.5      //
196 thilo.boehm      1.13 
197 kumpf            1.25 #if defined(PEGASUS_OS_TYPE_WINDOWS)
198                           Boolean success =
199                               FileSystem::changeFilePermissions(filePath, _S_IREAD | _S_IWRITE);
200                       #else
201                           Boolean success =
202                               FileSystem::changeFilePermissions(filePath, S_IRUSR | S_IWUSR);
203                       #endif
204                       
205                           if (!success)
206 tony             1.5      {
207 kumpf            1.25         // Unable to change the local auth file permissions, remove the file
208 tony             1.5          // and throw CannotOpenFile error.
209 yi.zhou          1.21         Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
210 kumpf            1.28             MessageLoaderParms(
211                                       "Security.Authentication.LocalAuthFile.NO_CHMOD",
212                                       "Changing permissions of the local authentication security "
213                                           "file $0 failed: $1",
214                                       filePath, strerror(errno)));
215 tony             1.5  
216                               if (filePath.size())
217                               {
218                                   if (FileSystem::exists(filePath))
219                                   {
220                                       FileSystem::removeFile(filePath);
221                                   }
222                               }
223                       
224 thilo.boehm      1.19         PEG_METHOD_EXIT();
225 tony             1.5          throw CannotOpenFile (filePath);
226                           }
227                       
228                           //
229                           // 3. Generate random token and write the token to the file.
230                           //
231                           String randomToken = _generateRandomTokenString();
232                           outfs << randomToken;
233 thilo.boehm      1.19 
234                           // test if the write was successful
235                           if (outfs.fail())
236                           {
237 yi.zhou          1.21         Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
238 kumpf            1.28             MessageLoaderParms(
239                                       "Security.Authentication.LocalAuthFile.NO_WRITE",
240                                       "Cannot write security token to the local authentication "
241                                           "security file $0.",
242                                       filePath));
243 thilo.boehm      1.19 
244                               if (filePath.size())
245                               {
246                                   if (FileSystem::exists(filePath))
247                                   {
248                                       FileSystem::removeFile(filePath);
249                                   }
250                               }
251                       
252                               PEG_METHOD_EXIT();
253                               throw CannotOpenFile (filePath);
254                       
255                           }
256 kumpf            1.25 
257 tony             1.5      outfs.close();
258                       
259                           //
260 thilo.boehm      1.13     // 4. Set file permission to read only by the owner.
261                           //
262 kumpf            1.25 #if defined(PEGASUS_OS_TYPE_WINDOWS)
263                           success = FileSystem::changeFilePermissions(filePath, _S_IREAD);
264                       #else
265                           success = FileSystem::changeFilePermissions(filePath, S_IRUSR);
266                       #endif
267 thilo.boehm      1.13 
268 kumpf            1.25     if (!success)
269 thilo.boehm      1.13     {
270 kumpf            1.25         // Unable to change the local auth file permissions, remove the file
271 thilo.boehm      1.13         // and throw CannotOpenFile error.
272 yi.zhou          1.21         Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
273 kumpf            1.28             MessageLoaderParms(
274                                       "Security.Authentication.LocalAuthFile.NO_CHMOD",
275                                       "Changing permissions of the local authentication security "
276                                           "file $0 failed: $1",
277                                       filePath, strerror(errno)));
278 thilo.boehm      1.13 
279                               if (filePath.size())
280                               {
281                                   if (FileSystem::exists(filePath))
282                                   {
283                                       FileSystem::removeFile(filePath);
284                                   }
285                               }
286                       
287 thilo.boehm      1.19         PEG_METHOD_EXIT();
288 thilo.boehm      1.13         throw CannotOpenFile (filePath);
289                           }
290                       
291                           //
292                           // 5. Change the file owner to the requesting user.
293 tony             1.5      //
294 msolomon         1.20 
295                           if (!FileSystem::changeFileOwner(filePath,_userName))
296 tony             1.5      {
297                               // Unable to change owner on local auth file, remove the file
298                               // and throw CannotOpenFile error.
299                       
300 yi.zhou          1.21         Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
301 kumpf            1.28             MessageLoaderParms(
302                                       "Security.Authentication.LocalAuthFile.NO_CHOWN_REQUSER",
303                                       "Changing ownership of the local authentication "
304                                           "security file $0 to the requesting user failed: $1",
305                                       filePath, strerror(errno)));
306 thilo.boehm      1.19 
307 tony             1.5          if (filePath.size())
308                               {
309                                   if (FileSystem::exists(filePath))
310                                   {
311                                       FileSystem::removeFile(filePath);
312                                   }
313                               }
314                       
315 thilo.boehm      1.19         PEG_METHOD_EXIT();
316 tony             1.5          throw CannotOpenFile (filePath);
317                           }
318                       
319 sushma.fernandes 1.23     _secret = randomToken;
320 tony             1.5  
321                           _filePathName = filePath;
322                       
323                           PEG_METHOD_EXIT();
324                       
325 kumpf            1.25     return _filePathName;
326 tony             1.5  }
327                       
328                       //
329                       //  Removes the file that was created
330                       //
331                       Boolean LocalAuthFile::remove()
332                       {
333                           PEG_METHOD_ENTER(TRC_AUTHENTICATION, "LocalAuthFile::remove()");
334                       
335                           Boolean retVal = true;
336                       
337                           //
338                           // remove the file
339                           //
340                           if (FileSystem::exists(_filePathName))
341                           {
342 kumpf            1.25 
343 a.dunfey         1.22 #if !defined(PEGASUS_OS_TYPE_WINDOWS)
344 a.dunfey         1.17         // change ownership back to the CIMOM
345 kumpf            1.25         int rc = chown(
346                                   (const char *)_filePathName.getCString(), geteuid(), getegid());
347                       
348                               if (rc == -1)
349                               {
350 yi.zhou          1.21             Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
351 kumpf            1.28                 MessageLoaderParms(
352                                           "Security.Authentication.LocalAuthFile.NO_CHOWN",
353                                           "Changing ownership of the local authentication "
354                                               "security file back to the CIMServer UserId failed."));
355 marek            1.16         }
356 a.dunfey         1.17 #endif
357 marek            1.16 
358 tony             1.5          retVal = FileSystem::removeFile(_filePathName);
359                           }
360                       
361                           PEG_METHOD_EXIT();
362                       
363 kumpf            1.25     return retVal;
364 tony             1.5  }
365                       
366                       //
367 sushma.fernandes 1.23 // Get the string that was created as a secret string
368 tony             1.5  //
369 sushma.fernandes 1.23 String LocalAuthFile::getSecretString()
370 tony             1.5  {
371 sushma.fernandes 1.23     PEG_METHOD_ENTER(TRC_AUTHENTICATION, "LocalAuthFile::getSecretString()");
372 tony             1.5  
373                           PEG_METHOD_EXIT();
374                       
375 kumpf            1.25     return _secret;
376 tony             1.5  }
377                       
378                       
379                       //
380                       // Generate  random token string
381                       //
382                       String LocalAuthFile::_generateRandomTokenString()
383                       {
384 kumpf            1.25     PEG_METHOD_ENTER(TRC_AUTHENTICATION,
385 tony             1.5          "LocalAuthFile::_generateRandomTokenString()");
386                       
387 sushma.fernandes 1.23     String randomToken;
388 tony             1.5  
389                           String randFile = String(DEV_URANDOM);
390                           FILE *fh;
391                       
392                           //
393                           // If /dev/urandom exists then read random token from /dev/urandom
394                           //
395 kumpf            1.25     if ((fh = fopen( (const char *)randFile.getCString(), "r")) != NULL)
396 tony             1.5      {
397                               char token[RANDOM_BYTES_NEEDED+1];
398                       
399                               setvbuf(fh, NULL, _IONBF, 0);   // need unbuffered input
400 a.dunfey         1.22         Uint32 n = (Uint32)fread( (unsigned char *)token, 1,
401                                   RANDOM_BYTES_NEEDED, fh );
402 tony             1.5          fclose(fh);
403                               token[n]=0;
404                       
405                               randomToken.clear();
406                               char hexChar[10];
407                       
408                               for (Uint32 i=0; i < n; i++)
409                               {
410                                   sprintf(hexChar, "%X", (unsigned char)token[i]);
411                                   randomToken.append(String(hexChar));
412                                   memset(hexChar, 0x00, sizeof(hexChar));
413                               }
414                           }
415                       
416                           char token[2*INT_BUFFER_SIZE];
417                           Uint32 seconds, milliseconds;
418                       
419                           System::getCurrentTime(seconds, milliseconds);
420                       
421                           //
422                           // generate a random token
423 tony             1.5      //
424                           char randnum[] = { '0' + (random() % 10), '0' + (random() % 10), '\0' };
425                           long randomNum = atol(randnum);
426                       
427 kumpf            1.27     sprintf (token,"%ld%u", randomNum, seconds + milliseconds );
428 tony             1.5      token[strlen(token)] = 0;
429                       
430                           randomToken.append(_userName);
431                           randomToken.append(token);
432                       
433                           PEG_METHOD_EXIT();
434                       
435 kumpf            1.25     return randomToken;
436 tony             1.5  }
437                       
438                       PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2