WIP on libradsec: 94e3f46 Example client crafting simple packet using freeradius...
authorLinus Nordberg <linus@nordu.net>
Mon, 27 Sep 2010 16:47:07 +0000 (18:47 +0200)
committerLinus Nordberg <linus@nordu.net>
Mon, 27 Sep 2010 16:57:06 +0000 (18:57 +0200)
lib/Makefile
lib/err.c [new file with mode: 0644]
lib/examples/Makefile
lib/examples/client.c
lib/libradsec-impl.h
lib/libradsec.h
lib/radsec.c

index 0c29f7a..bc35e88 100644 (file)
@@ -1,11 +1,15 @@
-CFLAGS = -Wall -g
+CFLAGS = -Wall -g -DDEBUG
+OFILES = radsec.o err.o packet.o attr.o
 
-all: base.o
+all: libradsec.a
 
 base.o: base.c libradsec-base.h libradsec.h ../tlv11.h
 
+libradsec.a: $(OFILES)
+       ar rc $@ $^
+
 doc:
        doxygen
 
 clean:
-       -rm *.o
+       -rm *.o *.a
diff --git a/lib/err.c b/lib/err.c
new file mode 100644 (file)
index 0000000..66c5d94
--- /dev/null
+++ b/lib/err.c
@@ -0,0 +1,121 @@
+#include <assert.h>
+#include "libradsec.h"
+#include "libradsec-impl.h"
+
+const char *_errtxt[] = {
+  "SUCCESS",                   /* 0 RSE_OK */
+  "NOMEM",                     /* 1 RSE_NOMEM */
+  "NYI -- not yet implemented",        /* 2 RSE_NOSYS */
+  "invalid handle"             /* 3 RSE_INVALID_CTX */
+  "invalid connection"         /* 4 RSE_INVALID_CONN */
+  "ERR 5"                      /*  RSE_ */
+  "ERR 6"                      /*  RSE_ */
+  "ERR 7"                      /*  RSE_ */
+  "ERR 8"                      /*  RSE_ */
+  "ERR 9"                      /*  RSE_ */
+  "ERR 10"                     /*  RSE_ */
+  "ERR 11"                     /*  RSE_ */
+  "ERR 12"                     /*  RSE_ */
+  "ERR 13"                     /*  RSE_ */
+  "ERR "                       /*  RSE_ */
+  "ERR "                       /*  RSE_ */
+  "ERR "                       /*  RSE_ */
+  "ERR "                       /*  RSE_ */
+  "ERR "                       /*  RSE_ */
+  "ERR "                       /*  RSE_ */
+  "ERR "                       /*  RSE_ */
+  "some error"                 /* 21 RSE_SOME_ERROR */
+};
+
+static struct rs_error *
+_err_new (unsigned int code, const char *msg)
+{
+  struct rs_error *err;
+
+  err = malloc (sizeof (struct rs_error));
+  if (err)
+    {
+      memset (err, 0, sizeof (struct rs_error));
+      err->code = code;
+      snprintf (err->buf, sizeof (err->buf), "%s: %s",
+               code < sizeof (_errtxt) / sizeof (*_errtxt) ?
+               _errtxt[code] : "invalid error index",
+               msg);
+    }
+  return err;
+}
+
+int
+rs_ctx_err_push (struct rs_handle *ctx, int code, const char *msg)
+{
+  struct rs_error *err = _err_new (code, msg);
+
+  if (err)
+    ctx->err = err;
+  return code;
+}
+
+int
+rs_conn_err_push (struct rs_connection *conn, int code, const char *msg)
+{
+  struct rs_error *err = _err_new (code, msg);
+
+  if (err)
+    conn->err = err;
+  return code;
+}
+
+struct rs_error *
+rs_ctx_err_pop (struct rs_handle *ctx)
+{
+  struct rs_error *err;
+
+  if (!ctx)
+    return NULL;               /* FIXME: RSE_INVALID_CTX.  */
+  err = ctx->err;
+  ctx->err = NULL;
+  return err;
+}
+
+struct rs_error *
+rs_conn_err_pop (struct rs_connection *conn)
+{
+  struct rs_error *err;
+
+  if (!conn)
+    return NULL;               /* FIXME: RSE_INVALID_CONN */
+  err = conn->err;
+  conn->err = NULL;
+  return err;
+}
+
+void
+rs_err_free (struct rs_error *err)
+{
+  assert (err);
+  if (err->msg)
+    free (err->msg);
+  free (err);
+}
+
+char *
+rs_err_msg (struct rs_error *err)
+{
+  char *msg;
+
+  if (err->msg)
+    msg = err->msg;
+  else
+    msg = strdup (err->buf);
+
+  rs_err_free (err);
+  return msg;
+}
+
+int
+rs_err_code (struct rs_error *err)
+{
+  int code = err->code;
+  rs_err_free(err);
+  return code;
+}
index 1817d90..e07a32b 100644 (file)
@@ -5,7 +5,7 @@ all: blocking.o
 blocking.o: blocking.c blocking.h ../libradsec-base.h ../libradsec.h
        $(CC) $(CFLAGS) -c -I .. $^
 
