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