Hello community,

here is the log from the commit of package openfortivpn for openSUSE:Leap:15.2 
checked in at 2020-03-01 20:32:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/openfortivpn (Old)
 and      /work/SRC/openSUSE:Leap:15.2/.openfortivpn.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openfortivpn"

Sun Mar  1 20:32:02 2020 rev:18 rq:780705 version:1.12.0

Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/openfortivpn/openfortivpn.changes      
2020-01-17 12:01:18.768500684 +0100
+++ /work/SRC/openSUSE:Leap:15.2/.openfortivpn.new.26092/openfortivpn.changes   
2020-03-01 20:32:06.197665050 +0100
@@ -1,0 +2,19 @@
+Thu Feb 27 15:14:15 UTC 2020 - Martin Hauke <[email protected]>
+
+- Update to version 1.12.0
+  * fix CVE-2020-7043: TLS Certificate CommonName NULL Byte
+    Vulnerability
+  * fix CVE-2020-7042: use of uninitialized memory in
+    X509_check_host
+  * fix CVE-2020-7041: incorrect use of X509_check_host
+    (regarding return value).
+  * always hide cleartest password in -vv output
+  * add a clear warning about sensitive information in the debug
+    output
+  * add a hint in debug output when password is read from config
+    file
+  * fix segfault when connecting with empty password
+  * use resolvconf if available to update resolv.conf file
+  * replace semicolon by space in dns-suffix string
+
+-------------------------------------------------------------------

Old:
----
  openfortivpn-1.11.0.tar.gz

New:
----
  openfortivpn-1.12.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ openfortivpn.spec ++++++
--- /var/tmp/diff_new_pack.7R1aqf/_old  2020-03-01 20:32:06.773666255 +0100
+++ /var/tmp/diff_new_pack.7R1aqf/_new  2020-03-01 20:32:06.797666305 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package openfortivpn
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           openfortivpn
-Version:        1.11.0
+Version:        1.12.0
 Release:        0
 Summary:        Client for PPP+SSL VPN tunnel services
 License:        GPL-3.0-or-later

++++++ openfortivpn-1.11.0.tar.gz -> openfortivpn-1.12.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/.github/SECURITY.md 
new/openfortivpn-1.12.0/.github/SECURITY.md
--- old/openfortivpn-1.11.0/.github/SECURITY.md 1970-01-01 01:00:00.000000000 
+0100
+++ new/openfortivpn-1.12.0/.github/SECURITY.md 2020-02-26 17:02:52.000000000 
+0100
@@ -0,0 +1,14 @@
+# Security Policy
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version                 | Supported          |
+| ----------------------- | ------------------ |
+| latest stable release   | :white_check_mark: |
+
+## Reporting a Vulnerability
+
+Send an email to [email protected].
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/CHANGELOG.md 
new/openfortivpn-1.12.0/CHANGELOG.md
--- old/openfortivpn-1.11.0/CHANGELOG.md        2019-11-28 17:08:40.000000000 
+0100
+++ new/openfortivpn-1.12.0/CHANGELOG.md        2020-02-26 17:02:52.000000000 
+0100
@@ -14,6 +14,18 @@
 This high level changelog is usually updated when a release is tagged.
 On the master branch there may be changes that are not (yet) described here.
 
+### 1.12.0
+
+* [-] fix CVE-2020-7043: TLS Certificate CommonName NULL Byte Vulnerability
+* [-] fix CVE-2020-7042: use of uninitialized memory in X509_check_host
+* [-] fix CVE-2020-7041: incorrect use of X509_check_host (regarding return 
value).
+* [-] always hide cleartest password in -vv output
+* [+] add a clear warning about sensitive information in the debug output
+* [+] add a hint in debug output when password is read from config file
+* [-] fix segfault when connecting with empty password
+* [+] use resolvconf if available to update resolv.conf file
+* [~] replace semicolon by space in dns-suffix string
+
 ### 1.11.0
 
 * [+] allow to connect with empty password (and with smartcard instead of 
username)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/Makefile.am 
new/openfortivpn-1.12.0/Makefile.am
--- old/openfortivpn-1.11.0/Makefile.am 2019-11-28 17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/Makefile.am 2020-02-26 17:02:52.000000000 +0100
@@ -5,11 +5,14 @@
                       src/http.c src/http.h src/io.c src/io.h src/ipv4.c \
                       src/ipv4.h src/log.c src/log.h src/tunnel.c \
                       src/tunnel.h src/main.c src/ssl.h src/xml.c \
-                      src/xml.h src/userinput.c src/userinput.h
+                      src/xml.h src/userinput.c src/userinput.h \
+                      src/openssl_hostname_validation.c \
+                      src/openssl_hostname_validation.h
 openfortivpn_CFLAGS = -Wall -pedantic -std=gnu99
 openfortivpn_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" \
                        -DPPP_PATH=\"@PPP_PATH@\" \
-                       -DNETSTAT_PATH=\"@NETSTAT_PATH@\"
+                       -DNETSTAT_PATH=\"@NETSTAT_PATH@\" \
+                       -DRESOLVCONF_PATH=\"@RESOLVCONF_PATH@\"
 
 openfortivpn_CPPFLAGS += $(OPENSSL_CFLAGS) $(LIBSYSTEMD_CFLAGS)
 openfortivpn_LDADD = $(OPENSSL_LIBS) $(LIBSYSTEMD_LIBS)
@@ -26,7 +29,8 @@
                mkdir -p $(DESTDIR)$(sysconfdir)/openfortivpn ; \
                cp -a $(DESTDIR)$(datadir)/config.template \
                         $(DESTDIR)$(sysconfdir)/openfortivpn/config ; \
