diff options
Diffstat (limited to 'src/lib/krad/t_remote.c')
-rw-r--r-- | src/lib/krad/t_remote.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/lib/krad/t_remote.c b/src/lib/krad/t_remote.c new file mode 100644 index 0000000..a521ecb --- /dev/null +++ b/src/lib/krad/t_remote.c @@ -0,0 +1,170 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* lib/krad/t_remote.c - Protocol 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 EVENT_COUNT 6 + +static struct +{ + int count; + struct event events[EVENT_COUNT]; +} record; + +static krad_attrset *set; +static krad_remote *rr; +static verto_ctx *vctx; + +static void +callback(krb5_error_code retval, const krad_packet *request, + const krad_packet *response, void *data) +{ + struct event *evt; + + evt = &record.events[record.count++]; + evt->error = retval != 0; + if (evt->error) + evt->result.retval = retval; + else + evt->result.code = krad_packet_get_code(response); + verto_break(vctx); +} + +static void +remote_new(krb5_context kctx, krad_remote **remote) +{ + struct addrinfo *ai = NULL, hints; + + 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(kr_remote_new(kctx, vctx, ai, "foo", remote)); + insist(kr_remote_equals(*remote, ai, "foo")); + freeaddrinfo(ai); +} + +static krb5_error_code +do_auth(const char *password, const krad_packet **pkt) +{ + const krad_packet *tmppkt; + krb5_error_code retval; + krb5_data tmp = string2data((char *)password); + + retval = krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp); + if (retval != 0) + return retval; + + retval = kr_remote_send(rr, krad_code_name2num("Access-Request"), set, + callback, NULL, 1000, 3, &tmppkt); + krad_attrset_del(set, krad_attr_name2num("User-Password"), 0); + if (retval != 0) + return retval; + + if (pkt != NULL) + *pkt = tmppkt; + return 0; +} + +static void +test_timeout(verto_ctx *ctx, verto_ev *ev) +{ + static const krad_packet *pkt; + + noerror(do_auth("accept", &pkt)); + kr_remote_cancel(rr, pkt); +} + +int +main(int argc, const char **argv) +{ + krb5_context kctx = NULL; + krb5_data tmp; + + if (!daemon_start(argc, argv)) { + fprintf(stderr, "Unable to start pyrad daemon, skipping test...\n"); + return 0; + } + + /* Initialize. */ + noerror(krb5_init_context(&kctx)); + vctx = verto_new(NULL, VERTO_EV_TYPE_IO | VERTO_EV_TYPE_TIMEOUT); + insist(vctx != NULL); + remote_new(kctx, &rr); + + /* Create attribute set. */ + noerror(krad_attrset_new(kctx, &set)); + tmp = string2data("testUser"); + noerror(krad_attrset_add(set, krad_attr_name2num("User-Name"), &tmp)); + + /* Send accept packet. */ + noerror(do_auth("accept", NULL)); + verto_run(vctx); + + /* Send reject packet. */ + noerror(do_auth("reject", NULL)); + verto_run(vctx); + + /* Send canceled packet. */ + insist(verto_add_timeout(vctx, VERTO_EV_FLAG_NONE, test_timeout, 0) != + NULL); + verto_run(vctx); + + /* Test timeout. */ + daemon_stop(); + noerror(do_auth("accept", NULL)); + verto_run(vctx); + + /* Test outstanding packet freeing. */ + noerror(do_auth("accept", NULL)); + kr_remote_free(rr); + krad_attrset_free(set); + + /* Verify the results. */ + insist(record.count == EVENT_COUNT); + insist(record.events[0].error == FALSE); + insist(record.events[0].result.code == + krad_code_name2num("Access-Accept")); + insist(record.events[1].error == FALSE); + insist(record.events[1].result.code == + krad_code_name2num("Access-Reject")); + insist(record.events[2].error == TRUE); + insist(record.events[2].result.retval == ECANCELED); + insist(record.events[3].error == TRUE); + insist(record.events[3].result.retval == ETIMEDOUT); + insist(record.events[4].error == TRUE); + insist(record.events[4].result.retval == ECANCELED); + insist(record.events[5].error == TRUE); + insist(record.events[5].result.retval == ECANCELED); + + verto_free(vctx); + krb5_free_context(kctx); + return 0; +} |