~ubuntu-branches/ubuntu/trusty/libpam-tacplus/trusty

« back to all changes in this revision

Viewing changes to libtac/lib/author_s.c

  • Committer: Bazaar Package Importer
  • Author(s): Jeroen Nijhof
  • Date: 2011-09-05 16:01:00 UTC
  • Revision ID: james.westby@ubuntu.com-20110905160100-7o4aqefbiflj4232
Tags: upstream-1.3.5
ImportĀ upstreamĀ versionĀ 1.3.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* author_s.c - Send authorization request to the server.
 
2
 * 
 
3
 * Copyright (C) 2010, Pawel Krawczyk <pawel.krawczyk@hush.com> and
 
4
 * Jeroen Nijhof <jeroen@nijhofnet.nl>
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program - see the file COPYING.
 
18
 *
 
19
 * See `CHANGES' file for revision history.
 
20
 */
 
21
 
 
22
#include "tacplus.h"
 
23
#include "libtac.h"
 
24
#include "xalloc.h"
 
25
 
 
26
/* Send authorization request to the server, along with attributes
 
27
   specified in attribute list prepared with tac_add_attrib.
 
28
 *
 
29
 * return value:
 
30
 *      0 : success
 
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)
 
35
 */
 
36
int tac_author_send(int fd, const char *user, char *tty, char *rem_addr,
 
37
    struct tac_attrib *attr) {
 
38
 
 
39
    HDR *th;
 
40
    struct author tb;
 
41
    u_char user_len, port_len, rem_addr_len;
 
42
    struct tac_attrib *a;
 
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 */
 
49
    int ret = 0;
 
50
 
 
51
    th=_tac_req_header(TAC_PLUS_AUTHOR, 0);
 
52
 
 
53
    /* set header options */
 
54
    th->version=TAC_PLUS_VER_0;
 
55
    th->encryption=tac_encryption ? TAC_PLUS_ENCRYPTED_FLAG : TAC_PLUS_UNENCRYPTED_FLAG;
 
56
 
 
57
    TACDEBUG((LOG_DEBUG, "%s: user '%s', tty '%s', rem_addr '%s', encrypt: %s", \
 
58
        __FUNCTION__, user, \
 
59
        tty, rem_addr, tac_encryption ? "yes" : "no"))
 
60
    
 
61
    user_len = (u_char) strlen(user);
 
62
    port_len = (u_char) strlen(tty);
 
63
    rem_addr_len = (u_char) strlen(rem_addr);
 
64
 
 
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;
 
71
    } else {
 
72
        tb.authen_type = TAC_PLUS_AUTHEN_TYPE_PAP;
 
73
    }
 
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;
 
78
 
 
79
    /* allocate packet */
 
80
    pkt = (u_char *) xcalloc(1, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE);
 
81
    pkt_len = sizeof(tb);
 
82
 
 
83
    /* fill attribute length fields */
 
84
    a = attr;
 
85
    while (a) {
 
86
        pktl = pkt_len;
 
87
        pkt_len += sizeof(a->attr_len);
 
88
        pkt = (u_char*) xrealloc(pkt, pkt_len);
 
89
 
 
90
        /* bad method: realloc() is allowed to return different pointer
 
91
           with each call
 
92
        pktp=pkt + pkt_len; 
 
93
        pkt_len += sizeof(a->attr_len);
 
94
        pkt = xrealloc(pkt, pkt_len);   
 
95
        */
 
96
                
 
97
        bcopy(&a->attr_len, pkt + pktl, sizeof(a->attr_len));
 
98
        i++;
 
99
 
 
100
        a = a->next;
 
101
    }
 
102
 
 
103
    /* fill the arg count field and add the fixed fields to packet */
 
104
    tb.arg_cnt = i;
 
105
    bcopy(&tb, pkt, TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE);
 
106
/*
 
107
#define PUTATTR(data, len) \
 
108
    pktp = pkt + pkt_len; \
 
109
    pkt_len += len; \
 
110
    pkt = xrealloc(pkt, pkt_len); \
 
111
    bcopy(data, pktp, len);
 
112
*/
 
113
 
 
114
#define PUTATTR(data, len) \
 
115
    pktl = pkt_len; \
 
116
    pkt_len += len; \
 
117
    pkt = (u_char*) xrealloc(pkt, pkt_len); \
 
118
    bcopy(data, pkt + pktl, len);
 
119
 
 
120
    /* fill user and port fields */
 
121
    PUTATTR(user, user_len)
 
122
    PUTATTR(tty, port_len)
 
123
    PUTATTR(rem_addr, rem_addr_len)
 
124
 
 
125
    /* fill attributes */
 
126
    a = attr;
 
127
    while (a) {
 
128
        PUTATTR(a->attr, a->attr_len)
 
129
 
 
130
        a = a->next;
 
131
    }
 
132
 
 
133
    /* finished building packet, fill len_from_header in header */
 
134
    th->datalength = htonl(pkt_len);
 
135
 
 
136
    /* write header */
 
137
    w = write(fd, th, TAC_PLUS_HDR_SIZE);
 
138
 
 
139
    if (w < TAC_PLUS_HDR_SIZE) {
 
140
        TACSYSLOG((LOG_ERR,\
 
141
            "%s: short write on header, wrote %d of %d: %m",\
 
142
            __FUNCTION__, w, TAC_PLUS_HDR_SIZE))
 
143
        free(pkt);
 
144
        free(th);
 
145
        return LIBTAC_STATUS_WRITE_ERR;
 
146
    }
 
147
    
 
148
    /* encrypt packet body  */
 
149
    _tac_crypt(pkt, th, pkt_len);
 
150
 
 
151
    /* write body */
 
152
    w = write(fd, pkt, pkt_len);
 
153
    if (w < pkt_len) {
 
154
        TACSYSLOG((LOG_ERR,\
 
155
            "%s: short write on body, wrote %d of %d: %m",\
 
156
            __FUNCTION__, w, pkt_len))
 
157
        ret = LIBTAC_STATUS_WRITE_ERR;
 
158
    }
 
159
 
 
160
    free(pkt);
 
161
    free(th);
 
162
    TACDEBUG((LOG_DEBUG, "%s: exit status=%d", __FUNCTION__, ret))
 
163
    return ret;
 
164
}