1/***************************************************************** 2** 3** @(#) zkt.c -- A library for managing a list of dns zone files. 4** 5** Copyright (c) 2005 - 2008, Holger Zuleger HZnet. All rights reserved. 6** 7** This software is open source. 8** 9** Redistribution and use in source and binary forms, with or without 10** modification, are permitted provided that the following conditions 11** are met: 12** 13** Redistributions of source code must retain the above copyright notice, 14** this list of conditions and the following disclaimer. 15** 16** Redistributions in binary form must reproduce the above copyright notice, 17** this list of conditions and the following disclaimer in the documentation 18** and/or other materials provided with the distribution. 19** 20** Neither the name of Holger Zuleger HZnet nor the names of its contributors may 21** be used to endorse or promote products derived from this software without 22** specific prior written permission. 23** 24** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 28** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34** POSSIBILITY OF SUCH DAMAGE. 35** 36*****************************************************************/ 37# include <stdio.h> 38# include <string.h> 39#ifdef HAVE_CONFIG_H 40# include <config.h> 41#endif 42# include "config_zkt.h" 43# include "dki.h" 44# include "misc.h" 45# include "strlist.h" 46# include "zconf.h" 47# include "domaincmp.h" 48# include "tcap.h" 49#define extern 50# include "zkt.h" 51#undef extern 52 53extern char *labellist; 54extern int headerflag; 55extern int timeflag; 56extern int exptimeflag; 57extern int lifetime; 58extern int ageflag; 59extern int lifetimeflag; 60extern int kskflag; 61extern int zskflag; 62extern int pathflag; 63extern int ljustflag; 64 65static void printkeyinfo (const dki_t *dkp, const char *oldpath); 66 67static void printkeyinfo (const dki_t *dkp, const char *oldpath) 68{ 69 time_t currtime; 70 71 if ( dkp == NULL ) /* print headline */ 72 { 73 if ( headerflag ) 74 { 75 tc_attr (stdout, TC_BOLD, 1); 76 printf ("%-33.33s %5s %3s %3.3s %-7s", "Keyname", 77 "Tag", "Typ", "Status", "Algorit"); 78 if ( timeflag ) 79 printf (" %-20s", "Generation Time"); 80 if ( exptimeflag ) 81 printf (" %-20s", "Expiration Time"); 82 if ( ageflag ) 83 printf (" %16s", "Age"); 84 if ( lifetimeflag ) 85 printf (" %4s", "LfTm"); 86 tc_attr (stdout, TC_BOLD, 0); 87 putchar ('\n'); 88 } 89 return; 90 } 91 time (&currtime); 92 93 /* TODO: use next line if dname is dynamically allocated */ 94 /* if ( pathflag && dkp->dname && strcmp (oldpath, dkp->dname) != 0 ) */ 95 if ( pathflag && strcmp (oldpath, dkp->dname) != 0 ) 96 printf ("%s/\n", dkp->dname); 97 98 if ( (kskflag && dki_isksk (dkp)) || (zskflag && !dki_isksk (dkp)) ) 99 { 100 int color; 101 102 if ( ljustflag ) 103 printf ("%-33.33s ", dkp->name); 104 else 105 printf ("%33.33s ", dkp->name); 106 printf ("%05d ", dkp->tag); 107 printf ("%3s ", dki_isksk (dkp) ? "KSK" : "ZSK"); 108 109 if ( dkp->status == DKI_ACT ) 110 color = TC_GREEN; 111 else if ( dkp->status == DKI_PUB ) 112 color = TC_BLUE; 113 else if ( dkp->status == DKI_DEP ) 114 color = TC_RED; 115 else 116 color = TC_BLACK; 117 tc_attr (stdout, color, 1); 118 printf ("%-3.3s ", dki_statusstr (dkp) ); 119 tc_attr (stdout, color, 0); 120 121 printf ("%-7s", dki_algo2sstr(dkp->algo)); 122 123 if ( currtime < dkp->time + dkp->lifetime ) 124 color = TC_GREEN; 125 else 126 color = TC_BOLD|TC_RED; 127 tc_attr (stdout, color, 1); 128 129 if ( timeflag ) 130 printf (" %-20s", time2str (dkp->gentime ? dkp->gentime: dkp->time, 's')); 131 if ( exptimeflag ) 132 printf (" %-20s", time2str (dkp->exptime, 's')); 133 if ( ageflag ) 134 printf (" %16s", age2str (dki_age (dkp, currtime))); 135 if ( lifetimeflag && dkp->lifetime ) 136 { 137 if ( dkp->status == 'a' ) 138 printf ("%c", (currtime < dkp->time + dkp->lifetime) ? '<' : '!'); 139 else 140 putchar (' '); 141 printf ("%hdd", dki_lifetimedays (dkp)); 142 } 143 tc_attr (stdout, color, 0); 144 putchar ('\n'); 145 } 146} 147 148#if defined(USE_TREE) && USE_TREE 149static void list_key (const dki_t **nodep, const VISIT which, int depth) 150{ 151 const dki_t *dkp; 152 static const char *oldpath = ""; 153 154 if ( nodep == NULL ) 155 return; 156//fprintf (stderr, "listkey %d %d %s\n", which, depth, dkp->name); 157 158 if ( which == INORDER || which == LEAF ) 159 { 160 dkp = *nodep; 161 while ( dkp ) /* loop through list */ 162 { 163 if ( labellist == NULL || isinlist (dkp->name, labellist) ) 164 printkeyinfo (dkp, oldpath); /* print entry */ 165 oldpath = dkp->dname; 166 dkp = dkp->next; 167 } 168 } 169} 170#endif 171 172void zkt_list_keys (const dki_t *data) 173{ 174#if ! defined(USE_TREE) || !USE_TREE 175 const dki_t *dkp; 176 const char *oldpath; 177#endif 178 179 if ( data ) /* print headline if list is not empty */ 180 printkeyinfo (NULL, ""); 181 182#if defined(USE_TREE) && USE_TREE 183 twalk (data, list_key); 184#else 185 oldpath = ""; 186 for ( dkp = data; dkp; dkp = dkp->next ) /* loop through list */ 187 { 188 if ( labellist == NULL || isinlist (dkp->name, labellist) ) 189 printkeyinfo (dkp, oldpath); /* print entry */ 190 oldpath = dkp->dname; 191 } 192#endif 193} 194 195#if defined(USE_TREE) && USE_TREE 196# if 0 197static void list_trustedkey (const dki_t **nodep, const VISIT which, int depth) 198{ 199 const dki_t *dkp; 200 201 if ( nodep == NULL ) 202 return; 203 204 dkp = *nodep; 205 if ( which == INORDER || which == LEAF ) 206 { 207// fprintf (stderr, "list_trustedkey order=%d(pre=0,in=1,post=2,leaf=3) depth=%d %s\n", which, depth, dkp->name); 208 /* loop through list */ 209 while ( dkp ) 210 { 211 if ( (dki_isksk (dkp) || zskflag) && 212 (labellist == NULL || isinlist (dkp->name, labellist)) ) 213 dki_prt_trustedkey (dkp, stdout); 214 dkp = dkp->next; 215 } 216 } 217} 218# else 219const dki_t *parent; 220static void list_trustedkey (const dki_t **nodep, const VISIT which, int depth) 221{ 222 const dki_t *dkp; 223 224 if ( nodep == NULL ) 225 return; 226 227 dkp = *nodep; 228 if ( which == INORDER || which == LEAF ) 229 { 230// fprintf (stderr, "list_trustedkey order=%d(pre=0,in=1,post=2,leaf=3) depth=%d %s\n", which, depth, dkp->name); 231 if ( labellist && !isinlist (dkp->name, labellist) ) 232 return; 233 234 if ( parent == NULL || !issubdomain (dkp->name, parent->name) ) 235 { 236 parent = dkp; 237 /* loop through list */ 238 while ( dkp ) 239 { 240 if ( (dki_isksk (dkp) || zskflag) ) 241 dki_prt_trustedkey (dkp, stdout); 242 dkp = dkp->next; 243 } 244 } 245 } 246} 247# endif 248#endif 249 250void zkt_list_trustedkeys (const dki_t *data) 251{ 252 253 /* print headline if list is not empty */ 254 if ( data && headerflag ) 255 printf ("trusted-keys {\n"); 256 257#if defined(USE_TREE) && USE_TREE 258 twalk (data, list_trustedkey); 259#else 260 for ( dkp = data; dkp; dkp = dkp->next ) /* loop through list */ 261 if ( (dki_isksk (dkp) || zskflag) && 262 (labellist == NULL || isinlist (dkp->name, labellist)) ) 263 dki_prt_trustedkey (dkp, stdout); 264#endif 265 266 /* print end of trusted-key section */ 267 if ( data && headerflag ) 268 printf ("};\n"); 269} 270 271#if defined(USE_TREE) && USE_TREE 272static void list_dnskey (const dki_t **nodep, const VISIT which, int depth) 273{ 274 const dki_t *dkp; 275 int ksk; 276 277 if ( nodep == NULL ) 278 return; 279 280 if ( which == INORDER || which == LEAF ) 281 for ( dkp = *nodep; dkp; dkp = dkp->next ) 282 { 283 ksk = dki_isksk (dkp); 284 if ( (ksk && !kskflag) || (!ksk && !zskflag) ) 285 continue; 286 287 if ( labellist == NULL || isinlist (dkp->name, labellist) ) 288 { 289 if ( headerflag ) 290 dki_prt_comment (dkp, stdout); 291 dki_prt_dnskey (dkp, stdout); 292 } 293 } 294} 295#endif 296 297void zkt_list_dnskeys (const dki_t *data) 298{ 299#if defined(USE_TREE) && USE_TREE 300 twalk (data, list_dnskey); 301#else 302 const dki_t *dkp; 303 int ksk; 304 305 for ( dkp = data; dkp; dkp = dkp->next ) 306 { 307 ksk = dki_isksk (dkp); 308 if ( (ksk && !kskflag) || (!ksk && !zskflag) ) 309 continue; 310 311 if ( labellist == NULL || isinlist (dkp->name, labellist) ) 312 { 313 if ( headerflag ) 314 dki_prt_comment (dkp, stdout); 315 dki_prt_dnskey (dkp, stdout); 316 } 317 } 318#endif 319} 320 321#if defined(USE_TREE) && USE_TREE 322static void set_keylifetime (const dki_t **nodep, const VISIT which, int depth) 323{ 324 const dki_t *dkp; 325 int ksk; 326 327 if ( nodep == NULL ) 328 return; 329 330 if ( which == INORDER || which == LEAF ) 331 for ( dkp = *nodep; dkp; dkp = dkp->next ) 332 { 333 ksk = dki_isksk (dkp); 334 if ( (ksk && !kskflag) || (!ksk && !zskflag) ) 335 continue; 336 337 if ( labellist == NULL || isinlist (dkp->name, labellist) ) 338 dki_setlifetime ((dki_t *)dkp, lifetime); 339 } 340} 341#endif 342 343void zkt_setkeylifetime (dki_t *data) 344{ 345#if defined(USE_TREE) && USE_TREE 346 twalk (data, set_keylifetime); 347#else 348 dki_t *dkp; 349 int ksk; 350 351 for ( dkp = data; dkp; dkp = dkp->next ) 352 { 353 ksk = dki_isksk (dkp); 354 if ( (ksk && !kskflag) || (!ksk && !zskflag) ) 355 continue; 356 357 if ( labellist == NULL || isinlist (dkp->name, labellist) ) 358 { 359 dki_setlifetime (dkp, lifetime); 360 } 361 } 362#endif 363} 364 365 366#if defined(USE_TREE) && USE_TREE 367static const dki_t *searchresult; 368static int searchitem; 369static void tag_search (const dki_t **nodep, const VISIT which, int depth) 370{ 371 const dki_t *dkp; 372 373 if ( nodep == NULL ) 374 return; 375 376 if ( which == PREORDER || which == LEAF ) 377 for ( dkp = *nodep; dkp; dkp = dkp->next ) 378 { 379 if ( dkp->tag == searchitem ) 380 { 381 if ( searchresult == NULL ) 382 searchresult = dkp; 383 else 384 searchitem = 0; 385 } 386 } 387} 388#endif 389const dki_t *zkt_search (const dki_t *data, int searchtag, const char *keyname) 390{ 391 const dki_t *dkp = NULL; 392 393#if defined(USE_TREE) && USE_TREE 394 if ( keyname == NULL || *keyname == '\0' ) 395 { 396 searchresult = NULL; 397 searchitem = searchtag; 398 twalk (data, tag_search); 399 if ( searchresult != NULL && searchitem == 0 ) 400 dkp = (void *)01; 401 else 402 dkp = searchresult; 403 } 404 else 405 dkp = (dki_t*)dki_tsearch (data, searchtag, keyname); 406#else 407 dkp = (dki_t*)dki_search (data, searchtag, keyname); 408#endif 409 return dkp; 410} 411 412