/*
* Copyright 2001 by Lionel Schwarz, Computing Center IN2P3
*/
#include <stdio.h>
#include <errno.h>
/*#ifdef HAVE_UNISTD_H*/
#include <unistd.h>
/*#endif*/
#include <syslog.h>
#include <sys/types.h>
#include <netinet/in.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include "gfw-misc.h"
#include "gfw.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
extern char *malloc();
#endif
FILE *display_file;
/*int verbose = 1;*/
static void display_status_1
(char *m, OM_uint32 code, int type) ;
int write_all(int fildes, char *buf, unsigned int nbyte)
{
int ret;
char *ptr;
for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
ret = write(fildes, ptr, nbyte);
if (ret < 0) {
if (errno == EINTR)
continue;
return(ret);
} else if (ret == 0) {
return(ptr-buf);
}
}
return(ptr-buf);
}
int read_all(int fildes, char *buf, unsigned int nbyte)
{
int ret;
char *ptr;
for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
ret = read(fildes, ptr, nbyte);
if (ret < 0) {
if (errno == EINTR)
continue;
return(ret);
} else if (ret == 0) {
return(ptr-buf);
}
}
return(ptr-buf);
}
/*
* Function: send_token
*
* Purpose: Writes a token to a file descriptor.
*
* Arguments:
*
* s (r) an open file descriptor
* tok (r) the token to write
*
* Returns: 0 on success, -1 on failure
*
* Effects:
*
* send_token writes the token length (as a network long) and then the
* token data to the file descriptor s. It returns 0 on success, and
* -1 if an error occurs or if it could not write all the data.
*/
int send_token(s, tok)
int s;
gss_buffer_t tok;
{
int ret;
long len;
#ifndef WORDS_BIGENDIAN
len = htonl(tok->length);
#else
len = tok->length;
#endif
ret = write_all(s, (char *) &len, sizeof(len));
if (ret < 0) {
perror("sending token length");
return -1;
} else if (ret != sizeof(len)) {
/* if (display_file)
fprintf(display_file,
"sending token length: %d of %d bytes written\n",
ret, sizeof(len));*/
return -1;
}
ret = write_all(s, tok->value, tok->length);
if (ret < 0) {
perror("sending token data");
return -1;
} else if (ret != tok->length) {
/* if (display_file)
fprintf(display_file,
"sending token data: %d of %d bytes written\n",
ret, tok->length);*/
return -1;
}
return 0;
}
/*
* Function: recv_token
*
* Purpose: Reads a token from a file descriptor.
*
* Arguments:
*
* s (r) an open file descriptor
* tok (w) the read token
*
* Returns: 0 on success, -1 on failure
*
* Effects:
*
* recv_token reads the token length (as a network long), allocates
* memory to hold the data, and then reads the token data from the
* file descriptor s. It blocks to read the length and data, if
* necessary. On a successful return, the token should be freed with
* gss_release_buffer. It returns 0 on success, and -1 if an error
* occurs or if it could not read all the data.
*/
int recv_token(s, tok)
int s;
gss_buffer_t tok;
{
int ret;
ret = read_all(s, (char *) &tok->length, sizeof(tok->length));
if (ret < 0) {
perror("reading token length");
return -1;
} else if (ret != sizeof(tok->length)) {
/* if (display_file)
fprintf(display_file,
"reading token length: %d of %d bytes read\n",
ret, sizeof(tok->length));*/
return -1;
}
#ifndef WORDS_BIGENDIAN
tok->length = ntohl(tok->length);
#endif
tok->value = (char *) malloc(tok->length);
if (tok->value == NULL) {
/*if (display_file)
fprintf(display_file,
"Out of memory allocating token data\n");*/
return -1;
}
ret = read_all(s, (char *) tok->value, tok->length);
if (ret < 0) {
perror("reading token data");
free(tok->value);
return -1;
} else if (ret != tok->length) {
/*fprintf(stderr, "sending token data: %d of %d bytes written\n",
ret, tok->length);*/
free(tok->value);
return -1;
}
return 0;
}
static void display_status_1(char *m, OM_uint32 code, int type)
{
OM_uint32 maj_stat, min_stat;
gss_buffer_desc msg;
OM_uint32 msg_ctx;
msg_ctx = 0;
while (1) {
maj_stat = gss_display_status(&min_stat, code,
type, GSS_C_NULL_OID,
&msg_ctx, &msg);
if (display_file)
fprintf(display_file, "GSS-API Error : %s (%s)\n", (char *)msg.value, m);
/* syslog(LOG_ERR,"GSS-API Error : %s\n", (char *)msg.value);*/
(void) gss_release_buffer(&min_stat, &msg);
if (!msg_ctx)
break;
}
}
void status_to_string(stat, logmsg)
OM_uint32 stat;
char *logmsg;
{
OM_uint32 maj_stat, min_stat;
gss_buffer_desc msg;
OM_uint32 msg_ctx;
msg_ctx = 0;
maj_stat = gss_display_status(&min_stat, stat,
GSS_C_GSS_CODE, GSS_C_NULL_OID,
&msg_ctx, &msg);
strcpy(logmsg, (char *)msg.value);
(void) gss_release_buffer(&min_stat, &msg);
}
void gfw_status_to_string(stat, logmsg)
OM_uint32 stat;
char **logmsg;
{
OM_uint32 maj_stat, min_stat;
gss_buffer_desc msg;
OM_uint32 msg_ctx;
msg_ctx = 0;
maj_stat = gss_display_status(&min_stat, stat,
GSS_C_GSS_CODE, GSS_C_NULL_OID,
&msg_ctx, &msg);
/*strcpy(logmsg, (char *)msg.value);*/
*logmsg = (char *)msg.value;
/*(void) gss_release_buffer(&min_stat, &msg);*/
}
void gfw_status_to_strings(major_stat, minor_stat, msgs)
OM_uint32 major_stat;
OM_uint32 minor_stat;
gfw_msgs_list **msgs;
{
OM_uint32 maj_stat, min_stat;
gss_buffer_desc msg;
OM_uint32 msg_ctx;
gfw_msgs_list *new_msg;
gfw_msgs_list *first_item;
gfw_msgs_list *used_item;
msg_ctx = 0;
first_item = NULL;
while (1) {
maj_stat = gss_display_status(&min_stat, major_stat,
GSS_C_GSS_CODE, GSS_C_NULL_OID,
&msg_ctx, &msg);
if ((new_msg = (gfw_msgs_list*)malloc(sizeof(gfw_msgs_list))) == NULL) {
printf("ERROR malloc struct\n");
}
if ((new_msg->msg = (char *) malloc( (int)msg.length + 1)) == NULL) {
printf("ERROR malloc char*\n");
}
sprintf(new_msg->msg,"%s",(char *)msg.value) ;
new_msg->next = NULL ;
if ( first_item == NULL ) {
first_item = new_msg ;
} else {
used_item = first_item ;
while ( used_item->next != NULL ) used_item = used_item->next ;
used_item->next = new_msg ;
}
if (!msg_ctx)
break;
}
msg_ctx = 0;
while (1) {
maj_stat = gss_display_status(&min_stat, minor_stat,
GSS_C_MECH_CODE, GSS_C_NULL_OID,
&msg_ctx, &msg);
if ((new_msg = (gfw_msgs_list*)malloc(sizeof(gfw_msgs_list))) == NULL) {
printf("ERROR malloc struct\n");
}
if ((new_msg->msg = (char *) malloc( (int)msg.length + 1)) == NULL) {
printf("ERROR malloc char*\n");
}
sprintf(new_msg->msg,"%s",(char *)msg.value) ;
new_msg->next = NULL ;
if ( first_item == NULL ) {
first_item = new_msg ;
} else {
used_item = first_item ;
while ( used_item->next != NULL ) used_item = used_item->next ;
used_item->next = new_msg ;
}
if (!msg_ctx)
break;
}
*msgs = first_item;
}
/*
* Function: display_status
*
* Purpose: displays GSS-API messages
*
* Arguments:
*
* msg a string to be displayed with the message
* maj_stat the GSS-API major status code
* min_stat the GSS-API minor status code
*
* Effects:
*
* The GSS-API messages associated with maj_stat and min_stat are
* displayed on stderr, each preceeded by "GSS-API error <msg>: " and
* followed by a newline.
*/
void display_status(msg, maj_stat, min_stat)
char *msg;
OM_uint32 maj_stat;
OM_uint32 min_stat;
{
display_status_1(msg, maj_stat, GSS_C_GSS_CODE);
display_status_1(msg, min_stat, GSS_C_MECH_CODE);
}
syntax highlighted by Code2HTML, v. 0.9.1