1
/* author_s.c - Send authorization request to the server.
3
* Copyright (C) 2010, Pawel Krawczyk <pawel.krawczyk@hush.com> and
4
* Jeroen Nijhof <jeroen@nijhofnet.nl>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program - see the file COPYING.
19
* See `CHANGES' file for revision history.
26
/* Send authorization request to the server, along with attributes
27
specified in attribute list prepared with tac_add_attrib.
31
* < 0 : error status code, see LIBTAC_STATUS_...
32
* LIBTAC_STATUS_WRITE_ERR
33
* LIBTAC_STATUS_WRITE_TIMEOUT (pending impl)
34
* LIBTAC_STATUS_ASSEMBLY_ERR (pending impl)
36
int tac_author_send(int fd, const char *user, char *tty, char *rem_addr,
37
struct tac_attrib *attr) {
41
u_char user_len, port_len, rem_addr_len;
43
int i = 0; /* attributes count */
44
int pkt_len = 0; /* current packet length */
45
int pktl = 0; /* temporary storage for previous pkt_len values */
46
int w; /* write() return value */
47
u_char *pkt = NULL; /* packet building pointer */
48
/* u_char *pktp; */ /* obsolete */
51
th=_tac_req_header(TAC_PLUS_AUTHOR, 0);
53
/* set header options */
54
th->version=TAC_PLUS_VER_0;
55
th->encryption=tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
57
TACDEBUG((LOG_DEBUG, "%s: user '%s', tty '%s', rem_addr '%s', encrypt: %s", \
59
tty, rem_addr, tac_encryption ? "yes" : "no"))
61
user_len = (u_char) strlen(user);
62
port_len = (u_char) strlen(tty);
63
rem_addr_len = (u_char) strlen(rem_addr);
65
tb.authen_method = tac_authen_method;
66
tb.priv_lvl = tac_priv_lvl;
67
if (strcmp(tac_login,"chap") == 0) {
68
tb.authen_type = TAC_PLUS_AUTHEN_TYPE_CHAP;
69
} else if (strcmp(tac_login,"login") == 0) {
70
tb.authen_type = TAC_PLUS_AUTHEN_TYPE_ASCII;
72
tb.authen_type = TAC_PLUS_AUTHEN_TYPE_PAP;
74
tb.service = tac_authen_service;
75
tb.user_len = user_len;
76
tb.port_len = port_len;
77
tb.rem_addr_len = rem_addr_len;
80
pkt = (u_char *) xcalloc(1, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE);
83
/* fill attribute length fields */
87
pkt_len += sizeof(a->attr_len);
88
pkt = (u_char*) xrealloc(pkt, pkt_len);
90
/* bad method: realloc() is allowed to return different pointer
93
pkt_len += sizeof(a->attr_len);
94
pkt = xrealloc(pkt, pkt_len);
97
bcopy(&a->attr_len, pkt + pktl, sizeof(a->attr_len));
103
/* fill the arg count field and add the fixed fields to packet */
105
bcopy(&tb, pkt, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE);
107
#define PUTATTR(data, len) \
108
pktp = pkt + pkt_len; \
110
pkt = xrealloc(pkt, pkt_len); \
111
bcopy(data, pktp, len);
114
#define PUTATTR(data, len) \
117
pkt = (u_char*) xrealloc(pkt, pkt_len); \
118
bcopy(data, pkt + pktl, len);
120
/* fill user and port fields */
121
PUTATTR(user, user_len)
122
PUTATTR(tty, port_len)
123
PUTATTR(rem_addr, rem_addr_len)
125
/* fill attributes */
128
PUTATTR(a->attr, a->attr_len)
133
/* finished building packet, fill len_from_header in header */
134
th->datalength = htonl(pkt_len);
137
w = write(fd, th, TAC_PLUS_HDR_SIZE);
139
if (w < TAC_PLUS_HDR_SIZE) {
141
"%s: short write on header, wrote %d of %d: %m",\
142
__FUNCTION__, w, TAC_PLUS_HDR_SIZE))
145
return LIBTAC_STATUS_WRITE_ERR;
148
/* encrypt packet body */
149
_tac_crypt(pkt, th, pkt_len);
152
w = write(fd, pkt, pkt_len);
155
"%s: short write on body, wrote %d of %d: %m",\
156
__FUNCTION__, w, pkt_len))
157
ret = LIBTAC_STATUS_WRITE_ERR;
162
TACDEBUG((LOG_DEBUG, "%s: exit status=%d", __FUNCTION__, ret))