diff --git a/configure.ac b/configure.ac index 5a8f5771..37c67478 100644 --- a/configure.ac +++ b/configure.ac @@ -226,7 +226,7 @@ AC_CHECK_MEMBER([struct sockaddr.sa_len], AC_CHECK_HEADERS([net/if_tun.h linux/if_tun.h netinet/in_systm.h], [], [], []) -AC_CHECK_FUNCS([setproctitle clock_gettime isatty pselect getpeereid sigaltstack posix_memalign malloc_trim]) +AC_CHECK_FUNCS([setproctitle vasprintf clock_gettime isatty pselect getpeereid sigaltstack posix_memalign malloc_trim]) if [ test -z "$LIBWRAP" ];then libwrap_enabled="no" diff --git a/src/Makefile.am b/src/Makefile.am index a39c1dea..74acda4f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,6 +76,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \ main-sup-config.c main-sup-config.h \ sup-config/file.c sup-config/file.h \ worker-bandwidth.c worker-bandwidth.h ctl.h main-ctl.h \ + vasprintf.c vasprintf.h \ str.c str.h gettime.h $(CCAN_SOURCES) $(HTTP_PARSER_SOURCES) \ $(PROTOBUF_SOURCES) diff --git a/src/str.c b/src/str.c index 025bf442..85789528 100644 --- a/src/str.c +++ b/src/str.c @@ -28,6 +28,7 @@ #include #include #include +#include "vasprintf.h" #define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y)) @@ -127,6 +128,27 @@ int str_append_str(str_st * dest, const char *src) return ret; } +int +str_append_printf(str_st *dest, const char *fmt, ...) +{ + va_list args; + int len; + char *str; + + va_start(args, fmt); + len = vasprintf(&str, fmt, args); + va_end(args); + + if (len < 0 || !str) + return -1; + + len = str_append_str(dest, str); + + free(str); + + return len; +} + int str_replace_str(str_st *str, const char *what, const char *with) { uint8_t *p, *final; diff --git a/src/str.h b/src/str.h index 79808002..aa39c1f0 100644 --- a/src/str.h +++ b/src/str.h @@ -53,6 +53,7 @@ inline static void str_reset(str_st * buf) buf->length = 0; } +int str_append_printf(str_st *dest, const char *fmt, ...); int str_append_str(str_st *, const char *str); int str_replace_str(str_st *, const char *what, const char *with); int str_append_data(str_st *, const void *data, size_t data_size); diff --git a/src/vasprintf.c b/src/vasprintf.c new file mode 100644 index 00000000..0c32ad3d --- /dev/null +++ b/src/vasprintf.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 Nikos Mavrogiannopoulos + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include "vasprintf.h" + +#ifndef HAVE_VASPRINTF + +#define MAX_BSIZE 1024 +#define NO_MORE_MAX (16*MAX_BSIZE) + +int _ocserv_vasprintf(char **strp, const char *fmt, va_list ap) +{ + char *buf; + int ret, max; + + max = MAX_BSIZE / 2; + + do { + max *= 2; + + buf = malloc(max); + if (buf == NULL) + return -1; + + ret = vsnprintf(buf, max, fmt, ap); + } + while (ret > max && max < NO_MORE_MAX); + + return ret; +} + +#endif diff --git a/src/vasprintf.h b/src/vasprintf.h new file mode 100644 index 00000000..ba05cf3c --- /dev/null +++ b/src/vasprintf.h @@ -0,0 +1,13 @@ +#ifndef VASPRINTF_H +#define VASPRINTF_H +#include +#include + +#ifndef HAVE_VASPRINTF + +int _ocserv_vasprintf(char **strp, const char *fmt, va_list ap); +#define vasprintf _ocserv_vasprintf + +#endif + +#endif diff --git a/src/worker-auth.c b/src/worker-auth.c index 16f83328..c23d7727 100644 --- a/src/worker-auth.c +++ b/src/worker-auth.c @@ -60,14 +60,13 @@ static const char ocv3_success_msg_head[] = "\n"; - -static const char oc_login_msg_start[] = - "\n" - "\n" - VERSION_MSG - "\n" - "%s\n" - "
\n"; +#define OC_LOGIN_MSG_START \ + "\n" \ + "\n" \ + VERSION_MSG \ + "\n" \ + "%s\n" \ + "\n" static const char oc_login_msg_end[] = "\n" "
"; @@ -78,11 +77,11 @@ static const char login_msg_user[] = static const char login_msg_password[] = "\n"; -static const char ocv3_login_msg_start[] = - "\n" - "\n" - "%s\n" - "
\n"; +#define OCV3_LOGIN_MSG_START \ + "\n" \ + "\n" \ + "%s\n" \ + "\n" static const char ocv3_login_msg_end[] = "
\n"; @@ -138,17 +137,16 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) { int ret; char context[BASE64_LENGTH(SID_SIZE) + 1]; - char temp[256]; unsigned int i, j; str_st str; const char *login_msg_start; const char *login_msg_end; if (ws->req.user_agent_type == AGENT_OPENCONNECT_V3) { - login_msg_start = ocv3_login_msg_start; + login_msg_start = OCV3_LOGIN_MSG_START; login_msg_end = ocv3_login_msg_end; } else { - login_msg_start = oc_login_msg_start; + login_msg_start = OC_LOGIN_MSG_START; login_msg_end = oc_login_msg_end; } @@ -188,8 +186,7 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) if (pmsg == NULL) pmsg = "Please enter your password."; - snprintf(temp, sizeof(temp), login_msg_start, pmsg); - ret = str_append_str(&str, temp); + ret = str_append_printf(&str, login_msg_start, pmsg); if (ret < 0) { ret = -1; goto cleanup; @@ -209,8 +206,7 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) } else { /* ask for username and groups */ - snprintf(temp, sizeof(temp), login_msg_start, "Please enter your username"); - ret = str_append_str(&str, temp); + ret = str_append_printf(&str, login_msg_start, "Please enter your username"); if (ret < 0) { ret = -1; goto cleanup; @@ -255,8 +251,7 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) } if (ws->config->default_select_group) { - snprintf(temp, sizeof(temp), "\n", ws->config->default_select_group); - ret = str_append_str(&str, temp); + ret = str_append_printf(&str, "\n", ws->config->default_select_group); if (ret < 0) { ret = -1; goto cleanup; @@ -282,8 +277,7 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) if (dup != 0) continue; - snprintf(temp, sizeof(temp), "\n", ws->cert_groups[i]); - ret = str_append_str(&str, temp); + ret = str_append_printf(&str, "\n", ws->cert_groups[i]); if (ret < 0) { ret = -1; goto cleanup;