1 /* Copyright 2010-2013 NORDUnet A/S. All rights reserved.
2 See LICENSE for licensing information. */
4 #if defined HAVE_CONFIG_H
10 #include <radius/client.h>
11 #include <event2/bufferevent.h>
12 #include <radsec/radsec.h>
13 #include <radsec/radsec-impl.h>
20 #include <sys/socket.h>
21 #include <event2/buffer.h>
25 packet_verify_response (struct rs_connection *conn,
26 struct rs_packet *response,
27 struct rs_packet *request)
32 assert (conn->active_peer);
33 assert (conn->active_peer->secret);
35 assert (response->rpkt);
37 assert (request->rpkt);
39 response->rpkt->secret = conn->active_peer->secret;
40 response->rpkt->sizeof_secret = strlen (conn->active_peer->secret);
42 /* Verify header and message authenticator. */
43 err = nr_packet_verify (response->rpkt, request->rpkt);
46 if (conn->is_connected)
47 rs_conn_disconnect(conn);
48 return rs_err_conn_push_fl (conn, -err, __FILE__, __LINE__,
52 /* Decode and decrypt. */
53 err = nr_packet_decode (response->rpkt, request->rpkt);
56 if (conn->is_connected)
57 rs_conn_disconnect(conn);
58 return rs_err_conn_push_fl (conn, -err, __FILE__, __LINE__,
66 /* Badly named function for preparing a RADIUS message and queue it.
69 packet_do_send (struct rs_packet *pkt)
75 assert (pkt->conn->active_peer);
76 assert (pkt->conn->active_peer->secret);
79 pkt->rpkt->secret = pkt->conn->active_peer->secret;
80 pkt->rpkt->sizeof_secret = strlen (pkt->rpkt->secret);
83 err = nr_packet_encode (pkt->rpkt, NULL);
85 return rs_err_conn_push_fl (pkt->conn, -err, __FILE__, __LINE__,
88 err = nr_packet_sign (pkt->rpkt, NULL);
90 return rs_err_conn_push_fl (pkt->conn, -err, __FILE__, __LINE__,
94 char host[80], serv[80];
96 getnameinfo (pkt->conn->active_peer->addr_cache->ai_addr,
97 pkt->conn->active_peer->addr_cache->ai_addrlen,
98 host, sizeof(host), serv, sizeof(serv),
99 0 /* NI_NUMERICHOST|NI_NUMERICSERV*/);
100 rs_debug (("%s: about to send this to %s:%s:\n", __func__, host, serv));
101 rs_dump_packet (pkt);
105 /* Put message in output buffer. */
106 if (pkt->conn->bev) /* TCP. */
108 int err = bufferevent_write (pkt->conn->bev, pkt->rpkt->data,
111 return rs_err_conn_push_fl (pkt->conn, RSE_EVENT, __FILE__, __LINE__,
112 "bufferevent_write: %s",
113 evutil_gai_strerror (err));
117 struct rs_packet **pp = &pkt->conn->out_queue;
119 while (*pp && (*pp)->next)
127 /* Public functions. */
129 rs_packet_create (struct rs_connection *conn, struct rs_packet **pkt_out)
137 rpkt = rs_malloc (conn->ctx, sizeof(*rpkt) + RS_MAX_PACKET_LEN);
139 return rs_err_conn_push (conn, RSE_NOMEM, __func__);
141 err = nr_packet_init (rpkt, NULL, NULL,
143 rpkt + 1, RS_MAX_PACKET_LEN);
145 return rs_err_conn_push (conn, -err, __func__);
147 p = (struct rs_packet *) rs_calloc (conn->ctx, 1, sizeof (*p));
150 rs_free (conn->ctx, rpkt);
151 return rs_err_conn_push (conn, RSE_NOMEM, __func__);
161 rs_packet_create_authn_request (struct rs_connection *conn,
162 struct rs_packet **pkt_out,
163 const char *user_name, const char *user_pw)
165 struct rs_packet *pkt;
168 if (rs_packet_create (conn, pkt_out))
172 pkt->rpkt->code = PW_ACCESS_REQUEST;
176 err = rs_packet_add_avp (pkt, PW_USER_NAME, 0, user_name,
184 err = rs_packet_add_avp (pkt, PW_USER_PASSWORD, 0, user_pw,
194 rs_packet_destroy (struct rs_packet *pkt)
198 assert (pkt->conn->ctx);
200 rs_avp_free (&pkt->rpkt->vps);
201 rs_free (pkt->conn->ctx, pkt->rpkt);
202 rs_free (pkt->conn->ctx, pkt);
206 rs_packet_add_avp (struct rs_packet *pkt,
207 unsigned int attr, unsigned int vendor,
208 const void *data, size_t data_len)
217 assert (pkt->conn->ctx);
219 da = nr_dict_attr_byvalue (attr, vendor);
221 return rs_err_conn_push (pkt->conn, RSE_ATTR_TYPE_UNKNOWN,
222 "nr_dict_attr_byvalue");
223 vp = rs_malloc (pkt->conn->ctx, sizeof(*vp));
225 return rs_err_conn_push (pkt->conn, RSE_NOMEM, NULL);
226 if (nr_vp_init (vp, da) == NULL)
229 return rs_err_conn_push (pkt->conn, RSE_INTERNAL, NULL);
231 err = nr_vp_set_data (vp, data, data_len);
235 return rs_err_conn_push (pkt->conn, -err, "nr_vp_set_data");
237 nr_vps_append (&pkt->rpkt->vps, vp);
242 /* TODO: Rename rs_packet_append_avp, indicating that encoding is
245 rs_packet_append_avp (struct rs_packet *pkt,
246 unsigned int attr, unsigned int vendor,
247 const void *data, size_t data_len)
254 da = nr_dict_attr_byvalue (attr, vendor);
256 return rs_err_conn_push (pkt->conn, RSE_ATTR_TYPE_UNKNOWN, __func__);
258 err = nr_packet_attr_append (pkt->rpkt, NULL, da, data, data_len);
260 return rs_err_conn_push (pkt->conn, -err, __func__);
266 rs_packet_avps (struct rs_packet *pkt, rs_avp ***vps)
269 *vps = &pkt->rpkt->vps;
273 rs_packet_code (struct rs_packet *pkt)
276 return pkt->rpkt->code;
280 rs_packet_find_avp (struct rs_packet *pkt, unsigned int attr, unsigned int vendor)
283 return rs_avp_find_const (pkt->rpkt->vps, attr, vendor);
287 rs_packet_set_id (struct rs_packet *pkt, int id)
289 int old = pkt->rpkt->id;