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