diff options
| -rw-r--r-- | lib/examples/client-blocking.c | 14 | ||||
| -rw-r--r-- | lib/include/radsec/radsec-impl.h | 1 | ||||
| -rw-r--r-- | lib/include/radsec/radsec.h | 1 | ||||
| -rw-r--r-- | lib/include/radsec/request-impl.h | 6 | ||||
| -rw-r--r-- | lib/packet.c | 41 | ||||
| -rw-r--r-- | lib/request.c | 126 | 
6 files changed, 49 insertions, 140 deletions
| diff --git a/lib/examples/client-blocking.c b/lib/examples/client-blocking.c index 66f4859..365b3b0 100644 --- a/lib/examples/client-blocking.c +++ b/lib/examples/client-blocking.c @@ -55,10 +55,16 @@ blocking_client (const char *av1, const char *av2)  #if !defined(USE_REQUEST_OBJECT)    if (rs_packet_send (req, NULL)) -    return rs_err_conn_pop (conn); -  req = NULL; -  if (rs_conn_receive_packet (conn, &resp)) -    return rs_err_conn_pop (conn); +    { +      rs_packet_destroy (req); +      return rs_err_conn_pop (conn); +    } +  if (rs_conn_receive_packet (conn, req, &resp)) +    { +      rs_packet_destroy (req); +      return rs_err_conn_pop (conn); +    } +  rs_packet_destroy (req);  #else    {      struct rs_request *request; diff --git a/lib/include/radsec/radsec-impl.h b/lib/include/radsec/radsec-impl.h index 3ce01d0..6e5ee83 100644 --- a/lib/include/radsec/radsec-impl.h +++ b/lib/include/radsec/radsec-impl.h @@ -76,6 +76,7 @@ struct rs_packet {      char hdr_read_flag;      uint8_t hdr[4];      RADIUS_PACKET *rpkt; +    struct rs_packet *original;  };  struct rs_attr { diff --git a/lib/include/radsec/radsec.h b/lib/include/radsec/radsec.h index db1e1a7..dd784cc 100644 --- a/lib/include/radsec/radsec.h +++ b/lib/include/radsec/radsec.h @@ -97,6 +97,7 @@ int rs_conn_select_server(struct rs_connection *conn, const char *name);  int rs_conn_get_current_server(struct rs_connection *conn,  			       const char *name, size_t buflen);  int rs_conn_receive_packet(struct rs_connection *conn, +			   struct rs_packet *request,  			   struct rs_packet **pkt_out);  int rs_conn_fd(struct rs_connection *conn); diff --git a/lib/include/radsec/request-impl.h b/lib/include/radsec/request-impl.h index 4fa0ca9..339dfea 100644 --- a/lib/include/radsec/request-impl.h +++ b/lib/include/radsec/request-impl.h @@ -7,10 +7,4 @@ struct rs_request    struct rs_packet *req;    struct rs_packet *resp;    struct rs_conn_callbacks saved_cb; -  int verified;  }; - -#define VENDORPEC_MS                        311 /* RFC 2548 */ - -#define PW_MS_MPPE_SEND_KEY                 16 -#define PW_MS_MPPE_RECV_KEY                 17 diff --git a/lib/packet.c b/lib/packet.c index 9abd698..7872a5a 100644 --- a/lib/packet.c +++ b/lib/packet.c @@ -44,6 +44,16 @@ static int  _do_send (struct rs_packet *pkt)  {    int err; +  VALUE_PAIR *vp; + +  assert (pkt->rpkt); +  assert (!pkt->original); + +  vp = paircreate (PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS); +  if (!vp) +    return rs_err_conn_push_fl (pkt->conn, RSE_NOMEM, __FILE__, __LINE__, +				"rad_encode: %s", fr_strerror ()); +  pairadd (&pkt->rpkt->vps, vp);    if (rad_encode (pkt->rpkt, NULL, pkt->conn->active_peer->secret))      return rs_err_conn_push_fl (pkt->conn, RSE_FR, __FILE__, __LINE__, @@ -51,7 +61,6 @@ _do_send (struct rs_packet *pkt)    if (rad_sign (pkt->rpkt, NULL, pkt->conn->active_peer->secret))      return rs_err_conn_push_fl (pkt->conn, RSE_FR, __FILE__, __LINE__,  				"rad_sign: %s", fr_strerror ()); -  assert (pkt->rpkt);  #if defined (DEBUG)    {      char host[80], serv[80]; @@ -183,11 +192,28 @@ _read_cb (struct bufferevent *bev, void *ctx)  #endif        if (!rad_packet_ok (pkt->rpkt, 0) != 0)  	return; -      if (rad_decode (pkt->rpkt, NULL, pkt->conn->active_peer->secret) != 0) -        return; +      assert (pkt->original); + +      /* Verify header and message authenticator.  */ +      if (rad_verify (pkt->rpkt, pkt->original->rpkt, +		      pkt->conn->active_peer->secret)) +	{ +	  rs_err_conn_push_fl (pkt->conn, RSE_FR, __FILE__, __LINE__, +			       "rad_verify: %s", fr_strerror ()); +	  return; +	} + +      /* decode and decrypt */ +      if (rad_decode (pkt->rpkt, pkt->original->rpkt, +		      pkt->conn->active_peer->secret)) +	{ +	  rs_err_conn_push_fl (pkt->conn, RSE_FR, __FILE__, __LINE__, +			       "rad_decode: %s", fr_strerror ()); +	  return; +	}        if (pkt->conn->callbacks.received_cb) -	pkt->conn->callbacks.received_cb(pkt, pkt->conn->user_data); +	pkt->conn->callbacks.received_cb (pkt, pkt->conn->user_data);        if (event_base_loopbreak (pkt->conn->evb) < 0)  	abort ();		/* FIXME */ @@ -396,7 +422,9 @@ rs_packet_send (struct rs_packet *pkt, void *user_data)  }  int -rs_conn_receive_packet (struct rs_connection *conn, struct rs_packet **pkt_out) +rs_conn_receive_packet (struct rs_connection *conn, +		        struct rs_packet *request, +		        struct rs_packet **pkt_out)  {    struct rs_packet *pkt; @@ -406,6 +434,7 @@ rs_conn_receive_packet (struct rs_connection *conn, struct rs_packet **pkt_out)      return -1;    pkt = *pkt_out;    pkt->conn = conn; +  pkt->original = request;    if (_conn_open (conn, pkt))      return -1; @@ -433,6 +462,8 @@ rs_conn_receive_packet (struct rs_connection *conn, struct rs_packet **pkt_out)  #endif      } +  pkt->original = NULL; +    return RSE_OK;  } diff --git a/lib/request.c b/lib/request.c index 85278f3..5cb87bb 100644 --- a/lib/request.c +++ b/lib/request.c @@ -8,9 +8,6 @@  #include <radsec/request.h>  #include <radsec/request-impl.h> -static int -_rs_decrypt_mppe(struct rs_request *request, VALUE_PAIR *vp); -  int  rs_request_create (struct rs_connection *conn, struct rs_request **req_out)  { @@ -55,37 +52,6 @@ static void  _rs_req_packet_received(const struct rs_packet *pkt, void *user_data)  {    struct rs_request *request = (struct rs_request *)user_data; -  int err; -  VALUE_PAIR *vp; - -  assert (request); -  assert (request->conn); -  assert (request->req); - -  err = rad_verify(pkt->rpkt, request->req->rpkt, -		   pkt->conn->active_peer->secret); -  if (err) -    return; - -  for (vp = pkt->rpkt->vps; vp != NULL; vp = vp->next) -    { -      if (VENDOR(vp->attribute) != VENDORPEC_MS) -	continue; - -      switch (vp->attribute & 0xffff) -	{ -	  case PW_MS_MPPE_SEND_KEY: -	  case PW_MS_MPPE_RECV_KEY: -	    err = _rs_decrypt_mppe (request, vp); -	    if (err) -	      return; -	    break; -	  default: -	    break; -	} -    } - -  request->verified = 1;  }  static void @@ -99,7 +65,6 @@ rs_request_send(struct rs_request *request, struct rs_packet *req,  	        struct rs_packet **resp)  {    int err; -  VALUE_PAIR *vp;    struct rs_connection *conn;    assert (request); @@ -114,104 +79,15 @@ rs_request_send(struct rs_request *request, struct rs_packet *req,    conn->callbacks.received_cb = _rs_req_packet_received;    conn->callbacks.sent_cb = _rs_req_packet_sent; -  assert(request->verified == 0); - -  vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS); -  pairadd(&request->req->rpkt->vps, vp); -    err = rs_packet_send(request->req, request);    if (err)      goto cleanup; -  err = rs_conn_receive_packet(request->conn, resp); +  err = rs_conn_receive_packet(request->conn, request->req, resp);    if (err)      goto cleanup; -  if (!request->verified) -    { -      err = rs_err_conn_push_fl (conn, RSE_BADAUTH, __FILE__, __LINE__, NULL); -      goto cleanup; -    } -  cleanup:    conn->callbacks = request->saved_cb;    return err;  } - -/* - * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ -#include <openssl/md5.h> - -static int -_rs_decrypt_mppe(struct rs_request *request, VALUE_PAIR *vp) -{ -  unsigned char *key = vp->vp_octets; -  size_t len = vp->length; -  unsigned char plain[1 + MAX_STRING_LEN], *ppos = plain, *res; -  const unsigned char *pos; -  size_t left, plen; -  unsigned char hash[MD5_DIGEST_LENGTH]; -  int i, first = 1; -  const unsigned char *addr[3]; -  struct rs_connection *conn; - -  assert (request); -  assert (request->conn); -  conn = request->conn; - -  if (vp->type != PW_TYPE_OCTETS) -    return rs_err_conn_push_fl (conn, RSE_BADAUTH, __FILE__, __LINE__, NULL); - -  pos = key + 2; -  left = len - 2; -  if (left % 16) -    return rs_err_conn_push_fl (conn, RSE_BADAUTH, __FILE__, __LINE__, NULL); - -  plen = left; -  if (plen > MAX_STRING_LEN) -    return rs_err_conn_push_fl (conn, RSE_BADAUTH, __FILE__, __LINE__, NULL); - -  plain[0] = 0; - -  while (left) -    { -      MD5_CTX md5; - -      MD5_Init (&md5); -      MD5_Update (&md5, conn->active_peer->secret, -	          strlen (conn->active_peer->secret)); -      if (first) -	{ -	  MD5_Update (&md5, request->req->rpkt->vector, MD5_DIGEST_LENGTH); -	  MD5_Update (&md5, key, 2); -	  first = 0; -	} -      else -	{ -	  MD5_Update (&md5, pos - MD5_DIGEST_LENGTH, MD5_DIGEST_LENGTH); -	} -      MD5_Final (hash, &md5); - -      for (i = 0; i < MD5_DIGEST_LENGTH; i++) -	*ppos++ = *pos++ ^ hash[i]; -      left -= MD5_DIGEST_LENGTH; -    } - -  if (plain[0] == 0 || plain[0] > plen - 1) -    return rs_err_conn_push_fl (conn, RSE_NOMEM, __FILE__, __LINE__, NULL); - -  memcpy (vp->vp_octets, plain + 1, plain[0]); -  vp->length = plain[0]; - -  return RSE_OK; -} | 
