/* * Copyright 2002 Christopher SEKIYA * portions copyright 1997-2000 by Pawel Krawczyk * * 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); }