-client: client.c ../radsec.o ../libradsec.h ../debug.h
+client: client.c ../libradsec.a ../libradsec.h ../libradsec-impl.h
        $(CC) $(CFLAGS) -o $@ -L /usr/lib/freeradius -lfreeradius-radius $^
 
 clean:
index 64a4436..37601b6 100644 (file)
@@ -3,7 +3,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
-#include <freeradius/libradius.h>
 #include "../libradsec.h"
 #include "../debug.h"
 
 #define USER_PW "hemligt"
 
 int
-rsx_client ()
+rsx_client (const char *srvname, int srvport)
 {
-  fr_randctx fr_ctx;
-  struct rs_handle *ctx;
-  struct rs_connection *conn;
-  RADIUS_PACKET *pkt;
-  VALUE_PAIR *vp;
-  char user_pw[MAX_STRING_LEN];
-  uint8_t reqauth[AUTH_VECTOR_LEN];
+  struct rs_context *h;
+  struct rs_connecion *conn;
+  struct rs_packet *req, *resp;
 
-  fr_log_fp = stderr;
-  fr_debug_flag = 1;
-  fr_randinit (&fr_ctx, 0);
-  fr_rand_seed (NULL, 0);
+  if (rs_context_create (&h, "/usr/share/freeradius/dictionary"))
+    return rs_err_code (rs_ctx_err_code (h));
 
-  printf ("creating context\n");
-  if (rs_context_create(&ctx))
-    return -1;
+  if (rs_conn_new (h, &conn))
+    return rs_err_code (rs_conn_err_code (conn));
+  if (rs_conn_add_server (conn, RS_CONN_TYPE_UDP, srvname, srvport, 10, 3, SECRET))
+    return rs_err_code (rs_conn_err_code (conn));
 
-#if 0
-  printf ("reading config\n");
-  if (rs_context_config_read(ctx, "libradsec.conf"))
-    return -1;
-#endif
+  if (rs_packet_create_acc_request (conn, &req, USER_NAME, USER_PW))
+    return rs_err_code (rs_conn_err_code (conn));
 
-  printf ("init dict");
-  if (dict_init("/usr/share/freeradius", "dictionary"))
-    return -1;
+  if (rs_packet_send (req))
+    return rs_err_code (rs_conn_err_code (conn));
+  req = NULL;
 
-#if 0
-  printf ("creating connection\n");
-  if (rs_conn_create(ctx, &conn))
-    return -1;
-#endif
+  if (rs_packet_recv (conn, &resp))
+    return rs_err_code (rs_conn_err_code (conn));
 
-  printf ("creating a packet\n");
-  pkt = rad_alloc (1);
-  if (!pkt) {
-    fr_perror ("pairmake");
-    return -1;
-  }
-
-  {
-    size_t pwlen =  sizeof(USER_PW);
-    strncpy (user_pw, USER_PW, sizeof(user_pw));
-    rad_pwencode(user_pw, &pwlen, SECRET, reqauth);
-  }
-
-  printf ("creating value pairs\n");
-  vp = pairmake ("User-Name", USER_NAME, 0);
-  if (!vp) {
-    fr_perror ("paircreate");
-    return -1;
-  }
-  pairadd (&vp, pairmake ("User-Password", user_pw, 0));
-  pkt->vps = vp;
-
-  printf ("attributes:\n");
-  vp_printlist (stdout, vp);
-
-  printf ("encoding packet\n");
-  rad_encode (pkt, NULL, SECRET);
-  print_hex (pkt);             /* DEBUG */
-
-#if 0
-  rs_packet_create (&pkt, RS_ACCESS_REQUEST);
-  rs_attrib_create (&attr, RS_...);
-  rs_packet_add_attrib (pkt, attr);
-#endif
-
-  //rs_packet_send (conn, pkt, ...);
-
-  rad_free(&pkt);
-
-#if 0
-  printf ("destroying connection\n");
-  if (rs_conn_destroy(conn))
-    return -1;
-#endif
-
-  printf ("destroying context\n");
-  rs_context_destroy(ctx);
-
-  return 0;
+  rs_conn_destroy (conn);
+  rs_context_destroy (h);
 }
 
 int
