1 /* See the file COPYING for licensing information. */
5 #include <event2/event.h>
6 #include <radsec/radsec.h>
7 #include <radsec/radsec-impl.h>
8 #include <radsec/request.h>
9 #include <radsec/request-impl.h>
12 _rs_decrypt_mppe(struct rs_request *request, VALUE_PAIR *vp);
15 rs_request_create (struct rs_connection *conn, struct rs_request **req_out)
17 struct rs_request *req = rs_malloc (conn->ctx, sizeof(*req));
19 return rs_err_conn_push_fl (conn, RSE_NOMEM, __FILE__, __LINE__, NULL);
20 memset (req, 0, sizeof(*req));
27 rs_request_destroy (struct rs_request *request)
29 rs_packet_destroy (request->req);
30 rs_packet_destroy (request->resp);
31 rs_free (request->conn->ctx, request);
36 _timer_cb(evutil_socket_t fd, short what, void *arg)
43 _rs_req_connected(void *user_data)
45 struct rs_request *request = (struct rs_request *)user_data;
49 _rs_req_disconnected(void *user_data)
51 struct rs_request *request = (struct rs_request *)user_data;
55 _rs_req_packet_received(const struct rs_packet *pkt, void *user_data)
57 struct rs_request *request = (struct rs_request *)user_data;
62 assert (request->conn);
63 assert (request->req);
65 err = rad_verify(pkt->rpkt, request->req->rpkt,
66 pkt->conn->active_peer->secret);
70 for (vp = pkt->rpkt->vps; vp != NULL; vp = vp->next)
72 if (VENDOR(vp->attribute) != VENDORPEC_MS)
75 switch (vp->attribute & 0xffff)
77 case PW_MS_MPPE_SEND_KEY:
78 case PW_MS_MPPE_RECV_KEY:
79 err = _rs_decrypt_mppe (request, vp);
88 request->verified = 1;
92 _rs_req_packet_sent(void *user_data)
94 struct rs_request *request = (struct rs_request *)user_data;
98 rs_request_send(struct rs_request *request, struct rs_packet *req,
99 struct rs_packet **resp)
103 struct rs_connection *conn;
106 assert (request->conn);
107 conn = request->conn;
109 request->req = req; /* take ownership */
110 request->saved_cb = conn->callbacks;
112 conn->callbacks.connected_cb = _rs_req_connected;
113 conn->callbacks.disconnected_cb = _rs_req_disconnected;
114 conn->callbacks.received_cb = _rs_req_packet_received;
115 conn->callbacks.sent_cb = _rs_req_packet_sent;
117 assert(request->verified == 0);
119 vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);
120 pairadd(&request->req->rpkt->vps, vp);
122 err = rs_packet_send(request->req, request);
126 err = rs_conn_receive_packet(request->conn, resp);
130 if (!request->verified)
132 err = rs_err_conn_push_fl (conn, RSE_BADAUTH, __FILE__, __LINE__, NULL);
137 conn->callbacks = request->saved_cb;
142 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
144 * This program is free software; you can redistribute it and/or modify
145 * it under the terms of the GNU General Public License version 2 as
146 * published by the Free Software Foundation.
148 * Alternatively, this software may be distributed under the terms of BSD
151 * See README and COPYING for more details.
153 #include <openssl/md5.h>
156 _rs_decrypt_mppe(struct rs_request *request, VALUE_PAIR *vp)
158 unsigned char *key = vp->vp_octets;
159 size_t len = vp->length;
160 unsigned char plain[1 + MAX_STRING_LEN], *ppos = plain, *res;
161 const unsigned char *pos;
163 unsigned char hash[MD5_DIGEST_LENGTH];
165 const unsigned char *addr[3];
166 struct rs_connection *conn;
169 assert (request->conn);
170 conn = request->conn;
172 if (vp->type != PW_TYPE_OCTETS)
173 return rs_err_conn_push_fl (conn, RSE_BADAUTH, __FILE__, __LINE__, NULL);
178 return rs_err_conn_push_fl (conn, RSE_BADAUTH, __FILE__, __LINE__, NULL);
181 if (plen > MAX_STRING_LEN)
182 return rs_err_conn_push_fl (conn, RSE_BADAUTH, __FILE__, __LINE__, NULL);
191 MD5_Update (&md5, conn->active_peer->secret,
192 strlen (conn->active_peer->secret));
195 MD5_Update (&md5, request->req->rpkt->vector, MD5_DIGEST_LENGTH);
196 MD5_Update (&md5, key, 2);
201 MD5_Update (&md5, pos - MD5_DIGEST_LENGTH, MD5_DIGEST_LENGTH);
203 MD5_Final (hash, &md5);
205 for (i = 0; i < MD5_DIGEST_LENGTH; i++)
206 *ppos++ = *pos++ ^ hash[i];
207 left -= MD5_DIGEST_LENGTH;
210 if (plain[0] == 0 || plain[0] > plen - 1)
211 return rs_err_conn_push_fl (conn, RSE_NOMEM, __FILE__, __LINE__, NULL);
213 memcpy (vp->vp_octets, plain + 1, plain[0]);
214 vp->length = plain[0];