Lines Matching refs:h
93 add_str_8(struct tac_handle *h, u_int8_t *fld, struct tac_str *cs) in add_str_8() argument
97 if (add_str_16(h, &len, cs) == -1) in add_str_8()
101 generr(h, "Field too long"); in add_str_8()
117 add_str_16(struct tac_handle *h, u_int16_t *fld, struct tac_str *cs) in add_str_16() argument
128 generr(h, "Field too long"); in add_str_16()
131 offset = ntohl(h->request.length); in add_str_16()
133 generr(h, "Message too long"); in add_str_16()
136 memcpy(h->request.u.body + offset, cs->data, len); in add_str_16()
137 h->request.length = htonl(offset + len); in add_str_16()
228 close_connection(struct tac_handle *h) in close_connection() argument
230 if (h->fd != -1) { in close_connection()
231 close(h->fd); in close_connection()
232 h->fd = -1; in close_connection()
237 conn_server(struct tac_handle *h) in conn_server() argument
239 struct tac_server *srvp = &h->servers[h->cur_server]; in conn_server()
242 if ((h->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { in conn_server()
243 generr(h, "Cannot create socket: %s", strerror(errno)); in conn_server()
246 if ((flags = fcntl(h->fd, F_GETFL, 0)) == -1 || in conn_server()
247 fcntl(h->fd, F_SETFL, flags | O_NONBLOCK) == -1) { in conn_server()
248 generr(h, "Cannot set non-blocking mode on socket: %s", in conn_server()
250 close(h->fd); in conn_server()
251 h->fd = -1; in conn_server()
254 if (connect(h->fd, (struct sockaddr *)&srvp->addr, in conn_server()
268 FD_SET(h->fd, &wfds); in conn_server()
271 nfds = select(h->fd + 1, NULL, &wfds, NULL, &tv); in conn_server()
273 generr(h, "select: %s", strerror(errno)); in conn_server()
274 close(h->fd); in conn_server()
275 h->fd = -1; in conn_server()
279 generr(h, "connect: timed out"); in conn_server()
280 close(h->fd); in conn_server()
281 h->fd = -1; in conn_server()
287 if (getpeername(h->fd, &peer, &peerlen) == 0) in conn_server()
291 generr(h, "getpeername: %s", strerror(errno)); in conn_server()
292 close(h->fd); in conn_server()
293 h->fd = -1; in conn_server()
299 getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &err, &errlen); in conn_server()
302 generr(h, "connect: %s", strerror(errno)); in conn_server()
303 close(h->fd); in conn_server()
304 h->fd = -1; in conn_server()
312 crypt_msg(struct tac_handle *h, struct tac_msg *msg) in crypt_msg() argument
321 secret = h->servers[h->cur_server].secret; in crypt_msg()
360 dup_str(struct tac_handle *h, const struct tac_str *ss, size_t *len) in dup_str() argument
364 if ((p = (unsigned char *)xmalloc(h, ss->len + 1)) == NULL) in dup_str()
375 establish_connection(struct tac_handle *h) in establish_connection() argument
379 if (h->fd >= 0) /* Already connected. */ in establish_connection()
381 if (h->num_servers == 0) { in establish_connection()
382 generr(h, "No TACACS+ servers specified"); in establish_connection()
390 for (i = 0; i < h->num_servers; i++) { in establish_connection()
391 if (conn_server(h) == 0) { in establish_connection()
392 h->single_connect = (h->servers[h->cur_server].flags & in establish_connection()
396 if (++h->cur_server >= h->num_servers) /* Wrap around */ in establish_connection()
397 h->cur_server = 0; in establish_connection()
418 generr(struct tac_handle *h, const char *format, ...) in generr() argument
423 vsnprintf(h->errmsg, ERRSIZE, format, ap); in generr()
445 get_srvr_end(struct tac_handle *h) in get_srvr_end() argument
449 len = ntohl(h->response.length); in get_srvr_end()
451 if (h->srvr_pos != len) { in get_srvr_end()
452 generr(h, "Invalid length field in response " in get_srvr_end()
454 h->srvr_pos, len); in get_srvr_end()
461 get_str(struct tac_handle *h, const char *field, in get_str() argument
464 if (h->srvr_pos + len > ntohl(h->response.length)) { in get_str()
465 generr(h, "Invalid length field in %s response from server " in get_str()
466 "(%lu > %lu)", field, (u_long)(h->srvr_pos + len), in get_str()
467 (u_long)ntohl(h->response.length)); in get_str()
470 ss->data = len != 0 ? h->response.u.body + h->srvr_pos : NULL; in get_str()
472 h->srvr_pos += len; in get_str()
484 read_timed(struct tac_handle *h, void *buf, size_t len, in read_timed() argument
493 n = read(h->fd, ptr, len); in read_timed()
499 generr(h, "Network read error: %s", in read_timed()
511 FD_SET(h->fd, &rfds); in read_timed()
513 select(h->fd + 1, &rfds, NULL, NULL, &tv); in read_timed()
515 generr(h, "select: %s", in read_timed()
522 generr(h, "Network read timed out"); in read_timed()
526 generr(h, "unexpected EOF from server"); in read_timed()
541 recv_msg(struct tac_handle *h) in recv_msg() argument
547 msg = &h->response; in recv_msg()
549 deadline.tv_sec += h->servers[h->cur_server].timeout; in recv_msg()
552 if (read_timed(h, msg, HDRSIZE, &deadline) == -1) in recv_msg()
554 if (memcmp(msg->session_id, h->request.session_id, in recv_msg()
556 generr(h, "Invalid session ID in received message"); in recv_msg()
559 if (msg->type != h->request.type) { in recv_msg()
560 generr(h, "Invalid type in received message" in recv_msg()
562 msg->type, h->request.type); in recv_msg()
567 generr(h, "Received message too large (%u > %u)", in recv_msg()
571 if (msg->seq_no != ++h->last_seq_no) { in recv_msg()
572 generr(h, "Invalid sequence number in received message" in recv_msg()
574 msg->seq_no, h->last_seq_no); in recv_msg()
579 if (read_timed(h, msg->u.body, len, &deadline) == -1) in recv_msg()
583 crypt_msg(h, msg); in recv_msg()
590 h->single_connect = 0; in recv_msg()
595 save_str(struct tac_handle *h, struct tac_str *cs, const void *data, in save_str() argument
600 if ((cs->data = xmalloc(h, len)) == NULL) in save_str()
613 send_msg(struct tac_handle *h) in send_msg() argument
620 if (h->last_seq_no & 1) { in send_msg()
621 generr(h, "Attempt to send message out of sequence"); in send_msg()
625 if (establish_connection(h) == -1) in send_msg()
628 msg = &h->request; in send_msg()
629 msg->seq_no = ++h->last_seq_no; in send_msg()
632 crypt_msg(h, msg); in send_msg()
634 if (h->single_connect) in send_msg()
639 deadline.tv_sec += h->servers[h->cur_server].timeout; in send_msg()
645 n = write(h->fd, ptr, len); in send_msg()
651 generr(h, "Network write error: %s", in send_msg()
663 FD_SET(h->fd, &wfds); in send_msg()
665 select(h->fd + 1, NULL, &wfds, NULL, &tv); in send_msg()
667 generr(h, "select: %s", in send_msg()
674 generr(h, "Network write timed out"); in send_msg()
686 tac_add_server_av(struct tac_handle *h, const char *host, int port, in tac_add_server_av() argument
694 if (h->num_servers >= MAXSERVERS) { in tac_add_server_av()
695 generr(h, "Too many TACACS+ servers specified"); in tac_add_server_av()
698 srvp = &h->servers[h->num_servers]; in tac_add_server_av()
707 generr(h, "%s: host not found", host); in tac_add_server_av()
714 if ((srvp->secret = xstrdup(h, secret)) == NULL) in tac_add_server_av()
721 generr(h, "too many AV pairs"); in tac_add_server_av()
727 generr(h, "invalid AV pair %d", i); in tac_add_server_av()
732 if ((srvp->avs[i].data = xstrdup(h, avs[i])) == NULL) in tac_add_server_av()
737 h->num_servers++; in tac_add_server_av()
752 tac_add_server(struct tac_handle *h, const char *host, int port, in tac_add_server() argument
757 return tac_add_server_av(h, host, port, secret, timeout, flags, avs); in tac_add_server()
761 tac_close(struct tac_handle *h) in tac_close() argument
765 if (h->fd != -1) in tac_close()
766 close(h->fd); in tac_close()
767 for (srv = 0; srv < h->num_servers; srv++) { in tac_close()
768 memset(h->servers[srv].secret, 0, in tac_close()
769 strlen(h->servers[srv].secret)); in tac_close()
770 free(h->servers[srv].secret); in tac_close()
772 free_str(&h->user); in tac_close()
773 free_str(&h->port); in tac_close()
774 free_str(&h->rem_addr); in tac_close()
775 free_str(&h->data); in tac_close()
776 free_str(&h->user_msg); in tac_close()
778 free_str(&(h->avs[i])); in tac_close()
781 memset(h, 0, sizeof(struct tac_handle)); in tac_close()
782 free(h); in tac_close()
796 tac_config(struct tac_handle *h, const char *path) in tac_config() argument
806 generr(h, "Cannot open \"%s\": %s", path, strerror(errno)); in tac_config()
828 generr(h, "%s:%d: missing shared secret", path, in tac_config()
843 generr(h, "%s:%d: invalid port", path, in tac_config()
856 generr(h, "%s:%d: invalid timeout", path, in tac_config()
870 if (tac_add_server_av(h, host, port, secret, timeout, in tac_config()
874 strcpy(msg, h->errmsg); in tac_config()
875 generr(h, "%s:%d: %s", path, linenum, msg); in tac_config()
888 tac_create_authen(struct tac_handle *h, int action, int type, int service) in tac_create_authen() argument
892 create_msg(h, TAC_AUTHEN, action, type); in tac_create_authen()
894 as = &h->request.u.authen_start; in tac_create_authen()
904 tac_create_author(struct tac_handle *h, int method, int type, int service) in tac_create_author() argument
908 create_msg(h, TAC_AUTHOR, method, type); in tac_create_author()
910 areq = &h->request.u.author_request; in tac_create_author()
920 tac_create_acct(struct tac_handle *h, int acct, int action, int type, int service) in tac_create_acct() argument
924 create_msg(h, TAC_ACCT, action, type); in tac_create_acct()
926 as = &h->request.u.acct_start; in tac_create_acct()
937 create_msg(struct tac_handle *h, int msg_type, int var, int type) in create_msg() argument
942 h->last_seq_no = 0; in create_msg()
944 msg = &h->request; in create_msg()
949 free_str(&h->user); in create_msg()
950 free_str(&h->port); in create_msg()
951 free_str(&h->rem_addr); in create_msg()
952 free_str(&h->data); in create_msg()
953 free_str(&h->user_msg); in create_msg()
956 free_str(&(h->avs[i])); in create_msg()
960 tac_get_data(struct tac_handle *h, size_t *len) in tac_get_data() argument
962 return dup_str(h, &h->srvr_data, len); in tac_get_data()
966 tac_get_msg(struct tac_handle *h) in tac_get_msg() argument
968 return dup_str(h, &h->srvr_msg, NULL); in tac_get_msg()
980 struct tac_handle *h; in tac_open() local
982 h = (struct tac_handle *)malloc(sizeof(struct tac_handle)); in tac_open()
983 if (h != NULL) { in tac_open()
984 h->fd = -1; in tac_open()
985 h->num_servers = 0; in tac_open()
986 h->cur_server = 0; in tac_open()
987 h->errmsg[0] = '\0'; in tac_open()
988 init_str(&h->user); in tac_open()
989 init_str(&h->port); in tac_open()
990 init_str(&h->rem_addr); in tac_open()
991 init_str(&h->data); in tac_open()
992 init_str(&h->user_msg); in tac_open()
994 init_str(&(h->avs[i])); in tac_open()
995 init_str(&(h->srvr_avs[i])); in tac_open()
997 init_str(&h->srvr_msg); in tac_open()
998 init_str(&h->srvr_data); in tac_open()
1000 return h; in tac_open()
1004 tac_send_authen(struct tac_handle *h) in tac_send_authen() argument
1008 if (h->num_servers == 0) in tac_send_authen()
1011 if (h->last_seq_no == 0) { /* Authentication START packet */ in tac_send_authen()
1014 as = &h->request.u.authen_start; in tac_send_authen()
1015 h->request.length = in tac_send_authen()
1017 if (add_str_8(h, &as->user_len, &h->user) == -1 || in tac_send_authen()
1018 add_str_8(h, &as->port_len, &h->port) == -1 || in tac_send_authen()
1019 add_str_8(h, &as->rem_addr_len, &h->rem_addr) == -1 || in tac_send_authen()
1020 add_str_8(h, &as->data_len, &h->data) == -1) in tac_send_authen()
1025 ac = &h->request.u.authen_cont; in tac_send_authen()
1027 h->request.length = in tac_send_authen()
1029 if (add_str_16(h, &ac->user_msg_len, &h->user_msg) == -1 || in tac_send_authen()
1030 add_str_16(h, &ac->data_len, &h->data) == -1) in tac_send_authen()
1035 if (send_msg(h) == -1 || recv_msg(h) == -1) in tac_send_authen()
1039 ar = &h->response.u.authen_reply; in tac_send_authen()
1040 h->srvr_pos = offsetof(struct tac_authen_reply, rest[0]); in tac_send_authen()
1041 if (get_str(h, "msg", &h->srvr_msg, ntohs(ar->msg_len)) == -1 || in tac_send_authen()
1042 get_str(h, "data", &h->srvr_data, ntohs(ar->data_len)) == -1 || in tac_send_authen()
1043 get_srvr_end(h) == -1) in tac_send_authen()
1046 if (!h->single_connect && in tac_send_authen()
1050 close_connection(h); in tac_send_authen()
1056 tac_send_author(struct tac_handle *h) in tac_send_author() argument
1060 struct tac_author_request *areq = &h->request.u.author_request; in tac_send_author()
1061 struct tac_author_response *ares = &h->response.u.author_response; in tac_send_author()
1064 h->request.length = in tac_send_author()
1069 if (h->avs[i].len && h->avs[i].data) in tac_send_author()
1076 h->request.length = ntohl(htonl(h->request.length) + areq->av_cnt); in tac_send_author()
1079 if (add_str_8(h, &areq->user_len, &h->user) == -1 || in tac_send_author()
1080 add_str_8(h, &areq->port_len, &h->port) == -1 || in tac_send_author()
1081 add_str_8(h, &areq->rem_addr_len, &h->rem_addr) == -1) in tac_send_author()
1086 if (h->avs[i].len && h->avs[i].data) { in tac_send_author()
1087 if (add_str_8(h, &areq->rest[current++], in tac_send_author()
1088 &(h->avs[i])) == -1) in tac_send_author()
1094 if (send_msg(h) == -1 || recv_msg(h) == -1) in tac_send_author()
1096 srvp = &h->servers[h->cur_server]; in tac_send_author()
1099 h->srvr_pos = offsetof(struct tac_author_response, rest[0]) + in tac_send_author()
1103 if (get_str(h, "msg", &h->srvr_msg, ntohs(ares->msg_len)) == -1 || in tac_send_author()
1104 get_str(h, "data", &h->srvr_data, ntohs(ares->data_len)) ==-1) in tac_send_author()
1108 clear_srvr_avs(h); in tac_send_author()
1111 if (get_str(h, dbgstr, &(h->srvr_avs[i]), in tac_send_author()
1114 h->srvr_navs++; in tac_send_author()
1118 if (get_srvr_end(h) == -1) in tac_send_author()
1122 if (!h->single_connect) in tac_send_author()
1123 close_connection(h); in tac_send_author()
1125 return (h->srvr_navs + srvp->navs) << 8 | ares->status; in tac_send_author()
1129 tac_send_acct(struct tac_handle *h) in tac_send_acct() argument
1132 struct tac_acct_start *as = &h->request.u.acct_start; in tac_send_acct()
1133 struct tac_acct_reply *ar = &h->response.u.acct_reply; in tac_send_acct()
1136 as = &h->request.u.acct_start; in tac_send_acct()
1137 h->request.length = htonl(offsetof(struct tac_acct_start, rest[0])); in tac_send_acct()
1139 if (h->avs[i].len && h->avs[i].data) in tac_send_acct()
1141 h->request.length = ntohl(htonl(h->request.length) + as->av_cnt); in tac_send_acct()
1143 if (add_str_8(h, &as->user_len, &h->user) == -1 || in tac_send_acct()
1144 add_str_8(h, &as->port_len, &h->port) == -1 || in tac_send_acct()
1145 add_str_8(h, &as->rem_addr_len, &h->rem_addr) == -1) in tac_send_acct()
1149 if (h->avs[i].len && h->avs[i].data) in tac_send_acct()
1150 if (add_str_8(h, &as->rest[current++], &(h->avs[i])) == -1) in tac_send_acct()
1154 if (send_msg(h) == -1 || recv_msg(h) == -1) in tac_send_acct()
1158 h->srvr_pos = offsetof(struct tac_acct_reply, rest[0]); in tac_send_acct()
1159 if (get_str(h, "msg", &h->srvr_msg, ntohs(ar->msg_len)) == -1 || in tac_send_acct()
1160 get_str(h, "data", &h->srvr_data, ntohs(ar->data_len)) == -1 || in tac_send_acct()
1161 get_srvr_end(h) == -1) in tac_send_acct()
1165 if (!h->single_connect) in tac_send_acct()
1166 close_connection(h); in tac_send_acct()
1172 tac_set_rem_addr(struct tac_handle *h, const char *addr) in tac_set_rem_addr() argument
1174 return save_str(h, &h->rem_addr, addr, addr != NULL ? strlen(addr) : 0); in tac_set_rem_addr()
1178 tac_set_data(struct tac_handle *h, const void *data, size_t data_len) in tac_set_data() argument
1180 return save_str(h, &h->data, data, data_len); in tac_set_data()
1184 tac_set_msg(struct tac_handle *h, const char *msg) in tac_set_msg() argument
1186 return save_str(h, &h->user_msg, msg, msg != NULL ? strlen(msg) : 0); in tac_set_msg()
1190 tac_set_port(struct tac_handle *h, const char *port) in tac_set_port() argument
1192 return save_str(h, &h->port, port, port != NULL ? strlen(port) : 0); in tac_set_port()
1196 tac_set_priv(struct tac_handle *h, int priv) in tac_set_priv() argument
1199 generr(h, "Attempt to set invalid privilege level"); in tac_set_priv()
1202 h->request.u.authen_start.priv_lvl = priv; in tac_set_priv()
1207 tac_set_user(struct tac_handle *h, const char *user) in tac_set_user() argument
1209 return save_str(h, &h->user, user, user != NULL ? strlen(user) : 0); in tac_set_user()
1213 tac_set_av(struct tac_handle *h, u_int index, const char *av) in tac_set_av() argument
1217 return save_str(h, &(h->avs[index]), av, av != NULL ? strlen(av) : 0); in tac_set_av()
1221 tac_get_av(struct tac_handle *h, u_int index) in tac_get_av() argument
1225 if (index < h->srvr_navs) in tac_get_av()
1226 return dup_str(h, &h->srvr_avs[index], NULL); in tac_get_av()
1227 index -= h->srvr_navs; in tac_get_av()
1228 srvp = &h->servers[h->cur_server]; in tac_get_av()
1230 return xstrdup(h, srvp->avs[index].data); in tac_get_av()
1235 tac_get_av_value(struct tac_handle *h, const char *attribute) in tac_get_av_value() argument
1242 struct tac_server *srvp = &h->servers[h->cur_server]; in tac_get_av_value()
1247 for (i = 0; i < h->srvr_navs + srvp->navs; i++) { in tac_get_av_value()
1248 if (i < h->srvr_navs) in tac_get_av_value()
1249 candidate = &h->srvr_avs[i]; in tac_get_av_value()
1251 candidate = &srvp->avs[i - h->srvr_navs]; in tac_get_av_value()
1286 return dup_str(h, &value, NULL); in tac_get_av_value()
1294 tac_clear_avs(struct tac_handle *h) in tac_clear_avs() argument
1298 save_str(h, &(h->avs[i]), NULL, 0); in tac_clear_avs()
1302 clear_srvr_avs(struct tac_handle *h) in clear_srvr_avs() argument
1306 for (i = 0; i < h->srvr_navs; i++) in clear_srvr_avs()
1307 init_str(&(h->srvr_avs[i])); in clear_srvr_avs()
1308 h->srvr_navs = 0; in clear_srvr_avs()
1313 tac_strerror(struct tac_handle *h) in tac_strerror() argument
1315 return h->errmsg; in tac_strerror()
1319 xmalloc(struct tac_handle *h, size_t size) in xmalloc() argument
1324 generr(h, "Out of memory"); in xmalloc()
1329 xstrdup(struct tac_handle *h, const char *s) in xstrdup() argument
1334 generr(h, "Out of memory"); in xstrdup()