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