From 2f52bb953f654393aaad2dd65c7fa338d0b7ec36 Mon Sep 17 00:00:00 2001 From: "David M. Syzdek" Date: Mon, 28 Mar 2022 15:07:10 -0800 Subject: tinyrad: adding url widget --- Makefile.am | 3 +- src/tru/tinyradutil.c | 22 ++++++ src/tru/tinyradutil.h | 7 ++ src/tru/widget-url.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 211 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index e6f3dfd..7c645c5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -481,7 +481,8 @@ install-data-hook: if test -f $(DESTDIR)/$(bindir)/tinyrad;then\ cd $(DESTDIR)/$(bindir) && \ ln -fs tinyrad tinyrad-conf && \ - ln -fs tinyrad tinyrad-dict; \ + ln -fs tinyrad tinyrad-dict && \ + ln -fs tinyrad tinyrad-url; \ fi; if test -f $(DESTDIR)/$(mandir)/man3/tinyrad_array.3;then\ cd $(DESTDIR)/$(mandir)/man3 && \ diff --git a/src/tru/tinyradutil.c b/src/tru/tinyradutil.c index 6a77ec4..5acfd7b 100644 --- a/src/tru/tinyradutil.c +++ b/src/tru/tinyradutil.c @@ -126,6 +126,13 @@ const TinyRadUtilWidget tru_widget_map[] = .aliases = (const char * const[]) { TRU_PREFIX"-dict", TRU_PREFIX"-dictionary", NULL }, .func = &tru_widget_dict }, + { + .name = "url", + .desc = "process TinyRad URL", + .usage = NULL, + .aliases = (const char * const[]) { TRU_PREFIX"-url", NULL }, + .func = &tru_widget_url + }, { .name = NULL, .func = NULL, @@ -356,6 +363,14 @@ tru_getopt( switch(c = getopt_long(argc, argv, short_opt, long_opt, opt_index)) { + case '4': + cnf->tr_opts |= TRAD_IPV4; + return(TRU_GETOPT_MATCHED); + + case '6': + cnf->tr_opts |= TRAD_IPV6; + return(TRU_GETOPT_MATCHED); + case 'b': cnf->tr_opts |= TRAD_BUILTIN_DICT; return(TRU_GETOPT_MATCHED); @@ -386,6 +401,10 @@ tru_getopt( cnf->opts &= ~TRUTILS_OPT_VERBOSE; return(TRU_GETOPT_MATCHED); + case 'r': + cnf->opts |= TRU_OPT_RESOLVE; + return(TRU_GETOPT_MATCHED); + case 'V': trutils_version(); return(TRU_GETOPT_EXIT); @@ -448,6 +467,8 @@ tru_usage_options( s = short_opt; printf("OPTIONS:\n"); + if ((strchr(s, '4'))) printf(" -4 use IPv4 addresses\n"); + if ((strchr(s, '6'))) printf(" -6 use IPv6 addresses\n"); if ((strchr(s, 'b'))) printf(" -b, --builtin-dict load built-in dictionary\n"); if ((strchr(s, 'D'))) printf(" -D dictionary include dictionary\n"); if ((strchr(s, 'd'))) printf(" -d level, --debug=level print debug messages\n"); @@ -455,6 +476,7 @@ tru_usage_options( if ((strchr(s, 'h'))) printf(" -h, --help print this help and exit\n"); if ((strchr(s, 'I'))) printf(" -I path add path to dictionary search paths\n"); if ((strchr(s, 'q'))) printf(" -q, --quiet, --silent do not print messages\n"); + if ((strchr(s, 'r'))) printf(" -r, --resolve resolve URLs\n"); if ((strchr(s, 'V'))) printf(" -V, --version print version number and exit\n"); if ((strchr(s, 'v'))) printf(" -v, --verbose print verbose messages\n"); diff --git a/src/tru/tinyradutil.h b/src/tru/tinyradutil.h index b3c9b18..328505a 100644 --- a/src/tru/tinyradutil.h +++ b/src/tru/tinyradutil.h @@ -76,6 +76,9 @@ #define TRU_GETOPT_EXIT -4 +#define TRU_OPT_RESOLVE 0x0001 + + #define TRU_COMMON_SHORT "d:hqVv" #define TRU_COMMON_LONG \ { "debug", optional_argument, NULL, 'd' }, \ @@ -92,6 +95,10 @@ { "builtin-dict", no_argument, NULL, 'b' }, \ +#define TRU_NET_SHORT "46" +#define TRU_NET_LONG \ + + #define TRU_REQ_SHORT "f:" #define TRU_REQ_LONG \ { "file", optional_argument, NULL, 'f' }, \ diff --git a/src/tru/widget-url.c b/src/tru/widget-url.c index 8106c32..ce14a20 100644 --- a/src/tru/widget-url.c +++ b/src/tru/widget-url.c @@ -40,9 +40,33 @@ #include "tinyradutil.h" #include +#include +#include +#include +#include +#include +#include #include +////////////////// +// // +// Prototypes // +// // +////////////////// +#pragma mark - Prototypes + +int +tru_widget_url_print( + TinyRadURLDesc * trudp ); + + +int +tru_widget_url_usage( + TinyRadUtilConf * cnf, + const char * short_opt ); + + ///////////////// // // // Functions // @@ -54,11 +78,164 @@ int tru_widget_url( TinyRadUtilConf * cnf ) { - int rc; - if ((rc = tru_load_tinyrad(cnf)) != TRAD_SUCCESS) - return(rc); + int rc; + int pos; + TinyRadURLDesc * trudp; + TinyRadURLDesc ** trudpp; + TinyRadURLDesc * trudp_next; + + // getopt options + static char short_opt[] = "r" TRU_COMMON_SHORT TRU_NET_SHORT; + static struct option long_opt[] = + { + { "resolve", no_argument, NULL, 'r' }, \ + TRU_NET_LONG \ + TRU_COMMON_LONG + }; + + trudp = NULL; + trudp_next = NULL; + + // process widget cli options + if ((rc = tru_cli_parse(cnf, cnf->argc, cnf->argv, short_opt, long_opt, &tru_widget_url_usage)) != 0) + { + return((rc == 0) ? 0 : 1); + }; + if (optind >= cnf->argc) + { + fprintf(stderr, "%s: missing required argument\n", PROGRAM_NAME); + fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->widget_name); + return(1); + }; + + // parse and resolve URLs + trudpp = &trudp; + for(pos = optind; (pos < cnf->argc); pos++) + { + if ((rc = tinyrad_urldesc_parse(cnf->argv[pos], trudpp)) != TRAD_SUCCESS) + { + if (!(cnf->opts & TRUTILS_OPT_QUIET)) + { + fprintf(stderr, "%s: %s: %s: %s\n", PROGRAM_NAME, cnf->widget_name, cnf->argv[pos], tinyrad_strerror(rc)); + fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->widget_name); + }; + return(1); + }; + if ((cnf->opts & TRU_OPT_RESOLVE)) + { + if ((rc = tinyrad_urldesc_resolve(*trudpp, cnf->tr_opts)) != TRAD_SUCCESS) + { + if (!(cnf->opts & TRUTILS_OPT_QUIET)) + { + fprintf(stderr, "%s: %s: %s: %s\n", PROGRAM_NAME, cnf->widget_name, cnf->argv[pos], tinyrad_strerror(rc)); + fprintf(stderr, "Try `%s %s --help' for more information.\n", PROGRAM_NAME, cnf->widget_name); + }; + return(1); + }; + }; + trudpp = &(*trudpp)->trud_next; + }; + + // exit if not displaying output + if (!(cnf->opts & TRUTILS_OPT_VERBOSE)) + { + tinyrad_urldesc_free(trudp); + return(0); + }; + + // display URLs + trudp_next = trudp; + while ((trudp_next)) + { + if ((tru_widget_url_print(trudp_next))) + { + tinyrad_urldesc_free(trudp); + return(1); + }; + trudp_next = trudp_next->trud_next; + }; + + tinyrad_urldesc_free(trudp); + return(TRAD_SUCCESS); } +int +tru_widget_url_print( + TinyRadURLDesc * trudp ) +{ + int pos; + char * str; + const char * scheme; + struct sockaddr_storage * sas; + char addr[INET6_ADDRSTRLEN]; + + if ((str = tinyrad_urldesc2str(trudp)) == NULL) + { + fprintf(stderr, "%s: out of virtual memory\n", PROGRAM_NAME); + tinyrad_urldesc_free(trudp); + return(1); + }; + switch(trudp->trud_opts & TRAD_SCHEME) + { + case TRAD_RADIUS: scheme = "radius (RFC2865 RADIUS)"; break;; + case TRAD_RADIUS_ACCT: scheme = "radius-acct (RFC2866 RADIUS Accounting)"; break;; + case TRAD_RADIUS_DYNAUTH: scheme = "radius-dynauth (RFC2866 RADIUS Dynamic Authorization)"; break;; + case TRAD_RADSEC: scheme = "radsec (RFC6614/RFC7360 RADIUS TLS/DTLS)"; break;; + default: scheme = "Unknown or unsupported URL scheme"; break; + }; + + printf("%s\n", str); + printf(" scheme: %s\n", scheme); + printf(" host: %s\n", trudp->trud_host); + printf(" port: %i\n", trudp->trud_port); + printf(" secret: %s\n", (((trudp->trud_secret)) ? trudp->trud_secret : "n/a")); + printf(" protocol: %s\n", ((trudp->trud_opts & TRAD_TCP)) ? "tcp" : "udp"); + if ( ((trudp->trud_sockaddrs)) && ((trudp->trud_sockaddrs[0])) ) + { + for(pos = 0; ((trudp->trud_sockaddrs[pos])); pos++) + { + sas = trudp->trud_sockaddrs[pos]; + switch(sas->ss_family) + { + case AF_INET: inet_ntop(sas->ss_family, &((struct sockaddr_in *)sas)->sin_addr, addr, sizeof(addr)); break; + case AF_INET6: inet_ntop(sas->ss_family, &((struct sockaddr_in6 *)sas)->sin6_addr, addr, sizeof(addr)); break; + default: + addr[0] = '\0'; + break; + }; + printf(" %s%s\n", ((!(pos)) ? "addresses: " : " "), addr); + }; + }; + printf("\n"); + + tinyrad_free(str); + + return(0); +} + + +int +tru_widget_url_usage( + TinyRadUtilConf * cnf, + const char * short_opt ) +{ + tru_usage_summary(cnf); + tru_usage_options(short_opt); + printf("\n"); + printf("URL Syntax:\n"); + printf(" radius://hostport/[secret][?proto] use RFC2865 (udp/port 1812)\n"); + printf(" radius-acct://hostport/[secret][?proto] use RFC2866 (udp/port 1813)\n"); + printf(" radsec://hostport/[?proto] use RFC6614/RFC7360 (tcp/port 2083)\n"); + printf(" radius-dynauth://hostport/[secret][?proto] use RFC5176 (udp/port 3799)\n"); + printf("\n"); + printf(" where:\n"); + printf(" 'hostport' is a host name with an optional ':portnumber'\n"); + printf(" 'secret' is the RADIUS secret encoded using character encoding in RFC3986\n"); + printf(" 'proto' is communication protocol used by the connection (UDP or TCP)\n"); + printf("\n"); + return(0); +} + /* end of source */ -- cgit v1.2.3