summaryrefslogtreecommitdiffstats
path: root/src/lib/krad/t_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krad/t_packet.c')
-rw-r--r--src/lib/krad/t_packet.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c
new file mode 100644
index 0000000000..0a92e9cc2b
--- /dev/null
+++ b/src/lib/krad/t_packet.c
@@ -0,0 +1,194 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/krad/t_packet.c - RADIUS packet test program */
+/*
+ * Copyright 2013 Red Hat, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "t_daemon.h"
+
+#define ACCEPT_PACKET 0
+#define REJECT_PACKET 1
+
+static krad_packet *packets[3];
+
+static const krad_packet *
+iterator(void *data, krb5_boolean cancel)
+{
+ krad_packet *tmp;
+ int *i = data;
+
+ if (cancel || packets[*i] == NULL)
+ return NULL;
+
+ tmp = packets[*i];
+ *i += 1;
+ return tmp;
+}
+
+static krb5_error_code
+make_packet(krb5_context ctx, const krb5_data *username,
+ const krb5_data *password, krad_packet **pkt)
+{
+ krad_attrset *set = NULL;
+ krad_packet *tmp = NULL;
+ krb5_error_code retval;
+ const krb5_data *data;
+ int i = 0;
+
+ retval = krad_attrset_new(ctx, &set);
+ if (retval != 0)
+ goto out;
+
+ retval = krad_attrset_add(set, krad_attr_name2num("User-Name"), username);
+ if (retval != 0)
+ goto out;
+
+ retval = krad_attrset_add(set, krad_attr_name2num("User-Password"),
+ password);
+ if (retval != 0)
+ goto out;
+
+ retval = krad_packet_new_request(ctx, "foo",
+ krad_code_name2num("Access-Request"),
+ set, iterator, &i, &tmp);
+ if (retval != 0)
+ goto out;
+
+ data = krad_packet_get_attr(tmp, krad_attr_name2num("User-Name"), 0);
+ if (data == NULL) {
+ retval = ENOENT;
+ goto out;
+ }
+
+ if (data->length != username->length ||
+ memcmp(data->data, username->data, data->length) != 0) {
+ retval = EINVAL;
+ goto out;
+ }
+
+ *pkt = tmp;
+ tmp = NULL;
+
+out:
+ krad_attrset_free(set);
+ krad_packet_free(tmp);
+ return retval;
+}
+
+static krb5_error_code
+do_auth(krb5_context ctx, struct addrinfo *ai, const char *secret,
+ const krad_packet *rqst, krb5_boolean *auth)
+{
+ const krad_packet *req = NULL;
+ char tmp[KRAD_PACKET_SIZE_MAX];
+ const krb5_data *request;
+ krad_packet *rsp = NULL;
+ krb5_error_code retval;
+ krb5_data response;
+ int sock = -1, i;
+
+ response = make_data(tmp, sizeof(tmp));
+
+ sock = socket(ai->ai_family, ai->ai_socktype, 0);
+ if (sock < 0) {
+ retval = errno;
+ goto out;
+ }
+
+ request = krad_packet_encode(rqst);
+ if (sendto(sock, request->data, request->length, 0, ai->ai_addr,
+ ai->ai_addrlen) < 0) {
+ retval = errno;
+ goto out;
+ }
+
+ i = recv(sock, response.data, sizeof(tmp), 0);
+ if (i < 0) {
+ retval = errno;
+ goto out;
+ }
+ response.length = i;
+
+ i = 0;
+ retval = krad_packet_decode_response(ctx, secret, &response, iterator, &i,
+ &req, &rsp);
+ if (retval != 0)
+ goto out;
+
+ if (req != rqst) {
+ retval = EBADMSG;
+ goto out;
+ }
+
+ *auth = krad_packet_get_code(rsp) == krad_code_name2num("Access-Accept");
+
+out:
+ krad_packet_free(rsp);
+ if (sock >= 0)
+ close(sock);
+ return retval;
+}
+
+int
+main(int argc, const char **argv)
+{
+ struct addrinfo *ai = NULL, hints;
+ krb5_data username, password;
+ krb5_boolean auth = FALSE;
+ krb5_context ctx;
+
+ username = string2data("testUser");
+
+ if (!daemon_start(argc, argv)) {
+ fprintf(stderr, "Unable to start pyrad daemon, skipping test...\n");
+ return 0;
+ }
+
+ noerror(krb5_init_context(&ctx));
+
+ password = string2data("accept");
+ noerror(make_packet(ctx, &username, &password, &packets[ACCEPT_PACKET]));
+
+ password = string2data("reject");
+ noerror(make_packet(ctx, &username, &password, &packets[REJECT_PACKET]));
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ noerror(gai_error_code(getaddrinfo("127.0.0.1", "radius", &hints, &ai)));
+
+ noerror(do_auth(ctx, ai, "foo", packets[ACCEPT_PACKET], &auth));
+ insist(auth == TRUE);
+
+ noerror(do_auth(ctx, ai, "foo", packets[REJECT_PACKET], &auth));
+ insist(auth == FALSE);
+
+ krad_packet_free(packets[ACCEPT_PACKET]);
+ krad_packet_free(packets[REJECT_PACKET]);
+ krb5_free_context(ctx);
+ freeaddrinfo(ai);
+ return 0;
+}