-       fi
+       sed -i 's/^/# /' $(DESTDIR)$(sysconfdir)/openfortivpn/config ; \
+       fi 
 
 dist_man_MANS = doc/openfortivpn.1
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/README.md 
new/openfortivpn-1.12.0/README.md
--- old/openfortivpn-1.11.0/README.md   2019-11-28 17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/README.md   2020-02-26 17:02:52.000000000 +0100
@@ -86,10 +86,10 @@
 * [openSUSE / SLE](https://software.opensuse.org/package/openfortivpn)
 * [Gentoo](https://packages.gentoo.org/packages/net-vpn/openfortivpn)
 * 
[NixOS](https://github.com/NixOS/nixpkgs/tree/master/pkgs/tools/networking/openfortivpn)
-* [Arch Linux](https://aur.archlinux.org/packages/openfortivpn)
+* [Arch 
Linux](https://www.archlinux.org/packages/community/x86_64/openfortivpn)
 * [Debian (testing)](https://packages.debian.org/buster/openfortivpn)
 * [Ubuntu (bionic and 
later)](https://packages.ubuntu.com/search?keywords=openfortivpn) and 
[pre-bionic (ppa)](https://launchpad.net/~ar-lex/+archive/ubuntu/fortisslvpn)
-* [Solus](https://packages.solus-project.com/unstable/o/openfortivpn/)
+* [Solus](https://dev.getsol.us/source/openfortivpn/)
 
 On macOS both [Homebrew](http://brewformulas.org/Openfortivpn) and
 [MacPorts](https://www.macports.org/ports.php?by=name&substr=openfortivpn)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/configure.ac 
new/openfortivpn-1.12.0/configure.ac
--- old/openfortivpn-1.11.0/configure.ac        2019-11-28 17:08:40.000000000 
+0100
+++ new/openfortivpn-1.12.0/configure.ac        2020-02-26 17:02:52.000000000 
+0100
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.63])
-AC_INIT([openfortivpn], [1.11.0])
+AC_INIT([openfortivpn], [1.12.0])
 AC_CONFIG_SRCDIR([src/main.c])
 AM_INIT_AUTOMAKE([foreign subdir-objects])
 
@@ -226,20 +226,19 @@
        ])
 )
 AS_IF([test "x$with_rt_dst" = "x" ], [
-AC_MSG_CHECKING(whether rtentry is available and has rt_dst )
-AC_TRY_RUN([
+AC_MSG_CHECKING(whether rtentry is available and has rt_dst)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <net/route.h>
 static inline struct sockaddr_in *cast_addr(struct sockaddr *addr)
 {
-       return (struct sockaddr_in *) addr;
+  return (struct sockaddr_in *) addr;
 }
+],[
 struct rtentry route;
-int main() {
-  cast_addr(&(&route)->rt_dst)->sin_family = AF_INET;
-  return (cast_addr(&(&route)->rt_dst)->sin_family == AF_INET) ? 0 : 1; }
-], [
+cast_addr(&(&route)->rt_dst)->sin_family = AF_INET;
+])],[
   AC_DEFINE(HAVE_RT_ENTRY_WITH_RT_DST)
   AC_MSG_RESULT(yes)
 ], AC_MSG_RESULT(no) )
@@ -247,6 +246,7 @@
 
 NETSTAT_PATH=""
 PPP_PATH=""
+RESOLVCONF_PATH=""
 
 # prepare possibility to override default locations
 AC_ARG_WITH([netstat],
@@ -274,6 +274,12 @@
                with_pppd="no"
        ])
 )
+# resolvconf if present
+AC_ARG_WITH([resolvconf],
+        AS_HELP_STRING([--with-resolvconf],
+                       [Set the path to the resolvconf executable]),
+        RESOLVCONF_PATH="$withval"
+)
 
 # override for /proc/net/route detection
 AC_ARG_ENABLE([proc],
@@ -350,6 +356,8 @@
    with_ppp="no"
 ])
 
+AC_PATH_PROG(RESOLVCONF_PATH, [resolvconf], [/sbin/resolvconf], 
"$PATH:/sbin:/usr/sbin")
+
 AS_IF([test "x$with_ppp" = "xyes"], [
        AC_DEFINE(HAVE_USR_SBIN_PPP, 1)
        AC_MSG_NOTICE([HAVE_USR_SBIN_PPP... 1])
@@ -380,5 +388,10 @@
     AC_MSG_NOTICE([NETSTAT_PATH...] $NETSTAT_PATH)
 ])
 
+AC_SUBST(RESOLVCONF_PATH)
+AS_IF([test "x$RESOLVCONF_PATH" != "x" ], [
+    AC_MSG_NOTICE([RESOLVCONF_PATH...] $RESOLVCONF_PATH)
+])
+
 AC_CONFIG_COMMANDS([timestamp], [touch src/.dirstamp])
 AC_OUTPUT(Makefile)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/doc/openfortivpn.1.in 
new/openfortivpn-1.12.0/doc/openfortivpn.1.in
--- old/openfortivpn-1.11.0/doc/openfortivpn.1.in       2019-11-28 
17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/doc/openfortivpn.1.in       2020-02-26 
17:02:52.000000000 +0100
@@ -1,4 +1,4 @@
-.TH OPENFORTIVPN 1 "November 27, 2019" ""
+.TH OPENFORTIVPN 1 "December 11, 2019" ""
 
 .SH NAME
 openfortivpn \- Client for PPP+SSL VPN tunnel services
@@ -92,13 +92,14 @@
 .TP
 \fB\-\-set\-dns=\fI<bool>\fR, \fB\-\-no\-dns\fR
 Set if openfortivpn should add DNS name servers in /etc/resolv.conf when
-tunnel is up. If used multiple times, the last one takes priority.
+tunnel is up. Also a dns\-suffix may be received from the peer and added
+to /etc/resolv.conf in the turn of adding the name servers.
+resolvconf is instructed to do the update of the resolv.conf file
+if it is installed, otherwise openfortivpn prepends its changes
+to the existing content of the resolv.conf file.
 Note that there may be other mechanisms to update /etc/resolv.conf,
 e.g., \fB\-\-pppd\-use\-peerdns\fR in conjunction with an ip-up-script,
 which may require that openfortivpn is called with \fB\-\-no\-dns\fR.
-Also a dns\-suffix may be received from the peer and added to
-/etc/resolv.conf in the turn of adding the name servers.
-
 \fB\-\-no\-dns\fR is the same as \fB\-\-set\-dns=\fI0\fR.
 .TP
 \fB\-\-ca\-file=\fI<file>\fR
@@ -131,8 +132,8 @@
 \fB\-\-trusted\-cert=\fI<digest>\fR
 Trust a given gateway. If classical SSL certificate validation fails, the
 gateway certificate will be matched against this value. \fI<digest>\fR is the
-X509 certificate's sha256 sum. This option can be used multiple times to trust
-several certificates.
+X509 certificate's sha256 sum. The certificate has to be encoded in DER form.
+This option can be used multiple times to trust several certificates.
 .TP
 \fB\-\-insecure\-ssl\fR
 Do not disable insecure SSL protocols/ciphers.
@@ -150,7 +151,8 @@
 .TP
 \fB\-\-use\-peer\-dns=\fI<bool>\fR, \fB\-\-pppd\-no\-peerdns\fR
 Whether to ask peer ppp server for DNS server addresses and let pppd
-rewrite /etc/resolv.conf. If the DNS server addresses are requested,
+rewrite /etc/resolv.conf. There is no mechanism to tell the dns\-suffix
+to pppd. If the DNS server addresses are requested,
 also \fB\-\-set\-dns=\fI1\fR may race with the mechanisms in pppd.
 
 \fB\-\-pppd\-no\-peerdns\fR is the same as \fB\-\-pppd\-use\-peerdns=\fI0\fR.
@@ -264,13 +266,17 @@
 .br
 # otp\-prompt = Please
 .br
+# pinentry = pinentry program
+.br
 user\-cert = @SYSCONFDIR@/openfortivpn/user\-cert.pem
 .br
+# user\-cert = pkcs1: # use smartcard as client certificate
+.br
 user\-key = @SYSCONFDIR@/openfortivpn/user\-key.pem
 .br
 # the sha256 digest of the trusted host certs obtained by
 .br
-# openssl dgst -sha256 server\-cert.pem:
+# openssl dgst -sha256 server\-cert.crt:
 .br
 trusted\-cert = certificatedigest4daa8c5fe6c...
 .br
@@ -315,3 +321,5 @@
 cipher\-list = HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4
 .br
 persistent = 0
+.br
+seclevel-1 = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/etc/openfortivpn/config.template 
new/openfortivpn-1.12.0/etc/openfortivpn/config.template
--- old/openfortivpn-1.11.0/etc/openfortivpn/config.template    2019-11-28 
17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/etc/openfortivpn/config.template    2020-02-26 
17:02:52.000000000 +0100
@@ -1,5 +1,6 @@
-# config file for openfortivpn, see man openfortivpn(1)
-host =
-port =
-username =
-password =
+### config file for openfortivpn, see man openfortivpn(1) ###
+
+host = vpn.example.org
+port = 443
+username = vpnuser
+password = VPNpassw0rd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/src/config.c 
new/openfortivpn-1.12.0/src/config.c
--- old/openfortivpn-1.11.0/src/config.c        2019-11-28 17:08:40.000000000 
+0100
+++ new/openfortivpn-1.12.0/src/config.c        2020-02-26 17:02:52.000000000 
+0100
@@ -108,7 +108,7 @@
        else if (isdigit(str[0]) == 0)
                return -1;
 
-       long int i = strtol(str, NULL, 0);
+       long i = strtol(str, NULL, 0);
        if (i < 0 || i > 1)
                return -1;
        return i;
@@ -122,9 +122,8 @@
  */
 int parse_min_tls(const char *str)
 {
-       if (str[0] != '1' || str[1] != '.' || str[2] == 0 || str[3] != 0) {
+       if (str[0] != '1' || str[1] != '.' || str[2] == 0 || str[3] != 0)
                return -1;
-       }
        switch (str[2]) {
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
        case '0':
@@ -230,8 +229,8 @@
                        strncpy(cfg->gateway_host, val, FIELD_SIZE);
                        cfg->gateway_host[FIELD_SIZE] = '\0';
                } else if (strcmp(key, "port") == 0) {
-                       unsigned long int port = strtoul(val, NULL, 0);
-                       if (port <= 0 || port > 65535) {
+                       unsigned long port = strtoul(val, NULL, 0);
+                       if (port == 0 || port > 65535) {
                                log_warn("Bad port in config file: \"%lu\".\n",
                                         port);
                                continue;
@@ -249,7 +248,7 @@
                        free(cfg->otp_prompt);
                        cfg->otp_prompt = strdup(val);
                } else if (strcmp(key, "otp-delay") == 0) {
-                       long int otp_delay = strtol(val, NULL, 0);
+                       long otp_delay = strtol(val, NULL, 0);
                        if (otp_delay < 0 || otp_delay > UINT_MAX) {
                                log_warn("Bad value for otp-delay in config 
file: \"%s\".\n",
                                         val);
@@ -287,7 +286,7 @@
                        }
                        cfg->half_internet_routes = half_internet_routes;
                } else if (strcmp(key, "persistent") == 0) {
-                       unsigned long int persistent = strtoul(val, NULL, 0);
+                       unsigned long persistent = strtoul(val, NULL, 0);
                        if (persistent > UINT_MAX) {
                                log_warn("Bad value for persistent in config 
file: \"%s\".\n",
                                         val);
@@ -508,9 +507,8 @@
                free(dst->cipher_list);
                dst->cipher_list = src->cipher_list;
        }
-       if (src->min_tls > 0) {
+       if (src->min_tls > 0)
                dst->min_tls = src->min_tls;
-       }
        if (src->seclevel_1 != invalid_cfg.seclevel_1)
                dst->seclevel_1 = src->seclevel_1;
        if (src->cert_whitelist) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/src/http.c 
new/openfortivpn-1.12.0/src/http.c
--- old/openfortivpn-1.11.0/src/http.c  2019-11-28 17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/src/http.c  2020-02-26 17:02:52.000000000 +0100
@@ -76,16 +76,20 @@
        va_start(args, request);
        length = vsnprintf(buffer, BUFSZ, request, args);
        va_end(args);
-       strcpy(logbuffer,buffer);
-       if (loglevel <= OFV_LOG_DEBUG_DETAILS && 
tunnel->config->password[0]!='\0') {
-               char* pwstart;
-               pwstart = strstr(logbuffer, tunnel->config->password);
+       strcpy(logbuffer, buffer);
+       if (loglevel <= OFV_LOG_DEBUG_DETAILS && tunnel->config->password[0] != 
'\0') {
+               char *pwstart;
+               char password[3 * FIELD_SIZE + 1];
+
+               url_encode(password, tunnel->config->password);
+               pwstart = strstr(logbuffer, password);
+
                if (pwstart != NULL) {
                        int pos, pwlen, i;
                        pos = pwstart - logbuffer;
                        pwlen = strlen(tunnel->config->password);
-                       for (i=pos; i<pos+pwlen; i++)
-                               logbuffer[i]='*';
+                       for (i = pos; i < pos + pwlen; i++)
+                               logbuffer[i] = '*';
                }
        }
 
@@ -94,7 +98,7 @@
        else if (length >= BUFSZ)
                return ERR_HTTP_TOO_LONG;
 
-       log_debug_details("%s: \n%s\n", __func__, logbuffer);
+       log_debug_details("%s:\n%s\n", __func__, logbuffer);
 
        while (n == 0)
                n = safe_ssl_write(tunnel->ssl_handle, (uint8_t *) buffer,
@@ -162,7 +166,7 @@
                                  (uint8_t *) buffer + bytes_read,
                                  BUFSZ - 1 - bytes_read);
                if (n > 0) {
-                       log_debug_details("%s: \n%s\n", __func__, buffer);
+                       log_debug_details("%s:\n%s\n", __func__, buffer);
                        const char *eoh;
 
                        bytes_read += n;
@@ -287,15 +291,13 @@
                         uint32_t *response_size
                        )
 {
-       int ret = do_http_request(
-                         tunnel, method, uri, data, response, response_size);
+       int ret = do_http_request(tunnel, method, uri, data,
+                                 response, response_size);
 
        if (ret == ERR_HTTP_SSL) {
                ssl_connect(tunnel);
-               ret = do_http_request(
-                             tunnel, method, uri, data, response,
-                             response_size
-                     );
+               ret = do_http_request(tunnel, method, uri, data,
+                                     response, response_size);
        }
 
        if (ret != 1)
@@ -573,19 +575,20 @@
 
        tunnel->cookie[0] = '\0';
 
-       if (tunnel->config->use_engine) {
+       if (tunnel->config->use_engine
+           || (username[0] == '\0' && tunnel->config->password[0] == '\0')) {
                snprintf(data, sizeof(data), "cert=&nup=1");
                ret = http_request(tunnel, "GET", "/remote/login",
                                   data, &res, &response_size);
        } else {
-               if (tunnel->config->password == '\0') {
-                       snprintf(data, sizeof(data), 
"username=%s&realm=%s&ajax=1"
-                                "&redir=%%2Fremote%%2Findex&just_logged_in=1",
+               if (tunnel->config->password[0] == '\0') {
+                       snprintf(data, sizeof(data),
+                                
"username=%s&realm=%s&ajax=1&redir=%%2Fremote%%2Findex&just_logged_in=1",
                                 username, realm);
                } else {
                        url_encode(password, tunnel->config->password);
-                       snprintf(data, sizeof(data), 
"username=%s&credential=%s&realm=%s&ajax=1"
-                                "&redir=%%2Fremote%%2Findex&just_logged_in=1",
+                       snprintf(data, sizeof(data),
+                                
"username=%s&credential=%s&realm=%s&ajax=1&redir=%%2Fremote%%2Findex&just_logged_in=1",
                                 username, password, realm);
                }
                ret = http_request(tunnel, "POST", "/remote/logincheck",
@@ -650,9 +653,8 @@
                }
 
                url_encode(tokenresponse, cfg->otp);
-               snprintf(data, sizeof(data), "username=%s&realm=%s&reqid=%s"
-                        "&polid=%s&grp=%s&code=%s&code2="
-                        "&redir=%%2Fremote%%2Findex&just_logged_in=1",
+               snprintf(data, sizeof(data),
+                        
"username=%s&realm=%s&reqid=%s&polid=%s&grp=%s&code=%s&code2=&redir=%%2Fremote%%2Findex&just_logged_in=1",
                         username, realm, reqid, polid, group, tokenresponse);
 
                delay_otp(tunnel);
@@ -722,7 +724,7 @@
                if (xml_find(' ', "domain=", val, 1)) {
                        tunnel->ipv4.dns_suffix
                                = xml_get(xml_find(' ', "domain=", val, 1));
-                       log_debug("found dns suffix %s in xml config",
+                       log_debug("found dns suffix %s in xml config\n",
                                  tunnel->ipv4.dns_suffix);
                        break;
                }
@@ -733,7 +735,7 @@
        while ((val = xml_find('<', "dns", val, 2))) {
                if (xml_find(' ', "ip=", val, 1)) {
                        dns_server = xml_get(xml_find(' ', "ip=", val, 1));
-                       log_debug("found dns server %s in xml config", 
dns_server);
+                       log_debug("found dns server %s in xml config\n", 
dns_server);
                        if (!tunnel->ipv4.ns1_addr.s_addr)
                                tunnel->ipv4.ns1_addr.s_addr = 
inet_addr(dns_server);
                        else if (!tunnel->ipv4.ns2_addr.s_addr)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/src/io.c 
new/openfortivpn-1.12.0/src/io.c
--- old/openfortivpn-1.11.0/src/io.c    2019-11-28 17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/src/io.c    2020-02-26 17:02:52.000000000 +0100
@@ -360,16 +360,16 @@
         && pkt_data(packet)[6] == 0x03)
 
 #define packet_is_end_negociation(packet) \
-       ((packet)->len == 6 \
-        && pkt_data(packet)[0] == 0x80 \
-        && pkt_data(packet)[1] == 0x21 \
-        && pkt_data(packet)[2] == 0x01 \
-        && pkt_data(packet)[4] == 0x00 \
-        && pkt_data(packet)[5] == 0x04) || \
-       ((packet)-> len >= 12 \
-        && pkt_data(packet)[0] == 0x80 \
-        && pkt_data(packet)[1] == 0x21 \
-        && pkt_data(packet)[2] == 0x02)
+       (((packet)->len == 6 \
+         && pkt_data(packet)[0] == 0x80 \
+         && pkt_data(packet)[1] == 0x21 \
+         && pkt_data(packet)[2] == 0x01 \
+         && pkt_data(packet)[4] == 0x00 \
+         && pkt_data(packet)[5] == 0x04) || \
+        ((packet)->len >= 12 \
+         && pkt_data(packet)[0] == 0x80 \
+         && pkt_data(packet)[1] == 0x21 \
+         && pkt_data(packet)[2] == 0x02))
 
 static inline void set_tunnel_ips(struct tunnel *tunnel,
                                   struct ppp_packet *packet)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/src/ipv4.c 
new/openfortivpn-1.12.0/src/ipv4.c
--- old/openfortivpn-1.11.0/src/ipv4.c  2019-11-28 17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/src/ipv4.c  2020-02-26 17:02:52.000000000 +0100
@@ -196,7 +196,7 @@
        }
 
 #else
-       FILE *fp;
+       FILE * fp;
        uint32_t total_bytes_read = 0;
 
        char *saveptr3 = NULL;
@@ -317,7 +317,7 @@
 #ifdef RTF_STATIC     // Manually added
        flag_table['S'] = RTF_STATIC & USHRT_MAX;
 #endif
-#ifdef RTF_UP         // Route usable
+#ifdef RTF_UP   // Route usable
        flag_table['U'] = RTF_UP & USHRT_MAX;
 #endif
 #ifdef RTF_WASCLONED  // Route was generated as a result of cloning
@@ -576,7 +576,7 @@
        if (err)
                return err;
 
-       if (rtfound==0) {
+       if (rtfound == 0) {
                // should not occur anymore unless there is no default route
                log_debug("Route not found.\n");
                // at least restore input values
@@ -741,7 +741,7 @@
                log_debug("ip route show %s\n", ipv4_show_route(gtw_rt));
                ipv4_del_route(gtw_rt);
        }
-       sprintf(route_iface(gtw_rt),"!%s",tunnel->ppp_iface);
+       sprintf(route_iface(gtw_rt), "!%s", tunnel->ppp_iface);
        ret = ipv4_get_route(gtw_rt);
        if (ret != 0) {
                log_warn("Could not get route to gateway (%s).\n",
@@ -779,8 +779,8 @@
                            const char *mask, const char *gw)
 {
        size_t l0, l1;
-       const char fmt[] = ",%s/%s/%s";
-       const char trigger[] = "openfortivpn";
+       static const char fmt[] = ",%s/%s/%s";
+       static const char trigger[] = "openfortivpn";
        char **target = &tunnel->config->pppd_ipparam;
        char *ptr;
 
@@ -791,7 +791,8 @@
        log_info("Registering route %s/%s via %s\n", dest, mask, gw);
        l0 = strlen(*target);
        l1 = strlen(fmt) + strlen(dest) + strlen(mask) + strlen(gw) + 1;
-       if ((ptr = realloc(*target, l0 + l1))) {
+       ptr = realloc(*target, l0 + l1);
+       if (ptr) {
                *target = ptr;
                snprintf(*target + l0, l1, fmt, dest, mask, gw);
        } else {
@@ -1006,6 +1007,16 @@
        return 0;
 }
 
+static inline char *replace_char(char *str, char find, char replace)
+{
+       int i;
+
+       for (i = 0; i < strlen(str); i++)
+               if (str[i] == find)
+                       str[i] = replace;
+       return str;
+}
+
 int ipv4_add_nameservers_to_resolv_conf(struct tunnel *tunnel)
 {
        int ret = -1;
@@ -1013,7 +1024,8 @@
        struct stat stat;
        char ns1[28], ns2[28]; // 11 + 15 + 1 + 1
        char dns_suffix[MAX_DOMAIN_LENGTH+8];  // 7 + MAX_DOMAIN_LENGTH + 1
-       char *buffer;
+       char *buffer = NULL;
+       int use_resolvconf = 0;
 
        tunnel->ipv4.ns1_was_there = 0;
        tunnel->ipv4.ns2_was_there = 0;
@@ -1025,40 +1037,68 @@
        if (tunnel->ipv4.ns2_addr.s_addr == 0)
                tunnel->ipv4.ns2_was_there = -1;
 
-       file = fopen("/etc/resolv.conf", "r+");
-       if (file == NULL) {
-               log_warn("Could not open /etc/resolv.conf (%s).\n",
-                        strerror(errno));
-               return 1;
-       }
+       if (access(RESOLVCONF_PATH, F_OK) == 0) {
+               int resolvconf_call_len
+                       = strlen(RESOLVCONF_PATH)
+                         + 20
+                         + strlen(tunnel->ppp_iface);
+               char *resolvconf_call = malloc(resolvconf_call_len);
+               if (resolvconf_call == NULL) {
+                       log_warn("Could not create command to run resolvconf 
(%s).\n",
+                                strerror(errno));
+                       return 1;
+               }
 
-       if (fstat(fileno(file), &stat) == -1) {
-               log_warn("Could not stat /etc/resolv.conf (%s).\n",
-                        strerror(errno));
-               goto err_close;
-       }
+               snprintf(resolvconf_call, resolvconf_call_len,
+                        "%s -a \"%s.openfortivpn\"",
+                        RESOLVCONF_PATH,
+                        tunnel->ppp_iface);
+
+               use_resolvconf = 1;
+               log_debug("resolvconf_call: %s\n", resolvconf_call);
+               file = popen(resolvconf_call, "w");
+               free(resolvconf_call);
+               if (file == NULL) {
+                       log_warn("Could not open pipe %s (%s).\n",
+                                resolvconf_call,
+                                strerror(errno));
+                       return 1;
+               }
+       } else {
+               file = fopen("/etc/resolv.conf", "r+");
+               if (file == NULL) {
+                       log_warn("Could not open /etc/resolv.conf (%s).\n",
+                                strerror(errno));
+                       return 1;
+               }
 
-       if (stat.st_size == 0) {
-               log_warn("Could not read /etc/resolv.conf (%s).\n",
-                        "Empty file");
-               goto err_close;
-       }
+               if (fstat(fileno(file), &stat) == -1) {
+                       log_warn("Could not stat /etc/resolv.conf (%s).\n",
+                                strerror(errno));
+                       goto err_close;
+               }
 
-       buffer = malloc(stat.st_size + 1);
-       if (buffer == NULL) {
-               log_warn("Could not read /etc/resolv.conf (%s).\n",
-                        strerror(errno));
-               goto err_close;
-       }
+               if (stat.st_size == 0) {
+                       log_warn("Could not read /etc/resolv.conf (%s).\n",
+                                "Empty file");
+                       goto err_close;
+               }
 
-       // Copy all file contents at once
-       if (fread(buffer, stat.st_size, 1, file) != 1) {
-               log_warn("Could not read /etc/resolv.conf.\n");
-               goto err_free;
-       }
+               buffer = malloc(stat.st_size + 1);
+               if (buffer == NULL) {
+                       log_warn("Could not read /etc/resolv.conf (%s).\n",
+                                strerror(errno));
+                       goto err_close;
+               }
 
-       buffer[stat.st_size] = '\0';
+               // Copy all file contents at once
+               if (fread(buffer, stat.st_size, 1, file) != 1) {
+                       log_warn("Could not read /etc/resolv.conf.\n");
+                       goto err_free;
+               }
 
+               buffer[stat.st_size] = '\0';
+       }
        if (tunnel->ipv4.ns1_addr.s_addr != 0) {
                strcpy(ns1, "nameserver ");
                strncat(ns1, inet_ntoa(tunnel->ipv4.ns1_addr), 15);
@@ -1076,59 +1116,63 @@
        if (tunnel->ipv4.dns_suffix != NULL) {
                strcpy(dns_suffix, "search ");
                strncat(dns_suffix, tunnel->ipv4.dns_suffix, MAX_DOMAIN_LENGTH);
+               replace_char(dns_suffix, ';', ' ');
        } else {
                dns_suffix[0] = '\0';
        }
 
-       for (const char *line = strtok(buffer, "\n");
-            line != NULL;
-            line = strtok(NULL, "\n")) {
-               if (strcmp(line, ns1) == 0) {
-                       tunnel->ipv4.ns1_was_there = 1;
-                       log_debug("ns1 already present in /etc/resolv.conf.\n");
-               }
-       }
-
-       if (tunnel->ipv4.ns1_was_there == 0)
-               log_debug("Adding \"%s\", to /etc/resolv.conf.\n", ns1);
-
-       for (const char *line = strtok(buffer, "\n");
-            line != NULL;
-            line = strtok(NULL, "\n")) {
-               if (strcmp(line, ns2) == 0) {
-                       tunnel->ipv4.ns2_was_there = 1;
-                       log_debug("ns2 already present in /etc/resolv.conf.\n");
+       if (use_resolvconf == 0) {
+               for (const char *line = strtok(buffer, "\n");
+                    line != NULL;
+                    line = strtok(NULL, "\n")) {
+                       if (strcmp(line, ns1) == 0) {
+                               tunnel->ipv4.ns1_was_there = 1;
+                               log_debug("ns1 already present in 
/etc/resolv.conf.\n");
+                       }
                }
-       }
 
-       if (tunnel->ipv4.ns2_was_there == 0)
-               log_debug("Adding \"%s\", to /etc/resolv.conf.\n", ns2);
+               if (tunnel->ipv4.ns1_was_there == 0)
+                       log_debug("Adding \"%s\", to /etc/resolv.conf.\n", ns1);
 
-       if (dns_suffix[0] == '\0') {
-               tunnel->ipv4.dns_suffix_was_there = -1;
-       } else {
                for (const char *line = strtok(buffer, "\n");
                     line != NULL;
                     line = strtok(NULL, "\n")) {
-                       if (dns_suffix[0] != '\0' && strcmp(line, dns_suffix) 
== 0) {
-                               tunnel->ipv4.dns_suffix_was_there = 1;
-                               log_debug("dns_suffix already present in 
/etc/resolv.conf.\n");
+                       if (strcmp(line, ns2) == 0) {
+                               tunnel->ipv4.ns2_was_there = 1;
+                               log_debug("ns2 already present in 
/etc/resolv.conf.\n");
                        }
                }
-       }
 
-       if (tunnel->ipv4.dns_suffix_was_there == 0)
-               log_debug("Adding \"%s\", to /etc/resolv.conf.\n", dns_suffix);
+               if (tunnel->ipv4.ns2_was_there == 0)
+                       log_debug("Adding \"%s\", to /etc/resolv.conf.\n", ns2);
 
-       rewind(file);
-       if (fread(buffer, stat.st_size, 1, file) != 1) {
-               log_warn("Could not read /etc/resolv.conf.\n");
-               goto err_free;
-       }
+               if (dns_suffix[0] == '\0') {
+                       tunnel->ipv4.dns_suffix_was_there = -1;
+               } else {
+                       for (const char *line = strtok(buffer, "\n");
+                            line != NULL;
+                            line = strtok(NULL, "\n")) {
+                               if (dns_suffix[0] != '\0'
+                                   && strcmp(line, dns_suffix) == 0) {
+                                       tunnel->ipv4.dns_suffix_was_there = 1;
+                                       log_debug("dns_suffix already present 
in /etc/resolv.conf.\n");
+                               }
+                       }
+               }
 
-       buffer[stat.st_size] = '\0';
+               if (tunnel->ipv4.dns_suffix_was_there == 0)
+                       log_debug("Adding \"%s\", to /etc/resolv.conf.\n", 
dns_suffix);
 
-       rewind(file);
+               rewind(file);
+               if (fread(buffer, stat.st_size, 1, file) != 1) {
+                       log_warn("Could not read /etc/resolv.conf.\n");
+                       goto err_free;
+               }
+
+               buffer[stat.st_size] = '\0';
+
+               rewind(file);
+       }
        if (tunnel->ipv4.ns1_was_there == 0) {
                strcat(ns1, "\n");
                fputs(ns1, file);
@@ -1141,14 +1185,18 @@
                strcat(dns_suffix, "\n");
                fputs(dns_suffix, file);
        }
-       fwrite(buffer, stat.st_size, 1, file);
+       if (use_resolvconf == 0)
+               fwrite(buffer, stat.st_size, 1, file);
 
        ret = 0;
 
 err_free:
        free(buffer);
 err_close:
-       fclose(file);
+       if (use_resolvconf == 0)
+               fclose(file);
+       else
+               pclose(file);
 
        return ret;
 }
@@ -1160,7 +1208,35 @@
        struct stat stat;
        char ns1[27], ns2[27]; // 11 + 15 + 1
        char dns_suffix[MAX_DOMAIN_LENGTH+8];  // 7 + MAX_DOMAIN_LENGTH + 1
-       char *buffer;
+       char *buffer = NULL;
+
+
+       if (access(RESOLVCONF_PATH, F_OK) == 0) {
+               int resolvconf_call_len
+                       = strlen(RESOLVCONF_PATH)
+                         + 20
+                         + strlen(tunnel->ppp_iface);
+               char *resolvconf_call = malloc(resolvconf_call_len);
+               if (resolvconf_call == NULL) {
+                       log_warn("Could not create command to run resolvconf 
(%s).\n",
+                                strerror(errno));
+                       return ERR_IPV4_SEE_ERRNO;
+               }
+
+               snprintf(resolvconf_call,
+                        resolvconf_call_len,
+                        "%s -d \"%s.openfortivpn\"",
+                        RESOLVCONF_PATH,
+                        tunnel->ppp_iface
+                       );
+
+               log_debug("resolvconf_call: %s\n", resolvconf_call);
+               ret = system(resolvconf_call);
+               free(resolvconf_call);
+               if (ret == -1)
+                       return ERR_IPV4_SEE_ERRNO;
+               return 0;
+       }
 
        file = fopen("/etc/resolv.conf", "r+");
        if (file == NULL) {
@@ -1190,18 +1266,18 @@
 
        buffer[stat.st_size] = '\0';
 
-       ns1[0]='\0';
+       ns1[0] = '\0';
        if (tunnel->ipv4.ns1_addr.s_addr != 0) {
                strcpy(ns1, "nameserver ");
                strncat(ns1, inet_ntoa(tunnel->ipv4.ns1_addr), 15);
        }
-       ns2[0]='\0';
+       ns2[0] = '\0';
        if (tunnel->ipv4.ns2_addr.s_addr != 0) {
                strcpy(ns2, "nameserver ");
                strncat(ns2, inet_ntoa(tunnel->ipv4.ns2_addr), 15);
        }
-       dns_suffix[0]='\0';
-       if (tunnel->ipv4.dns_suffix != NULL && 
tunnel->ipv4.dns_suffix[0]!='\0') {
+       dns_suffix[0] = '\0';
+       if (tunnel->ipv4.dns_suffix != NULL && tunnel->ipv4.dns_suffix[0] != 
'\0') {
                strcpy(dns_suffix, "search ");
                strncat(dns_suffix, tunnel->ipv4.dns_suffix, MAX_DOMAIN_LENGTH);
        }
@@ -1216,13 +1292,13 @@
        for (const char *line = strtok(buffer, "\n");
             line != NULL;
             line = strtok(NULL, "\n")) {
-               if (ns1[0]!='\0' && strcmp(line, ns1) == 0
+               if (ns1[0] != '\0' && strcmp(line, ns1) == 0
                    && (tunnel->ipv4.ns1_was_there == 0)) {
                        log_debug("Deleting \"%s\" from /etc/resolv.conf.\n", 
ns1);
-               } else if (ns2[0]!='\0' && strcmp(line, ns2) == 0
+               } else if (ns2[0] != '\0' && strcmp(line, ns2) == 0
                           && (tunnel->ipv4.ns2_was_there == 0)) {
                        log_debug("Deleting \"%s\" from /etc/resolv.conf.\n", 
ns2);
-               } else if (dns_suffix[0]!='\0' && strcmp(line, dns_suffix) == 0
+               } else if (dns_suffix[0] != '\0' && strcmp(line, dns_suffix) == 0
                           && (tunnel->ipv4.dns_suffix_was_there == 0)) {
                        log_debug("Deleting \"%s\" from /etc/resolv.conf.\n", 
dns_suffix);
                } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/src/main.c 
new/openfortivpn-1.12.0/src/main.c
--- old/openfortivpn-1.11.0/src/main.c  2019-11-28 17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/src/main.c  2020-02-26 17:02:52.000000000 +0100
@@ -99,17 +99,17 @@
 "  -p <pass>, --password=<pass>  VPN account password.\n" \
 "  -o <otp>, --otp=<otp>         One-Time-Password.\n" \
 "  --otp-prompt=<prompt>         Search for the OTP prompt starting with this 
string\n" \
-"  --otp-delay=<delay>          Wait <delay> seconds before sending the 
OTP.\n" \
+"  --otp-delay=<delay>           Wait <delay> seconds before sending the 
OTP.\n" \
 "  --pinentry=<program>          Use the program to supply a secret instead of 
asking for it\n" \
-"  --realm=<realm>               Use specified authentication realm on VPN 
gateway\n" \
+"  --realm=<realm>               Use specified authentication realm.\n" \
+"  --set-routes=[01]             Set if openfortivpn should configure 
routes\n" \
 "                                when tunnel is up.\n" \
-"  --set-routes=[01]             Set if openfortivpn should configure output 
routes through\n" \
-"                                the VPN when tunnel is up.\n" \
 "  --no-routes                   Do not configure routes, same as 
--set-routes=0.\n" \
 "  --half-internet-routes=[01]   Add two 0.0.0.0/1 and 128.0.0.0/1 routes with 
higher\n" \
 "                                priority instead of replacing the default 
route.\n" \
-"  --set-dns=[01]                Set if openfortivpn should add DNS name 
servers \n" \
-"                                and domain seach list in /etc/resolv.conf.\n" 
\
+"  --set-dns=[01]                Set if openfortivpn should add DNS name 
servers\n" \
+"                                and domain search list in 
/etc/resolv.conf.\n" \
+"                                If installed resolvconf is used for the 
update.\n" \
 "  --no-dns                      Do not reconfigure DNS, same as 
--set-dns=0\n" \
 "  --ca-file=<file>              Use specified PEM-encoded certificate 
bundle\n" \
 "                                instead of system-wide store to verify the 
gateway\n" \
@@ -407,7 +407,7 @@
                        }
                        if (strcmp(long_options[option_index].name,
                                   "otp-delay") == 0) {
-                               long int otp_delay = strtol(optarg, NULL, 0);
+                               long otp_delay = strtol(optarg, NULL, 0);
                                if (otp_delay < 0 || otp_delay > UINT_MAX) {
                                        log_warn("Bad otp-delay option: 
\"%s\"\n",
                                                 optarg);
@@ -418,7 +418,7 @@
                        }
                        if (strcmp(long_options[option_index].name,
                                   "persistent") == 0) {
-                               long int persistent = strtol(optarg, NULL, 0);
+                               long persistent = strtol(optarg, NULL, 0);
                                if (persistent < 0 || persistent > UINT_MAX) {
                                        log_warn("Bad persistent option: 
\"%s\"\n",
                                                 optarg);
@@ -474,6 +474,8 @@
        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_all("ATTENTION: the output contains sensitive information 
such as the THE CLEAR TEXT PASSWORD.\n");
+
        log_debug("openfortivpn " VERSION "\n");
 
        // Load config file
@@ -485,6 +487,14 @@
                        log_warn("Could not load config file \"%s\" (%s).\n",
                                 config_file, err_cfg_str(ret));
        }
+       if (cfg.password != NULL && cli_cfg.password == NULL) {
+               if (cfg.password[0] == '\0')
+                       log_debug("Disabled password due to empty entry in 
config file \"%s\"\n",
+                                 config_file);
+               else
+                       log_debug("Loaded password from config file \"%s\"\n",
+                                 config_file);
+       }
        // Then apply CLI config
        merge_config(&cfg, &cli_cfg);
        set_syslog(cfg.use_syslog);
@@ -497,7 +507,7 @@
                        port_str[0] = '\0';
                        port_str++;
                        cfg.gateway_port = strtol(port_str, NULL, 0);
-                       if (cfg.gateway_port <= 0 || cfg.gateway_port > 65535) {
+                       if (cfg.gateway_port == 0 || cfg.gateway_port > 65535) {
                                log_error("Specify a valid port.\n");
                                goto user_error;
                        }
@@ -512,12 +522,12 @@
                goto user_error;
        }
        // Check username
-       if (cfg.username[0] == '\0' && cfg.use_engine != 1) {
-               log_error("Specify an username.\n");
+       if (cfg.username[0] == '\0' && cfg.user_cert == NULL) {
+               log_error("Specify a username.\n");
                goto user_error;
        }
        // If username but no password given, interactively ask user
-       if (cfg.password == NULL && cfg.username[0] != '\0' ) {
+       if (cfg.password == NULL && cfg.username[0] != '\0') {
                char *tmp_password = malloc(PWD_BUFSIZ); // allocate large 
buffer
                read_password(cfg.pinentry, "password",
                              "VPN account password: ", tmp_password, 
PWD_BUFSIZ);
@@ -531,6 +541,8 @@
                log_debug("Config username = \"%s\"\n", cfg.username);
        if (cfg.password != NULL)
                log_debug_all("Config password = \"%s\"\n", cfg.password);
+       else
+               cfg.password = strdup("");
        if (cfg.otp[0] != '\0')
                log_debug("One-time password = \"%s\"\n", cfg.otp);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openfortivpn-1.11.0/src/openssl_hostname_validation.c 
new/openfortivpn-1.12.0/src/openssl_hostname_validation.c
--- old/openfortivpn-1.11.0/src/openssl_hostname_validation.c   1970-01-01 
01:00:00.000000000 +0100
+++ new/openfortivpn-1.12.0/src/openssl_hostname_validation.c   2020-02-26 
17:02:52.000000000 +0100
@@ -0,0 +1,165 @@
+/* Obtained from: https://github.com/iSECPartners/ssl-conservatory */
+
+/*
+ * Helper functions to perform basic hostname validation using OpenSSL.
+ *
+ * Author:  Alban Diquet
+ *
+ * Copyright (C) 2012, iSEC Partners.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a 
copy of
+ * this software and associated documentation files (the "Software"), to deal 
in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
copies
+ * of the Software, and to permit persons to whom the Software is furnished to 
do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in 
all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ */
+ 
+
+#include <strings.h>
+#include <openssl/x509v3.h>
+#include <openssl/ssl.h>
+
+#define HOSTNAME_MAX_SIZE 255
+
+#ifndef HAVE_X509_CHECK_HOST
+
+#include "openssl_hostname_validation.h"
+
+
+/**
+* Tries to find a match for hostname in the certificate's Common Name field.
+*
+* Returns MatchFound if a match was found.
+* Returns MatchNotFound if no matches were found.
+* Returns MalformedCertificate if the Common Name had a NUL character embedded 
in it.
+* Returns Error if the Common Name could not be extracted.
+*/
+static HostnameValidationResult matches_common_name(const char *hostname, 
const X509 *server_cert) {
+       int common_name_loc = -1;
+       X509_NAME_ENTRY *common_name_entry = NULL;
+       ASN1_STRING *common_name_asn1 = NULL;
+       char *common_name_str = NULL;
+
+       // Find the position of the CN field in the Subject field of the 
certificate
+       common_name_loc = 
X509_NAME_get_index_by_NID(X509_get_subject_name((X509 *) server_cert), 
NID_commonName, -1);
+       if (common_name_loc < 0) {
+               return Error;
+       }
+
+       // Extract the CN field
+       common_name_entry = X509_NAME_get_entry(X509_get_subject_name((X509 *) 
server_cert), common_name_loc);
+       if (common_name_entry == NULL) {
+               return Error;
+       }
+
+       // Convert the CN field to a C string
+       common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);
+       if (common_name_asn1 == NULL) {
+               return Error;
+       }                       
+       common_name_str = (char *) ASN1_STRING_data(common_name_asn1);
+
+       // Make sure there isn't an embedded NUL character in the CN
+       if (ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) {
+               return MalformedCertificate;
+       }
+
+       // Compare expected hostname with the CN
+       if (strcasecmp(hostname, common_name_str) == 0) {
+               return MatchFound;
+       }
+       else {
+               return MatchNotFound;
+       }
+}
+
+
+/**
+* Tries to find a match for hostname in the certificate's Subject Alternative 
Name extension.
+*
+* Returns MatchFound if a match was found.
+* Returns MatchNotFound if no matches were found.
+* Returns MalformedCertificate if any of the hostnames had a NUL character 
embedded in it.
+* Returns NoSANPresent if the SAN extension was not present in the certificate.
+*/
+static HostnameValidationResult matches_subject_alternative_name(const char 
*hostname, const X509 *server_cert) {
+       HostnameValidationResult result = MatchNotFound;
+       int i;
+       int san_names_nb = -1;
+       STACK_OF(GENERAL_NAME) *san_names = NULL;
+
+       // Try to extract the names within the SAN extension from the 
certificate
+       san_names = X509_get_ext_d2i((X509 *) server_cert, 
NID_subject_alt_name, NULL, NULL);
+       if (san_names == NULL) {
+               return NoSANPresent;
+       }
+       san_names_nb = sk_GENERAL_NAME_num(san_names);
+
+       // Check each name within the extension
+       for (i=0; i<san_names_nb; i++) {
+               const GENERAL_NAME *current_name = 
sk_GENERAL_NAME_value(san_names, i);
+
+               if (current_name->type == GEN_DNS) {
+                       // Current name is a DNS name, let's check it
+                       char *dns_name = (char *) 
ASN1_STRING_data(current_name->d.dNSName);
+
+                       // Make sure there isn't an embedded NUL character in 
the DNS name
+                       if (ASN1_STRING_length(current_name->d.dNSName) != 
strlen(dns_name)) {
+                               result = MalformedCertificate;
+                               break;
+                       }
+                       else { // Compare expected hostname with the DNS name
+                               if (strcasecmp(hostname, dns_name) == 0) {
+                                       result = MatchFound;
+                                       break;
+                               }
+                       }
+               }
+       }
+       sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
+
+       return result;
+}
+
+
+/**
+* Validates the server's identity by looking for the expected hostname in the
+* server's certificate. As described in RFC 6125, it first tries to find a 
match
+* in the Subject Alternative Name extension. If the extension is not present in
+* the certificate, it checks the Common Name instead.
+*
+* Returns MatchFound if a match was found.
+* Returns MatchNotFound if no matches were found.
+* Returns MalformedCertificate if any of the hostnames had a NUL character 
embedded in it.
+* Returns Error if there was an error.
+*/
+HostnameValidationResult validate_hostname(const char *hostname, const X509 
*server_cert) {
+       HostnameValidationResult result;
+
+       if((hostname == NULL) || (server_cert == NULL))
+               return Error;
+
+       // First try the Subject Alternative Names extension
+       result = matches_subject_alternative_name(hostname, server_cert);
+       if (result == NoSANPresent) {
+               // Extension was not found: try the Common Name
+               result = matches_common_name(hostname, server_cert);
+       }
+
+       return result;
+}
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openfortivpn-1.11.0/src/openssl_hostname_validation.h 
new/openfortivpn-1.12.0/src/openssl_hostname_validation.h
--- old/openfortivpn-1.11.0/src/openssl_hostname_validation.h   1970-01-01 
01:00:00.000000000 +0100
+++ new/openfortivpn-1.12.0/src/openssl_hostname_validation.h   2020-02-26 
17:02:52.000000000 +0100
@@ -0,0 +1,53 @@
+/* Obtained from: https://github.com/iSECPartners/ssl-conservatory */
+
+/*
+ * Helper functions to perform basic hostname validation using OpenSSL.
+ *
+ * Author:  Alban Diquet
+ *
+ * Copyright (C) 2012, iSEC Partners.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a 
copy of
+ * this software and associated documentation files (the "Software"), to deal 
in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
copies
+ * of the Software, and to permit persons to whom the Software is furnished to 
do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in 
all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef HAVE_X509_CHECK_HOST
+ 
+typedef enum {
+       MatchFound,
+       MatchNotFound,
+       NoSANPresent,
+       MalformedCertificate,
+       Error
+} HostnameValidationResult;
+
+/**
+* Validates the server's identity by looking for the expected hostname in the
+* server's certificate. As described in RFC 6125, it first tries to find a 
match
+* in the Subject Alternative Name extension. If the extension is not present in
+* the certificate, it checks the Common Name instead.
+*
+* Returns MatchFound if a match was found.
+* Returns MatchNotFound if no matches were found.
+* Returns MalformedCertificate if any of the hostnames had a NUL character 
embedded in it.
+* Returns Error if there was an error.
+*/
+HostnameValidationResult validate_hostname(const char *hostname, const X509 
*server_cert);
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/src/tunnel.c 
new/openfortivpn-1.12.0/src/tunnel.c
--- old/openfortivpn-1.11.0/src/tunnel.c        2019-11-28 17:08:40.000000000 
+0100
+++ new/openfortivpn-1.12.0/src/tunnel.c        2020-02-26 17:02:52.000000000 
+0100
@@ -29,6 +29,9 @@
 #include "tunnel.h"
 #include "http.h"
 #include "log.h"
+#ifndef HAVE_X509_CHECK_HOST
+#include "openssl_hostname_validation.h"
+#endif
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -61,8 +64,8 @@
 #endif
 
 struct ofv_varr {
-       unsigned cap;           // current capacity
-       unsigned off;           // next slot to write, always < max(cap - 1, 1)
+       unsigned int cap;       // current capacity
+       unsigned int off;       // next slot to write, always < max(cap - 1, 1)
        const char **data;      // NULL terminated
 };
 
@@ -70,9 +73,9 @@
 {
        if (p->off + 1 >= p->cap) {
                const char **ndata;
-               unsigned ncap = (p->off + 1) * 2;
+               unsigned int ncap = (p->off + 1) * 2;
                if (p->off + 1 >= ncap) {
-                       log_error("ofv_append_varr: ncap exceeded\n");
+                       log_error("%s: ncap exceeded\n", __func__);
                        return 1;
                };
                ndata = realloc(p->data, ncap * sizeof(const char *));
@@ -85,17 +88,16 @@
                }
        }
        if (p->data == NULL) {
-               log_error("ofv_append_varr: NULL data\n");
+               log_error("%s: NULL data\n", __func__);
                return 1;
        }
-       if (p->off + 1 < p->cap) {
-               p->data[p->off] = x;
-               p->data[++p->off] = NULL;
-               return 0;
-       } else {
-               log_error("ofv_append_varr: cap exceeded in p\n");
+       if (p->off + 1 >= p->cap) {
+               log_error("%s: cap exceeded in p\n", __func__);
                return 1;
        }
+       p->data[p->off] = x;
+       p->data[++p->off] = NULL;
+       return 0;
 }
 
 static int on_ppp_if_up(struct tunnel *tunnel)
@@ -109,9 +111,8 @@
 
                ret = ipv4_set_tunnel_routes(tunnel);
 
-               if (ret != 0) {
+               if (ret != 0)
                        log_warn("Adding route table is incomplete. Please 
check route table.\n");
-               }
        }
 
        if (tunnel->config->set_dns) {
@@ -193,11 +194,11 @@
                 * e.g. the name of the configuration or options
                 * to send interactively to ppp will be added later
                 */
-               const char *v[] = {
+               static const char *const v[] = {
                        ppp_path,
                        "-direct"
                };
-               for (unsigned i = 0; i < ARRAY_SIZE(v); i++)
+               for (unsigned int i = 0; i < ARRAY_SIZE(v); i++)
                        if (ofv_append_varr(&pppd_args, v[i]))
                                return 1;
 #endif
@@ -210,7 +211,7 @@
                        if (ofv_append_varr(&pppd_args, 
tunnel->config->pppd_call))
                                return 1;
                } else {
-                       const char *v[] = {
+                       static const char *const v[] = {
                                ppp_path,
                                "115200", // speed
                                ":192.0.2.1", // 
<local_IP_address>:<remote_IP_address>
@@ -225,7 +226,7 @@
                                "lcp-max-configure", "40",
                                "mru", "1354"
                        };
-                       for (unsigned i = 0; i < ARRAY_SIZE(v); i++)
+                       for (unsigned int i = 0; i < ARRAY_SIZE(v); i++)
                                if (ofv_append_varr(&pppd_args, v[i]))
                                        return 1;
                }
@@ -408,12 +409,12 @@
                            (tunnel->config->pppd_ifname
                             && strstr(ifa->ifa_name, 
tunnel->config->pppd_ifname)
                             != NULL)
-                           || strstr(ifa->ifa_name, "ppp") != NULL)
+                           || strstr(ifa->ifa_name, "ppp") != NULL
 #endif
 #if HAVE_USR_SBIN_PPP
-                   strstr(ifa->ifa_name, "tun") != NULL)
+                           strstr(ifa->ifa_name, "tun") != NULL
 #endif
-                       && ifa->ifa_flags& IFF_UP) {
+                   ) && ifa->ifa_flags & IFF_UP) {
                        if (&(ifa->ifa_addr->sa_family) != NULL
                            && ifa->ifa_addr->sa_family == AF_INET) {
                                struct in_addr if_ip_addr =
@@ -589,7 +590,7 @@
                        }
 
                        // detect "200"
-                       const char HTTP_STATUS_200[] = "200";
+                       static const char HTTP_STATUS_200[] = "200";
                        response = strstr(request, HTTP_STATUS_200);
 
                        // detect end-of-line after "200"
@@ -611,7 +612,7 @@
                                 *      recognize a single LF as a line 
terminator
                                 *      and ignore the leading CR.
                                 */
-                               static const char *HTTP_EOL[] = {
+                               static const char *const HTTP_EOL[] = {
                                        "\r\n\r\n",
                                        "\n\n"
                                };
@@ -654,7 +655,6 @@
        char *line;
        int i;
        X509_NAME *subj;
-       char common_name[FIELD_SIZE + 1];
 
        SSL_set_verify(tunnel->ssl_handle, SSL_VERIFY_PEER, NULL);
 
@@ -668,16 +668,15 @@
 
 #ifdef HAVE_X509_CHECK_HOST
        // Use OpenSSL native host validation if v >= 1.0.2.
-       if (X509_check_host(cert, common_name, FIELD_SIZE, 0, NULL))
+       // compare against gateway_host and correctly check return value
+       // to fix piror Incorrect use of X509_check_host
+       if (X509_check_host(cert, tunnel->config->gateway_host,
+                           0, 0, NULL) == 1)
                cert_valid = 1;
 #else
-       // Use explicit Common Name check if native validation not available.
-       // Note: this will ignore Subject Alternative Name fields.
-       if (subj
-           && X509_NAME_get_text_by_NID(subj, NID_commonName, common_name,
-                                        FIELD_SIZE) > 0
-           && strncasecmp(common_name, tunnel->config->gateway_host,
-                          FIELD_SIZE) == 0)
+       // Use validate_hostname form iSECPartners if native validation not 
available
+       // in order to avoid TLS Certificate CommonName NULL Byte Vulnerability
+       if (validate_hostname(tunnel->config->gateway_host, cert) == MatchFound)
                cert_valid = 1;
 #endif
 
@@ -831,8 +830,8 @@
                        return 1;
                }
 
-               EVP_PKEY *privkey = ENGINE_load_private_key(
-                                           e, parms.uri, UI_OpenSSL(), NULL);
+               EVP_PKEY * privkey = ENGINE_load_private_key(
+                                            e, parms.uri, UI_OpenSSL(), NULL);
                if (!privkey) {
                        log_error("PKCS11 ENGINE_load_private_key: %s\n",
                                  ERR_error_string(ERR_peek_last_error(), 
NULL));
@@ -905,17 +904,15 @@
                if (!tunnel->config->cipher_list) {
                        const char *cipher_list;
                        if (tunnel->config->seclevel_1)
-                               cipher_list = 
"HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4"
-                                             "@SECLEVEL=1";
+                               cipher_list = 
"HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4@SECLEVEL=1";
                        else
                                cipher_list = 
"HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4";
                        tunnel->config->cipher_list = strdup(cipher_list);
                }
        } else {
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
-               if (tunnel->config->min_tls <= 0) {
+               if (tunnel->config->min_tls <= 0)
                        tunnel->config->min_tls = TLS1_VERSION;
-               }
 #endif
                if (!tunnel->config->cipher_list && tunnel->config->seclevel_1) 
{
                        const char *cipher_list = "DEFAULT@SECLEVEL=1";
@@ -924,7 +921,7 @@
        }
 
        if (tunnel->config->cipher_list) {
-               log_debug("Setting cipher list to: %s", 
tunnel->config->cipher_list);
+               log_debug("Setting cipher list to: %s\n", 
tunnel->config->cipher_list);
                if (!SSL_set_cipher_list(tunnel->ssl_handle,
                                         tunnel->config->cipher_list)) {
                        log_error("SSL_set_cipher_list failed: %s\n",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/src/tunnel.h 
new/openfortivpn-1.12.0/src/tunnel.h
--- old/openfortivpn-1.11.0/src/tunnel.h        2019-11-28 17:08:40.000000000 
+0100
+++ new/openfortivpn-1.12.0/src/tunnel.h        2020-02-26 17:02:52.000000000 
+0100
@@ -75,8 +75,8 @@
 
        struct ipv4_config ipv4;
 
-       int (*on_ppp_if_up)(struct tunnel *);
-       int (*on_ppp_if_down)(struct tunnel *);
+       int (*on_ppp_if_up)(struct tunnel *tunnel);
+       int (*on_ppp_if_down)(struct tunnel *tunnel);
 };
 
 struct token {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/tests/lint/astyle.sh 
new/openfortivpn-1.12.0/tests/lint/astyle.sh
--- old/openfortivpn-1.11.0/tests/lint/astyle.sh        2019-11-28 
17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/tests/lint/astyle.sh        2020-02-26 
17:02:52.000000000 +0100
@@ -2,7 +2,7 @@
 # Copyright (C) 2015 Adrien Vergé
 
 # Check that astyle is installed
-if ! which astyle &>/dev/null; then
+if ! command -v astyle &>/dev/null; then
   echo "error: astyle is not installed" >&2
   exit -1
 fi
@@ -17,15 +17,15 @@
     --indent=tab=8 \
     --pad-header \
     --align-reference=type \
-    <"$file" >$tmp
+    <"$file" >"$tmp"
 
-  if ! cmp -s "$file" $tmp; then
-    echo "error: $file does not comply with coding style"
-    git --no-pager diff --no-index -U0 "$file" $tmp
+  if ! cmp -s "$file" "$tmp"; then
+    echo "error: $file does not comply with coding style" >&2
+    git --no-pager diff --no-index -U0 "$file" "$tmp"
     rc=1
   fi
 
-  rm $tmp
+  rm "$tmp"
 done
 
 exit $rc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/tests/lint/eol-at-eof.sh 
new/openfortivpn-1.12.0/tests/lint/eol-at-eof.sh
--- old/openfortivpn-1.11.0/tests/lint/eol-at-eof.sh    2019-11-28 
17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/tests/lint/eol-at-eof.sh    2020-02-26 
17:02:52.000000000 +0100
@@ -5,12 +5,12 @@
 
 for file in "$@"; do
   if [ "$(sed -n '$p' "$file")" = "" ]; then
-    echo "$file: too many newlines at end of file"
+    echo "$file: too many newlines at end of file" >&2
     rc=1
   fi
 
   if [ "$(tail -c 1 "$file")" != "" ]; then
-    echo "$file: no newline at end of file"
+    echo "$file: no newline at end of file" >&2
     rc=1
   fi
 done
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/tests/lint/line-length.py 
new/openfortivpn-1.12.0/tests/lint/line-length.py
--- old/openfortivpn-1.11.0/tests/lint/line-length.py   2019-11-28 
17:08:40.000000000 +0100
+++ new/openfortivpn-1.12.0/tests/lint/line-length.py   1970-01-01 
01:00:00.000000000 +0100
@@ -1,53 +0,0 @@
-#!/usr/bin/python3
-# -*- coding: utf-8 -*-
-# Copyright (C) 2015 Adrien Vergé
-
-import sys
-
-# Guidelines say 80, let's tolerate a bit more
-MAX = 90
-
-
-def endswithstring(line):
-    """Detect lines from C source code ending with a string.
-
-    Parameters
-    ----------
-    line : str
-        Line of C source code.
-
-    Returns
-    -------
-    bool
-        True if line ends with string, False otherwise.
-
-    """
-    for end in ('"', '",', '");', '" \\'):
-        if line.endswith(end):
-            return True
-    return False
-
-
-def main():
-    exit_status = 0
-
-    for arg in sys.argv[1:]:
-        with open(arg, "r") as source_file:
-            for i, line in enumerate(source_file):
-                line = line.rstrip()
-                # Lines that end with a string are exempted
-                if endswithstring(line):
-                    continue
-                # Replace tabs with 8 spaces
-                line = line.replace("\t", "        ")
-                # Lines longer than MAX are reported as an error
-                if len(line) > MAX:
-                    print("{}: {}: line too long ({} characters)"
-                          .format(arg, i, len(line)))
-                    exit_status = 1
-
-    sys.exit(exit_status)
-
-
-if __name__ == "__main__":
-    main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/tests/lint/line_length.py 
new/openfortivpn-1.12.0/tests/lint/line_length.py
--- old/openfortivpn-1.11.0/tests/lint/line_length.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/openfortivpn-1.12.0/tests/lint/line_length.py   2020-02-26 
17:02:52.000000000 +0100
@@ -0,0 +1,53 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+# Copyright (C) 2015 Adrien Vergé
+
+import sys
+
+# Guidelines say 80, let's tolerate a bit more
+MAX = 90
+
+
+def endswithstring(line):
+    """Detect lines from C source code ending with a string.
+
+    Parameters
+    ----------
+    line : str
+        Line of C source code.
+
+    Returns
+    -------
+    bool
+        True if line ends with string, False otherwise.
+
+    """
+    for end in ('"', '",', '");', '";', '" \\'):
+        if line.endswith(end):
+            return True
+    return False
+
+
+def main():
+    exit_status = 0
+
+    for arg in sys.argv[1:]:
+        with open(arg, "r") as source_file:
+            for i, line in enumerate(source_file):
+                line = line.rstrip()
+                # Lines that end with a string are exempted
+                if endswithstring(line):
+                    continue
+                # Replace tabs with 8 spaces
+                line = line.replace("\t", "        ")
+                # Lines longer than MAX are reported as an error
+                if len(line) > MAX:
+                    print("{}: {}: line too long ({} characters)"
+                          .format(arg, i, len(line)))
+                    exit_status = 1
+
+    sys.exit(exit_status)
+
+
+if __name__ == "__main__":
+    main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openfortivpn-1.11.0/tests/lint/run.sh 
new/openfortivpn-1.12.0/tests/lint/run.sh
--- old/openfortivpn-1.11.0/tests/lint/run.sh   2019-11-28 17:08:40.000000000 
+0100
+++ new/openfortivpn-1.12.0/tests/lint/run.sh   2020-02-26 17:02:52.000000000 
+0100
@@ -3,13 +3,10 @@
 
 rc=0
 
-bash tests/lint/eol-at-eof.sh $(git ls-files)
-[ $? -ne 0 ] && rc=1
+./tests/lint/eol-at-eof.sh $(git ls-files | grep -v 
openssl_hostname_validation) || rc=1
 
-python3 tests/lint/line-length.py $(git ls-files '*.[ch]')
-[ $? -ne 0 ] && rc=1
+./tests/lint/line_length.py $(git ls-files '*.[ch]' | grep -v 
openssl_hostname_validation) || rc=1
 
-bash tests/lint/astyle.sh $(git ls-files '*.[ch]')
-[ $? -ne 0 ] && rc=1
+./tests/lint/astyle.sh $(git ls-files '*.[ch]' | grep -v 
openssl_hostname_validation) || rc=1
 
 exit $rc


Reply via email to