diff options
| author | David M. Syzdek <david@syzdek.net> | 2022-05-31 15:49:27 -0800 |
|---|---|---|
| committer | David M. Syzdek <david@syzdek.net> | 2022-05-31 15:49:27 -0800 |
| commit | 70cbc4217eed1833324485b939417ecc50be75f5 (patch) | |
| tree | fbb23118cf88579c37226ce9d160600121028e05 | |
| parent | aee914aa06acce16e5d5f01fcbfa298545f23026 (diff) | |
| download | tinytac-70cbc4217eed1833324485b939417ecc50be75f5.tar.gz tinytac-70cbc4217eed1833324485b939417ecc50be75f5.tar.bz2 tinytac-70cbc4217eed1833324485b939417ecc50be75f5.tar.xz tinytac-70cbc4217eed1833324485b939417ecc50be75f5.zip | |
libtinytac: adding initial support for rc files
| -rw-r--r-- | Makefile.am | 2 | ||||
| -rw-r--r-- | lib/libtinytac/lconf.c | 475 | ||||
| -rw-r--r-- | lib/libtinytac/lconf.h | 57 | ||||
| -rw-r--r-- | lib/libtinytac/libtinytac.h | 7 | ||||
| -rw-r--r-- | lib/libtinytac/lmemory.c | 13 |
5 files changed, 554 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 755b8de..4162d03 100644 --- a/Makefile.am +++ b/Makefile.am | |||
| @@ -166,6 +166,8 @@ lib_libtinytac_a_SOURCES = $(lib_libbindle_a_SOURCES) \ | |||
| 166 | include/tinytac_plus.h \ | 166 | include/tinytac_plus.h \ |
| 167 | include/tinytac_compat.h \ | 167 | include/tinytac_compat.h \ |
| 168 | lib/libtinytac/libtinytac.h \ | 168 | lib/libtinytac/libtinytac.h \ |
| 169 | lib/libtinytac/lconf.c \ | ||
| 170 | lib/libtinytac/lconf.h \ | ||
| 169 | lib/libtinytac/ldebug.c \ | 171 | lib/libtinytac/ldebug.c \ |
| 170 | lib/libtinytac/ldebug.h \ | 172 | lib/libtinytac/ldebug.h \ |
| 171 | lib/libtinytac/lerror.c \ | 173 | lib/libtinytac/lerror.c \ |
diff --git a/lib/libtinytac/lconf.c b/lib/libtinytac/lconf.c new file mode 100644 index 0000000..e3aa339 --- /dev/null +++ b/lib/libtinytac/lconf.c | |||
| @@ -0,0 +1,475 @@ | |||
| 1 | /* | ||
| 2 | * Tiny TACACS+ Client Library | ||
| 3 | * Copyright (C) 2022 David M. Syzdek <david@syzdek.net>. | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions are | ||
| 8 | * met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * * Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * * Neither the name of David M. Syzdek nor the | ||
| 16 | * names of its contributors may be used to endorse or promote products | ||
| 17 | * derived from this software without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 20 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 21 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID M. SYZDEK BE LIABLE FOR | ||
| 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | * SUCH DAMAGE. | ||
| 30 | */ | ||
| 31 | #define _LIB_LIBTINYTAC_LCONF_C 1 | ||
| 32 | #include "lconf.h" | ||
| 33 | |||
| 34 | |||
| 35 | /////////////// | ||
| 36 | // // | ||
| 37 | // Headers // | ||
| 38 | // // | ||
| 39 | /////////////// | ||
| 40 | #pragma mark - Headers | ||
| 41 | |||
| 42 | #include <stdlib.h> | ||
| 43 | #include <string.h> | ||
| 44 | #include <strings.h> | ||
| 45 | #include <unistd.h> | ||
| 46 | #include <fcntl.h> | ||
| 47 | #include <syslog.h> | ||
| 48 | #include <pwd.h> | ||
| 49 | #include <stdatomic.h> | ||
| 50 | #include <assert.h> | ||
| 51 | |||
| 52 | #include "lmemory.h" | ||
| 53 | |||
| 54 | |||
| 55 | /////////////////// | ||
| 56 | // // | ||
| 57 | // Definitions // | ||
| 58 | // // | ||
| 59 | /////////////////// | ||
| 60 | #pragma mark - Definitions | ||
| 61 | |||
| 62 | #ifndef SYSCONFDIR | ||
| 63 | # define SYSCONFDIR "/etc" | ||
| 64 | #endif | ||
| 65 | |||
| 66 | |||
| 67 | ///////////////// | ||
| 68 | // // | ||
| 69 | // Variables // | ||
| 70 | // // | ||
| 71 | ///////////////// | ||
| 72 | #pragma mark - Variables | ||
| 73 | |||
| 74 | #pragma mark tinytac_conf_init | ||
| 75 | static atomic_int tinytac_conf_init; | ||
| 76 | |||
| 77 | |||
| 78 | #pragma mark tinytac_conf_options[] | ||
| 79 | static bindle_map_t tinytac_conf_options[] = | ||
| 80 | { | ||
| 81 | { .map_name = "AUTHEN_ASCII", .map_value = TTAC_OPT_AUTHEN_ASCII }, | ||
| 82 | { .map_name = "AUTHEN_CHAP", .map_value = TTAC_OPT_AUTHEN_CHAP }, | ||
| 83 | { .map_name = "AUTHEN_MSCHAP", .map_value = TTAC_OPT_AUTHEN_MSCHAP }, | ||
| 84 | { .map_name = "AUTHEN_MSCHAPV2", .map_value = TTAC_OPT_AUTHEN_MSCHAPV2 }, | ||
| 85 | { .map_name = "AUTHEN_PAP", .map_value = TTAC_OPT_AUTHEN_PAP }, | ||
| 86 | { .map_name = "DEBUG_LEVEL", .map_value = TTAC_OPT_DEBUG_LEVEL }, | ||
| 87 | { .map_name = "DEBUG_SYSLOG", .map_value = TTAC_OPT_DEBUG_SYSLOG }, | ||
| 88 | { .map_name = "HOST", .map_value = TTAC_OPT_HOSTS }, | ||
| 89 | { .map_name = "IPV4", .map_value = TTAC_OPT_IPV4 }, | ||
| 90 | { .map_name = "IPV6", .map_value = TTAC_OPT_IPV6 }, | ||
| 91 | { .map_name = "KEY", .map_value = TTAC_OPT_KEY }, | ||
| 92 | { .map_name = "NETWORK_TIMEOUT", .map_value = TTAC_OPT_NETWORK_TIMEOUT }, | ||
| 93 | { .map_name = "RANDOM", .map_value = TTAC_OPT_RANDOM }, | ||
| 94 | { .map_name = "STOPINIT", .map_value = TTAC_OPT_STOPINIT }, | ||
| 95 | { .map_name = "TIMEOUT", .map_value = TTAC_OPT_TIMEOUT }, | ||
| 96 | { .map_name = NULL, .map_value = 0 } | ||
| 97 | }; | ||
| 98 | |||
| 99 | |||
| 100 | ////////////////// | ||
| 101 | // // | ||
| 102 | // Prototypes // | ||
| 103 | // // | ||
| 104 | ////////////////// | ||
| 105 | #pragma mark - Prototypes | ||
| 106 | |||
| 107 | static int | ||
| 108 | tinytac_conf_environment( | ||
| 109 | void ); | ||
| 110 | |||
| 111 | |||
| 112 | static int | ||
| 113 | tinytac_conf_file( | ||
| 114 | const char * path ); | ||
| 115 | |||
| 116 | |||
| 117 | static int | ||
| 118 | tinytac_conf_opt( | ||
| 119 | const bindle_map_t * opt, | ||
| 120 | const char * value ); | ||
| 121 | |||
| 122 | |||
| 123 | static int | ||
| 124 | tinytac_conf_opt_flag( | ||
| 125 | const bindle_map_t * opt, | ||
| 126 | const char * value ); | ||
| 127 | |||
| 128 | |||
| 129 | static int | ||
| 130 | tinytac_conf_opt_int( | ||
| 131 | const bindle_map_t * opt, | ||
| 132 | const char * value ); | ||
| 133 | |||
| 134 | |||
| 135 | static int | ||
| 136 | tinytac_conf_opt_timeval( | ||
| 137 | const bindle_map_t * opt, | ||
| 138 | const char * value ); | ||
| 139 | |||
| 140 | |||
| 141 | ///////////////// | ||
| 142 | // // | ||
| 143 | // Functions // | ||
| 144 | // // | ||
| 145 | ///////////////// | ||
| 146 | #pragma mark - Functions | ||
| 147 | |||
| 148 | |||
| 149 | int | ||
| 150 | tinytac_conf( | ||
| 151 | unsigned opts ) | ||
| 152 | { | ||
| 153 | const char * tintacrc; | ||
| 154 | const char * tinytacconf; | ||
| 155 | char buff[4096]; | ||
| 156 | char path[128]; | ||
| 157 | const char * home; | ||
| 158 | struct passwd pwd; | ||
| 159 | struct passwd * pwres; | ||
| 160 | |||
| 161 | TinyTacDebugTrace(); | ||
| 162 | |||
| 163 | // exit if init is disabled or already initialized | ||
| 164 | if ( ((opts & TTAC_NOINIT)) || ((tinytac_dflt.opts & TTAC_NOINIT)) ) | ||
| 165 | return(TTAC_SUCCESS); | ||
| 166 | if ((atomic_fetch_or(&tinytac_conf_init, 1))) | ||
| 167 | return(TTAC_SUCCESS); | ||
| 168 | if ((getenv("TINYTACNOINIT"))) | ||
| 169 | return(TTAC_SUCCESS); | ||
| 170 | if ((getenv("TINYTAC_NOINIT"))) | ||
| 171 | return(TTAC_SUCCESS); | ||
| 172 | |||
| 173 | // system information | ||
| 174 | getpwuid_r(getuid(), &pwd, buff, sizeof(buff), &pwres); | ||
| 175 | home = (((pwres)) ? pwres->pw_dir : "/"); | ||
| 176 | |||
| 177 | // process "/usr/local/etc/tinytac.conf" | ||
| 178 | tinytac_conf_file(SYSCONFDIR "/tinytac.conf"); | ||
| 179 | |||
| 180 | // process "~/tinytacrc" | ||
| 181 | tinytacb_strlcpy(path, home, sizeof(path)); | ||
| 182 | tinytacb_strlcat(path, "/tinytacrc", sizeof(path)); | ||
| 183 | if (tinytac_conf_file(path) == TTAC_ESTOPINIT) | ||
| 184 | return(TTAC_SUCCESS); | ||
| 185 | |||
| 186 | // process "~/.tinytacrc" | ||
| 187 | tinytacb_strlcpy(path, home, sizeof(path)); | ||
| 188 | tinytacb_strlcat(path, "/.tinytacrc", sizeof(path)); | ||
| 189 | if (tinytac_conf_file(path) == TTAC_ESTOPINIT) | ||
| 190 | return(TTAC_SUCCESS); | ||
| 191 | |||
| 192 | // process "./tinytacrc" | ||
| 193 | tinytacb_strlcpy(path, "./tinytacrc", sizeof(path)); | ||
| 194 | if (tinytac_conf_file(path) == TTAC_ESTOPINIT) | ||
| 195 | return(TTAC_SUCCESS); | ||
| 196 | |||
| 197 | // process "${TINYTACCONF}" | ||
| 198 | if ((tinytacconf = getenv("TINYTACCONF")) != NULL) | ||
| 199 | if (tinytac_conf_file(tinytacconf) == TTAC_ESTOPINIT) | ||
| 200 | return(TTAC_SUCCESS); | ||
| 201 | |||
| 202 | // determine TINYTACRC suffix | ||
| 203 | if ((tintacrc = getenv("TINYTACRC")) != NULL) | ||
| 204 | { | ||
| 205 | // process "~/${TINYTACRC}" | ||
| 206 | tinytacb_strlcpy(path, home, sizeof(path)); | ||
| 207 | tinytacb_strlcat(path, "/", sizeof(path)); | ||
| 208 | tinytacb_strlcat(path, tintacrc, sizeof(path)); | ||
| 209 | if (tinytac_conf_file(path) == TTAC_ESTOPINIT) | ||
| 210 | return(TTAC_SUCCESS); | ||
| 211 | |||
| 212 | // process "~/.{$TINYTACRC}" | ||
| 213 | tinytacb_strlcpy(path, home, sizeof(path)); | ||
| 214 | tinytacb_strlcat(path, "/.", sizeof(path)); | ||
| 215 | tinytacb_strlcat(path, tintacrc, sizeof(path)); | ||
| 216 | if (tinytac_conf_file(path) == TTAC_ESTOPINIT) | ||
| 217 | return(TTAC_SUCCESS); | ||
| 218 | |||
| 219 | // process "./${TINYTACRC}" | ||
| 220 | tinytacb_strlcpy(path, "./", sizeof(path)); | ||
| 221 | tinytacb_strlcat(path, tintacrc, sizeof(path)); | ||
| 222 | if (tinytac_conf_file(path) == TTAC_ESTOPINIT) | ||
| 223 | return(TTAC_SUCCESS); | ||
| 224 | }; | ||
| 225 | |||
| 226 | // process environment variables | ||
| 227 | if (tinytac_conf_environment() == TTAC_ESTOPINIT) | ||
| 228 | return(TTAC_SUCCESS); | ||
| 229 | |||
| 230 | return(TTAC_SUCCESS); | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 234 | int | ||
| 235 | tinytac_conf_environment( | ||
| 236 | void ) | ||
| 237 | { | ||
| 238 | size_t pos; | ||
| 239 | char * value; | ||
| 240 | char varname[64]; | ||
| 241 | bindle_map_t * opt; | ||
| 242 | |||
| 243 | TinyTacDebugTrace(); | ||
| 244 | |||
| 245 | for(pos = 0; ((tinytac_conf_options[pos].map_name)); pos++) | ||
| 246 | { | ||
| 247 | opt = &tinytac_conf_options[pos]; | ||
| 248 | if (opt->map_value == TTAC_OPT_STOPINIT) | ||
| 249 | continue; | ||
| 250 | tinytacb_strlcpy(varname, "TINYTAC_", sizeof(varname)); | ||
| 251 | tinytacb_strlcat(varname, opt->map_name, sizeof(varname)); | ||
| 252 | if ((value = getenv(varname)) != NULL) | ||
| 253 | tinytac_conf_opt(opt, value); | ||
| 254 | }; | ||
| 255 | |||
| 256 | if (getenv("TINYTAC_STOPINIT") != NULL) | ||
| 257 | return(TTAC_ESTOPINIT); | ||
| 258 | |||
| 259 | return(TTAC_SUCCESS); | ||
| 260 | } | ||
| 261 | |||
| 262 | |||
| 263 | int | ||
| 264 | tinytac_conf_file( | ||
| 265 | const char * path ) | ||
| 266 | { | ||
| 267 | int fd; | ||
| 268 | int rc; | ||
| 269 | ssize_t len; | ||
| 270 | int argc; | ||
| 271 | char buff[TTAC_LINE_MAX_LEN]; | ||
| 272 | char value[TTAC_LINE_MAX_LEN]; | ||
| 273 | char ** argv; | ||
| 274 | const char * val; | ||
| 275 | const bindle_map_t * opt; | ||
| 276 | |||
| 277 | TinyTacDebugTrace(); | ||
| 278 | |||
| 279 | len = 1; | ||
| 280 | rc = TTAC_SUCCESS; | ||
| 281 | |||
| 282 | if (!(path)) | ||
| 283 | return(TTAC_SUCCESS); | ||
| 284 | if ((fd = open(path, O_RDONLY)) == -1) | ||
| 285 | return(TTAC_SUCCESS); | ||
| 286 | |||
| 287 | while( ((len)) && (rc == TTAC_SUCCESS) ) | ||
| 288 | { | ||
| 289 | if ((len = tinytacb_readline(fd, buff, sizeof(buff))) == -1) | ||
| 290 | { | ||
| 291 | close(fd); | ||
| 292 | return(TTAC_EUNKNOWN); | ||
| 293 | }; | ||
| 294 | if (!(len)) | ||
| 295 | continue; | ||
| 296 | if (tinytacb_strtoargs(buff, &argv, &argc) != TTAC_SUCCESS) | ||
| 297 | { | ||
| 298 | close(fd); | ||
| 299 | return(TTAC_ESYNTAX); | ||
| 300 | }; | ||
| 301 | if ( (argc < 1) || (argc > 2) ) | ||
| 302 | { | ||
| 303 | tinytacb_strsfree(argv); | ||
| 304 | continue; | ||
| 305 | }; | ||
| 306 | if (tinytacb_map_lookup_name(tinytac_conf_options, argv[0], &opt) == 0) | ||
| 307 | { | ||
| 308 | tinytacb_strsfree(argv); | ||
| 309 | continue; | ||
| 310 | }; | ||
| 311 | val = tinytacb_strexpand(value, argv[1], sizeof(value), TTAC_NO); | ||
| 312 | switch(tinytac_conf_opt(opt, val)) | ||
| 313 | { | ||
| 314 | case TTAC_ESTOPINIT: rc = TTAC_ESTOPINIT; break; | ||
| 315 | case TTAC_ENOMEM: rc = TTAC_ENOMEM; break; | ||
| 316 | default: break; | ||
| 317 | }; | ||
| 318 | tinytacb_strsfree(argv); | ||
| 319 | }; | ||
| 320 | |||
| 321 | close(fd); | ||
| 322 | |||
| 323 | return(rc); | ||
| 324 | } | ||
| 325 | |||
| 326 | |||
| 327 | int | ||
| 328 | tinytac_conf_opt( | ||
| 329 | const bindle_map_t * opt, | ||
| 330 | const char * value ) | ||
| 331 | { | ||
| 332 | int ival; | ||
| 333 | |||
| 334 | TinyTacDebugTrace(); | ||
| 335 | |||
| 336 | switch(opt->map_value) | ||
| 337 | { | ||
| 338 | case TTAC_OPT_AUTHEN_ASCII: | ||
| 339 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_AUTHEN_ASCII, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 340 | return(tinytac_conf_opt_flag(opt, value)); | ||
| 341 | |||
| 342 | case TTAC_OPT_AUTHEN_CHAP: | ||
| 343 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_AUTHEN_CHAP, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 344 | return(tinytac_conf_opt_flag(opt, value)); | ||
| 345 | |||
| 346 | case TTAC_OPT_AUTHEN_MSCHAP: | ||
| 347 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_AUTHEN_MSCHAP, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 348 | return(tinytac_conf_opt_flag(opt, value)); | ||
| 349 | |||
| 350 | case TTAC_OPT_AUTHEN_MSCHAPV2: | ||
| 351 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_AUTHEN_MSCHAPV2, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 352 | return(tinytac_conf_opt_flag(opt, value)); | ||
| 353 | |||
| 354 | case TTAC_OPT_AUTHEN_PAP: | ||
| 355 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_AUTHEN_PAP, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 356 | return(tinytac_conf_opt_flag(opt, value)); | ||
| 357 | |||
| 358 | case TTAC_OPT_DEBUG_LEVEL: | ||
| 359 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_DEBUG_LEVEL, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 360 | return(tinytac_conf_opt_int(opt, value)); | ||
| 361 | |||
| 362 | case TTAC_OPT_DEBUG_SYSLOG: | ||
| 363 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_DEBUG_SYSLOG, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 364 | return(tinytac_conf_opt_flag(opt, value)); | ||
| 365 | |||
| 366 | case TTAC_OPT_HOSTS: | ||
| 367 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_HOSTS, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 368 | return(tinytac_set_option(NULL, TTAC_OPT_HOSTS, value)); | ||
| 369 | |||
| 370 | case TTAC_OPT_IPV4: | ||
| 371 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_IPV4, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 372 | return(tinytac_conf_opt_flag(opt, value)); | ||
| 373 | |||
| 374 | case TTAC_OPT_IPV6: | ||
| 375 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_IPV6, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 376 | return(tinytac_conf_opt_flag(opt, value)); | ||
| 377 | |||
| 378 | case TTAC_OPT_KEY: | ||
| 379 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_KEY, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 380 | if ((tinytac_dflt.keys)) | ||
| 381 | return(TTAC_SUCCESS); | ||
| 382 | return(tinytac_set_option(NULL, TTAC_OPT_KEY, value)); | ||
| 383 | |||
| 384 | case TTAC_OPT_NETWORK_TIMEOUT: | ||
| 385 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_NETWORK_TIMEOUT, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 386 | return(tinytac_conf_opt_timeval(opt, value)); | ||
| 387 | |||
| 388 | case TTAC_OPT_NOINIT: | ||
| 389 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_NOINIT, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 390 | return(tinytac_conf_opt_flag(opt, value)); | ||
| 391 | |||
| 392 | case TTAC_OPT_RANDOM: | ||
| 393 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( tr, TTAC_OPT_RANDOM, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 394 | if (!(strcasecmp(value, "rand"))) ival = TTAC_RND_RAND; | ||
| 395 | else if (!(strcasecmp(value, "random"))) ival = TTAC_RND_RANDOM; | ||
| 396 | else if (!(strcasecmp(value, "urandom"))) ival = TTAC_RND_URANDOM; | ||
| 397 | else return(TTAC_SUCCESS); | ||
| 398 | return(tinytac_set_option(NULL, TTAC_OPT_RANDOM, &ival)); | ||
| 399 | |||
| 400 | case TTAC_OPT_STOPINIT: | ||
| 401 | return(TTAC_ESTOPINIT); | ||
| 402 | |||
| 403 | case TTAC_OPT_TIMEOUT: | ||
| 404 | TinyTacDebug(TTAC_DEBUG_ARGS, " == %s( TTAC_OPT_TIMEOUT, \"%s\" )", __func__, (((value)) ? value : "(null)")); | ||
| 405 | return(tinytac_conf_opt_int(opt, value)); | ||
| 406 | |||
| 407 | default: | ||
| 408 | break; | ||
| 409 | }; | ||
| 410 | |||
| 411 | return(TTAC_SUCCESS); | ||
| 412 | } | ||
| 413 | |||
| 414 | |||
| 415 | int | ||
| 416 | tinytac_conf_opt_flag( | ||
| 417 | const bindle_map_t * opt, | ||
| 418 | const char * value ) | ||
| 419 | { | ||
| 420 | int i; | ||
| 421 | |||
| 422 | TinyTacDebugTrace(); | ||
| 423 | |||
| 424 | switch(i = ((value)) ? tinytacb_strtobool(value) : TTAC_YES) | ||
| 425 | { | ||
| 426 | case TTAC_NO: return(tinytac_set_option(NULL, (int)opt->map_value, &i)); | ||
| 427 | case TTAC_YES: return(tinytac_set_option(NULL, (int)opt->map_value, &i)); | ||
| 428 | default: break; | ||
| 429 | }; | ||
| 430 | |||
| 431 | return(TTAC_SUCCESS); | ||
| 432 | } | ||
| 433 | |||
| 434 | |||
| 435 | int | ||
| 436 | tinytac_conf_opt_int( | ||
| 437 | const bindle_map_t * opt, | ||
| 438 | const char * value ) | ||
| 439 | { | ||
| 440 | int i; | ||
| 441 | char * endptr; | ||
| 442 | |||
| 443 | TinyTacDebugTrace(); | ||
| 444 | |||
| 445 | if ((i = (int)strtoll(value, &endptr, 10)) < 1) | ||
| 446 | return(TTAC_SUCCESS); | ||
| 447 | if ((endptr[0])) | ||
| 448 | return(TTAC_SUCCESS); | ||
| 449 | |||
| 450 | return(tinytac_set_option(NULL, (int)opt->map_value, &i)); | ||
| 451 | } | ||
| 452 | |||
| 453 | |||
| 454 | int | ||
| 455 | tinytac_conf_opt_timeval( | ||
| 456 | const bindle_map_t * opt, | ||
| 457 | const char * value ) | ||
| 458 | { | ||
| 459 | char * endptr; | ||
| 460 | struct timeval tv; | ||
| 461 | |||
| 462 | TinyTacDebugTrace(); | ||
| 463 | |||
| 464 | tv.tv_usec = 0; | ||
| 465 | if ((tv.tv_sec = strtoull(value, &endptr, 10)) < 1) | ||
| 466 | return(TTAC_SUCCESS); | ||
| 467 | if ((endptr[0])) | ||
| 468 | return(TTAC_SUCCESS); | ||
| 469 | |||
| 470 | return(tinytac_set_option(NULL, (int)opt->map_value, &tv)); | ||
| 471 | } | ||
| 472 | |||
| 473 | |||
| 474 | |||
| 475 | /* end of source */ | ||
diff --git a/lib/libtinytac/lconf.h b/lib/libtinytac/lconf.h new file mode 100644 index 0000000..4cbbaef --- /dev/null +++ b/lib/libtinytac/lconf.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* | ||
| 2 | * Tiny TACACS+ Client Library | ||
| 3 | * Copyright (C) 2022 David M. Syzdek <david@syzdek.net>. | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions are | ||
| 8 | * met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * * Redistributions in binary form must reproduce the above copyright | ||
| 13 | * notice, this list of conditions and the following disclaimer in the | ||
| 14 | * documentation and/or other materials provided with the distribution. | ||
| 15 | * * Neither the name of David M. Syzdek nor the | ||
| 16 | * names of its contributors may be used to endorse or promote products | ||
| 17 | * derived from this software without specific prior written permission. | ||
| 18 | * | ||
| 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 20 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
| 21 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID M. SYZDEK BE LIABLE FOR | ||
| 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 29 | * SUCH DAMAGE. | ||
| 30 | */ | ||
| 31 | #ifndef _LIB_LIBTINYTAC_LCONF_H | ||
| 32 | #define _LIB_LIBTINYTAC_LCONF_H 1 | ||
| 33 | |||
| 34 | |||
| 35 | /////////////// | ||
| 36 | // // | ||
| 37 | // Headers // | ||
| 38 | // // | ||
| 39 | /////////////// | ||
| 40 | #pragma mark - Headers | ||
| 41 | |||
| 42 | #include "libtinytac.h" | ||
| 43 | |||
| 44 | |||
| 45 | ////////////////// | ||
| 46 | // // | ||
| 47 | // Prototypes // | ||
| 48 | // // | ||
| 49 | ////////////////// | ||
| 50 | #pragma mark - Prototypes | ||
| 51 | |||
| 52 | int | ||
| 53 | tinytac_conf( | ||
| 54 | unsigned opts ); | ||
| 55 | |||
| 56 | |||
| 57 | #endif /* end of header */ | ||
diff --git a/lib/libtinytac/libtinytac.h b/lib/libtinytac/libtinytac.h index 83fbc6a..1aaaa52 100644 --- a/lib/libtinytac/libtinytac.h +++ b/lib/libtinytac/libtinytac.h | |||
| @@ -93,6 +93,13 @@ | |||
| 93 | #define TTAC_MAGIC ((const uint8_t *)"\0TnyTac\0") | 93 | #define TTAC_MAGIC ((const uint8_t *)"\0TnyTac\0") |
| 94 | 94 | ||
| 95 | 95 | ||
| 96 | #define TTAC_LINE_MAX_LEN 256 | ||
| 97 | |||
| 98 | |||
| 99 | // internal library get/set options | ||
| 100 | #define TTAC_OPT_STOPINIT 10000 | ||
| 101 | |||
| 102 | |||
| 96 | ////////////////// | 103 | ////////////////// |
| 97 | // // | 104 | // // |
| 98 | // Data Types // | 105 | // Data Types // |
diff --git a/lib/libtinytac/lmemory.c b/lib/libtinytac/lmemory.c index ca1332b..ccbb3ec 100644 --- a/lib/libtinytac/lmemory.c +++ b/lib/libtinytac/lmemory.c | |||
| @@ -54,6 +54,8 @@ | |||
| 54 | #include <errno.h> | 54 | #include <errno.h> |
| 55 | #include <assert.h> | 55 | #include <assert.h> |
| 56 | 56 | ||
| 57 | #include "lconf.h" | ||
| 58 | |||
| 57 | 59 | ||
| 58 | /////////////////// | 60 | /////////////////// |
| 59 | // // | 61 | // // |
| @@ -194,6 +196,7 @@ tinytac_get_option( | |||
| 194 | int option, | 196 | int option, |
| 195 | void * outvalue ) | 197 | void * outvalue ) |
| 196 | { | 198 | { |
| 199 | int rc; | ||
| 197 | const char * str; | 200 | const char * str; |
| 198 | unsigned * optsp; | 201 | unsigned * optsp; |
| 199 | 202 | ||
| @@ -201,6 +204,9 @@ tinytac_get_option( | |||
| 201 | 204 | ||
| 202 | assert(outvalue != NULL); | 205 | assert(outvalue != NULL); |
| 203 | 206 | ||
| 207 | if ((rc = tinytac_conf(0)) != TTAC_SUCCESS) | ||
| 208 | return(rc); | ||
| 209 | |||
| 204 | // get global options | 210 | // get global options |
| 205 | switch(option) | 211 | switch(option) |
| 206 | { | 212 | { |
| @@ -301,6 +307,9 @@ tinytac_initialize( | |||
| 301 | 307 | ||
| 302 | assert(ttp != NULL); | 308 | assert(ttp != NULL); |
| 303 | 309 | ||
| 310 | if ((rc = tinytac_conf(0)) != TTAC_SUCCESS) | ||
| 311 | return(rc); | ||
| 312 | |||
| 304 | if ((tt = tinytac_obj_alloc(sizeof(TinyTac), (void(*)(void*))&tinytac_tinytac_free)) == NULL) | 313 | if ((tt = tinytac_obj_alloc(sizeof(TinyTac), (void(*)(void*))&tinytac_tinytac_free)) == NULL) |
| 305 | return(TTAC_ENOMEM); | 314 | return(TTAC_ENOMEM); |
| 306 | 315 | ||
| @@ -334,6 +343,7 @@ tinytac_set_option( | |||
| 334 | int option, | 343 | int option, |
| 335 | const void * invalue ) | 344 | const void * invalue ) |
| 336 | { | 345 | { |
| 346 | int rc; | ||
| 337 | int ival; | 347 | int ival; |
| 338 | int idflt; | 348 | int idflt; |
| 339 | const char * istr; | 349 | const char * istr; |
| @@ -343,6 +353,9 @@ tinytac_set_option( | |||
| 343 | 353 | ||
| 344 | assert(invalue != NULL); | 354 | assert(invalue != NULL); |
| 345 | 355 | ||
| 356 | if ((rc = tinytac_conf(0)) != TTAC_SUCCESS) | ||
| 357 | return(rc); | ||
| 358 | |||
| 346 | switch(option) | 359 | switch(option) |
| 347 | { | 360 | { |
| 348 | case TTAC_OPT_AUTHEN_ASCII: | 361 | case TTAC_OPT_AUTHEN_ASCII: |