index 913de4a..e9ec644 100644 (file)
@@ -3,19 +3,12 @@
 
 /* See the file COPYING for licensing information.  */
 
+#include <freeradius/libradius.h>
+
 /* Constants.  */
 #define RS_HEADER_LEN 4
 
 /* Data types.  */
-enum rs_conn_type {
-    RS_CONN_TYPE_NONE = 0,
-    RS_CONN_TYPE_UDP,
-    RS_CONN_TYPE_TCP,
-    RS_CONN_TYPE_TLS,
-    RS_CONN_TYPE_DTLS,
-};
-typedef unsigned int rs_conn_type_t;
-
 enum rs_cred_type {
     RS_CRED_NONE = 0,
     RS_CRED_TLS_PSK_RSA,       /* RFC 4279.  */
@@ -28,6 +21,12 @@ struct rs_credentials {
     char *secret;
 };
 
+struct rs_error {
+    int code;
+    char *msg;
+    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);
@@ -59,29 +58,39 @@ struct rs_conn_callbacks {
 
 struct rs_handle {
     struct rs_alloc_scheme alloc_scheme;
+    struct rs_error *err;
+    fr_randctx fr_randctx;
+
     /* TODO: dictionary? */
 };
 
+struct rs_peer {
+    struct addrinfo addr;
+    char *secret;
+    int timeout;               /* client only */
+    int tries;                 /* client only */
+};
+
 struct rs_connection {
     struct rs_handle *ctx;
     enum rs_conn_type conn_type;
     struct rs_credentials transport_credentials;
     struct rs_conn_callbacks callbacks;
+    struct rs_error *err;
+    struct rs_peer *peer;
 };
 
-struct rs_attribute {
-    uint8_t type;
-    uint8_t length;
-    uint8_t *value;
+struct rs_packet {
+    struct rs_connection *conn;
+    RADIUS_PACKET *rpkt;
 };
 
-struct rs_packet {
-    uint8_t code;
-    uint8_t id;
-    uint8_t auth[16];
-    struct list *attrs;
+struct rs_attr {
+    struct rs_packet *pkt;
+    VALUE_PAIR *vp;
 };
 
+
 /* Convenience macros.  */
 #define rs_calloc(ctx, nmemb, size) \
     (ctx->alloc_scheme.calloc ? ctx->alloc_scheme.calloc : calloc)(nmemb, size)
index e371747..629e7e1 100644 (file)
@@ -4,6 +4,24 @@
 
 #include <unistd.h>
 
+enum rs_err_code {
+    RSE_OK = 0,
+    RSE_NOMEM = 1,
+    RSE_NOSYS = 2,
+    RSE_INVALID_CTX = 3,
+    RSE_INVALID_CONN = 4,
+    RSE_SOME_ERROR = 21
+};
+
+enum rs_conn_type {
+    RS_CONN_TYPE_UDP = 0,
+    RS_CONN_TYPE_TCP,
+    RS_CONN_TYPE_TLS,
+    RS_CONN_TYPE_DTLS,
+};
+typedef unsigned int rs_conn_type_t;
+
+
 /* Data types.  */
 struct rs_handle;              /* radsec-impl.h */
 struct rs_alloc_scheme;                /* radsec-impl.h */
@@ -11,23 +29,53 @@ 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 */
+struct rs_error;               /* radsec-impl.h */
 struct event_base;             /* <event.h> */
 
 /* Function prototypes.  */
-int rs_context_create(struct rs_handle **ctx);
+int rs_context_create(struct rs_handle **ctx, const char *dict);
 void rs_context_destroy(struct rs_handle *ctx);
 int rs_context_set_alloc_scheme(struct rs_handle *ctx, struct rs_alloc_scheme *scheme);
 int rs_context_config_read(struct rs_handle *ctx, const char *config_file);
 
 int rs_conn_create(const struct rs_handle *ctx, struct rs_connection **conn);
+int rs_conn_add_server(struct rs_connection  *conn, rs_conn_type_t type, const char *host, int port, int timeout, int tries, const char *secret);
+int rs_conn_add_listener(struct rs_connection  *conn, rs_conn_type_t type, const char *host, int port, const char *secret);
 int rs_conn_destroy(struct rs_connection  *conn);
 int rs_conn_set_eventbase(struct rs_connection *conn, struct event_base *eb);
 int rs_conn_set_callbacks(struct rs_connection *conn, struct rs_conn_callbacks *cb);
 int rs_conn_set_server(struct rs_connection *conn, const char *name);
 int rs_conn_get_server(const struct rs_connection *conn, const char *name, size_t buflen); /* NAME <-- most recent server we spoke to */
 
-int rs_packet_send(const struct rs_conn *conn, const struct rs_packet *pkt, void *user_data);
-int rs_packet_receive(const struct rs_conn *conn, struct rs_packet **pkt);
+int rs_packet_create_acc_request(struct rs_connection *conn, struct rs_packet **pkt, const char *user_name, const char *user_pw);
+//int rs_packet_create_acc_accept(cstruct rs_connection *conn, struct rs_packet **pkt);
+//int rs_packet_create_acc_reject(struct rs_connection *conn, struct rs_packet **pkt);
+//int rs_packet_create_acc_challenge(struct rs_connection *conn, struct rs_packet **pkt);
+void rs_packet_destroy(struct rs_packet *pkt);
+int rs_packet_add_attr(struct rs_packet *pkt, const struct rs_attr *attr);
+//int rs_packet_add_new_attr(struct rs_packet *pkt, const char *attr_name, const char *attr_val);
+
+int rs_attr_create(struct rs_connection *conn, struct rs_attr **attr, const char *type, const char *val);
+void rs_attr_destroy(struct rs_attr *attr);
+
+int rs_packet_send(struct rs_conn *conn, const struct rs_packet *pkt, void *user_data);
+int rs_packet_receive(struct rs_conn *conn, struct rs_packet **pkt);
+
+
+int rs_ctx_err_push (struct rs_handle *ctx, int code, const char *msg);
+int rs_conn_err_push (struct rs_connection *conn, int code, const char *msg);
+struct rs_error *rs_ctx_err_pop (struct rs_handle *ctx);
+struct rs_error *rs_conn_err_pop (struct rs_connection *conn);
+void rs_err_free (struct rs_error *err);
+char *rs_err_msg (struct rs_error *err);
+int rs_err_code (struct rs_error *err);
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
+
+
 
 /* Local Variables: */
 /* c-file-style: "stroustrup" */
index 760da84..f645ee1 100644 (file)
@@ -1,17 +1,51 @@
+#include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <libgen.h>
+
+#include <freeradius/libradius.h>
 #include "libradsec.h"
 #include "libradsec-impl.h"
 
-#define ERR_OK 0
-#define ERR_NOMEM 1
-#define ERR_NOSYS 2
-#define ERR_SOME_ERROR 99
-
-int rs_context_create(struct rs_handle **ctx)
+int
+rs_context_create(struct rs_handle **ctx, const char *dict)
 {
-  *ctx = (struct rs_handle *) malloc (sizeof (struct rs_handle));
-  return (ctx ? ERR_OK : ERR_NOMEM);
+  struct rs_handle *h;
+
+  *ctx = NULL;
+  h = (struct rs_handle *) malloc (sizeof (struct rs_handle));
+  if (h)
+    {
+      char *buf;
+      char *dir, *fn;
+
+      buf = malloc (strlen (dict) + 1);
+      if (!buf)
+       {
+         free (h);
+         return RSE_NOMEM;
+       }
+      strcpy (buf, dict);
+      dir = dirname (buf);
+      free (buf);
+      strcpy (buf, dict);
+      fn = basename (buf);
+      free (buf);
+      if (dict_init (dir, fn) < 0)
+       {
+         free (h);
+         return RSE_SOME_ERROR;
+       }
+#if defined (DEBUG)
+      fr_log_fp = stderr;
+      fr_debug_flag = 1;
+#endif
+      fr_randinit (&h->fr_randctx, 0);
+      fr_rand_seed (NULL, 0);
+
+      *ctx = h;
+    }
+  return (h ? RSE_OK : RSE_NOMEM);
 }
 
 void rs_context_destroy(struct rs_handle *ctx)
@@ -21,51 +55,50 @@ void rs_context_destroy(struct rs_handle *ctx)
 
 int rs_context_set_alloc_scheme(struct rs_handle *ctx, struct rs_alloc_scheme *scheme)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
 
 int rs_context_config_read(struct rs_handle *ctx, const char *config_file)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
 
 int rs_conn_create(const struct rs_handle *ctx, struct rs_connection **conn)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
 
-int rs_conn_destroy(struct rs_connection  *conn)
+int rs_conn_add_server(struct rs_connection  *conn, rs_conn_type_t type, const char *host, int port, int timeout, int tries, const char *secret)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
 
-int rs_conn_set_eventbase(struct rs_connection *conn, struct event_base *eb)
+int rs_conn_add_listener(struct rs_connection  *conn, rs_conn_type_t type, const char *host, int port, const char *secret)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
 
-int rs_conn_set_callbacks(struct rs_connection *conn, struct rs_conn_callbacks *cb)
+int rs_conn_destroy(struct rs_connection  *conn)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
 
-int rs_conn_set_server(struct rs_connection *conn, const char *name)
+int rs_conn_set_eventbase(struct rs_connection *conn, struct event_base *eb)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
 
-int rs_conn_get_server(const struct rs_connection *conn, const char *name, size_t buflen)
+int rs_conn_set_callbacks(struct rs_connection *conn, struct rs_conn_callbacks *cb)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
 
-int rs_packet_send(const struct rs_conn *conn, const struct rs_packet *pkt, void *user_data)
+int rs_conn_set_server(struct rs_connection *conn, const char *name)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
 
-int rs_packet_receive(const struct rs_conn *conn, struct rs_packet **pkt)
+int rs_conn_get_server(const struct rs_connection *conn, const char *name, size_t buflen)
 {
-  return ERR_NOSYS;
+  return RSE_NOSYS;
 }
-