/*
 * Copyright 2002 Christopher SEKIYA <wileyc@rezrov.net>
 * portions copyright 1997-2000 by Pawel Krawczyk <kravietz@ceti.pl>
 *
 * authen_s.c  Send authentication request to the server.
 */

#include "tacshell.h"

int
tac_authen_send(int fd, char *user, char *tty)
{
	struct tacacs_header header;	/* TACACS+ packet header */
	struct authen_start body;	/* message body */
	int             user_length;
	int             port_length;
	int             body_length;
	int             status;
	int             packet_length = 0;
	unsigned char  *packet;
	int             ret = 0;

	/* set header options */
	header.type = TAC_PLUS_AUTHEN;
	header.seq_no = sequence_number;
	sequence_number++;
	header.session_id = htonl(session_id);
	header.version = TAC_PLUS_VER_1;
	header.encryption = tac_encryption ? TAC_PLUS_ENCRYPTED : TAC_PLUS_CLEAR;

#if DEBUG
	fprintf(stderr, "tacshell: user '%s', tty '%s', encrypt: %s\n", \
		user, tty, \
		(tac_encryption) ? "yes" : "no");
#endif

	/* get size of submitted data */
	user_length = strlen(user);
	port_length = strlen(tty);

	/* fill the body of message */
	body.action = TAC_PLUS_AUTHEN_LOGIN;
	body.priv_lvl = TAC_PLUS_PRIV_LVL_MIN;
	body.authen_type = TAC_PLUS_AUTHEN_TYPE_ASCII;
	body.service = TAC_PLUS_AUTHEN_SVC_LOGIN;
	body.user_len = user_length;
	body.port_len = port_length;
	body.rem_addr_len = 0;
	body.data_len = 0;

	/* fill body length in header */
	body_length = TAC_AUTHEN_START_FIXED_FIELDS_SIZE + user_length + port_length;

	header.datalength = htonl(body_length);

	/* we can now write the header */
	status = write(fd, &header, TAC_PLUS_HDR_SIZE);
	if (status < 0 || status < TAC_PLUS_HDR_SIZE) {
		fprintf(stderr, "tacshell: short write on header during authenticate send phase: %i of %i\n",
			status, TAC_PLUS_HDR_SIZE);
		return -1;
	}
	/* build the packet */
	packet = malloc(body_length + 10);

	memcpy(packet + packet_length, &body, sizeof(body));	/* packet body beginning */
	packet_length += sizeof(body);
	memcpy(packet + packet_length, user, user_length);	/* user */
	packet_length += user_length;
	memcpy(packet + packet_length, tty, port_length);	/* tty */
	packet_length += port_length;

	if (packet_length != body_length) {
		fprintf(stderr, "tac_authen_send: body_length %i != packet_length %i\n", body_length, packet_length);
	}
	/* encrypt the body */
	tac_crypt(packet, &header, body_length);

	status = write(fd, packet, packet_length);
	if (status < 0 || status < packet_length) {
		fprintf(stderr, "tacshell: short body write during authentication send phase: wrote %i of %i\n",
			status, packet_length);
		ret = -1;
	}
	free(packet);

	return (ret);
}


syntax highlighted by Code2HTML, v. 0.9.1