示例#1
0
char *
gfarm_auth_shared_key_get(unsigned int *expirep, char *shared_key,
			  char *home, int create, int period)
{
	FILE *fp;
	static char keyfile_basename[] = "/" GFARM_AUTH_SHARED_KEY_BASENAME;
	char *keyfilename;
	unsigned int expire;

	keyfilename = malloc(strlen(home) + sizeof(keyfile_basename));
	if (keyfilename == NULL)
		return (GFARM_ERR_NO_MEMORY);
	strcpy(keyfilename, home);
	strcat(keyfilename, keyfile_basename);
	if ((fp = fopen(keyfilename, "r+")) != NULL) {
		if (skip_space(fp) || read_hex(fp, &expire, sizeof(expire))) {
			fclose(fp);
			free(keyfilename);
			return ("~/" GFARM_AUTH_SHARED_KEY_BASENAME
				": invalid expire field");
		}
		expire = ntohl(expire);
		if (skip_space(fp) ||
		    read_hex(fp, shared_key, GFARM_AUTH_SHARED_KEY_LEN)) {
			fclose(fp);
			free(keyfilename);
			return ("~/" GFARM_AUTH_SHARED_KEY_BASENAME
				": invalid key field");
		}
	}
	if (fp == NULL) {
		if (create == GFARM_AUTH_SHARED_KEY_GET) {
			free(keyfilename);
			return ("~/" GFARM_AUTH_SHARED_KEY_BASENAME
				": not exist");
		}
		fp = fopen(keyfilename, "w+");
		if (fp == NULL) {
			free(keyfilename);
			return (gfarm_errno_to_error(errno));
		}
		if (chmod(keyfilename, 0600) == -1) {
			fclose(fp);
			free(keyfilename);
			return (gfarm_errno_to_error(errno));
		}
		expire = 0; /* force to regenerate key */
	}
	if (create == GFARM_AUTH_SHARED_KEY_CREATE_FORCE ||
	    time(NULL) >= expire) {
		if (create == GFARM_AUTH_SHARED_KEY_GET) {
			fclose(fp);
			free(keyfilename);
			return (GFARM_ERR_EXPIRED);
		}
		if (fseek(fp, 0L, SEEK_SET) == -1) {
			fclose(fp);
			free(keyfilename);
			return (gfarm_errno_to_error(errno));
		}
		gfarm_auth_random(shared_key, GFARM_AUTH_SHARED_KEY_LEN);
		if (period <= 0)
			period = GFARM_AUTH_EXPIRE_DEFAULT;
		expire = time(NULL) + period;
		expire = htonl(expire);
		write_hex(fp, &expire, sizeof(expire));
		expire = ntohl(expire);
		fputc(' ', fp);
		write_hex(fp, shared_key, GFARM_AUTH_SHARED_KEY_LEN);
		fputc('\n', fp);
	}
	fclose(fp);
	free(keyfilename);
	*expirep = expire;
	return (NULL);
}
示例#2
0
/*
 * We switch the user's privilege to read ~/.gfarm_shared_key.
 *
 * NOTE: reading this file with root privilege may not work,
 *	if home directory is NFS mounted and root access for
 *	the home directory partition is not permitted.
 *
 * Do not leave the user privilege switched here, even in the switch_to case,
 * because it is necessary to switch back to the original user privilege when
 * gfarm_auth_sharedsecret fails.
 */
