diff options
-rw-r--r-- | libglouglou/Makefile | 2 | ||||
-rw-r--r-- | libglouglou/libglouglou.c | 74 | ||||
-rw-r--r-- | libglouglou/libglouglou.h | 40 | ||||
-rw-r--r-- | libglouglou/utils.c | 196 |
4 files changed, 239 insertions, 73 deletions
diff --git a/libglouglou/Makefile b/libglouglou/Makefile index b47507f..83ac0b5 100644 --- a/libglouglou/Makefile +++ b/libglouglou/Makefile @@ -6,7 +6,7 @@ LIBDIR=$(PREFIX)/lib LIBNAME=libglouglou TARGET = ${LIBNAME}.so -SOURCES = libglouglou.c sendbuf.c +SOURCES = libglouglou.c sendbuf.c utils.c HEADERS = libglouglou.h OBJECTS = $(SOURCES:.c=.o) diff --git a/libglouglou/libglouglou.c b/libglouglou/libglouglou.c index 0b0ab48..1ec8916 100644 --- a/libglouglou/libglouglou.c +++ b/libglouglou/libglouglou.c @@ -17,7 +17,7 @@ #define error(fmt, ...) \ if (_verbosity >= 0) \ - printf("libgg: %s: ERROR: " fmt "\n", __func__, ##__VA_ARGS__) + printf("libgg: %s: ERROR: " fmt "\n", __func__, ##__VA_ARGS__) #define verbose(fmt, ...) \ if (_verbosity >= 1) \ printf("libgg: %s: " fmt "\n", __func__, ##__VA_ARGS__) @@ -41,6 +41,23 @@ int pkt_encode(struct gg_packet *, struct gg_packet *); int _verbosity = 0; +gg_packet_props_t gg_packet_props[] = { + [PACKET_NEWCONN] = \ + { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.newconn) }, + [PACKET_DELCONN] = \ + { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.delconn) }, + [PACKET_DATA] = \ + { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.data) }, + [PACKET_NAME] = \ + { ((PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.name) - GG_PKTARG_MAX) }, + [PACKET_FORK] = \ + { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.fork) }, + [PACKET_EXEC] = \ + { ((PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.exec) - GG_PKTARG_MAX) }, + [PACKET_EXIT] = \ + { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.exit) }, +}; + /* * Server */ @@ -702,58 +719,3 @@ gg_verbosity_set(int verb) { _verbosity = verb; } - -/* - * Utils - */ - -void * -xmalloc(size_t size) -{ - void *data; - - data = malloc(size); - if (!data) - err(1, "could not malloc %d", (int)size); - return data; -} - -void * -xcalloc(size_t nmemb, size_t size) -{ - void *data; - - data = calloc(nmemb, size); - if (!data) - err(1, "could not calloc %d", (int)size); - return data; -} - -void -fd_nonblock(int fd) -{ - int flags = fcntl(fd, F_GETFL, 0); - int rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK); - if (rc == -1) - error("failed to set fd %i non-blocking", fd); -} - -void -addrcpy(struct sockaddr_in *dst, struct sockaddr_in *src) -{ - dst->sin_addr.s_addr = src->sin_addr.s_addr; - dst->sin_port = src->sin_port; - dst->sin_family = src->sin_family; -} - -int -addrcmp(struct sockaddr_in *a, struct sockaddr_in *b) -{ - if (a->sin_addr.s_addr != b->sin_addr.s_addr) - return -1; - if (a->sin_port != b->sin_port) - return -2; - if (a->sin_family != b->sin_family) - return -3; - return 0; -} diff --git a/libglouglou/libglouglou.h b/libglouglou/libglouglou.h index 473c7a2..474c119 100644 --- a/libglouglou/libglouglou.h +++ b/libglouglou/libglouglou.h @@ -7,6 +7,11 @@ */ #include <sys/queue.h> +#ifndef _LIBGLOUGLOU_H_ +#define _LIBGLOUGLOU_H_ + +/* libglouglou.c */ + #define GLOUGLOU_PROBE_DEFAULT_PORT 4430 #define GLOUGLOU_ANALY_DEFAULT_PORT 4431 @@ -96,22 +101,7 @@ typedef struct gg_packet_props_t { int size; } gg_packet_props_t; -gg_packet_props_t gg_packet_props[] = { - [PACKET_NEWCONN] = \ - { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.newconn) }, - [PACKET_DELCONN] = \ - { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.delconn) }, - [PACKET_DATA] = \ - { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.data) }, - [PACKET_NAME] = \ - { ((PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.name) - GG_PKTARG_MAX) }, - [PACKET_FORK] = \ - { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.fork) }, - [PACKET_EXEC] = \ - { ((PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.exec) - GG_PKTARG_MAX) }, - [PACKET_EXIT] = \ - { (PACKET_HEADER_SIZE + sizeof((struct gg_packet *)0)->pdat.exit) }, -}; +extern gg_packet_props_t gg_packet_props[]; struct gg_user { LIST_ENTRY(gg_user) entry; @@ -175,9 +165,27 @@ void gg_client_send_flush(struct gg_client *); int gg_verbosity_get(void); void gg_verbosity_set(int); +/* utils.c */ + +#define GGLOG_FORCED -2 +#define GGLOG_FATAL -1 +#define GGLOG_WARN 0 +#define GGLOG_INFO 1 +#define GGLOG_DEBUG 2 + +int log_init(char *, int); +void log_shutdown(void); +void log_tmp(const char *, ...); +void log_debug(const char *, ...); +void log_info(const char *, ...); +void log_warn(const char *, ...); +void fatal(const char *, ...); + void *xmalloc(size_t); void *xcalloc(size_t, size_t); void fd_nonblock(int); void addrcpy(struct sockaddr_in *, struct sockaddr_in *); int addrcmp(struct sockaddr_in *, struct sockaddr_in *); +void droppriv(char *); +#endif /* _LIBGLOUGLOU_H_ */ diff --git a/libglouglou/utils.c b/libglouglou/utils.c new file mode 100644 index 0000000..4f53afa --- /dev/null +++ b/libglouglou/utils.c @@ -0,0 +1,196 @@ +#include <sys/types.h> + +#if !defined(__OpenBSD__) +#define __USE_GNU +#define _GNU_SOURCE +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <err.h> +#include <unistd.h> +#include <fcntl.h> +#include <time.h> +#include <pwd.h> +#include <grp.h> +#include <string.h> + +#include "libglouglou.h" + +FILE *_logfile; +static int _loglevel; + +static void logit(int, const char *, const char *, va_list); + +/* + * Log + * handles only one log file per process + */ + +int +log_init(char *filename, int level) +{ + _logfile = fopen(filename, "a+"); + if (!_logfile) { + printf("cannot open log file %s!\n", filename); + return -1; + } + _loglevel = level; + return 0; +} + +void +log_shutdown(void) +{ + fclose(_logfile); +} + +void +log_tmp(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + logit(GGLOG_FORCED, "XXX ", msg, ap); + va_end(ap); +} + +void +log_debug(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + logit(GGLOG_DEBUG, "", msg, ap); + va_end(ap); +} + +void +log_info(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + logit(GGLOG_INFO, "", msg, ap); + va_end(ap); +} + +void +log_warn(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + logit(GGLOG_WARN, "", msg, ap); + va_end(ap); +} + +#if defined(__OpenBSD__) +void __dead +#else +void +#endif +fatal(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + logit(GGLOG_FATAL, "fatal: ", msg, ap); + va_end(ap); + + exit(1); +} + +/* XXX mpsafe */ +static void +logit(int level, const char *prefix, const char *msg, va_list ap) +{ + time_t clock; + + if (level <= _loglevel) { + time(&clock); + fprintf(_logfile, "%d ", (int)clock); + vfprintf(_logfile, prefix, ap); + vfprintf(_logfile, msg, ap); + fprintf(_logfile, "\n"); + fflush(_logfile); + } +} + +/* + * Various utils + */ + +void * +xmalloc(size_t size) +{ + void *data; + + data = malloc(size); + if (!data) + err(1, "could not malloc %d", (int)size); + return data; +} + +void * +xcalloc(size_t nmemb, size_t size) +{ + void *data; + + data = calloc(nmemb, size); + if (!data) + err(1, "could not calloc %d", (int)size); + return data; +} + +void +fd_nonblock(int fd) +{ + int flags = fcntl(fd, F_GETFL, 0); + int rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (rc == -1) + err(1, "failed to set fd %i non-blocking", fd); +} + +void +addrcpy(struct sockaddr_in *dst, struct sockaddr_in *src) +{ + dst->sin_addr.s_addr = src->sin_addr.s_addr; + dst->sin_port = src->sin_port; + dst->sin_family = src->sin_family; +} + +int +addrcmp(struct sockaddr_in *a, struct sockaddr_in *b) +{ + if (a->sin_addr.s_addr != b->sin_addr.s_addr) + return -1; + if (a->sin_port != b->sin_port) + return -2; + if (a->sin_family != b->sin_family) + return -3; + return 0; +} + +void +droppriv(char *user) +{ + struct passwd *pw; + + pw = getpwnam(user); + if (!pw) + err(1, "unknown user %s", user); + if (chroot(pw->pw_dir) != 0) + err(1, "unable to chroot"); + if (chdir("/") != 0) + err(1, "unable to chdir"); + if (setgroups(1, &pw->pw_gid) == -1) + err(1, "setgroups() failed"); + if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) + err(1, "setresgid failed"); + if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) + err(1, "setresuid() failed"); + endpwent(); +} + |