From d05b3ed01ece4ee5429f737c49c7069e475b339c Mon Sep 17 00:00:00 2001
From: Nathan Knotts <nknotts@gmail.com>
Date: Fri, 14 Dec 2018 09:49:52 -0500
Subject: [PATCH] allocate larger password buffer (#361)

---
 src/config.c | 10 +++++-----
 src/config.h |  2 +-
 src/main.c   | 20 +++++++++++++-------
 3 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/src/config.c b/src/config.c
index 1aa168d..a9d4a37 100644
--- a/src/config.c
+++ b/src/config.c
@@ -30,7 +30,7 @@ const struct vpn_config invalid_cfg = {
 	.gateway_host = {'\0'},
 	.gateway_port = 0,
 	.username = {'\0'},
-	.password = {'\0'},
+	.password = NULL,
 	.otp = {'\0'},
 	.realm = {'\0'},
 	.set_routes = -1,
@@ -201,8 +201,7 @@ int load_config(struct vpn_config *cfg, const char *filename)
 			strncpy(cfg->username, val, FIELD_SIZE - 1);
 			cfg->username[FIELD_SIZE] = '\0';
 		} else if (strcmp(key, "password") == 0) {
-			strncpy(cfg->password, val, FIELD_SIZE - 1);
-			cfg->password[FIELD_SIZE] = '\0';
+			cfg->password = strdup(val);
 		} else if (strcmp(key, "otp") == 0) {
 			strncpy(cfg->otp, val, FIELD_SIZE - 1);
 			cfg->otp[FIELD_SIZE] = '\0';
@@ -330,6 +329,7 @@ err_close:
 
 void destroy_vpn_config(struct vpn_config *cfg)
 {
+	free(cfg->password);
 #if HAVE_USR_SBIN_PPPD
 	free(cfg->pppd_log);
 	free(cfg->pppd_plugin);
@@ -359,8 +359,8 @@ void merge_config(struct vpn_config *dst, struct vpn_config *src)
 		dst->gateway_port = src->gateway_port;
 	if (src->username[0])
 		strcpy(dst->username, src->username);
-	if (src->password[0])
-		strcpy(dst->password, src->password);
+	if (src->password != NULL && src->password[0])
+		dst->password = strdup(src->password);
 	if (src->otp[0])
 		strcpy(dst->otp, src->otp);
 	if (src->realm[0])
diff --git a/src/config.h b/src/config.h
index 8ff3b39..35c091f 100644
--- a/src/config.h
+++ b/src/config.h
@@ -64,7 +64,7 @@ struct vpn_config {
 	struct in_addr	gateway_ip;
 	uint16_t	gateway_port;
 	char		username[FIELD_SIZE + 1];
-	char		password[FIELD_SIZE + 1];
+	char		*password;
 	char		otp[FIELD_SIZE + 1];
 	char		realm[FIELD_SIZE + 1];
 
diff --git a/src/main.c b/src/main.c
index 1d60f42..03eecf2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -27,6 +27,9 @@
 #include <string.h>
 #include <limits.h>
 
+#define PWD_BUFSIZ	4096
+
+
 #if HAVE_USR_SBIN_PPPD
 #define PPPD_USAGE \
 "                    [--pppd-no-peerdns] [--pppd-log=<file>]\n" \
@@ -153,7 +156,7 @@ int main(int argc, char **argv)
 		.gateway_host = {'\0'},
 		.gateway_port = 443,
 		.username = {'\0'},
-		.password = {'\0'},
+		.password = NULL,
 		.otp = {'\0'},
 		.realm = {'\0'},
 		.set_routes = 1,
@@ -376,8 +379,7 @@ int main(int argc, char **argv)
 			cli_cfg.username[FIELD_SIZE] = '\0';
 			break;
 		case 'p':
-			strncpy(cli_cfg.password, optarg, FIELD_SIZE);
-			cli_cfg.password[FIELD_SIZE] = '\0';
+			cli_cfg.password = strdup(optarg);
 			break;
 		case 'o':
 			strncpy(cli_cfg.otp, optarg, FIELD_SIZE);
@@ -391,7 +393,7 @@ int main(int argc, char **argv)
 	if (optind < argc - 1 || optind > argc)
 		goto user_error;
 
-	if (cli_cfg.password[0] != '\0')
+	if (cli_cfg.password != NULL && cli_cfg.password[0] != '\0')
 		log_warn("You should not pass the password on the command line. Type it interactively or use a config file instead.\n");
 
 	log_debug("openfortivpn " VERSION "\n", config_file);
@@ -437,9 +439,13 @@ int main(int argc, char **argv)
 		goto user_error;
 	}
 	// If no password given, interactively ask user
-	if (cfg.password[0] == '\0')
-		read_password("VPN account password: ", cfg.password,
-		              FIELD_SIZE);
+	if (cfg.password == NULL || cfg.password[0] == '\0') {
+		free(cfg.password);
+		char *tmp_password = malloc(PWD_BUFSIZ); // allocate large buffer
+		read_password("VPN account password: ", tmp_password, PWD_BUFSIZ);
+		cfg.password = strdup(tmp_password); // copy string of correct size
+		free(tmp_password);
+	}
 	// Check password
 	if (cfg.password[0] == '\0') {
 		log_error("Specify a password.\n");
-- 
GitLab