summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordu.net>2010-09-27 18:47:07 +0200
committerLinus Nordberg <linus@nordu.net>2010-09-27 18:57:06 +0200
commitaa354bb116fb38c9b049070dea4752afe9a3ea34 (patch)
tree51001c4157aef25682eeb5c460438dc5c47ed323
parent94e3f46ef6c976f6bbd670555262ec6466314d8a (diff)
WIP on libradsec: 94e3f46 Example client crafting simple packet using freeradius-libradius.
-rw-r--r--lib/Makefile10
-rw-r--r--lib/err.c121
-rw-r--r--lib/examples/Makefile2
-rw-r--r--lib/examples/client.c97
-rw-r--r--lib/libradsec-impl.h45
-rw-r--r--lib/libradsec.h54
-rw-r--r--lib/radsec.c85
7 files changed, 285 insertions, 129 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 0c29f7a..bc35e88 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -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
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;
+}
diff --git a/lib/examples/Makefile b/lib/examples/Makefile
index 1817d90..e07a32b 100644
--- a/lib/examples/Makefile
+++ b/lib/examples/Makefile
@@ -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:
diff --git a/lib/examples/client.c b/lib/examples/client.c
index 64a4436..37601b6 100644
--- a/lib/examples/client.c
+++ b/lib/examples/client.c
@@ -3,7 +3,6 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <freeradius/libradius.h>
#include "../libradsec.h"
#include "../debug.h"
@@ -12,90 +11,32 @@
#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
diff --git a/lib/libradsec-impl.h b/lib/libradsec-impl.h
index 913de4a..e9ec644 100644
--- a/lib/libradsec-impl.h
+++ b/lib/libradsec-impl.h
@@ -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)
diff --git a/lib/libradsec.h b/lib/libradsec.h
index e371747..629e7e1 100644
--- a/lib/libradsec.h
+++ b/lib/libradsec.h
@@ -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" */
diff --git a/lib/radsec.c b/lib/radsec.c
index 760da84..f645ee1 100644
--- a/lib/radsec.c
+++ b/lib/radsec.c
@@ -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;
}
-