diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/HACKING | 8 | ||||
| -rw-r--r-- | lib/README | 11 | ||||
| -rw-r--r-- | lib/examples/client.c | 17 | ||||
| -rw-r--r-- | lib/libradsec-impl.h | 32 | ||||
| -rw-r--r-- | lib/libradsec.h | 31 | ||||
| -rw-r--r-- | lib/packet.c | 114 | 
6 files changed, 158 insertions, 55 deletions
| diff --git a/lib/HACKING b/lib/HACKING new file mode 100644 index 0000000..cf42339 --- /dev/null +++ b/lib/HACKING @@ -0,0 +1,8 @@ +HACKING file for libradsec (in Emacs -*- org -*- mode). +* Design of the libraray +* Features +** Not implemented +** Not tested +- short read +- short write +** Tested and verified diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..c4d0609 --- /dev/null +++ b/lib/README @@ -0,0 +1,11 @@ +This is a non-working RADIUS library doing UDP, TCP, TLS and DTLS. + +It depends on libradius from FreeRADIUS freeradius-server and +libevent2. + +The parts of it thathas been tested has been so on Linux (Ubuntu +10.04) with libfreeradius2 (2.1.8+dfsg-1ubuntu1) and +libevent-2.0.7-rc-dev. + +The file HACKING contains more detailed info on the state of the +various parts of the library. diff --git a/lib/examples/client.c b/lib/examples/client.c index d7e7270..1e9f209 100644 --- a/lib/examples/client.c +++ b/lib/examples/client.c @@ -6,7 +6,6 @@  #include <stdlib.h>  #include <event2/event.h>  #include "../libradsec.h" -#include "../debug.h"  #define SECRET "sikrit"  #define USER_NAME "bob" @@ -18,7 +17,7 @@ rsx_client (const char *srvname, int srvport)    struct rs_handle *h;    struct rs_connection *conn;    struct rs_peer *server; -  struct rs_packet *req; +  struct rs_packet *req, *resp;    if (rs_context_create (&h, "/usr/share/freeradius/dictionary"))      return NULL; @@ -39,13 +38,19 @@ rsx_client (const char *srvname, int srvport)    req = NULL;  #if 0 -  if (rs_packet_recv (conn, &resp)) +  if (rs_packet_create_acc_request (conn, &req, USER_NAME, USER_PW))      return rs_conn_err_pop (conn); -#if defined (DEBUG) -  rs_dump_packet (resp); -#endif + +  if (rs_packet_send (conn, req, NULL)) +    return rs_conn_err_pop (conn); +  req = NULL;  #endif +  if (rs_packet_receive (conn, &resp)) +    return rs_conn_err_pop (conn); +  /* TODO: do something interesting with the response */ +  rs_packet_destroy (resp); +    rs_conn_destroy (conn);    rs_context_destroy (h);    return NULL; diff --git a/lib/libradsec-impl.h b/lib/libradsec-impl.h index a4ce7c2..3abb71e 100644 --- a/lib/libradsec-impl.h +++ b/lib/libradsec-impl.h @@ -30,40 +30,10 @@ struct rs_error {      char buf[1024];  }; -typedef void * (*rs_calloc_fp)(size_t nmemb, size_t size); -typedef void * (*rs_malloc_fp)(size_t size); -typedef void (*rs_free_fp)(void *ptr); -typedef void * (*rs_realloc_fp)(void *ptr, size_t size); -struct rs_alloc_scheme { -    rs_calloc_fp calloc; -    rs_malloc_fp malloc; -    rs_free_fp free; -    rs_realloc_fp realloc; -}; - -typedef void (*rs_conn_connected_cb)(void *user_data /* FIXME: peer? */); -typedef void (*rs_conn_disconnected_cb)(void *user_data /* FIXME: reason? */); -typedef void (*rs_conn_packet_received_cb)(const struct rs_packet *packet, -					   void *user_data); -typedef void (*rs_conn_packet_sent_cb)(void *user_data); - -/** Connection callbacks.  */ -struct rs_conn_callbacks { -    /** Callback invoked when the connection has been established.  */ -    rs_conn_connected_cb connected_cb; -    /** Callback invoked when the connection has been torn down.  */ -    rs_conn_disconnected_cb disconnected_cb; -    /** Callback invoked when a packet was received.  */ -    rs_conn_packet_received_cb received_cb; -    /** Callback invoked when a packet was successfully sent.  */ -    rs_conn_packet_sent_cb sent_cb; -}; -  struct rs_handle {      struct rs_alloc_scheme alloc_scheme;      struct rs_error *err;      fr_randctx fr_randctx; -      /* TODO: dictionary? */  }; @@ -93,6 +63,8 @@ struct rs_connection {  struct rs_packet {      struct rs_connection *conn; +    char hdr_read_flag; +    uint8_t hdr[4];      RADIUS_PACKET *rpkt;  }; diff --git a/lib/libradsec.h b/lib/libradsec.h index 2ccafe2..29fb1f6 100644 --- a/lib/libradsec.h +++ b/lib/libradsec.h @@ -31,9 +31,7 @@ typedef unsigned int rs_conn_type_t;  /* Data types.  */  struct rs_handle;		/* radsec-impl.h */ -struct rs_alloc_scheme;		/* radsec-impl.h */  struct rs_connection;		/* radsec-impl.h */ -struct rs_conn_callbacks;	/* radsec-impl.h */  struct rs_packet;		/* radsec-impl.h */  struct rs_conn;			/* radsec-impl.h */  struct rs_attr;			/* radsec-impl.h */ @@ -41,6 +39,33 @@ struct rs_error;		/* radsec-impl.h */  struct rs_peer;			/* radsec-impl.h */  struct event_base;		/* <event.h> */ +typedef void * (*rs_calloc_fp)(size_t nmemb, size_t size); +typedef void * (*rs_malloc_fp)(size_t size); +typedef void (*rs_free_fp)(void *ptr); +typedef void * (*rs_realloc_fp)(void *ptr, size_t size); +struct rs_alloc_scheme { +    rs_calloc_fp calloc; +    rs_malloc_fp malloc; +    rs_free_fp free; +    rs_realloc_fp realloc; +}; + +typedef void (*rs_conn_connected_cb)(void *user_data /* FIXME: peer? */); +typedef void (*rs_conn_disconnected_cb)(void *user_data /* FIXME: reason? */); +typedef void (*rs_conn_packet_received_cb)(const struct rs_packet *packet, +					   void *user_data); +typedef void (*rs_conn_packet_sent_cb)(void *user_data); +struct rs_conn_callbacks { +    /** Callback invoked when the connection has been established.  */ +    rs_conn_connected_cb connected_cb; +    /** Callback invoked when the connection has been torn down.  */ +    rs_conn_disconnected_cb disconnected_cb; +    /** Callback invoked when a packet was received.  */ +    rs_conn_packet_received_cb received_cb; +    /** Callback invoked when a packet was successfully sent.  */ +    rs_conn_packet_sent_cb sent_cb; +}; +  /* Function prototypes.  */  int rs_context_create(struct rs_handle **ctx, const char *dict);  void rs_context_destroy(struct rs_handle *ctx); @@ -72,7 +97,7 @@ int rs_attr_create(struct rs_connection *conn, struct rs_attr **attr, const char  void rs_attr_destroy(struct rs_attr *attr);  int rs_packet_send(struct rs_connection *conn, struct rs_packet *pkt, void *data); -int rs_packet_recv(struct rs_connection *conn, struct rs_packet **pkt); +int rs_packet_receive(struct rs_connection *conn, struct rs_packet **pkt_out);  int rs_ctx_err_push(struct rs_handle *ctx, int code, const char *fmt, ...);  int rs_ctx_err_push_fl(struct rs_handle *ctx, int code, const char *file, int line, const char *fmt, ...); diff --git a/lib/packet.c b/lib/packet.c index 90c8c31..c90511b 100644 --- a/lib/packet.c +++ b/lib/packet.c @@ -9,9 +9,8 @@  #include "debug.h"  #endif -int -_packet_create (struct rs_connection *conn, struct rs_packet **pkt_out, -		int code) +static int +_packet_create (struct rs_connection *conn, struct rs_packet **pkt_out)  {    struct rs_packet *p;    RADIUS_PACKET *rpkt; @@ -22,7 +21,6 @@ _packet_create (struct rs_connection *conn, struct rs_packet **pkt_out,    if (!rpkt)      return rs_conn_err_push (conn, RSE_NOMEM, __func__);    rpkt->id = -1; -  rpkt->code = code;    p = (struct rs_packet *) malloc (sizeof (struct rs_packet));    if (!p) @@ -46,9 +44,10 @@ rs_packet_create_acc_request (struct rs_connection *conn,    struct rs_packet *pkt;    struct rs_attr *attr; -  if (_packet_create (conn, pkt_out, PW_AUTHENTICATION_REQUEST)) +  if (_packet_create (conn, pkt_out))      return -1;    pkt = *pkt_out; +  pkt->rpkt->code = PW_AUTHENTICATION_REQUEST;    if (rs_attr_create (conn, &attr, "User-Name", user_name))      return -1; @@ -83,6 +82,7 @@ _event_cb (struct bufferevent *bev, short events, void *ctx)        fprintf (stderr, "%s: connected\n", __func__);  #endif        rad_encode (pkt->rpkt, NULL, pkt->conn->active_peer->secret); +      assert (pkt->rpkt);  #if defined (DEBUG)        fprintf (stderr, "%s: about to send this to %s:\n", __func__, "<fixme>");        rs_dump_packet (pkt); @@ -118,6 +118,62 @@ _write_cb (struct bufferevent *bev, void *ctx)    rs_packet_destroy (pkt);  } +static void +_read_cb (struct bufferevent *bev, void *ctx) +{ +  struct rs_packet *pkt = (struct rs_packet *) ctx; +  size_t n; + +  assert (pkt); +  assert (pkt->conn); +  if (!pkt->hdr_read_flag) +    { +      n = bufferevent_read (pkt->conn->bev, pkt->hdr, 4); +      if (n == 4) +	{ +	  uint16_t len = (pkt->hdr[2] << 8) + pkt->hdr[3]; +	  uint8_t *buf = rs_malloc (pkt->conn->ctx, len); + +	  pkt->hdr_read_flag = 1; +	  if (!buf) +	    { +	      rs_conn_err_push_fl (pkt->conn, RSE_NOMEM, __FILE__, +				   __LINE__, NULL); +	      abort ();	/* FIXME: recovering takes reading of packet */ +	    } +	  pkt->rpkt->data = buf; +	  pkt->rpkt->data_len = len; +	  bufferevent_setwatermark (pkt->conn->bev, EV_READ, len - 4, 0); +#if defined (DEBUG) +	  fprintf (stderr, "%s: packet header read, pkt len=%d\n", __func__, +		   len); +#endif +	} +      else if (n < 0) +	return;	/* Buffer frozen, i suppose.  Let's hope it thaws.  */ +      else +	{ +	  assert (n < 4); +	  return;		/* Need more to complete header.  */ +	  } +    } + +  printf ("%s: trying to read %d octets of packet data\n", __func__, pkt->rpkt->data_len - 4); +  n = bufferevent_read (pkt->conn->bev, pkt->rpkt->data, pkt->rpkt->data_len - 4); +  printf ("%s: read %d octets of packet data\n", __func__, n); +  if (n == pkt->rpkt->data_len - 4) +    { +      bufferevent_disable (pkt->conn->bev, EV_READ); +      pkt->hdr_read_flag = 0; +      memset (pkt->hdr, 0, sizeof(*pkt->hdr)); +#if defined (DEBUG) +      fprintf (stderr, "%s: complete packet read\n", __func__); +#endif +      if (event_base_loopbreak (pkt->conn->evb) < 0) +	abort ();		/* FIXME */ +    } +} +  static int  _init_evb (struct rs_connection *conn)  { @@ -158,8 +214,7 @@ _pick_peer (struct rs_connection *conn)  }  static int -_init_bev (struct rs_connection *conn, struct rs_peer *peer, -	   struct rs_packet *pkt) +_init_bev (struct rs_connection *conn, struct rs_peer *peer)  {    if (!conn->bev)      { @@ -167,7 +222,6 @@ _init_bev (struct rs_connection *conn, struct rs_peer *peer,        if (!conn->bev)  	return rs_conn_err_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,  				    "bufferevent_socket_new"); -      bufferevent_setcb (conn->bev, NULL, _write_cb, _event_cb, pkt);      }    return RSE_OK;  } @@ -198,8 +252,9 @@ _conn_open(struct rs_connection *conn, struct rs_packet *pkt)    if (_init_socket (conn, p))      return -1; -  if (_init_bev (conn, p, pkt)) +  if (_init_bev (conn, p))      return -1; +  bufferevent_setcb (conn->bev, _read_cb, _write_cb, _event_cb, pkt);    if (!p->is_connected)      if (!p->is_connecting) @@ -213,13 +268,16 @@ rs_packet_send (struct rs_connection *conn, struct rs_packet *pkt, void *data)  {    assert (conn);    assert (pkt->rpkt); +    if (_conn_open (conn, pkt))      return -1;    assert (conn->evb);    assert (conn->bev);    assert (conn->active_peer);    assert (conn->active_peer->s >= 0); +    event_base_dispatch (conn->evb); +  #if defined (DEBUG)    fprintf (stderr, "%s: event loop done\n", __func__);    assert (event_base_got_break(conn->evb)); @@ -228,15 +286,40 @@ rs_packet_send (struct rs_connection *conn, struct rs_packet *pkt, void *data)    return RSE_OK;  } -int rs_packet_receive(struct rs_connection *conn, struct rs_packet **pkt) +int +rs_packet_receive(struct rs_connection *conn, struct rs_packet **pkt_out)  { -  //struct bufferevent *bev; +  struct rs_packet *pkt; -  //skalleper; -  //bufferevent_enable(bev, EV_READ); -  return 0;			/* FIXME */ -} +  assert (conn); + +  if (_packet_create (conn, pkt_out)) +    return -1; +  pkt = *pkt_out; +  pkt->conn = conn; + +  if (_conn_open (conn, pkt)) +    return -1; +  assert (conn->evb); +  assert (conn->bev); +  assert (conn->active_peer); +  assert (conn->active_peer->s >= 0); +  bufferevent_setwatermark (conn->bev, EV_READ, 4, 0); +  bufferevent_enable (conn->bev, EV_READ); +  event_base_dispatch (conn->evb); +#if defined (DEBUG) +  fprintf (stderr, "%s: event loop done\n", __func__); +  assert (event_base_got_break(conn->evb)); +#endif + +#if defined (DEBUG) +  fprintf (stderr, "%s: got this:\n", __func__); +  rs_dump_packet (pkt); +#endif + +  return RSE_OK; +}  void  rs_packet_add_attr(struct rs_packet *pkt, struct rs_attr *attr) @@ -244,4 +327,3 @@ rs_packet_add_attr(struct rs_packet *pkt, struct rs_attr *attr)    pairadd (&pkt->rpkt->vps, attr->vp);    attr->pkt = pkt;  } - | 
