Restructure code, moving most code out of packet.c
[radsecproxy.git] / lib / packet.c
1 /* Copyright 2010, 2011 NORDUnet A/S. All rights reserved.
2    See the file COPYING for licensing information.  */
3
4 #if defined HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7
8 #include <assert.h>
9 #include <event2/bufferevent.h>
10 #include <radsec/radsec.h>
11 #include <radsec/radsec-impl.h>
12 #include "debug.h"
13 #include "packet.h"
14
15 #if defined (DEBUG)
16 #include <netdb.h>
17 #include <sys/socket.h>
18 #include <event2/buffer.h>
19 #endif
20
21 /* Badly named helper function for preparing a RADIUS message and
22    queue it.  FIXME: Rename.  */
23 int
24 packet_do_send (struct rs_packet *pkt)
25 {
26   VALUE_PAIR *vp = NULL;
27
28   assert (pkt->rpkt);
29   assert (!pkt->original);
30
31   /* Add Message-Authenticator, RFC 2869.  */
32   /* FIXME: Make Message-Authenticator optional?  */
33   vp = paircreate (PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);
34   if (!vp)
35     return rs_err_conn_push_fl (pkt->conn, RSE_FR, __FILE__, __LINE__,
36                                 "paircreate: %s", fr_strerror ());
37   pairadd (&pkt->rpkt->vps, vp);
38
39   if (rad_encode (pkt->rpkt, NULL, pkt->conn->active_peer->secret))
40     return rs_err_conn_push_fl (pkt->conn, RSE_FR, __FILE__, __LINE__,
41                                 "rad_encode: %s", fr_strerror ());
42   if (rad_sign (pkt->rpkt, NULL, pkt->conn->active_peer->secret))
43     return rs_err_conn_push_fl (pkt->conn, RSE_FR, __FILE__, __LINE__,
44                                 "rad_sign: %s", fr_strerror ());
45 #if defined (DEBUG)
46   {
47     char host[80], serv[80];
48
49     getnameinfo (pkt->conn->active_peer->addr->ai_addr,
50                  pkt->conn->active_peer->addr->ai_addrlen,
51                  host, sizeof(host), serv, sizeof(serv),
52                  0 /* NI_NUMERICHOST|NI_NUMERICSERV*/);
53     rs_debug (("%s: about to send this to %s:%s:\n", __func__, host, serv));
54     rs_dump_packet (pkt);
55   }
56 #endif
57
58   if (pkt->conn->bev)
59     {
60       int err = bufferevent_write (pkt->conn->bev, pkt->rpkt->data,
61                                    pkt->rpkt->data_len);
62       if (err < 0)
63         return rs_err_conn_push_fl (pkt->conn, RSE_EVENT, __FILE__, __LINE__,
64                                     "bufferevent_write: %s",
65                                     evutil_gai_strerror (err));
66     }
67   else
68     {
69       struct rs_packet **pp = &pkt->conn->out_queue;
70
71       while (*pp && (*pp)->next)
72         *pp = (*pp)->next;
73       *pp = pkt;
74     }
75
76   return RSE_OK;
77 }
78
79 /* Public functions.  */
80 int
81 rs_packet_create (struct rs_connection *conn, struct rs_packet **pkt_out)
82 {
83   struct rs_packet *p;
84   RADIUS_PACKET *rpkt;
85
86   *pkt_out = NULL;
87
88   rpkt = rad_alloc (1);
89   if (!rpkt)
90     return rs_err_conn_push (conn, RSE_NOMEM, __func__);
91   rpkt->id = conn->nextid++;
92
93   p = (struct rs_packet *) malloc (sizeof (struct rs_packet));
94   if (!p)
95     {
96       rad_free (&rpkt);
97       return rs_err_conn_push (conn, RSE_NOMEM, __func__);
98     }
99   memset (p, 0, sizeof (struct rs_packet));
100   p->conn = conn;
101   p->rpkt = rpkt;
102
103   *pkt_out = p;
104   return RSE_OK;
105 }
106
107 int
108 rs_packet_create_authn_request (struct rs_connection *conn,
109                                 struct rs_packet **pkt_out,
110                                 const char *user_name, const char *user_pw)
111 {
112   struct rs_packet *pkt;
113   struct rs_attr *attr;
114
115   if (rs_packet_create (conn, pkt_out))
116     return -1;
117   pkt = *pkt_out;
118   pkt->rpkt->code = PW_AUTHENTICATION_REQUEST;
119
120   if (user_name)
121     {
122       if (rs_attr_create (conn, &attr, "User-Name", user_name))
123         return -1;
124       rs_packet_add_attr (pkt, attr);
125
126       if (user_pw)
127         {
128           if (rs_attr_create (conn, &attr, "User-Password", user_pw))
129             return -1;
130           rs_packet_add_attr (pkt, attr);
131         }
132     }
133
134   return RSE_OK;
135 }
136
137 void
138 rs_packet_add_attr (struct rs_packet *pkt, struct rs_attr *attr)
139 {
140   pairadd (&pkt->rpkt->vps, attr->vp);
141   attr->pkt = pkt;
142 }
143
144 struct radius_packet *
145 rs_packet_frpkt (struct rs_packet *pkt)
146 {
147   assert (pkt);
148   return pkt->rpkt;
149 }
150
151 void
152 rs_packet_destroy (struct rs_packet *pkt)
153 {
154   if (pkt)
155     {
156       // FIXME: memory leak! TODO: free all attributes
157       rad_free (&pkt->rpkt);
158       rs_free (pkt->conn->ctx, pkt);
159     }
160 }
161