From 02013228914a1d17e8df15d4e2b7950469395a5c Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 15 May 2015 10:23:51 +0200 Subject: ripe-atlas-fw: imported version 4520 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- libbb/Kbuild | 5 ++ libbb/atlas_bb64.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++ libbb/atlas_bb64.h | 18 +++++++ libbb/atlas_probe.c | 35 +++++++++++++ libbb/atlas_probe.h | 6 +++ libbb/find_pid_by_name.c | 2 +- libbb/getopt32.c | 22 ++++++-- libbb/strlcat.c | 46 +++++++++++++++++ libbb/strlcpy.c | 64 +++++++++++++++++++++++ libbb/validate_filename.c | 33 ++++++++++++ libbb/xconnect.c | 38 ++++++++++++++ libbb/xfuncs_printf.c | 56 +++++++++++++++++++++ 12 files changed, 445 insertions(+), 6 deletions(-) create mode 100644 libbb/atlas_bb64.c create mode 100644 libbb/atlas_bb64.h create mode 100644 libbb/atlas_probe.c create mode 100644 libbb/atlas_probe.h create mode 100644 libbb/strlcat.c create mode 100644 libbb/strlcpy.c create mode 100644 libbb/validate_filename.c (limited to 'libbb') diff --git a/libbb/Kbuild b/libbb/Kbuild index 786cbee..dead4bf 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild @@ -8,6 +8,8 @@ lib-y:= lib-y += appletlib.o lib-y += ask_confirmation.o +lib-y += atlas_bb64.o +lib-y += atlas_probe.o lib-y += bb_askpass.o lib-y += bb_basename.o lib-y += bb_do_delay.o @@ -97,6 +99,7 @@ lib-y += trim.o lib-y += u_signal_names.o lib-y += udp_io.o lib-y += uuencode.o +lib-y += validate_filename.o lib-y += vdprintf.o lib-y += verror_msg.o lib-y += vfork_daemon_rexec.o @@ -113,6 +116,8 @@ lib-y += xgetcwd.o lib-y += xgethostbyname.o lib-y += xreadlink.o lib-y += xrealloc_vector.o +lib-y += strlcat.o +lib-y += strlcpy.o # conditionally compiled objects: lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o diff --git a/libbb/atlas_bb64.c b/libbb/atlas_bb64.c new file mode 100644 index 0000000..bcd073b --- /dev/null +++ b/libbb/atlas_bb64.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013 RIPE NCC + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" +#define BUF_CHUNK 256 + +struct buf +{ + size_t offset; + size_t size; + size_t maxsize; + unsigned char *buf; + int fd; +}; + +void buf_init(struct buf *buf, int fd) +{ + buf->maxsize= 0; + buf->size= 0; + buf->offset= 0; + buf->buf= NULL; + buf->fd= fd; +} + +int buf_add(struct buf *buf, const void *data, size_t len ) +{ + size_t maxsize; + void *newbuf; + + if (buf->size+len <= buf->maxsize) + { + /* Easy case, just add data */ + memcpy(buf->buf+buf->size, data, len); + buf->size += len; + return 0; + } + + /* Just get a new buffer */ + maxsize= buf->size-buf->offset + len + BUF_CHUNK; + + newbuf= malloc(maxsize); + if (!newbuf) + { + fprintf(stderr, "unable to allocate %ld bytes\n", maxsize); + return (1); + } + + if (buf->offset < buf->size) + { + /* Copy existing data */ + memcpy(newbuf, buf->buf+buf->offset, buf->size-buf->offset); + buf->size -= buf->offset; + buf->offset= 0; + } + else + { + buf->size= buf->offset= 0; + } + buf->maxsize= maxsize; + free(buf->buf); + buf->buf= newbuf; + + memcpy(buf->buf+buf->size, data, len); + buf->size += len; + return 0; +} + +int buf_add_b64(struct buf *buf, void *data, size_t len, int mime_nl) +{ + char b64[]= + "ABCDEFGHIJKLMNOP" + "QRSTUVWXYZabcdef" + "ghijklmnopqrstuv" + "wxyz0123456789+/"; + int i; + uint8_t *p; + uint32_t v; + char str[4]; + + p= data; + + for (i= 0; i+3 <= len; i += 3, p += 3) + { + v= (p[0] << 16) + (p[1] << 8) + p[2]; + str[0]= b64[(v >> 18) & 63]; + str[1]= b64[(v >> 12) & 63]; + str[2]= b64[(v >> 6) & 63]; + str[3]= b64[(v >> 0) & 63]; + buf_add(buf, str, 4); + if(mime_nl) + if (i % 48 == 45) + buf_add(buf, "\n", 1); + } + switch(len-i) + { + case 0: break; /* Nothing to do */ + case 1: + v= (p[0] << 16); + str[0]= b64[(v >> 18) & 63]; + str[1]= b64[(v >> 12) & 63]; + str[2]= '='; + str[3]= '='; + buf_add(buf, str, 4); + break; + case 2: + v= (p[0] << 16) + (p[1] << 8); + str[0]= b64[(v >> 18) & 63]; + str[1]= b64[(v >> 12) & 63]; + str[2]= b64[(v >> 6) & 63]; + str[3]= '='; + buf_add(buf, str, 4); + break; + default: + fprintf(stderr, "bad state in buf_add_b64"); + } +} + +void buf_cleanup(struct buf *buf) +{ + if(buf->maxsize) + free(buf->buf); + buf->buf = NULL; + buf->offset= buf->size= buf->maxsize= 0; +} diff --git a/libbb/atlas_bb64.h b/libbb/atlas_bb64.h new file mode 100644 index 0000000..d745a9b --- /dev/null +++ b/libbb/atlas_bb64.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2013 RIPE NCC + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +struct buf +{ + size_t offset; + size_t size; + size_t maxsize; + char *buf; + int fd; +}; + +void buf_init(struct buf *buf, int fd); +int buf_add(struct buf *buf, const void *data, size_t len ); +int buf_add_b64(struct buf *buf, void *data, size_t len, int mime_nl); +void buf_cleanup(struct buf *buf); diff --git a/libbb/atlas_probe.c b/libbb/atlas_probe.c new file mode 100644 index 0000000..a3264fb --- /dev/null +++ b/libbb/atlas_probe.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013 RIPE NCC + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" +int get_probe_id(void) +{ + int probe_id; + size_t len; + char *check; + const char *key; + FILE *fp; + char buf[80]; + + fp= fopen("/home/atlas/status/reg_init_reply.txt", "r"); + if (!fp) + return -1; + + probe_id= -1; + while (fgets(buf, sizeof(buf), fp) != NULL) + { + if (strchr(buf, '\n') == NULL) + continue; + key= "PROBE_ID "; + len= strlen(key); + + if (strncmp(buf, key, len) != 0 || strlen(buf) <= len) + continue; + probe_id= strtol(buf+len, &check, 10); + break; + } + fclose(fp); + return probe_id; +} diff --git a/libbb/atlas_probe.h b/libbb/atlas_probe.h new file mode 100644 index 0000000..2787985 --- /dev/null +++ b/libbb/atlas_probe.h @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2013 RIPE NCC + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +int get_probe_id(void); diff --git a/libbb/find_pid_by_name.c b/libbb/find_pid_by_name.c index 92d6d02..90851eb 100644 --- a/libbb/find_pid_by_name.c +++ b/libbb/find_pid_by_name.c @@ -38,7 +38,7 @@ execXXX("/proc/self/exe", applet_name, params....) and therefore comm field contains "exe". */ -static int comm_match(procps_status_t *p, const char *procName) +int comm_match(procps_status_t *p, const char *procName) { int argv1idx; diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 17babcd..198149d 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c @@ -3,6 +3,7 @@ * universal getopt32 implementation for busybox * * Copyright (C) 2003-2005 Vladimir Oleynik + * Copyright (c) 2013 RIPE NCC * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ @@ -327,6 +328,7 @@ getopt32(char **argv, const char *applet_opts, ...) unsigned flags = 0; unsigned requires = 0; t_complementary complementary[33]; /* last stays zero-filled */ + char first_char; int c; const unsigned char *s; t_complementary *on_off; @@ -357,6 +359,11 @@ getopt32(char **argv, const char *applet_opts, ...) on_off = complementary; memset(on_off, 0, sizeof(complementary)); + /* skip bbox extension */ + first_char = applet_opts[0]; + if (first_char == '!') + applet_opts++; + /* skip GNU extension */ s = (const unsigned char *)applet_opts; if (*s == '+' || *s == '-') @@ -549,11 +556,11 @@ getopt32(char **argv, const char *applet_opts, ...) * is always NULL (see above) */ if (on_off->opt_char == '\0' /* && c != '\0' */) { /* c is probably '?' - "bad option" */ - bb_show_usage(); + goto error; } } if (flags & on_off->incongruously) - bb_show_usage(); + goto error; trigger = on_off->switch_on & on_off->switch_off; flags &= ~(on_off->switch_off ^ trigger); flags |= on_off->switch_on ^ trigger; @@ -579,14 +586,19 @@ getopt32(char **argv, const char *applet_opts, ...) for (on_off = complementary; on_off->opt_char; on_off++) { if (on_off->requires && (flags & on_off->switch_on) && (flags & on_off->requires) == 0) - bb_show_usage(); + goto error; } if (requires && (flags & requires) == 0) - bb_show_usage(); + goto error; argc -= optind; if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) - bb_show_usage(); + goto error; option_mask32 = flags; return flags; + + error: + if (first_char != '!') + bb_show_usage(); + return (int32_t)-1; } diff --git a/libbb/strlcat.c b/libbb/strlcat.c new file mode 100644 index 0000000..6dd7747 --- /dev/null +++ b/libbb/strlcat.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2002 Manuel Novoa III + * Copyright (C) 2000-2005 Erik Andersen + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +/* OpenBSD function: + * Append at most n-1-strlen(dst) chars from src to dst and nul-terminate dst. + * Returns strlen(src) + strlen({original} dst), so truncation occurred if the + * return val is >= n. + * Note: If dst doesn't contain a nul in the first n chars, strlen(dst) is + * taken as n. */ + +#include "libbb.h" + +size_t strlcat(register char *__restrict dst, + register const char *__restrict src, + size_t n) +{ + size_t len; + char dummy[1]; + + len = 0; + + while (1) { + if (len >= n) { + dst = dummy; + break; + } + if (!*dst) { + break; + } + ++dst; + ++len; + } + + while ((*dst = *src) != 0) { + if (++len < n) { + ++dst; + } + ++src; + } + + return len; +} diff --git a/libbb/strlcpy.c b/libbb/strlcpy.c new file mode 100644 index 0000000..02cd55a --- /dev/null +++ b/libbb/strlcpy.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2002 Manuel Novoa III + * Copyright (C) 2000-2005 Erik Andersen + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include "libbb.h" + +#ifdef WANT_WIDE +# define Wstrlcpy __wcslcpy +# define Wstrxfrm wcsxfrm +#else +// libc_hidden_proto(strlcpy) +# define Wstrlcpy strlcpy +# define Wstrxfrm strxfrm +# define Wchar char +#endif + + +/* OpenBSD function: + * Copy at most n-1 chars from src to dst and nul-terminate dst. + * Returns strlen(src), so truncation occurred if the return value is >= n. */ + +#ifdef WANT_WIDE +size_t Wstrlcpy(register Wchar *__restrict dst, + register const Wchar *__restrict src, + size_t n) attribute_hidden; +#endif +size_t Wstrlcpy(register Wchar *__restrict dst, + register const Wchar *__restrict src, + size_t n) +{ + const Wchar *src0 = src; + Wchar dummy[1]; + + if (!n) { + dst = dummy; + } else { + --n; + } + + while ((*dst = *src) != 0) { + if (n) { + --n; + ++dst; + } + ++src; + } + + return src - src0; +} +#ifndef WANT_WIDE +//libc_hidden_def(strlcpy) +#ifndef __UCLIBC_HAS_LOCALE__ +//libc_hidden_proto(strxfrm) +//strong_alias(strlcpy,strxfrm) +//libc_hidden_def(strxfrm) +#endif +#else +#ifndef __UCLIBC_HAS_LOCALE__ +strong_alias(__wcslcpy,wcsxfrm) +#endif +#endif diff --git a/libbb/validate_filename.c b/libbb/validate_filename.c new file mode 100644 index 0000000..2b9b80a --- /dev/null +++ b/libbb/validate_filename.c @@ -0,0 +1,33 @@ +#include "libbb.h" + +int validate_filename(const char *path, const char *prefix) +{ + size_t path_len, prefix_len; + + /* Check for the following properties: + * 1) path start with prefix + * 2) the next character after prefix is a '/' + * 3) path does not contain '/../' + * 4) path does not end in '/..' + * return 0 if any of the properties does not hold + * return 1 if all properties hold + */ + path_len= strlen(path); + prefix_len= strlen(prefix); + if (path_len < prefix_len) + return 0; + + if (memcmp(path, prefix, prefix_len) != 0) + return 0; /* property 1 */ + + if (path[prefix_len] != '/') + return 0; /* property 2 */ + + if (strstr(path, "/../") != NULL) + return 0; /* property 3 */ + + if (path_len >= 3 && strcmp(&path[path_len-3], "/..") == 0) + return 0; /* property 4 */ + + return 1; +} diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 27c7424..f313655 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c @@ -32,6 +32,24 @@ int FAST_FUNC setsockopt_bindtodevice(int fd, const char *iface) return r; } +len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd) +{ + len_and_sockaddr lsa; + len_and_sockaddr *lsa_ptr; + + lsa.len = LSA_SIZEOF_SA; + if (getsockname(fd, &lsa.u.sa, &lsa.len) != 0) + return NULL; + + lsa_ptr = xzalloc(LSA_LEN_SIZE + lsa.len); + if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */ + lsa_ptr->len = lsa.len; + getsockname(fd, &lsa_ptr->u.sa, &lsa_ptr->len); + } else { + memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len); + } + return lsa_ptr; +} void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) { @@ -46,6 +64,26 @@ void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) } } +void FAST_FUNC xrconnect(int s, + const struct sockaddr *s_addr, socklen_t addrlen, + void (*reportf)(int err)) +{ + if (connect(s, s_addr, addrlen) < 0) { + if (reportf) { + int t_errno= errno; + reportf(t_errno); + errno= t_errno; + } + if (ENABLE_FEATURE_CLEAN_UP) + close(s); + if (s_addr->sa_family == AF_INET) + bb_perror_msg_and_die("%s (%s)", + "cannot connect to remote host", + inet_ntoa(((struct sockaddr_in *)s_addr)->sin_addr)); + bb_perror_msg_and_die("cannot connect to remote host"); + } +} + /* Return port number for a service. * If "port" is a number use it as the port. * If "port" is a name it is looked up in /etc/services, if it isnt found return diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index 108e140..0bee40a 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c @@ -409,6 +409,21 @@ void FAST_FUNC xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind"); } +// Call a user supplied reporting function and die with an error message if we +// can't bind a socket to an address. +void FAST_FUNC xrbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen, + void (*reportf)(int err)) +{ + if (bind(sockfd, my_addr, addrlen)) { + if (reportf) { + int t_errno= errno; + reportf(t_errno); + errno= t_errno; + } + bb_perror_msg_and_die("bind"); + } +} + // Die with an error message if we can't listen for connections on a socket. void FAST_FUNC xlisten(int s, int backlog) { @@ -429,6 +444,47 @@ ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct sock return ret; } +/* Call a user supplied function and die with an error message if sendto failed. + * Return bytes sent otherwise */ +ssize_t FAST_FUNC xrsendto(int s, const void *buf, size_t len, + const struct sockaddr *to, socklen_t tolen, + void (*reportf)(int err)) +{ + ssize_t ret = sendto(s, buf, len, 0, to, tolen); + if (ret < 0) { + if (reportf) { + int t_errno= errno; + reportf(t_errno); + t_errno= errno; + } + if (ENABLE_FEATURE_CLEAN_UP) + close(s); + bb_perror_msg_and_die("sendto"); + } + return ret; +} + +/* Call a user supplied function with an error message if sendto failed. + * Return bytes sent otherwise */ +ssize_t FAST_FUNC rsendto(int s, const void *buf, size_t len, + const struct sockaddr *to, socklen_t tolen, + void (*reportf)(int err)) +{ + ssize_t ret = sendto(s, buf, len, 0, to, tolen); + if (ret < 0) { + int t_errno= errno; + if (reportf) { + reportf(t_errno); + } + if (ENABLE_FEATURE_CLEAN_UP) + close(s); + errno= t_errno; + bb_perror_msg("sendto"); + errno= t_errno; + } + return ret; +} + // xstat() - a stat() which dies on failure with meaningful error message void FAST_FUNC xstat(const char *name, struct stat *stat_buf) { -- cgit v1.2.3