1 kumpf 1.2 /*
2 //%2006////////////////////////////////////////////////////////////////////////
3 //
4 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
5 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
6 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
7 // IBM Corp.; EMC Corporation, The Open Group.
8 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
9 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
10 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
11 // EMC Corporation; VERITAS Software Corporation; The Open Group.
12 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
13 // EMC Corporation; Symantec Corporation; The Open Group.
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining a copy
16 // of this software and associated documentation files (the "Software"), to
17 // deal in the Software without restriction, including without limitation the
18 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
19 // sell copies of the Software, and to permit persons to whom the Software is
20 // furnished to do so, subject to the following conditions:
21 //
22 kumpf 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
23 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
24 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
25 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
26 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 //%/////////////////////////////////////////////////////////////////////////////
32 */
33 #include "LocalAuth.h"
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
38 #include <sys/time.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <pthread.h>
43 kumpf 1.2 #include "Defines.h"
44 #include "Strlcpy.h"
45 #include "Strlcat.h"
46 #include "User.h"
47 #include "Random.h"
48 #include "Log.h"
49 #include "User.h"
50
51 #define TOKEN_LENGTH 40
52
53 /*
54 **==============================================================================
55 **
56 ** CreateLocalAuthFile()
57 **
58 ** This function creates a local authentication file for the given *user*.
59 ** it populates the *path* argument and return 0 on success. The file has
60 ** the following format.
61 **
62 ** PEGASUS_LOCAL_AUTH_DIR/cimclient_<user>_<timestamp>_<seq>
63 **
64 kumpf 1.2 ** For example:
65 **
66 **
67 ** The algorithm:
68 **
69 ** 1. Form the path name as shown above.
70 ** (e.g., /tmp/cimclient_jsmith_1_232).
71 **
72 ** 2. Generate a random token
73 ** (e.g., 8F85CB1129B2B93F77F5CCA16850D659CCD16FE0).
74 **
75 ** 3. Create the file (owner=root, permissions=0400).
76 **
77 ** 4. Write random token to file.
78 **
79 ** 5. Change owner of file to *user*.
80 **
81 **==============================================================================
82 */
83
84 static int CreateLocalAuthFile(
85 kumpf 1.2 const char* user,
86 char path[EXECUTOR_BUFFER_SIZE])
87 {
88 static unsigned int _nextSeq = 1;
89 static pthread_mutex_t _nextSeqMutex = PTHREAD_MUTEX_INITIALIZER;
90 unsigned int seq;
91 struct timeval tv;
92 char buffer[EXECUTOR_BUFFER_SIZE];
93 char token[TOKEN_LENGTH+1];
94 int fd;
95 int uid;
96 int gid;
97
98 /* Assign next sequence number. */
99
100 pthread_mutex_lock(&_nextSeqMutex);
101 seq = _nextSeq++;
102 pthread_mutex_unlock(&_nextSeqMutex);
103
104 /* Get microseconds elapsed since epoch. */
105
106 kumpf 1.2 gettimeofday(&tv, NULL);
107
108 /* Build path: */
109
110 Strlcpy(path, PEGASUS_LOCAL_AUTH_DIR, EXECUTOR_BUFFER_SIZE);
111 Strlcat(path, "/cimclient_", EXECUTOR_BUFFER_SIZE);
112 Strlcat(path, user, EXECUTOR_BUFFER_SIZE);
113 sprintf(buffer, "_%u_%u", seq, (int)(tv.tv_usec / 1000));
114 Strlcat(path, buffer, EXECUTOR_BUFFER_SIZE);
115
116 /* Generate random token. */
117
118 {
119 unsigned char data[TOKEN_LENGTH/2];
120 FillRandomBytes(data, sizeof(data));
121 RandBytesToHexASCII(data, sizeof(data), token);
122 }
123
124 /* If file already exists, remove it. */
125
126 /* Flawfinder: ignore */
127 kumpf 1.2 if (access(path, F_OK) == 0 && unlink(path) != 0)
128 return -1;
129
130 /* Create the file as read-only by user. */
131
132 fd = open(path, O_WRONLY | O_EXCL | O_CREAT | O_TRUNC, S_IRUSR);
133
134 if (fd < 0)
135 return -1;
136
137 /* Write the random token. */
138
139 if (write(fd, token, TOKEN_LENGTH) != TOKEN_LENGTH)
140 {
141 close(fd);
142 unlink(path);
143 return -1;
144 }
145
146 /* Change owner of file. */
147
148 kumpf 1.2 if (GetUserInfo(user, &uid, &gid) != 0)
149 {
150 close(fd);
151 unlink(path);
152 return -1;
153 }
154
155 if (fchown(fd, uid, gid) != 0)
156 {
157 close(fd);
158 unlink(path);
159 return -1;
160 }
161
162 close(fd);
163 return 0;
164 }
165
166 /*
167 **==============================================================================
168 **
169 kumpf 1.2 ** CheckLocalAuthToken()
170 **
171 ** Compare the *token* with the token in the given file. Return 0 if they
172 ** are identical.
173 **
174 **==============================================================================
175 */
176
177 static int CheckLocalAuthToken(
178 const char* path,
179 const char* token)
180 {
181 char buffer[TOKEN_LENGTH+1];
182 int fd;
183
184 /* Open the file: */
185
186 if ((fd = open(path, O_RDONLY)) < 0)
187 return -1;
188
189 /* Read the token. */
190 kumpf 1.2
191 if (read(fd, buffer, TOKEN_LENGTH) != TOKEN_LENGTH)
192 {
193 close(fd);
194 return -1;
195 }
196
197 buffer[TOKEN_LENGTH] = '\0';
198
199 /* Compare the token. */
200
201 if (strcmp(token, buffer) != 0)
202 {
203 close(fd);
204 return -1;
205 }
206
207 /* Okay! */
208 close(fd);
209 return 0;
210 }
211 kumpf 1.2
212 /*
213 **==============================================================================
214 **
215 ** StartLocalAuthentication()
216 **
217 ** Initiate first phase of local authentication.
218 **
219 **==============================================================================
220 */
221
222 int StartLocalAuthentication(
223 const char* user,
224 char challenge[EXECUTOR_BUFFER_SIZE])
225 {
226 /* Get uid: */
227
228 int uid;
229 int gid;
230
231 if (GetUserInfo(user, &uid, &gid) != 0)
232 kumpf 1.2 return -1;
233
234 /* Create the local authentication file. */
235
236 if (CreateLocalAuthFile(user, challenge) != 0)
237 return -1;
238
239 return 0;
240 }
241
242 /*
243 **==============================================================================
244 **
245 ** FinishLocalAuthentication()
246 **
247 ** Initiate second and last phase of local authentication. Else return
248 ** negative one.
249 **
250 **==============================================================================
251 */
252
253 kumpf 1.2 int FinishLocalAuthentication(
254 const char* challenge,
255 const char* response)
256 {
257 /* Check token against the one in the file. */
258
259 int rc = CheckLocalAuthToken(challenge, response);
260
261 if (challenge)
262 unlink((char*)challenge);
263
264 return rc;
265 }
|