📄 myproxy_creds.c
字号:
/* * myproxy_creds.c * * Routines for storing and retrieving credentials. * * See myproxy_creds.h for documentation. */#include "myproxy_common.h" /* all needed headers included here *//* Files should only be readable by me */#define FILE_MODE 0600/********************************************************************** * * Internal variables * */static char *storage_dir = NULL;/********************************************************************** * * Internal functions * *//* * mystrdup() * * Wrapper around strdup() */static char *mystrdup(const char *string){ char *dup = NULL; assert(string != NULL); dup = strdup(string); if (dup == NULL) { verror_put_errno(errno); } return dup;}/* * file_exists() * * Check for existance of a file. * * Returns 1 if exists, 0 if not, -1 on error. */static intfile_exists(const char *path){ struct stat statbuf = {0}; /* initialize with 0s */ int return_value = -1; if (path == NULL) { verror_put_errno(EINVAL); return -1; } if (stat(path, &statbuf) == -1) { switch (errno) { case ENOENT: case ENOTDIR: /* File does not exist */ return_value = 0; break; default: /* Some error */ return_value = -1; break; } } else { /* File exists */ return_value = 1; } return return_value;}/* * check_storage_directory() * * Check for existance and permissions on storage directory. * Create storage directory if it doesn't exist. * * Returns 0 if ok, -1 on error. */static intcheck_storage_directory(){ struct stat statbuf = {0}; /* initialize with 0s */ int return_code = -1; char *gl_storage_dir = NULL; if (storage_dir == NULL) { /* Choose a default storage directory */ char *GL; GL = getenv("GLOBUS_LOCATION"); if (stat("/var/myproxy", &statbuf) == 0) { storage_dir = mystrdup("/var/myproxy"); if (!storage_dir) goto error; } /* if /var/myproxy doesn't exist, look for $GL/var/myproxy */ if (storage_dir == NULL && GL != NULL) { gl_storage_dir = (char *)malloc(strlen(GL)+strlen("/var/myproxy")+1); if (!gl_storage_dir) { verror_put_errno(errno); verror_put_string("malloc() failed"); goto error; } sprintf(gl_storage_dir, "%s/var/myproxy", GL); if (stat(gl_storage_dir, &statbuf) == 0) { storage_dir = gl_storage_dir; gl_storage_dir = NULL; } } /* if neither exist, try creating one */ if (storage_dir == NULL) { if (mkdir("/var/myproxy", 0700) == 0) { storage_dir = mystrdup("/var/myproxy"); if (stat("/var/myproxy", &statbuf) == -1) { verror_put_errno(errno); verror_put_string("could not stat directory /var/myproxy"); goto error; } } else if (gl_storage_dir) { sprintf(gl_storage_dir, "%s/var", GL); if (mkdir(gl_storage_dir, 0755) < 0 && errno != EEXIST) { verror_put_errno(errno); verror_put_string("mkdir(%s) failed", gl_storage_dir); goto error; } sprintf(gl_storage_dir, "%s/var/myproxy", GL); if (mkdir(gl_storage_dir, 0700) < 0) { verror_put_errno(errno); verror_put_string("mkdir(%s) failed", gl_storage_dir); goto error; } storage_dir = gl_storage_dir; gl_storage_dir = NULL; if (stat(storage_dir, &statbuf) == -1) { verror_put_errno(errno); verror_put_string("could not stat directory %s", storage_dir); goto error; } } } if (storage_dir == NULL) { verror_put_string("failed to find or create a storage directory"); if (!GL) verror_put_string("GLOBUS_LOCATION not set"); goto error; } myproxy_log("using storage directory %s", storage_dir); } else { /* storage directory already chosen; just check it */ if (stat(storage_dir, &statbuf) == -1) { verror_put_errno(errno); verror_put_string("could not stat directory %s", storage_dir); goto error; } } if (!S_ISDIR(statbuf.st_mode)) { verror_put_string("%s is not a directory", storage_dir); goto error; } /* Make sure it's owned by me */ if (statbuf.st_uid != geteuid()) { struct passwd *pw; pw = getpwuid(geteuid()); if (pw) { verror_put_string("%s not owned by %s", storage_dir, pw->pw_name); } else { verror_put_string("%s not owned by uid %d", storage_dir, geteuid()); } goto error; } /* Make sure it's not readable or writable by anyone else */ if ((statbuf.st_mode & S_IRWXG) || (statbuf.st_mode & S_IRWXO)) { verror_put_string("permissions on %s must be 0700", storage_dir); goto error; } /* Success */ return_code = 0; error: if (gl_storage_dir) free(gl_storage_dir); return return_code;}static char *strmd5(const char *s, unsigned char *digest){ MD5_CTX md5; unsigned char d[16]; int i; char mbuf[33]; MD5_Init(&md5); MD5_Update(&md5,s,strlen(s)); MD5_Final(d,&md5); if (digest) memcpy(digest,d,sizeof(d)); for (i=0; i<16; i++) { int dd = d[i] & 0x0f; mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; dd = d[i] >> 4; mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a'; } mbuf[32] = 0; return mystrdup(mbuf);} /* * get_storage_locations() * * Given an user name return the path where the credentials for that * username should be stored and the path where data about the credentials * should be stored. * * Return 0 on success, -1 on error. */static intget_storage_locations(const char *username, const char *credname, char **creds_path, char **data_path, char **lock_path){ int return_code = -1; char *sterile_username = NULL; char *sterile_credname = NULL; const char *creds_suffix = ".creds"; const char *data_suffix = ".data"; const char *lock_suffix = ".lock"; assert(username != NULL); assert(creds_path != NULL); assert(data_path != NULL); assert(lock_path != NULL); if (check_storage_directory() == -1) { goto error; } if (strchr(username, '/')) { sterile_username = strmd5(username, NULL); if (sterile_username == NULL) goto error; } else { sterile_username = mystrdup(username); if (sterile_username == NULL) { goto error; } sterilize_string(sterile_username); } if (*creds_path) (*creds_path)[0] = '\0'; if (*data_path) (*data_path)[0] = '\0'; if (*lock_path) (*lock_path)[0] = '\0'; if (!credname) { if (my_append(creds_path, storage_dir, "/", sterile_username, creds_suffix, NULL) == -1) { verror_put_string("Internal error: creds_path too small: " "%s line %s", __FILE__, __LINE__); goto error; } if (my_append(data_path, storage_dir, "/", sterile_username, data_suffix, NULL) == -1) { verror_put_string("Internal error: data_path too small: " "%s line %s", __FILE__, __LINE__); goto error; } if (my_append(lock_path, storage_dir, "/", sterile_username, lock_suffix, NULL) == -1) { verror_put_string("Internal error: lock_path too small: " "%s line %s", __FILE__, __LINE__); goto error; } } else { sterile_credname = mystrdup(credname); if (sterile_credname == NULL) { goto error; } sterilize_string(sterile_credname); if (my_append(creds_path, storage_dir, "/", sterile_username, "-", sterile_credname, creds_suffix, NULL) == -1) { verror_put_string("Internal error: creds_path too small: %s line %s", __FILE__, __LINE__); goto error; } if (my_append(data_path, storage_dir, "/", sterile_username, "-", sterile_credname, data_suffix, NULL) == -1) { verror_put_string("Internal error: data_path too small: %s line %s", __FILE__, __LINE__); goto error; } if (my_append(lock_path, storage_dir, "/", sterile_username, "-", sterile_credname, lock_suffix, NULL) == -1) { verror_put_string("Internal error: lock_path too small: %s line %s", __FILE__, __LINE__); goto error; } } /* Success */ return_code = 0; error: if (sterile_username != NULL) { free(sterile_username); } if (sterile_credname != NULL) { free(sterile_credname); } return return_code;}/* * write_data_file() * * Write the data in the myproxy_creds structure to the * file name given, creating the file with the given mode. * * Returns 0 on success, -1 on error. */static intwrite_data_file(const struct myproxy_creds *creds, const char *data_file_path, const mode_t data_file_mode){ int data_fd = -1; FILE *data_stream = NULL; int data_file_open_flags = O_CREAT | O_EXCL | O_WRONLY; int return_code = -1; /* Unlink the file if it exists so we are sure to create it with the correct mode. */ unlink(data_file_path); /* * Open with open() first to minimize any race condition with * file permissions. */ data_fd = open(data_file_path, data_file_open_flags, data_file_mode); if (data_fd == -1) { verror_put_errno(errno); verror_put_string("opening storage file %s", data_file_path); goto error; } /* Now open as stream for easier IO */ data_stream = fdopen(data_fd, "w"); if (data_stream == NULL) { verror_put_errno(errno); verror_put_string("reopening storage file %s", data_file_path); goto error; } fprintf (data_stream, "OWNER=%s\n",creds->owner_name); fprintf (data_stream, "LIFETIME=%d\n", creds->lifetime); if (creds->credname != NULL) fprintf (data_stream, "NAME=%s\n", creds->credname); if (creds->creddesc != NULL) fprintf (data_stream, "DESCRIPTION=%s\n", creds->creddesc); if (creds->retrievers != NULL) fprintf (data_stream, "RETRIEVERS=%s\n", creds->retrievers); if (creds->keyretrieve != NULL) fprintf (data_stream, "KEYRETRIEVERS=%s\n", creds->keyretrieve); if (creds->trusted_retrievers != NULL) fprintf (data_stream, "TRUSTED_RETRIEVERS=%s\n", creds->trusted_retrievers); if (creds->renewers != NULL) fprintf (data_stream, "RENEWERS=%s\n", creds->renewers); fprintf (data_stream, "END_OPTIONS\n"); fflush(data_stream); /* Success */ return_code = 0; error: if (data_fd != -1) { close(data_fd); if (return_code == -1) { unlink(data_file_path); } } if (data_stream != NULL) { fclose(data_stream); } return return_code;}/* * read_data_file() * * Read the data contained in the given data file and fills in the * given creds structure. * * Returns 0 on success, -1 on error. */static intread_data_file(struct myproxy_creds *creds, const char *datafile_path){ FILE *data_stream = NULL; char *data_stream_mode = "r"; int done = 0; int line_number = 0; int return_code = -1; assert(creds != NULL); assert(datafile_path != NULL); myproxy_creds_free_contents(creds); /* initialize creds structure */ data_stream = fopen(datafile_path, data_stream_mode); if (data_stream == NULL) { verror_put_errno(errno); verror_put_string("opening %s for reading", datafile_path); goto error; } while (!done) { char buffer[512]; char *variable; char *value; int len; if (fgets(buffer, sizeof(buffer), data_stream) == NULL) { int errno_save = errno; if (feof(data_stream)) { verror_put_string("unexpected EOF reading %s", datafile_path); goto error; } else { verror_put_errno(errno_save); verror_put_string("reading %s", datafile_path); goto error; } /* Not reached */ } /* Remove carriage return from credentials */ len = strlen(buffer); if (buffer[len - 1] == '\n') { buffer[len - 1] = '\0'; } line_number++; variable = buffer; value = strchr(buffer, '='); if (value != NULL) { /* NUL-terminate variable name */ *value = '\0'; /* ...and advance value to point at value */ value++; } if (strcmp(variable, "END_OPTIONS") == 0) { done = 1; break; } /* Everything else requires values to be non-NULL */ if (value == NULL) { verror_put_string("malformed line: %s line %d", datafile_path, line_number); goto error; } if (strcmp(variable, "OWNER") == 0) { creds->owner_name = mystrdup(value); if (creds->owner_name == NULL) { goto error; } continue; } /* We no longer store a PASSPHRASE element. Read it in for backwards compatibility only. */ if (strcmp(variable, "PASSPHRASE") == 0) { creds->passphrase = mystrdup(value); if (creds->passphrase == NULL) { goto error; } continue; } if (strcmp(variable, "RETRIEVERS") == 0) { creds->retrievers = mystrdup(value); if (creds->retrievers == NULL) { goto error; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -