/* * Copyright (c) 2004 Maxim Sobolev * 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 AUTHOR 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 AUTHOR 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. * * $Id: radiusclient.c,v 1.8 2010/02/04 10:30:26 aland Exp $ */ #include #include #include #include #include #include #define BUF_LEN 4096 int process(void *, VALUE_PAIR *, int, int); static void usage(void) { fprintf(stderr, "usage: radiusclient [-f config_file] [-p nas_port] [-s | [-a] a1=v1 [a2=v2[...[aN=vN]...]]]\n"); exit(1); } int main(int argc, char **argv) { int i, nas_port, ch, acct, server, ecount, firstline, theend; void *rh; size_t len; VALUE_PAIR *send, **vp; char *rc_conf, *cp; char lbuf[4096]; rc_conf = RC_CONFIG_FILE; nas_port = 5060; acct = 0; server = 0; while ((ch = getopt(argc, argv, "af:p:s")) != -1) { switch (ch) { case 'f': rc_conf = optarg; break; case 'p': nas_port = atoi(optarg); break; case 'a': acct = 1; break; case 's': server = 1; break; default: usage(); } } argc -= optind; argv += optind; if ((argc == 0 && server == 0) || (argc != 0 && server != 0)) usage(); if ((rh = rc_read_config(rc_conf)) == NULL) { fprintf(stderr, "error opening radius configuration file\n"); exit(1); } if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) { fprintf(stderr, "error reading radius dictionary\n"); exit(2); } if (server == 0) { send = NULL; vp = &send; for (i = 0; i < argc; i++) { if (rc_avpair_parse(rh, argv[i], vp) < 0) { fprintf(stderr, "%s: can't parse AV pair\n", argv[i]); exit(3); } vp = &send->next; } exit(process(rh, send, acct, nas_port)); } while (1 == 1) { send = NULL; vp = &send; ecount = 0; firstline = 1; acct = 0; do { len = 0; cp = rc_fgetln(stdin, &len); theend = 1; if (cp != NULL && len > 0) { if (firstline != 0) { if (len >= 4 && memcmp(cp, "ACCT", 4) == 0) acct = 1; firstline = 0; theend = 0; continue; } for (i = 0; i < len; i++) { if (!isspace(cp[i])) { theend = 0; break; } } if (theend == 0) { memcpy(lbuf, cp, len); lbuf[len] = '\0'; if (rc_avpair_parse(rh, lbuf, vp) < 0) { fprintf(stderr, "%s: can't parse AV pair\n", lbuf); ecount++; } else { vp = &send->next; } } } } while (theend == 0); if (send != NULL && ecount == 0) printf("%d\n\n", process(rh, send, acct, nas_port)); else printf("%d\n\n", -1); fflush(stdout); if (send != NULL) rc_avpair_free(send); if (cp == NULL || len == 0) break; } exit(0); } int process(void *rh, VALUE_PAIR *send, int acct, int nas_port) { VALUE_PAIR *received; char msg[PW_MAX_MSG_SIZE]; char buf[BUF_LEN]; int i; received = NULL; if (acct == 0) { i = rc_auth(rh, nas_port, send, &received, msg); if (received != NULL) { printf("%s", rc_avpair_log(rh, received, buf, BUF_LEN)); rc_avpair_free(received); } } else { i = rc_acct(rh, nas_port, send); } return (i == OK_RC) ? 0 : 1; }