diff options
author | Othmar Gsenger <otti@anytun.org> | 2008-05-25 09:50:42 +0000 |
---|---|---|
committer | Othmar Gsenger <otti@anytun.org> | 2008-05-25 09:50:42 +0000 |
commit | 71da41451212389bea25d67bc5da696b6d194bff (patch) | |
tree | a3b20decbd8bc9e47640af5fa4b39f731477955a /keyexchange/isakmpd-20041012/log.c | |
parent | improved presentation again (diff) |
moved keyexchange to http://anytun.org/svn/keyexchange
Diffstat (limited to 'keyexchange/isakmpd-20041012/log.c')
-rw-r--r-- | keyexchange/isakmpd-20041012/log.c | 706 |
1 files changed, 0 insertions, 706 deletions
diff --git a/keyexchange/isakmpd-20041012/log.c b/keyexchange/isakmpd-20041012/log.c deleted file mode 100644 index 5d8080c..0000000 --- a/keyexchange/isakmpd-20041012/log.c +++ /dev/null @@ -1,706 +0,0 @@ -/* $OpenBSD: log.c,v 1.49 2004/08/08 19:11:06 deraadt Exp $ */ -/* $EOM: log.c,v 1.30 2000/09/29 08:19:23 niklas Exp $ */ - -/* - * Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved. - * Copyright (c) 1999, 2000, 2001, 2003 Håkan Olsson. 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 ``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 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. - */ - -/* - * This code was written under funding by Ericsson Radio Systems. - */ - -#include <sys/types.h> -#include <sys/time.h> - -#ifdef USE_DEBUG -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/uio.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/ip6.h> -#include <netinet/udp.h> -#include <arpa/inet.h> - -#ifdef HAVE_PCAP -#include <pcap.h> -#else -#include "sysdep/common/pcap.h" -#endif - -#endif /* USE_DEBUG */ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <stdarg.h> -#include <unistd.h> - -#include "conf.h" -#include "isakmp_num.h" -#include "log.h" -#include "monitor.h" -#include "util.h" - -static void _log_print(int, int, const char *, va_list, int, int); - -static FILE *log_output; - -int verbose_logging = 0; -#if defined (USE_DEBUG) -static int log_level[LOG_ENDCLASS]; - -#define TCPDUMP_MAGIC 0xa1b2c3d4 -#define SNAPLEN (64 * 1024) - -struct packhdr { - struct pcap_pkthdr pcap;/* pcap file packet header */ - union { - struct ip ip4; /* IPv4 header (w/o options) */ - struct ip6_hdr ip6; /* IPv6 header */ - } ip; -}; - -struct isakmp_hdr { - u_int8_t icookie[8], rcookie[8]; - u_int8_t next, ver, type, flags; - u_int32_t msgid, len; -}; - -static char *pcaplog_file = NULL; -static FILE *packet_log; -static u_int8_t *packet_buf = NULL; - -static int udp_cksum(struct packhdr *, const struct udphdr *, - u_int16_t *, int); -static u_int16_t in_cksum(const u_int16_t *, int); -#endif /* USE_DEBUG */ - -void -log_init(int debug) -{ - if (debug) - log_output = stderr; - else - log_to(0); /* syslog */ -} - -void -log_reinit(void) -{ - struct conf_list *logging; -#ifdef USE_DEBUG - struct conf_list_node *logclass; - int class, level; -#endif /* USE_DEBUG */ - - logging = conf_get_list("General", "Logverbose"); - if (logging) { - verbose_logging = 1; - conf_free_list(logging); - } -#ifdef USE_DEBUG - logging = conf_get_list("General", "Loglevel"); - if (!logging) - return; - - for (logclass = TAILQ_FIRST(&logging->fields); logclass; - logclass = TAILQ_NEXT(logclass, link)) { - if (sscanf(logclass->field, "%d=%d", &class, &level) != 2) { - if (sscanf(logclass->field, "A=%d", &level) == 1) - for (class = 0; class < LOG_ENDCLASS; class++) - log_debug_cmd(class, level); - else { - log_print("init: invalid logging class or " - "level: %s", logclass->field); - continue; - } - } else - log_debug_cmd(class, level); - } - conf_free_list(logging); -#endif /* USE_DEBUG */ -} - -void -log_to(FILE *f) -{ - if (!log_output && f) - closelog(); - log_output = f; - if (!f) - openlog("isakmpd", LOG_PID | LOG_CONS, LOG_DAEMON); -} - -FILE * -log_current(void) -{ - return log_output; -} - -static char * -_log_get_class(int error_class) -{ - /* XXX For test purposes. To be removed later on? */ - static char *class_text[] = LOG_CLASSES_TEXT; - - if (error_class < 0) - return "Dflt"; - else if (error_class >= LOG_ENDCLASS) - return "Unkn"; - else - return class_text[error_class]; -} - -static void -_log_print(int error, int syslog_level, const char *fmt, va_list ap, - int class, int level) -{ - char buffer[LOG_SIZE], nbuf[LOG_SIZE + 32]; - static const char fallback_msg[] = - "write to log file failed (errno %d), redirecting to syslog"; - int len; - struct tm *tm; - struct timeval now; - time_t t; - - len = vsnprintf(buffer, sizeof buffer, fmt, ap); - if (len > 0 && len < (int) sizeof buffer - 1 && error) - snprintf(buffer + len, sizeof buffer - len, ": %s", - strerror(errno)); - if (log_output) { - gettimeofday(&now, 0); - t = now.tv_sec; - tm = localtime(&t); - if (class >= 0) - snprintf(nbuf, sizeof nbuf, - "%02d%02d%02d.%06ld %s %02d ", - tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec, - _log_get_class(class), level); - else /* LOG_PRINT (-1) or LOG_REPORT (-2) */ - snprintf(nbuf, sizeof nbuf, "%02d%02d%02d.%06ld %s ", - tm->tm_hour, tm->tm_min, tm->tm_sec, now.tv_usec, - class == LOG_PRINT ? "Default" : "Report>"); - strlcat(nbuf, buffer, sizeof nbuf); -#if defined (USE_PRIVSEP) - strlcat(nbuf, getuid() ? "" : " [priv]", LOG_SIZE + 32); -#endif - strlcat(nbuf, "\n", sizeof nbuf); - - if (fwrite(nbuf, strlen(nbuf), 1, log_output) == 0) { - /* Report fallback. */ - syslog(LOG_ALERT, fallback_msg, errno); - fprintf(log_output, fallback_msg, errno); - - /* - * Close log_output to prevent isakmpd from locking - * the file. We may need to explicitly close stdout - * to do this properly. - * XXX - Figure out how to match two FILE *'s and - * rewrite. - */ - if (fileno(log_output) != -1 && - fileno(stdout) == fileno(log_output)) - fclose(stdout); - fclose(log_output); - - /* Fallback to syslog. */ - log_to(0); - - /* (Re)send current message to syslog(). */ - syslog(class == LOG_REPORT ? LOG_ALERT : - syslog_level, "%s", buffer); - } - } else - syslog(class == LOG_REPORT ? LOG_ALERT : syslog_level, "%s", - buffer); -} - -#ifdef USE_DEBUG -void -log_debug(int cls, int level, const char *fmt, ...) -{ - va_list ap; - - /* - * If we are not debugging this class, or the level is too low, just - * return. - */ - if (cls >= 0 && (log_level[cls] == 0 || level > log_level[cls])) - return; - va_start(ap, fmt); - _log_print(0, LOG_INFO, fmt, ap, cls, level); - va_end(ap); -} - -void -log_debug_buf(int cls, int level, const char *header, const u_int8_t *buf, - size_t sz) -{ - size_t i, j; - char s[73]; - - /* - * If we are not debugging this class, or the level is too low, just - * return. - */ - if (cls >= 0 && (log_level[cls] == 0 || level > log_level[cls])) - return; - - log_debug(cls, level, "%s:", header); - for (i = j = 0; i < sz;) { - snprintf(s + j, sizeof s - j, "%02x", buf[i++]); - j += 2; - if (i % 4 == 0) { - if (i % 32 == 0) { - s[j] = '\0'; - log_debug(cls, level, "%s", s); - j = 0; - } else - s[j++] = ' '; - } - } - if (j) { - s[j] = '\0'; - log_debug(cls, level, "%s", s); - } -} - -void -log_debug_cmd(int cls, int level) -{ - if (cls < 0 || cls >= LOG_ENDCLASS) { - log_print("log_debug_cmd: invalid debugging class %d", cls); - return; - } - if (level < 0) { - log_print("log_debug_cmd: invalid debugging level %d for " - "class %d", level, cls); - return; - } - if (level == log_level[cls]) - log_print("log_debug_cmd: log level unchanged for class %d", - cls); - else { - log_print("log_debug_cmd: log level changed from %d to %d " - "for class %d", log_level[cls], level, cls); - log_level[cls] = level; - } -} - -void -log_debug_toggle(void) -{ - static int log_level_copy[LOG_ENDCLASS], toggle = 0; - - if (!toggle) { - LOG_DBG((LOG_MISC, 50, "log_debug_toggle: " - "debug levels cleared")); - memcpy(&log_level_copy, &log_level, sizeof log_level); - memset(&log_level, 0, sizeof log_level); - } else { - memcpy(&log_level, &log_level_copy, sizeof log_level); - LOG_DBG((LOG_MISC, 50, "log_debug_toggle: " - "debug levels restored")); - } - toggle = !toggle; -} -#endif /* USE_DEBUG */ - -void -log_print(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - _log_print(0, LOG_NOTICE, fmt, ap, LOG_PRINT, 0); - va_end(ap); -} - -void -log_verbose(const char *fmt, ...) -{ - va_list ap; -#ifdef USE_DEBUG - int i; -#endif /* USE_DEBUG */ - - if (verbose_logging == 0) - return; - -#ifdef USE_DEBUG - for (i = 0; i < LOG_ENDCLASS; i++) - if (log_level[i] > 0) - return; -#endif - - va_start(ap, fmt); - _log_print(0, LOG_NOTICE, fmt, ap, LOG_PRINT, 0); - va_end(ap); -} - -void -log_error(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - _log_print(1, LOG_ERR, fmt, ap, LOG_PRINT, 0); - va_end(ap); -} - -void -log_fatal(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - _log_print(1, LOG_CRIT, fmt, ap, LOG_PRINT, 0); - va_end(ap); -#ifdef USE_PRIVSEP - monitor_exit(1); -#else - exit(1); -#endif -} - -#ifdef USE_DEBUG -void -log_packet_init(char *newname) -{ - struct pcap_file_header sf_hdr; - struct stat st; - mode_t old_umask; - char *mode; - - /* Allocate packet buffer first time through. */ - if (!packet_buf) - packet_buf = malloc(SNAPLEN); - - if (!packet_buf) { - log_error("log_packet_init: malloc (%d) failed", SNAPLEN); - return; - } - if (pcaplog_file && strcmp(pcaplog_file, PCAP_FILE_DEFAULT) != 0) - free(pcaplog_file); - - pcaplog_file = strdup(newname); - if (!pcaplog_file) { - log_error("log_packet_init: strdup (\"%s\") failed", newname); - return; - } - /* Does the file already exist? XXX lstat() or stat()? */ -#if defined (USE_PRIVSEP) - /* XXX This is a fstat! */ - if (monitor_stat(pcaplog_file, &st) == 0) { -#else - if (lstat(pcaplog_file, &st) == 0) { -#endif - /* Sanity checks. */ - if ((st.st_mode & S_IFMT) != S_IFREG) { - log_print("log_packet_init: existing capture file is " - "not a regular file"); - return; - } - if ((st.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - log_print("log_packet_init: existing capture " - "file has bad modes"); - return; - } - /* - * XXX It would be nice to check if it actually is a pcap - * file... - */ - - mode = "a"; - } else - mode = "w"; - - old_umask = umask(S_IRWXG | S_IRWXO); - packet_log = monitor_fopen(pcaplog_file, mode); - umask(old_umask); - - if (!packet_log) { - log_error("log_packet_init: fopen (\"%s\", \"%s\") failed", - pcaplog_file, mode); - return; - } - log_print("log_packet_init: " - "starting IKE packet capture to file \"%s\"", pcaplog_file); - - /* If this is a new file, we need to write a PCAP header to it. */ - if (*mode == 'w') { - sf_hdr.magic = TCPDUMP_MAGIC; - sf_hdr.version_major = PCAP_VERSION_MAJOR; - sf_hdr.version_minor = PCAP_VERSION_MINOR; - sf_hdr.thiszone = 0; - sf_hdr.snaplen = SNAPLEN; - sf_hdr.sigfigs = 0; - sf_hdr.linktype = DLT_LOOP; - - fwrite((char *) &sf_hdr, sizeof sf_hdr, 1, packet_log); - fflush(packet_log); - } -} - -void -log_packet_restart(char *newname) -{ - if (packet_log) { - log_print("log_packet_restart: capture already active on " - "file \"%s\"", pcaplog_file); - return; - } - if (newname) - log_packet_init(newname); - else if (!pcaplog_file) - log_packet_init(PCAP_FILE_DEFAULT); - else - log_packet_init(pcaplog_file); -} - -void -log_packet_stop(void) -{ - /* Stop capture. */ - if (packet_log) { - fclose(packet_log); - log_print("log_packet_stop: stopped capture"); - } - packet_log = 0; -} - -void -log_packet_iov(struct sockaddr *src, struct sockaddr *dst, struct iovec *iov, - int iovcnt) -{ - struct isakmp_hdr *isakmphdr; - struct packhdr hdr; - struct udphdr udp; - struct timeval tv; - int off, datalen, hdrlen, i, add_espmarker = 0; - const u_int32_t espmarker = 0; - - for (i = 0, datalen = 0; i < iovcnt; i++) - datalen += iov[i].iov_len; - - if (!packet_log || datalen > SNAPLEN) - return; - - /* copy packet into buffer */ - for (i = 0, off = 0; i < iovcnt; i++) { - memcpy(packet_buf + off, iov[i].iov_base, iov[i].iov_len); - off += iov[i].iov_len; - } - - memset(&hdr, 0, sizeof hdr); - memset(&udp, 0, sizeof udp); - - /* isakmp - turn off the encryption bit in the isakmp hdr */ - isakmphdr = (struct isakmp_hdr *) packet_buf; - isakmphdr->flags &= ~(ISAKMP_FLAGS_ENC); - - /* udp */ - udp.uh_sport = sockaddr_port(src); - udp.uh_dport = sockaddr_port(dst); - datalen += sizeof udp; -#if defined (USE_NAT_TRAVERSAL) - if (ntohs(udp.uh_sport) == 4500 || - ntohs(udp.uh_dport) == 4500) { /* XXX Quick and dirty */ - add_espmarker = 1; - datalen += sizeof espmarker; - } -#endif - udp.uh_ulen = htons(datalen); - - /* ip */ - switch (src->sa_family) { - default: - /* Assume IPv4. XXX Can 'default' ever happen here? */ - hdr.ip.ip4.ip_src.s_addr = 0x02020202; - hdr.ip.ip4.ip_dst.s_addr = 0x01010101; - /* The rest of the setup is common to AF_INET. */ - goto setup_ip4; - - case AF_INET: - hdr.ip.ip4.ip_src.s_addr = - ((struct sockaddr_in *)src)->sin_addr.s_addr; - hdr.ip.ip4.ip_dst.s_addr = - ((struct sockaddr_in *)dst)->sin_addr.s_addr; - -setup_ip4: - hdrlen = sizeof hdr.ip.ip4; - hdr.ip.ip4.ip_v = 0x4; - hdr.ip.ip4.ip_hl = 0x5; - hdr.ip.ip4.ip_p = IPPROTO_UDP; - hdr.ip.ip4.ip_len = htons(datalen + hdrlen); - /* Let's use the IP ID as a "packet counter". */ - i = ntohs(hdr.ip.ip4.ip_id) + 1; - hdr.ip.ip4.ip_id = htons(i); - /* Calculate IP header checksum. */ - hdr.ip.ip4.ip_sum = in_cksum((u_int16_t *) & hdr.ip.ip4, - hdr.ip.ip4.ip_hl << 2); - break; - - case AF_INET6: - hdrlen = sizeof(hdr.ip.ip6); - hdr.ip.ip6.ip6_vfc = IPV6_VERSION; - hdr.ip.ip6.ip6_nxt = IPPROTO_UDP; - hdr.ip.ip6.ip6_plen = udp.uh_ulen; - memcpy(&hdr.ip.ip6.ip6_src, - &((struct sockaddr_in6 *)src)->sin6_addr, - sizeof hdr.ip.ip6.ip6_src); - memcpy(&hdr.ip.ip6.ip6_dst, - &((struct sockaddr_in6 *)dst)->sin6_addr, - sizeof hdr.ip.ip6.ip6_dst); - break; - } - - /* Calculate UDP checksum. */ - udp.uh_sum = udp_cksum(&hdr, &udp, (u_int16_t *) packet_buf, src->sa_family); - /* pcap file packet header */ - gettimeofday(&tv, 0); - hdr.pcap.ts.tv_sec = tv.tv_sec; - hdr.pcap.ts.tv_usec = tv.tv_usec; - hdr.pcap.caplen = datalen + hdrlen; - hdr.pcap.len = datalen + hdrlen; - - hdrlen += sizeof(struct pcap_pkthdr); - datalen -= sizeof(struct udphdr); - - /* Write to pcap file. */ - fwrite(&hdr, hdrlen, 1, packet_log); /* pcap + IP */ - fwrite(&udp, sizeof(struct udphdr), 1, packet_log); /* UDP */ - if (add_espmarker) { - fwrite(&espmarker, sizeof espmarker, 1, packet_log); - datalen -= sizeof espmarker; - } - fwrite(packet_buf, datalen, 1, packet_log); /* IKE-data */ - fflush(packet_log); -} - -/* Copied from tcpdump/print-udp.c, mostly rewritten. */ -static int -udp_cksum(struct packhdr *hdr, const struct udphdr *u, u_int16_t *d, int af) -{ - struct ip *ip4; - struct ip6_hdr *ip6; - int i, hdrlen, tlen = ntohs(u->uh_ulen) - sizeof(struct udphdr); - - union phu { - struct ip4pseudo { - struct in_addr src; - struct in_addr dst; - u_int8_t z; - u_int8_t proto; - u_int16_t len; - } ip4p; - struct ip6pseudo { - struct in6_addr src; - struct in6_addr dst; - u_int32_t plen; - u_int16_t z0; - u_int8_t z1; - u_int8_t nxt; - } ip6p; - u_int16_t pa[20]; - } phu; - const u_int16_t *sp; - u_int32_t sum; - - /* Setup pseudoheader. */ - memset(phu.pa, 0, sizeof phu); - switch (af) { - case AF_INET: - ip4 = &hdr->ip.ip4; - memcpy(&phu.ip4p.src, &ip4->ip_src, sizeof(struct in_addr)); - memcpy(&phu.ip4p.dst, &ip4->ip_dst, sizeof(struct in_addr)); - phu.ip4p.proto = ip4->ip_p; - phu.ip4p.len = u->uh_ulen; - hdrlen = sizeof phu.ip4p; - break; - - case AF_INET6: - ip6 = &hdr->ip.ip6; - memcpy(&phu.ip6p.src, &ip6->ip6_src, sizeof(phu.ip6p.src)); - memcpy(&phu.ip6p.dst, &ip6->ip6_dst, sizeof(phu.ip6p.dst)); - phu.ip6p.plen = u->uh_ulen; - phu.ip6p.nxt = ip6->ip6_nxt; - hdrlen = sizeof phu.ip6p; - break; - - default: - return 0; - } - - /* IPv6 wants a 0xFFFF checksum "on error", not 0x0. */ - if (tlen < 0) - return (af == AF_INET ? 0 : 0xFFFF); - - sum = 0; - for (i = 0; i < hdrlen; i += 2) - sum += phu.pa[i / 2]; - - sp = (u_int16_t *) u; - for (i = 0; i < (int)sizeof(struct udphdr); i += 2) - sum += *sp++; - - sp = d; - for (i = 0; i < (tlen & ~1); i += 2) - sum += *sp++; - - if (tlen & 1) - sum += htons((*(const char *)sp) << 8); - - while (sum > 0xffff) - sum = (sum & 0xffff) + (sum >> 16); - sum = ~sum & 0xffff; - - return sum; -} - -/* Copied from tcpdump/print-ip.c, modified. */ -static u_int16_t -in_cksum(const u_int16_t *w, int len) -{ - int nleft = len, sum = 0; - u_int16_t answer; - - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } - if (nleft == 1) - sum += htons(*(u_char *) w << 8); - - sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ - sum += (sum >> 16); /* add carry */ - answer = ~sum; /* truncate to 16 bits */ - return answer; -} - -#endif /* USE_DEBUG */ |