xref: /freebsd/crypto/krb5/src/lib/krad/t_remote.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /* lib/krad/t_remote.c - Protocol test program */
3*7f2fe78bSCy Schubert /*
4*7f2fe78bSCy Schubert  * Copyright 2013 Red Hat, Inc.  All rights reserved.
5*7f2fe78bSCy Schubert  *
6*7f2fe78bSCy Schubert  * Redistribution and use in source and binary forms, with or without
7*7f2fe78bSCy Schubert  * modification, are permitted provided that the following conditions are met:
8*7f2fe78bSCy Schubert  *
9*7f2fe78bSCy Schubert  *    1. Redistributions of source code must retain the above copyright
10*7f2fe78bSCy Schubert  *       notice, this list of conditions and the following disclaimer.
11*7f2fe78bSCy Schubert  *
12*7f2fe78bSCy Schubert  *    2. Redistributions in binary form must reproduce the above copyright
13*7f2fe78bSCy Schubert  *       notice, this list of conditions and the following disclaimer in
14*7f2fe78bSCy Schubert  *       the documentation and/or other materials provided with the
15*7f2fe78bSCy Schubert  *       distribution.
16*7f2fe78bSCy Schubert  *
17*7f2fe78bSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18*7f2fe78bSCy Schubert  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19*7f2fe78bSCy Schubert  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20*7f2fe78bSCy Schubert  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21*7f2fe78bSCy Schubert  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22*7f2fe78bSCy Schubert  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23*7f2fe78bSCy Schubert  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24*7f2fe78bSCy Schubert  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25*7f2fe78bSCy Schubert  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26*7f2fe78bSCy Schubert  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27*7f2fe78bSCy Schubert  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*7f2fe78bSCy Schubert  */
29*7f2fe78bSCy Schubert 
30*7f2fe78bSCy Schubert #include "t_daemon.h"
31*7f2fe78bSCy Schubert 
32*7f2fe78bSCy Schubert #define EVENT_COUNT 6
33*7f2fe78bSCy Schubert 
34*7f2fe78bSCy Schubert static struct
35*7f2fe78bSCy Schubert {
36*7f2fe78bSCy Schubert     int count;
37*7f2fe78bSCy Schubert     struct event events[EVENT_COUNT];
38*7f2fe78bSCy Schubert } record;
39*7f2fe78bSCy Schubert 
40*7f2fe78bSCy Schubert static krad_attrset *set;
41*7f2fe78bSCy Schubert static krad_remote *rr;
42*7f2fe78bSCy Schubert static verto_ctx *vctx;
43*7f2fe78bSCy Schubert 
44*7f2fe78bSCy Schubert static void
callback(krb5_error_code retval,const krad_packet * request,const krad_packet * response,void * data)45*7f2fe78bSCy Schubert callback(krb5_error_code retval, const krad_packet *request,
46*7f2fe78bSCy Schubert          const krad_packet *response, void *data)
47*7f2fe78bSCy Schubert {
48*7f2fe78bSCy Schubert     struct event *evt;
49*7f2fe78bSCy Schubert 
50*7f2fe78bSCy Schubert     evt = &record.events[record.count++];
51*7f2fe78bSCy Schubert     evt->error = retval != 0;
52*7f2fe78bSCy Schubert     if (evt->error)
53*7f2fe78bSCy Schubert         evt->result.retval = retval;
54*7f2fe78bSCy Schubert     else
55*7f2fe78bSCy Schubert         evt->result.code = krad_packet_get_code(response);
56*7f2fe78bSCy Schubert     verto_break(vctx);
57*7f2fe78bSCy Schubert }
58*7f2fe78bSCy Schubert 
59*7f2fe78bSCy Schubert static void
remote_new(krb5_context kctx,krad_remote ** remote)60*7f2fe78bSCy Schubert remote_new(krb5_context kctx, krad_remote **remote)
61*7f2fe78bSCy Schubert {
62*7f2fe78bSCy Schubert     struct addrinfo *ai = NULL, hints;
63*7f2fe78bSCy Schubert 
64*7f2fe78bSCy Schubert     memset(&hints, 0, sizeof(hints));
65*7f2fe78bSCy Schubert     hints.ai_family = AF_INET;
66*7f2fe78bSCy Schubert     hints.ai_socktype = SOCK_DGRAM;
67*7f2fe78bSCy Schubert     noerror(gai_error_code(getaddrinfo("127.0.0.1", "radius", &hints, &ai)));
68*7f2fe78bSCy Schubert 
69*7f2fe78bSCy Schubert     noerror(kr_remote_new(kctx, vctx, ai, "foo", remote));
70*7f2fe78bSCy Schubert     insist(kr_remote_equals(*remote, ai, "foo"));
71*7f2fe78bSCy Schubert     freeaddrinfo(ai);
72*7f2fe78bSCy Schubert }
73*7f2fe78bSCy Schubert 
74*7f2fe78bSCy Schubert static krb5_error_code
do_auth(const char * password,const krad_packet ** pkt)75*7f2fe78bSCy Schubert do_auth(const char *password, const krad_packet **pkt)
76*7f2fe78bSCy Schubert {
77*7f2fe78bSCy Schubert     const krad_packet *tmppkt;
78*7f2fe78bSCy Schubert     krb5_error_code retval;
79*7f2fe78bSCy Schubert     krb5_data tmp = string2data((char *)password);
80*7f2fe78bSCy Schubert 
81*7f2fe78bSCy Schubert     retval = krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp);
82*7f2fe78bSCy Schubert     if (retval != 0)
83*7f2fe78bSCy Schubert         return retval;
84*7f2fe78bSCy Schubert 
85*7f2fe78bSCy Schubert     retval = kr_remote_send(rr, krad_code_name2num("Access-Request"), set,
86*7f2fe78bSCy Schubert                             callback, NULL, 1000, 3, &tmppkt);
87*7f2fe78bSCy Schubert     krad_attrset_del(set, krad_attr_name2num("User-Password"), 0);
88*7f2fe78bSCy Schubert     if (retval != 0)
89*7f2fe78bSCy Schubert         return retval;
90*7f2fe78bSCy Schubert 
91*7f2fe78bSCy Schubert     if (pkt != NULL)
92*7f2fe78bSCy Schubert         *pkt = tmppkt;
93*7f2fe78bSCy Schubert     return 0;
94*7f2fe78bSCy Schubert }
95*7f2fe78bSCy Schubert 
96*7f2fe78bSCy Schubert static void
test_timeout(verto_ctx * ctx,verto_ev * ev)97*7f2fe78bSCy Schubert test_timeout(verto_ctx *ctx, verto_ev *ev)
98*7f2fe78bSCy Schubert {
99*7f2fe78bSCy Schubert     static const krad_packet *pkt;
100*7f2fe78bSCy Schubert 
101*7f2fe78bSCy Schubert     noerror(do_auth("accept", &pkt));
102*7f2fe78bSCy Schubert     kr_remote_cancel(rr, pkt);
103*7f2fe78bSCy Schubert }
104*7f2fe78bSCy Schubert 
105*7f2fe78bSCy Schubert int
main(int argc,const char ** argv)106*7f2fe78bSCy Schubert main(int argc, const char **argv)
107*7f2fe78bSCy Schubert {
108*7f2fe78bSCy Schubert     krb5_context kctx = NULL;
109*7f2fe78bSCy Schubert     krb5_data tmp;
110*7f2fe78bSCy Schubert 
111*7f2fe78bSCy Schubert     if (!daemon_start(argc, argv)) {
112*7f2fe78bSCy Schubert         fprintf(stderr, "Unable to start pyrad daemon, skipping test...\n");
113*7f2fe78bSCy Schubert         return 0;
114*7f2fe78bSCy Schubert     }
115*7f2fe78bSCy Schubert 
116*7f2fe78bSCy Schubert     /* Initialize. */
117*7f2fe78bSCy Schubert     noerror(krb5_init_context(&kctx));
118*7f2fe78bSCy Schubert     vctx = verto_new(NULL, VERTO_EV_TYPE_IO | VERTO_EV_TYPE_TIMEOUT);
119*7f2fe78bSCy Schubert     insist(vctx != NULL);
120*7f2fe78bSCy Schubert     remote_new(kctx, &rr);
121*7f2fe78bSCy Schubert 
122*7f2fe78bSCy Schubert     /* Create attribute set. */
123*7f2fe78bSCy Schubert     noerror(krad_attrset_new(kctx, &set));
124*7f2fe78bSCy Schubert     tmp = string2data("testUser");
125*7f2fe78bSCy Schubert     noerror(krad_attrset_add(set, krad_attr_name2num("User-Name"), &tmp));
126*7f2fe78bSCy Schubert 
127*7f2fe78bSCy Schubert     /* Send accept packet. */
128*7f2fe78bSCy Schubert     noerror(do_auth("accept", NULL));
129*7f2fe78bSCy Schubert     verto_run(vctx);
130*7f2fe78bSCy Schubert 
131*7f2fe78bSCy Schubert     /* Send reject packet. */
132*7f2fe78bSCy Schubert     noerror(do_auth("reject", NULL));
133*7f2fe78bSCy Schubert     verto_run(vctx);
134*7f2fe78bSCy Schubert 
135*7f2fe78bSCy Schubert     /* Send canceled packet. */
136*7f2fe78bSCy Schubert     insist(verto_add_timeout(vctx, VERTO_EV_FLAG_NONE, test_timeout, 0) !=
137*7f2fe78bSCy Schubert            NULL);
138*7f2fe78bSCy Schubert     verto_run(vctx);
139*7f2fe78bSCy Schubert 
140*7f2fe78bSCy Schubert     /* Test timeout. */
141*7f2fe78bSCy Schubert     daemon_stop();
142*7f2fe78bSCy Schubert     noerror(do_auth("accept", NULL));
143*7f2fe78bSCy Schubert     verto_run(vctx);
144*7f2fe78bSCy Schubert 
145*7f2fe78bSCy Schubert     /* Test outstanding packet freeing. */
146*7f2fe78bSCy Schubert     noerror(do_auth("accept", NULL));
147*7f2fe78bSCy Schubert     kr_remote_free(rr);
148*7f2fe78bSCy Schubert     krad_attrset_free(set);
149*7f2fe78bSCy Schubert 
150*7f2fe78bSCy Schubert     /* Verify the results. */
151*7f2fe78bSCy Schubert     insist(record.count == EVENT_COUNT);
152*7f2fe78bSCy Schubert     insist(record.events[0].error == FALSE);
153*7f2fe78bSCy Schubert     insist(record.events[0].result.code ==
154*7f2fe78bSCy Schubert            krad_code_name2num("Access-Accept"));
155*7f2fe78bSCy Schubert     insist(record.events[1].error == FALSE);
156*7f2fe78bSCy Schubert     insist(record.events[1].result.code ==
157*7f2fe78bSCy Schubert            krad_code_name2num("Access-Reject"));
158*7f2fe78bSCy Schubert     insist(record.events[2].error == TRUE);
159*7f2fe78bSCy Schubert     insist(record.events[2].result.retval == ECANCELED);
160*7f2fe78bSCy Schubert     insist(record.events[3].error == TRUE);
161*7f2fe78bSCy Schubert     insist(record.events[3].result.retval == ETIMEDOUT);
162*7f2fe78bSCy Schubert     insist(record.events[4].error == TRUE);
163*7f2fe78bSCy Schubert     insist(record.events[4].result.retval == ECANCELED);
164*7f2fe78bSCy Schubert     insist(record.events[5].error == TRUE);
165*7f2fe78bSCy Schubert     insist(record.events[5].result.retval == ECANCELED);
166*7f2fe78bSCy Schubert 
167*7f2fe78bSCy Schubert     verto_free(vctx);
168*7f2fe78bSCy Schubert     krb5_free_context(kctx);
169*7f2fe78bSCy Schubert     return 0;
170*7f2fe78bSCy Schubert }
171