read_file()
In the case that the message to be transferred is contained in a file, this function, called by call_server(), opens and reads the file.
Example A-5 read_file()
void read_file(file_name, in_buf)
char *file_name;
gss_buffer_t in_buf;
{
int fd, bytes_in, count;
struct stat stat_buf;
if ((fd = open(file_name, O_RDONLY, 0)) < 0) {
perror("open");
fprintf(stderr, "Couldn't open file %s\n", file_name);
exit(1);
}
if (fstat(fd, &stat_buf) < 0) {
perror("fstat");
exit(1);
}
in_buf->length = stat_buf.st_size;
in_buf->value = malloc(in_buf->length);
if (in_buf->value == 0) {
fprintf(stderr, "Couldn't allocate %ld byte buffer for reading file\n",
in_buf->length);
exit(1);
}
memset(in_buf->value, 0, in_buf->length);
for (bytes_in = 0; bytes_in < in_buf->length; bytes_in += count) {
count = read(fd, in_buf->value, (OM_uint32)in_buf->length);
if (count < 0) {
perror("read");
exit(1);
}
if (count == 0)
break;
}
if (bytes_in != count)
fprintf(stderr, "Warning, only read in %d bytes, expected %d\n",
bytes_in, count);
}
|
client_establish_context()
Calls gss_init_sec_context() to establish a context with the server.
Example A-6 client_establish_context()
/*
* Function: client_establish_context
*
* Purpose: establishes a GSS-API context with a specified service and
* returns the context handle
*
* Arguments:
*
* s (r) an established TCP connection to the service
* service_name (r) the ASCII service name of the service
* context (w) the established GSS-API context
* ret_flags (w) the returned flags from init_sec_context
*
* Returns: 0 on success, -1 on failure
*
* Effects:
*
* service_name is imported as a GSS-API name and a GSS-API context is
* established with the corresponding service; the service should be
* listening on the TCP connection s. The default GSS-API mechanism
* is used, and mutual authentication and replay detection are
* requested.
*
* If successful, the context handle is returned in context. If
* unsuccessful, the GSS-API error messages are displayed on stderr
* and -1 is returned.
*/
int client_establish_context(s, service_name, deleg_flag, oid,
gss_context, ret_flags)
int s;
char *service_name;
gss_OID oid;
OM_uint32 deleg_flag;
gss_ctx_id_t *gss_context;
OM_uint32 *ret_flags;
{
gss_buffer_desc send_tok, recv_tok, *token_ptr;
gss_name_t target_name;
OM_uint32 maj_stat, min_stat;
/*
* Import the name into target_name. Use send_tok to save
* local variable space.
*/
send_tok.value = service_name;
send_tok.length = strlen(service_name) + 1;
maj_stat = gss_import_name(&min_stat, &send_tok,
(gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &target_name);
if (maj_stat != GSS_S_COMPLETE) {
display_status("parsing name", maj_stat, min_stat);
return -1;
}
/*
* Perform the context-establishement loop.
*
* On each pass through the loop, token_ptr points to the token
* to send to the server (or GSS_C_NO_BUFFER on the first pass).
* Every generated token is stored in send_tok which is then
* transmitted to the server; every received token is stored in
* recv_tok, which token_ptr is then set to, to be processed by
* the next call to gss_init_sec_context.
*
* GSS-API guarantees that send_tok's length will be non-zero
* if and only if the server is expecting another token from us,
* and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if
* and only if the server has another token to send us.
*/
token_ptr = GSS_C_NO_BUFFER;
*gss_context = GSS_C_NO_CONTEXT;
do {
maj_stat =
gss_init_sec_context(&min_stat,
GSS_C_NO_CREDENTIAL,
gss_context,
target_name,
oid,
GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
deleg_flag,
0,
NULL, /* no channel bindings */
token_ptr,
NULL, /* ignore mech type */
&send_tok,
ret_flags,
NULL); /* ignore time_rec */
if (gss_context == NULL){
printf("Cannot create context\n");
return GSS_S_NO_CONTEXT;
}
if (token_ptr != GSS_C_NO_BUFFER)
(void) gss_release_buffer(&min_stat, &recv_tok);
if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) {
display_status("initializing context", maj_stat, min_stat);
(void) gss_release_name(&min_stat, &target_name);
return -1;
}
if (send_tok.length != 0) {
fprintf(stdout, "Sending init_sec_context token (size=%ld)...",
send_tok.length);
if (send_token(s, &send_tok) < 0) {
(void) gss_release_buffer(&min_stat, &send_tok);
(void) gss_release_name(&min_stat, &target_name);
return -1;
}
}
(void) gss_release_buffer(&min_stat, &send_tok);
if (maj_stat == GSS_S_CONTINUE_NEEDED) {
fprintf(stdout, "continue needed...");
if (recv_token(s, &recv_tok) < 0) {
(void) gss_release_name(&min_stat, &target_name);
return -1;
}
token_ptr = &recv_tok;
}
printf("\n");
} while (maj_stat == GSS_S_CONTINUE_NEEDED);
(void) gss_release_name(&min_stat, &target_name);
return 0;
}
|