/* $CoreSDI: version.c,v 1.6 2001/10/10 00:30:11 claudio Exp $ */ /* * Copyright (c) 2000, 2001, Core SDI S.A., Argentina * 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. * 3. Neither name of the Core SDI S.A. 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 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. */ /* * Version handling functions. * Author: Claudio Castiglia */ #include #include #include #include #include #include #ifdef __linux__ #include /* in_addr_t */ #endif #ifndef WIN32 #include #else #include "exits.h" #include "winsyslog.h" #endif /* WIN32 */ #include "sysdep.h" #include "packet.h" #include "version.h" #include "log.h" /* * Extract version numbers (major and minor) from specified string; * returns 0 on success or -1 on error (invalid version number). */ int extract_version_numbers(const char *ver, int *major, int *minor) { char *ma, *mi, *err, version[10]; long i; if (version == NULL) { errno = EINVAL; return (-1); } strlcpy(version, ver, sizeof(version)); mi = version; ma = strsep(&mi, "."); if (ma != NULL && major != NULL) { i = strtol(ma, &err, 10); if (*err != '\0' || i == LONG_MIN || i == LONG_MAX) return (-1); *major = (int)i; } if (mi != NULL && minor != NULL) { i = strtol(mi, &err, 10); if (*err != '\0' || i == LONG_MIN || i == LONG_MAX) return (-1); *minor = (int)i; } return (0); } /* * id_exchange() * Exchange identification strings; * return 0 on success and -1 on error; * abort program execution on protocol violation. */ int id_exchange(PACKET *p, int *his_major, int *his_minor) { char msg[20] = { "audit-" }; if (p == NULL || his_major == NULL || his_minor == NULL) { errno = EINVAL; return (-1); } /* Send our identification string, receive peer's */ strlcat(msg, AUDIT_VERSION, sizeof(msg)); packet_put_string(p, msg); packet_get_string(p, msg, sizeof(msg)); /* Check and extract peer's version numbers */ if (!strncmp("audit-", msg, 6)) if (!extract_version_numbers(msg + 6, his_major, his_minor)) return (0); fatal(EX_PROTOCOL, "Protocol violation: " "Invalid identification string: '%s'.", msg); /* NOTREACHED */ return (-1); } /* * compatible_peer() * Exchange version numbers and check compatibility; * return nonzero value if compatible and 0 if not. */ int compatible_peer(PACKET *p) { int my_major, my_minor, his_major, his_minor; if (extract_version_numbers(AUDIT_VERSION, &my_major, &my_minor) < 0) { fatal(EX_SOFTWARE, "Invalid internal id: '%s'.", AUDIT_VERSION); /* NOTREACHED */ } if (id_exchange(p, &his_major, &his_minor) < 0) { fatal(EX_SOFTWARE, "Unknown error: %s.", strerror(errno)); /* NOTREACHED */ } log_debug("my version: %d.%d, his version: %d.%d.", my_major, my_minor, his_major, his_minor); /* Check compatibility */ return ((my_major == his_major) && (my_minor == his_minor)); }