📄 myproxy.c
字号:
/* * myproxy.c * * See myproxy.h for documentation * */#include "myproxy_common.h" /* all needed headers included here *//********************************************************************** * * Internal functions * */static int convert_message(const char *buffer, const char *varname, int flags, char **line);/* Values for convert_message() flags */#define CONVERT_MESSAGE_NO_FLAGS 0x0000#define CONVERT_MESSAGE_ALLOW_MULTIPLE 0x0001#define CONVERT_MESSAGE_DEFAULT_FLAGS CONVERT_MESSAGE_NO_FLAGS#define CONVERT_MESSAGE_KNOWN_FLAGS CONVERT_MESSAGE_ALLOW_MULTIPLEstatic int parse_command(const char *command_str, myproxy_proto_request_type_t *command_value);/* returns 0 if character not found */static int findchr (const char *p, const char c){ int i = 0; while (*(p+i) != c && *(p+i) != '\0') i++; return (*(p+i) == '\0')?0:i; }static int countchr (const char *p, const char c){ int i=0; while (*p != '\0') { if (*p == c) i++; p++; } return i;}static int parse_add_creds (char *response_str, char ***pstrs, int *num_creds){ char *p = response_str; int tmp = 0, len = 0; int idx = 0; int num_entries; char **strs; /* allocate memory for a string-list, returned to caller */ num_entries = countchr(response_str, ',')+1; *pstrs = strs = (char **)malloc(num_entries*sizeof(char *)); do { tmp = findchr(p+len, ','); if (tmp == 0) /* last credential name */ { size_t slen; slen = strlen (p+len); strs[idx] = (char *) malloc(slen+1); if (strncpy (strs[idx], p+len, slen) == NULL) return -1; strs[idx++][slen] = '\0'; } else { strs[idx] = (char *) malloc (tmp+1); if (strncpy (strs[idx], p+len, tmp) == NULL) return -1; strs[idx++][tmp] = '\0'; } len += (tmp+1); } while (tmp != 0); assert(num_entries == idx); *num_creds = idx; return 0;} static const char *encode_command(const myproxy_proto_request_type_t command_value);static intparse_string(const char *str, int *value);static intencode_integer(int value, char *string, int string_len); static intparse_response_type(const char *type_str, myproxy_proto_response_type_t *type_value);static const char *encode_response(myproxy_proto_response_type_t response_value);static intstring_to_int(const char *string, int *integer);static char *parse_entry(char *buffer, authorization_data_t *data);static intparse_auth_data(char *buffer, authorization_data_t ***auth_data);/* Values for string_to_int() */#define STRING_TO_INT_SUCCESS 1#define STRING_TO_INT_ERROR -1#define STRING_TO_INT_NONNUMERIC 0/********************************************************************** * * Exported functions * */char *myproxy_version(int *major, int *minor, int *micro) { if (major) *major = MYPROXY_VERSION_MAJOR; if (minor) *minor = MYPROXY_VERSION_MINOR; if (micro) *micro = MYPROXY_VERSION_MICRO; return MYPROXY_VERSION_DATE;}intmyproxy_check_version_ex(int major, int minor, int micro) { if (major != MYPROXY_VERSION_MAJOR) return 1; if (minor != MYPROXY_VERSION_MINOR) return 2; if (micro != MYPROXY_VERSION_MICRO) return 3; return 0;}int myproxy_init_client(myproxy_socket_attrs_t *attrs) { struct sockaddr_in sin; struct hostent *host_info; char *port_range; myproxy_debug("MyProxy %s", myproxy_version(0,0,0)); attrs->socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (attrs->socket_fd == -1) { verror_put_errno(errno); verror_put_string("socket() failed"); return -1; } host_info = gethostbyname(attrs->pshost); if ((port_range = getenv("MYPROXY_TCP_PORT_RANGE")) || (port_range = getenv("GLOBUS_TCP_PORT_RANGE"))) { unsigned short port=0, min_port=0, max_port=0; char *c; c = strchr(port_range, ','); if (c) { *c = ' '; } if (sscanf(port_range, "%hu %hu", &min_port, &max_port) == 2) { port = min_port; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(port); while (bind(attrs->socket_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { if (errno != EADDRINUSE) { verror_put_errno(errno); verror_put_string("Error in bind()"); return -1; } else if (port >= max_port) { verror_put_string("No available ports in range %hu-%hu.", min_port, max_port); return -1; } sin.sin_port = htons(++port); } myproxy_debug("Socket bound to port %hu.\n", port); } else { verror_put_errno(errno); verror_put_string("Error parsing port range (%s)", port_range); return -1; } } if (host_info == NULL) { verror_put_string("Unknown host \"%s\"\n", attrs->pshost); return -1; } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; memcpy(&(sin.sin_addr), host_info->h_addr, sizeof(sin.sin_addr)); sin.sin_port = htons(attrs->psport); if (connect(attrs->socket_fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { verror_put_errno(errno); verror_put_string("Unable to connect to %s:%d\n", attrs->pshost, attrs->psport); return -1; } attrs->gsi_socket = GSI_SOCKET_new(attrs->socket_fd); if (attrs->gsi_socket == NULL) { verror_put_string("GSI_SOCKET_new()\n"); return -1; } return attrs->socket_fd;} int myproxy_authenticate_init(myproxy_socket_attrs_t *attrs, const char *proxyfile) { char error_string[1024]; char peer_name[1024] = ""; char *accepted_peer_names[3] = { 0 }; char *server_dn; int rval, return_value = -1; if (GSI_SOCKET_use_creds(attrs->gsi_socket, proxyfile) == GSI_SOCKET_ERROR) { GSI_SOCKET_get_error_string(attrs->gsi_socket, error_string, sizeof(error_string)); verror_put_string("Error setting credentials to use: %s\n", error_string); goto error; } /* * What identity to we expect the server to have? */ server_dn = getenv("MYPROXY_SERVER_DN"); if (server_dn) { myproxy_debug("Expecting non-standard server DN \"%s\"\n", server_dn); accepted_peer_names[0] = strdup(server_dn); } else { char *fqhn, *buf; fqhn = GSI_SOCKET_get_peer_hostname(attrs->gsi_socket); if (!fqhn) { GSI_SOCKET_get_error_string(attrs->gsi_socket, error_string, sizeof(error_string)); verror_put_string("Error getting name of remote party: %s\n", error_string); return_value = 1; goto error; } buf = malloc(strlen(fqhn)+strlen("myproxy@")+1); sprintf(buf, "myproxy@%s", fqhn); accepted_peer_names[0] = buf; buf = malloc(strlen(fqhn)+strlen("host@")+1); sprintf(buf, "host@%s", fqhn); accepted_peer_names[1] = buf; free(fqhn); } rval = GSI_SOCKET_authentication_init(attrs->gsi_socket, accepted_peer_names); if (rval == GSI_SOCKET_UNAUTHORIZED) { /* This is a common error. Send the GSI errors to debug and return a more friendly error message in verror(). */ GSI_SOCKET_get_error_string(attrs->gsi_socket, error_string, sizeof(error_string)); myproxy_debug("Error authenticating: %s\n", error_string); GSI_SOCKET_get_peer_name(attrs->gsi_socket, peer_name, sizeof(peer_name)); if (server_dn) { verror_put_string("Server authorization failed. Server identity\n" "(%s)\ndoes not match $MYPROXY_SERVER_DN\n" "(%s).\nIf the server identity is acceptable, " "set\nMYPROXY_SERVER_DN=\"%s\"\n" "and try again.\n", peer_name, server_dn, peer_name); } else { verror_put_string("Server authorization failed. Server identity\n" "(%s)\ndoes not match expected identities\n" "%s or %s.\n" "If the server identity is acceptable, " "set\nMYPROXY_SERVER_DN=\"%s\"\n" "and try again.\n", peer_name, accepted_peer_names[0], accepted_peer_names[1], peer_name); } goto error; } else if (rval == GSI_SOCKET_ERROR) { GSI_SOCKET_get_error_string(attrs->gsi_socket, error_string, sizeof(error_string)); verror_put_string("Error authenticating: %s\n", error_string); goto error; } return_value = 0; error: if (accepted_peer_names[0]) free(accepted_peer_names[0]); if (accepted_peer_names[1]) free(accepted_peer_names[1]); if (accepted_peer_names[2]) free(accepted_peer_names[2]); return return_value;}int myproxy_authenticate_accept(myproxy_socket_attrs_t *attrs, char *client_name, const int namelen) { char error_string[1024]; assert(client_name != NULL); if (GSI_SOCKET_authentication_accept(attrs->gsi_socket) == GSI_SOCKET_ERROR) { GSI_SOCKET_get_error_string(attrs->gsi_socket, error_string, sizeof(error_string)); verror_put_string("Error authenticating client: %s\n", error_string); return -1; } if (GSI_SOCKET_get_peer_name(attrs->gsi_socket, client_name, namelen) == GSI_SOCKET_ERROR) { GSI_SOCKET_get_error_string(attrs->gsi_socket, error_string, sizeof(error_string)); verror_put_string("Error getting client name: %s\n", error_string); return -1; } return 0;}intmyproxy_init_delegation(myproxy_socket_attrs_t *attrs, const char *delegfile, const int lifetime, char *passphrase){ char error_string[1024]; if (attrs == NULL) return -1; if (GSI_SOCKET_delegation_init_ext(attrs->gsi_socket, delegfile, lifetime, passphrase) == GSI_SOCKET_ERROR) { GSI_SOCKET_get_error_string(attrs->gsi_socket, error_string, sizeof(error_string)); verror_put_string("Error delegating credentials: %s\n", error_string); return -1; } return 0;}intmyproxy_accept_delegation(myproxy_socket_attrs_t *attrs, char *data, const int datalen, char *passphrase){ char error_string[1024]; assert(data != NULL); if (GSI_SOCKET_delegation_accept_ext(attrs->gsi_socket, data, datalen, passphrase) == GSI_SOCKET_ERROR) { GSI_SOCKET_get_error_string(attrs->gsi_socket, error_string, sizeof(error_string)); verror_put_string("Error accepting delegated credentials: %s\n", error_string); return -1; } return 0;}intmyproxy_serialize_request(const myproxy_request_t *request, char *data, const int datalen) { int len; char *buf = NULL; assert(data != NULL); assert(datalen > 0); len = myproxy_serialize_request_ex(request, &buf); if (len <= 0) { if (buf) free(buf); return len; } if (len >= datalen) { verror_put_string("Buffer size exceeded in myproxy_serialize_request()."); if (buf) free(buf); return -1; } memcpy(data, buf, len); free(buf); return len;}intmyproxy_serialize_request_ex(const myproxy_request_t *request, char **data) { int len; char lifetime_string[64]; const char *command_string; assert(data != NULL); if (*data) (*data)[0] = '\0'; /* version */ len = my_append(data, MYPROXY_VERSION_STRING, request->version, "\n", NULL); if (len < 0) return -1; /* command type */ command_string = encode_command((myproxy_proto_request_type_t)request->command_type); if (command_string == NULL) { return -1; } len = my_append(data, MYPROXY_COMMAND_STRING, command_string, "\n", NULL); if (len < 0) return -1; /* username */ len = my_append(data, MYPROXY_USERNAME_STRING, request->username, "\n", NULL); if (len < 0) return -1; /* passphrase */ len = my_append(data, MYPROXY_PASSPHRASE_STRING, request->passphrase, "\n", NULL); if (len < 0) return -1; /* new passphrase */ if (request->new_passphrase[0]!= '\0') { len = my_append(data, MYPROXY_NEW_PASSPHRASE_STRING, request->new_passphrase, "\n", NULL); if (len < 0) return -1; } /* lifetime */ if (encode_integer(request->proxy_lifetime, lifetime_string, sizeof(lifetime_string)) == -1) { return -1; } len = my_append(data, MYPROXY_LIFETIME_STRING, lifetime_string, "\n", NULL); if (len < 0) return -1; /* retrievers */ if (request->retrievers != NULL) { len = my_append(data, MYPROXY_RETRIEVER_STRING, request->retrievers, "\n", NULL); if (len < 0) return -1; } /* renewers */ if (request->renewers != NULL) { len = my_append(data, MYPROXY_RENEWER_STRING, request->renewers, "\n", NULL); if (len < 0) return -1; } /* credential name */ if (request->credname!= NULL) { char *buf = strdup (request->credname); strip_char ( buf, '\n'); len = my_append(data, MYPROXY_CRED_PREFIX, "_", MYPROXY_CRED_NAME_STRING, buf, "\n", NULL); free(buf); if (len < 0) return -1; } /* credential description */ if (request->creddesc != NULL) { char *buf = strdup (request->creddesc); strip_char ( buf, '\n'); len = my_append(data, MYPROXY_CRED_PREFIX, "_", MYPROXY_CRED_DESC_STRING, buf, "\n", NULL); free(buf); if (len < 0) return -1; } /* key retrievers */ if (request->keyretrieve != NULL) { len = my_append(data, MYPROXY_KEY_RETRIEVER_STRING, request->keyretrieve, "\n", NULL); if (len < 0) return -1; } /* trusted retrievers */ if (request->trusted_retrievers != NULL) { len = my_append(data, MYPROXY_TRUSTED_RETRIEVER_STRING, request->trusted_retrievers, "\n", NULL); if (len < 0) return -1; } /* trusted root certificates */ myproxy_debug("want_trusted_certs = %d", request->want_trusted_certs); if (request->want_trusted_certs) { len = my_append(data, MYPROXY_TRUSTED_CERTS_STRING, "1", "\n", NULL); if (len < 0) return -1; } return len+1;}int myproxy_deserialize_request(const char *data, const int datalen, myproxy_request_t *request){ int len, return_code = -1; char *tmp=NULL, *buf=NULL, *new_data=NULL; assert(request != NULL); assert(data != NULL); /* if the input data isn't null terminated, fix it now. */ if (data[datalen-1] != '\0') { new_data = malloc(datalen+1); memcpy(new_data, data, datalen); new_data[datalen] = '\0'; data = new_data; } /* version */ len = convert_message(data, MYPROXY_VERSION_STRING, CONVERT_MESSAGE_DEFAULT_FLAGS, &buf); if (len <= -1) { verror_prepend_string("Error parsing version from client request"); goto error; } request->version = strdup(buf); if (request->version == NULL) { verror_put_errno(errno); goto error; } /* command */ len = convert_message(data, MYPROXY_COMMAND_STRING, CONVERT_MESSAGE_DEFAULT_FLAGS, &buf); if (len <= -1) { verror_prepend_string("Error parsing command from client request"); goto error; } if (parse_command(buf, &request->command_type) == -1) { goto error; } /* username */ len = convert_message(data, MYPROXY_USERNAME_STRING, CONVERT_MESSAGE_DEFAULT_FLAGS, &buf); if (len <= -1) { verror_prepend_string("Error parsing usename from client request"); goto error; } request->username = strdup(buf); if (request->username == NULL) { verror_put_errno(errno); goto error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -