15 #include <openssl/md5.h>
16 #include "boost/filesystem.hpp"
18 #ifndef windows_platform
20 #include <sys/types.h>
37 static char fname[] =
"osauthVerifyResponse";
38 char authenticator[16];
54 "%s: error retrieving key.", fname );
64 "%s: could not generate the authenticator", fname );
72 memset( md5buffer, 0,
sizeof( md5buffer ) );
73 memset( md5digest, 0,
sizeof( md5digest ) );
78 MD5_Final( (
unsigned char* )md5digest, &ctx );
82 if ( md5digest[i] ==
'\0' ) {
89 if ( response[i] != md5digest[i] ) {
108 char *challenge,
char *key,
int key_len,
109 char *authenticator,
int authenticator_len ) {
110 static char fname[] =
"osauthGenerateAuthenticator";
116 if ( authenticator ==
NULL ||
117 authenticator_len < 16 ) {
122 buflen = username ? strlen( username ) : 0;
124 buffer = (
char* )malloc( buflen );
127 "%s: could not allocate memory buffer. errno = %d",
134 if ( username && strlen( username ) ) {
135 memcpy( bufp, username, strlen( username ) );
136 bufp += strlen( username );
138 memcpy( bufp, &uid,
sizeof( uid ) );
139 bufp +=
sizeof( uid );
145 memcpy( bufp, key, key_len );
151 MD5_Update( &ctx, (
unsigned char* )
buffer, buflen );
152 MD5_Final( (
unsigned char* )md5digest, &ctx );
153 memcpy( authenticator, md5digest, 16 );
168 static char fname[] =
"osauthGetKey";
170 int buflen, key_fd, nb;
172 if ( key ==
NULL || key_len ==
NULL ) {
178 std::string default_os_auth_keyfile_path_string = default_os_auth_keyfile_path.string();
180 keyfile = getenv(
"irodsOsAuthKeyfile" );
181 if ( keyfile ==
NULL || *keyfile ==
'\0' ) {
182 keyfile = default_os_auth_keyfile_path_string.c_str();
185 key_fd = open( keyfile, O_RDONLY, 0 );
188 "%s: couldn't open %s for reading. errno = %d",
189 fname, keyfile, errno );
192 off_t lseek_return = lseek( key_fd, 0, SEEK_END );
194 if ( ( off_t ) - 1 == lseek_return ) {
195 fprintf( stderr,
"SEEK_END lseek failed with error %d.\n", errsv );
199 if ( lseek_return > std::numeric_limits<long long>::max() ) {
200 fprintf( stderr,
"file of size %ju is too large for a long long.\n", ( uintmax_t )lseek_return );
204 buflen = lseek_return;
205 lseek_return = lseek( key_fd, 0, SEEK_SET );
207 if ( ( off_t ) - 1 == lseek_return ) {
208 fprintf( stderr,
"SEEK_SET lseek failed with error %d.\n", errsv );
213 char * keybuf = (
char* )malloc( buflen );
214 if ( keybuf ==
NULL ) {
216 "%s: could not allocate memory for key buffer. errno = %d",
221 nb = read( key_fd, keybuf, buflen );
225 "%s: couldn't read key from %s. errno = %d",
226 fname, keyfile, errno );
245 int authenticator_buflen ) {
246 static char fname[] =
"osauthGetAuth";
247 int pipe1[2], pipe2[2];
249 int child_stdin, child_stdout, nb;
253 if ( challenge ==
NULL || username ==
NULL || authenticator ==
NULL ) {
257 if ( pipe( pipe1 ) < 0 ) {
262 if ( pipe( pipe2 ) < 0 ) {
275 posix_spawnattr_t attr;
276 posix_spawnattr_init(&attr);
278 posix_spawn_file_actions_t file_actions;
279 posix_spawn_file_actions_init(&file_actions);
280 posix_spawn_file_actions_addclose(&file_actions, pipe1[1]);
281 posix_spawn_file_actions_addclose(&file_actions, pipe2[0]);
282 posix_spawn_file_actions_adddup2(&file_actions, pipe1[0], 0);
283 posix_spawn_file_actions_adddup2(&file_actions, pipe2[1], 1);
285 std::string os_auth_command_path_string(os_auth_command_path.string());
286 char * argv[] = {&os_auth_command_path_string[0],
nullptr};
289 for (environ_end =
environ; *environ_end !=
nullptr; ++environ_end);
290 std::vector<char *> envp(
environ, environ_end);
292 env_var.append(username);
293 envp.back() = &env_var[0];
294 envp.push_back(
nullptr);
296 int status = posix_spawn(&childPid, os_auth_command_path_string.c_str(), &file_actions, &attr, &argv[0], &envp[0]);
297 posix_spawnattr_destroy(&attr);
298 posix_spawn_file_actions_destroy(&file_actions);
310 child_stdin = pipe1[1];
312 child_stdout = pipe2[0];
315 nb = write( child_stdin, &challenge_len,
sizeof( challenge_len ) );
318 "%s: error writing challenge_len to %s. errno = %d",
319 fname, os_auth_command_path.string().c_str(), errno );
320 close( child_stdin );
321 close( child_stdout );
324 nb = write( child_stdin, challenge, challenge_len );
327 "%s: error writing challenge to %s. errno = %d",
328 fname, os_auth_command_path.string().c_str(), errno );
329 close( child_stdin );
330 close( child_stdout );
335 buflen = read( child_stdout,
buffer, 128 );
338 fname, os_auth_command_path.string().c_str(), errno );
339 close( child_stdin );
340 close( child_stdout );
344 close( child_stdin );
345 close( child_stdout );
347 if ( waitpid( childPid, &childStatus, 0 ) < 0 ) {
353 if ( WIFEXITED( childStatus ) ) {
354 if ( WEXITSTATUS( childStatus ) ) {
356 "%s: command failed: %s", fname,
buffer );
362 "%s: some error running %s", fname, os_auth_command_path.string().c_str() );
366 if ( buflen > authenticator_buflen ) {
368 "%s: not enough space in return buffer for authenticator", fname );
371 memcpy( authenticator,
buffer, buflen );
382 if (
NULL == username ) {
383 rodsLog(
LOG_ERROR,
"Error: osauthGetUid called with null username argument." );
386 static char fname[] =
"osauthGetUid";
389 struct passwd *pwent = getpwnam( username );
390 if ( pwent ==
NULL ) {
393 "%s: error calling getpwnam for %s. errno = %d",
394 fname, username, errno );
399 "%s: no such user %s", fname, username );
403 return pwent->pw_uid;
414 static char fname[] =
"osauthGetUsername";
415 struct passwd *pwent;
420 pwent = getpwuid( uid );
421 if ( pwent ==
NULL ) {
424 "%s: error calling getpwuid for uid %d. errno = %d",
434 if ( (
unsigned int )username_len <= strlen( pwent->pw_name ) ) {
436 fname, username_len, strlen( pwent->pw_name ) );
439 strcpy( username, pwent->pw_name );