gfarm_error_t
gfarm_auth_shared_key_get(unsigned int *expirep, char *shared_key,
	char *home, struct passwd *pwd, int create, int period)
{
	gfarm_error_t e;
	FILE *fp;
	static char keyfile_basename[] = "/" GFARM_AUTH_SHARED_KEY_BASENAME;
	char *keyfilename;
	unsigned int expire;

	static pthread_mutex_t privilege_mutex = PTHREAD_MUTEX_INITIALIZER;
	uid_t o_uid;
	gid_t o_gid;

#ifdef __GNUC__ /* workaround gcc warning: might be used uninitialized */
	o_uid = o_gid = 0;
#endif
	GFARM_MALLOC_ARRAY(keyfilename, 
		strlen(home) + sizeof(keyfile_basename));
	if (keyfilename == NULL)
		return (GFARM_ERR_NO_MEMORY);
	strcpy(keyfilename, home);
	strcat(keyfilename, keyfile_basename);

	if (pwd != NULL) {
		pthread_mutex_lock(&privilege_mutex);
		o_gid = getegid();
		o_uid = geteuid();
		seteuid(0); /* recover root privilege */
		initgroups(pwd->pw_name, pwd->pw_gid);
		setegid(pwd->pw_gid);
		seteuid(pwd->pw_uid);
	}

	if ((fp = fopen(keyfilename, "r+")) != NULL) {
		if (skip_space(fp) || read_hex(fp, &expire, sizeof(expire))) {
			fclose(fp);
			free(keyfilename);
			e = GFARM_ERRMSG_SHAREDSECRET_INVALID_EXPIRE_FIELD;
			goto finish;
		}
		expire = ntohl(expire);
		if (skip_space(fp) ||
		    read_hex(fp, shared_key, GFARM_AUTH_SHARED_KEY_LEN)) {
			fclose(fp);
			free(keyfilename);
			e = GFARM_ERRMSG_SHAREDSECRET_INVALID_KEY_FIELD;
			goto finish;
		}
	}
	if (fp == NULL) {
		if (create == GFARM_AUTH_SHARED_KEY_GET) {
			free(keyfilename);
			e = GFARM_ERRMSG_SHAREDSECRET_KEY_FILE_NOT_EXIST;
			goto finish;
		}
		fp = fopen(keyfilename, "w+");
		if (fp == NULL) {
			e = gfarm_errno_to_error(errno);
			free(keyfilename);
			goto finish;
		}
		if (chmod(keyfilename, 0600) == -1) {
			e = gfarm_errno_to_error(errno);
			fclose(fp);
			free(keyfilename);
			goto finish;
		}
		expire = 0; /* force to regenerate key */
	}
	if (create == GFARM_AUTH_SHARED_KEY_CREATE_FORCE ||
	    time(NULL) >= expire) {
		if (create == GFARM_AUTH_SHARED_KEY_GET) {
			fclose(fp);
			free(keyfilename);
			e = GFARM_ERR_EXPIRED;
			goto finish;
		}
		if (fseek(fp, 0L, SEEK_SET) == -1) {
			e = gfarm_errno_to_error(errno);
			fclose(fp);
			free(keyfilename);
			goto finish;
		}
		gfarm_auth_random(shared_key, GFARM_AUTH_SHARED_KEY_LEN);
		if (period <= 0)
			period = GFARM_AUTH_EXPIRE_DEFAULT;
		expire = time(NULL) + period;
		expire = htonl(expire);
		write_hex(fp, &expire, sizeof(expire));
		expire = ntohl(expire);
		fputc(' ', fp);
		write_hex(fp, shared_key, GFARM_AUTH_SHARED_KEY_LEN);
		fputc('\n', fp);
	}
	fclose(fp);
	free(keyfilename);
	*expirep = expire;
	e = GFARM_ERR_NO_ERROR;
finish:
	if (pwd != NULL) {
		seteuid(0); /* recover root privilege */
		setgroups(1, &o_gid); /* abandon group privileges */
		setegid(o_gid);
		seteuid(o_uid); /* suppress root privilege, if possible */
		pthread_mutex_unlock(&privilege_mutex);
	}
	return (e);
}
示例#3
0
/*
 * the following function is for client,
 * server/daemon process shouldn't call it.
 * Because this function may read incorrect setting from user specified
 * $USER or $HOME.
 */
gfarm_error_t
gfarm_initialize(int *argcp, char ***argvp)
{
	gfarm_error_t e;
	enum gfarm_auth_method auth_method;
#ifdef HAVE_GSI
	int saved_auth_verb;
#endif

	e = gfarm_set_local_user_for_this_local_account();
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	e = gfarm_config_read();
	if (e != GFARM_ERR_NO_ERROR)
		return (e);
#ifdef HAVE_GSI
	/*
	 * Suppress verbose error messages.  The message will be
	 * displayed later in gfarm_auth_request_gsi().
	 */
	saved_auth_verb = gflog_auth_set_verbose(0);

	(void)gfarm_gsi_client_initialize();

	(void)gflog_auth_set_verbose(saved_auth_verb);
#endif
	/*
	 * In sharedsecret authentication, a global user name is
	 * required to be set to access a metadata server.
	 */
	e = gfarm_set_global_user_for_sharedsecret();
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	/*
	 * XXX FIXME this shouldn't be necessary here
	 * to support multiple metadata server
	 */
	e = gfm_client_connection_acquire(gfarm_metadb_server_name,
	    gfarm_metadb_server_port, &gfarm_metadb_server);
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "connecting gfmd: %s\n",
		    gfarm_error_string(e));
		exit(1);
	}
	gfarm_metadb_set_server(gfarm_metadb_server);

	/* metadb access is required to obtain a global user name by GSI */
	auth_method = gfm_client_connection_auth_method(gfarm_metadb_server);
	if (GFARM_IS_AUTH_GSI(auth_method)) {
		e = gfarm_set_global_user_by_gsi();
		if (e != GFARM_ERR_NO_ERROR)
			return (e);
	}
	if (argvp != NULL) {
#if 0 /* not yet in gfarm v2 */
		if (getenv("DISPLAY") != NULL)
			gfarm_debug_initialize((*argvp)[0]);
		e = gfarm_parse_argv(argcp, argvp);
		if (e != GFARM_ERR_NO_ERROR)
			return (e);
#endif /* not yet in gfarm v2 */
	}

	gfarm_auth_random(gfarm_client_pid_key, gfarm_client_pid_key_len);
	e = gfm_client_process_alloc(gfarm_metadb_server,
	    gfarm_client_pid_key_type,
	    gfarm_client_pid_key, gfarm_client_pid_key_len, &gfarm_client_pid);
	if (e != GFARM_ERR_NO_ERROR)
		gflog_fatal("failed to allocate gfarm PID: %s",
		    gfarm_error_string(e));
			
#if 0 /* not yet in gfarm v2 */
	gfarm_initialized = 1;
#endif /* not yet in gfarm v2 */

	return (GFARM_ERR_NO_ERROR);
}