/*****************************************************************
**
** @(#) misc.c -- helper functions for the dnssec zone key tools
**
** Copyright (c) Jan 2005, Holger Zuleger HZnet. All rights reserved.
**
** This software is open source.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
**
** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 REGENTS 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.
**
*****************************************************************/
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <unistd.h> /* for link(), unlink() */
# include <ctype.h>
# include <time.h>
# include <utime.h>
# include <assert.h>
# include <errno.h>
# include <fcntl.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
# include "config_zkt.h"
# include "zconf.h"
# include "log.h"
# include "debug.h"
#define extern
# include "misc.h"
#undef extern
extern const char *progname;
/*****************************************************************
** getnameappendix (progname, basename)
** return a pointer to the substring in progname subsequent
** following "<basename>-".
*****************************************************************/
{
const char *p;
int baselen;
p++;
else
p = progname;
{
p += baselen + 1;
if ( *p )
return p;
}
return NULL;
}
/*****************************************************************
** getdefconfname (view)
** returns a pointer to a dynamic string containing the
** default configuration file name
*****************************************************************/
{
char *p;
char *file;
char *buf;
int size;
file = CONFIG_FILE;
return buf;
}
/*****************************************************************
** domain_canonicdup (s)
** returns NULL or a pointer to a dynamic string containing the
** canonic (all lower case letters and ending with a '.')
** domain name
*****************************************************************/
char *domain_canonicdup (const char *s)
{
char *new;
char *p;
int len;
int add_dot;
if ( s == NULL )
return NULL;
add_dot = 0;
return NULL;
while ( *s )
*p++ = tolower (*s++);
if ( add_dot )
*p++ = '.';
*p = '\0';
return new;
}
#if 0 /* replaced by domain_canonicdup */
/*****************************************************************
** str_tolowerdup (s)
*****************************************************************/
char *str_tolowerdup (const char *s)
{
char *new;
char *p;
return NULL;
while ( *s )
*p++ = tolower (*s++);
*p = '\0';
return new;
}
#endif
/*****************************************************************
** str_delspace (s)
** Remove in string 's' all white space char
*****************************************************************/
char *str_delspace (char *s)
{
char *start;
char *p;
if ( !s ) /* no string present ? */
return NULL;
start = s;
for ( p = s; *p; p++ )
if ( !isspace (*p) )
*s++ = *p; /* copy each nonspace */
*s = '\0'; /* terminate string */
return start;
}
/*****************************************************************
** in_strarr (str, arr, cnt)
** check if string array 'arr' contains the string 'str'
** return 1 if true or 'arr' or 'str' is empty, otherwise 0
*****************************************************************/
{
return 1;
return 0;
while ( --cnt >= 0 )
return 1;
return 0;
}
/*****************************************************************
** str_untaint (s)
** Remove in string 's' all TAINTED chars
*****************************************************************/
{
char *p;
for ( p = str; *p; p++ )
if ( strchr (TAINTEDCHARS, *p) )
*p = ' ';
return str;
}
/*****************************************************************
** str_chop (str, c)
** delete all occurrences of char 'c' at the end of string 's'
*****************************************************************/
{
int len;
return str;
}
/*****************************************************************
** parseurl (url, &proto, &host, &port, ¶ )
** and set the pointer variables to the corresponding part of the string.
*****************************************************************/
{
char *start;
char *p;
/* parse protocol */
p = url;
else /* looks like a protocol string */
if ( p[1] == '/' && p[2] == '/' ) /* protocol string ? */
{
*p = '\0';
p += 3;
if ( proto )
}
else /* no protocol string found ! */
p = url;
/* parse host */
if ( *p == '[' ) /* ipv6 address as hostname ? */
{
for ( start = ++p; *p && *p != ']'; p++ )
;
if ( *p )
*p++ = '\0';
}
else
;
if ( host )
/* parse port */
if ( *p == ':' )
{
*p++ = '\0';
;
if ( *p )
*p++ = '\0';
if ( port )
}
if ( *p == '/' )
*p++ = '\0';
if ( *p && para )
*para = p;
}
/*****************************************************************
** splitpath (path, pathsize, filename)
** and split of the filename part.
** return pointer to filename part in path or NULL if path is too
** small to hold "path+filename"
*****************************************************************/
{
char *p;
if ( !path )
return NULL;
*path = '\0';
if ( !filename )
return filename;
{
return filename;
filename = ++p;
}
return filename;
}
/*****************************************************************
** pathname (path, size, dir, file, ext)
** Concatenate 'dir', 'file' and 'ext' (if not null) to build
** a pathname, and store the result in the character array
** with length 'size' pointed to by 'path'.
*****************************************************************/
{
int len;
return path;
if ( dir )
if ( ext )
return path;
*path = '\0';
{
{
}
}
if ( ext )
return path;
}
/*****************************************************************
** is_directory (name)
** Check if the given pathname 'name' exists and is a directory.
** returns 0 | 1
*****************************************************************/
{
return 0;
}
/*****************************************************************
** fileexist (name)
** Check if a file with the given pathname 'name' exists.
** returns 0 | 1
*****************************************************************/
{
}
/*****************************************************************
** filesize (name)
** return the size of the file with the given pathname 'name'.
** returns -1 if the file not exist
*****************************************************************/
{
return -1L;
}
/*****************************************************************
** is_keyfilename (name)
** Check if the given name looks like a dnssec (public)
** keyfile name. Returns 0 | 1
*****************************************************************/
{
int len;
return 0;
return 1;
return 0;
}
/*****************************************************************
** is_dotfilename (name)
** Check if the given pathname 'name' looks like "." or "..".
** Returns 0 | 1
*****************************************************************/
{
if ( name && (
return 1;
return 0;
}
/*****************************************************************
** touch (name, sec)
** Set the modification time of the given pathname 'fname' to
** 'sec'. Returns 0 on success.
*****************************************************************/
{
}
/*****************************************************************
** linkfile (fromfile, tofile)
*****************************************************************/
{
int ret;
/* fprintf (stderr, "linkfile (%s, %s)\n", fromfile, tofile); */
return ret;
}
/*****************************************************************
** copyfile (fromfile, tofile, dnskeyfile)
** copy fromfile into tofile.
** Add (optional) the content of dnskeyfile to tofile.
*****************************************************************/
{
int c;
/* fprintf (stderr, "copyfile (%s, %s)\n", fromfile, tofile); */
return -1;
{
return -2;
}
{
}
return 0;
}
/*****************************************************************
** copyzonefile (fromfile, tofile, dnskeyfile)
** copy a already signed zonefile and replace all zone DNSKEY
** resource records by one "$INCLUDE dnskey.db" line
*****************************************************************/
{
int len;
int dnskeys;
int multi_line_dnskey;
int bufoverflow;
char *p;
else
return -1;
else
{
if ( fromfile )
return -2;
}
multi_line_dnskey = 0;
dnskeys = 0;
bufoverflow = 0;
{
p = buf;
{
do
p++;
while ( isspace (*p) ) ;
/* skip TTL */
while ( isdigit (*p) )
p++;
while ( isspace (*p) )
p++;
/* skip Class */
{
p += 2;
while ( isspace (*p) )
p++;
}
{
dnskeys++;
p += 6;
while ( *p )
{
if ( *p == '(' )
multi_line_dnskey = 1;
if ( *p == ')' )
multi_line_dnskey = 0;
p++;
}
if ( dnskeys == 1 )
}
else
}
else
{
if ( bufoverflow )
if ( !multi_line_dnskey )
else
{
while ( *p && *p != ')' )
p++;
if ( *p == ')' )
multi_line_dnskey = 0;
}
}
}
if ( fromfile )
if ( tofile )
return 0;
}
/*****************************************************************
** cmpfile (file1, file2)
** returns -1 on error, 1 if the files differ and 0 if they
** are identical.
*****************************************************************/
{
int c1;
int c2;
/* fprintf (stderr, "cmpfile (%s, %s)\n", file1, file2); */
return -1;
{
return -1;
}
do {
return 0;
return 1;
}
/*****************************************************************
** file_age (fname)
*****************************************************************/
{
}
/*****************************************************************
** file_mtime (fname)
*****************************************************************/
{
return 0;
}
/*****************************************************************
** is_exec_ok (prog)
** Check if we are running as root or if the file owner of
** "prog" do not match the current user or the file permissions
** allows file modification for others then the owner.
** The same condition will be checked for the group ownership.
** return 1 if the execution of the command "prog" will not
** open a big security whole, 0 otherwise
*****************************************************************/
{
return 0;
if ( curr_uid == 0 ) /* don't run the cmd if we are root */
return 0;
/* if the file owner and the current user matches and */
/* the file mode is not writable except for the owner, we are save */
return 1;
/* if the file group and the current group matches and */
/* the file mode is not writable except for the group, we are also save */
return 1;
return 0;
}
/*****************************************************************
** fatal (fmt, ...)
*****************************************************************/
{
if ( progname )
exit (127);
}
/*****************************************************************
** error (fmt, ...)
*****************************************************************/
{
}
/*****************************************************************
** logmesg (fmt, ...)
*****************************************************************/
{
#if defined (LOG_WITH_PROGNAME) && LOG_WITH_PROGNAME
#endif
}
/*****************************************************************
** verbmesg (verblvl, conf, fmt, ...)
*****************************************************************/
{
str[0] = '\0';
//fprintf (stderr, "verbmesg (%d stdout=%d filelog=%d str = :%s:\n", verblvl, conf->verbosity, conf->verboselog, str);
}
/*****************************************************************
** logflush ()
*****************************************************************/
void logflush ()
{
}
/*****************************************************************
** timestr2time (timestr)
** timestr should look like "20071211223901" for 12 dec 2007 22:39:01
*****************************************************************/
{
struct tm t;
// fprintf (stderr, "timestr = \"%s\"\n", timestr);
return 0L;
t.tm_year -= 1900;
t.tm_mon -= 1;
t.tm_isdst = 0;
#if defined(HAVE_TIMEGM) && HAVE_TIMEGM
#else
{
char *tz;
tzset();
if (tz)
else
tzset();
}
#endif
}
/*****************************************************************
** time2str (sec, precison)
** sec is seconds since 1.1.1970
** precison is currently either 's' (for seconds) or 'm' (minutes)
*****************************************************************/
{
struct tm *t;
#if defined(HAVE_STRFTIME) && HAVE_STRFTIME
timestr[0] = '\0';
if ( sec <= 0L )
return timestr;
if ( precision == 's' )
else
# if PRINT_TIMEZONE
# endif
#else /* no strftime available */
static char *mstr[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
timestr[0] = '\0';
if ( sec <= 0L )
return timestr;
# if PRINT_TIMEZONE
{
int h, s;
h = t->tm_gmtoff / 3600;
s = t->tm_gmtoff % 3600;
if ( precision == 's' )
h, s);
else
h, s);
}
# else
if ( precision == 's' )
else
# endif
#endif
return timestr;
}
/*****************************************************************
** time2isostr (sec, precison)
** sec is seconds since 1.1.1970
** precison is currently either 's' (for seconds) or 'm' (minutes)
*****************************************************************/
{
struct tm *t;
timestr[0] = '\0';
if ( sec <= 0L )
return timestr;
if ( precision == 's' )
else
return timestr;
}
/*****************************************************************
** age2str (sec)
** !!Attention: This function is not reentrant
*****************************************************************/
{
int len;
len = 0;
# if PRINT_AGE_WITH_YEAR
{
}
else
# endif
{
}
else
{
}
else
{
}
else
{
}
else
if ( sec > 0 )
else
return str;
}
/*****************************************************************
** start_timer ()
*****************************************************************/
{
}
/*****************************************************************
** stop_timer ()
*****************************************************************/
{
}
/****************************************************************
**
** int gensalt (saltstr, sizeofsaltstr, bits)
**
** generate a random hexstring of 'bits' salt and store it
** in saltstr. return 1 on success, otherwise 0.
**
*****************************************************************/
{
int i;
int hex;
if ( seed == 0 )
return 0;
for ( i = 0; i < saltlen; i++ )
{
}
salt[i] = '\0';
return 1;
}
#ifdef COPYZONE_TEST
const char *progname;
{
}
#endif
#ifdef URL_TEST
const char *progname;
{
char *proto;
char *host;
char *port;
char *para;
if ( --argc <= 0 )
{
exit (1);
}
if ( proto )
if ( host )
if ( port )
if ( para )
}
#endif