/*
 * Copyright 2002 Christopher SEKIYA <wileyc@rezrov.net>
 * portions copyright 1997-2000 by Pawel Krawczyk <kravietz@ceti.pl>
 *
 * authen_r.c  Read authentication reply from server.
 */

#include "tacshell.h"

int
tac_authen_read(int fd)
{
	struct tacacs_header header;
	struct authen_reply *body;
	int             packet_size, r;

	/* read the reply header */
	r = read(fd, &header, TAC_PLUS_HDR_SIZE);
	if (r < TAC_PLUS_HDR_SIZE) {
		fprintf(stderr,
			"tacshell: error reading authen header, read %i of %i\n",
			r, TAC_PLUS_HDR_SIZE);
		return TAC_PLUS_AUTHEN_STATUS_ERROR;
	}
	/* check the reply fields in header */
	if ( tac_check_header(&header, TAC_PLUS_AUTHEN) ) {
		fprintf(stderr, "reply header corrupt.\n");
		return TAC_PLUS_AUTHEN_STATUS_ERROR;
	}
#if DEBUG
	fprintf(stderr, "received header:\n");
	fprintf(stderr, "\t%x %x %x %x\n", header.version, header.type, header.seq_no, header.encryption);
	fprintf(stderr, "\t%x %x\n", header.session_id, header.datalength);
#endif

	packet_size = ntohl(header.datalength);
	body = (struct authen_reply *) malloc(packet_size);

	/* read reply packet body */
	r = read(fd, body, packet_size);
	if (r < packet_size) {
		fprintf(stderr,
		    "tacshell: incomplete message body, %i bytes, expected %i.\n",
			r, packet_size);
		free (body);
		return TAC_PLUS_AUTHEN_STATUS_ERROR;
	}
	/* decrypt the body */
	if (header.encryption == TAC_PLUS_ENCRYPTED) {
		tac_crypt((u_int8_t *) body, &header, packet_size);
	}
#if DEBUG
	fprintf(stderr, "received packet:\n");
	fprintf(stderr, "\t%x %x %x\n", body->status, body->flags, body->msg_len);
	fprintf(stderr, "\t%x\n", body->data_len);
	fprintf(stderr, "\t");
	fprintf(stderr, "\t addresses: %lx %lx\n", (unsigned long) body, (unsigned long) temp);
	for (i = 0; i < ntohs(body->msg_len); i++)
		fprintf(stderr, "%x (%c)", (unsigned char) temp[i], (unsigned char) temp[i]);
	fprintf(stderr, "\n");
#endif

	/* check the length fields */
	if (packet_size != (TAC_AUTHEN_REPLY_FIXED_FIELDS_SIZE +
			    ntohs(body->msg_len) + ntohs(body->data_len))) {
		free (body);
		return TAC_PLUS_AUTHEN_STATUS_ERROR;
	}
	/* save status and clean up */

	if (body->msg_len) {
		challenge = (char *) malloc(ntohs(body->msg_len) + 2);
		snprintf(challenge, ntohs(body->msg_len) + 1, (char *) ((char *) body + TAC_AUTHEN_REPLY_FIXED_FIELDS_SIZE));
	}
	free(body);

	return (body->status);

}


syntax highlighted by Code2HTML, v. 0.9.1