[PATCH] chg: add --version-string and optional detailed platform info

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



and there is, of course, a typo. if needed i'll send the entire thing
again. let me know.

@@ -1506,7 +1506,7 @@ int main(int argc, char **argv)
                           - sudo -E openconnect ....
                         */

-                       if (!strcmp(config_arg, "linux-64") ||
!strcmp(os, "mac-intel")) {
+                       if (!strcmp(config_arg, "linux-64") ||
!strcmp(config_arg, "mac-intel")) {
                                vpn_progress(vpninfo, PRG_INFO,
_("providing device info\n"));

On Sat, Sep 8, 2018 at 2:58 PM <rschmied at janus.inka.de> wrote:
>
> [ ok, sending plain text without wrapping long lines seems to be harder
> than it should be. sorry for the additional list submission]
>
> I've included a patch that provides better compatibility with CSD on
> ASA head ends. E.g. it allows to specify the version string that is
> presented to the ASA. Previous to this patch, OC presents it's own
> version e.g. 0.7.8 but that could cause rejection on the head end if
> it looks for a matching AC version string.
>
> It also contains a change that allows to even control more of the
> client system data that is passed in the XML during authentication.
> This part is entirely optional but might help to provide better
> compatibility going forward.
>
> The patch works for me... especially the version-string seems to be
> important in some environments to allow a successful connection, the
> XML changes using the mobile_info struct might be seen as experimental
> / optional.
>
>
>
> Thanks,
> -ralph
>
>
>
> Signed-off-by: Ralph Schmieder <ralph.schmieder at gmail.com>
> ---
>  auth.c                 | 12 ++++++--
>  cstp.c                 |  2 +-
>  env.sh                 | 60 ++++++++++++++++++++++++++++++++++++++
>  http.c                 | 10 +++++++
>  library.c              |  5 +++-
>  main.c                 | 65 +++++++++++++++++++++++++++++++++++++++++-
>  openconnect-internal.h |  3 ++
>  openconnect.8.in       | 23 +++++++++++++++
>  openconnect.h          |  3 +-
>  9 files changed, 177 insertions(+), 6 deletions(-)
>  create mode 100644 env.sh
>
> diff --git a/auth.c b/auth.c
> index 5883988..1236f3f 100644
> --- a/auth.c
> +++ b/auth.c
> @@ -705,7 +705,7 @@ static xmlDocPtr xmlpost_new_query(struct openconnect_info *vpninfo, const char
>                                    xmlNodePtr *rootp)
>  {
>         xmlDocPtr doc;
> -       xmlNodePtr root, node;
> +       xmlNodePtr root, node, child;
>
>         doc = xmlNewDoc(XCAST("1.0"));
>         if (!doc)
> @@ -720,7 +720,7 @@ static xmlDocPtr xmlpost_new_query(struct openconnect_info *vpninfo, const char
>                 goto bad;
>         xmlDocSetRootElement(doc, root);
>
> -       node = xmlNewTextChild(root, NULL, XCAST("version"), XCAST(openconnect_version_str));
> +       node = xmlNewTextChild(root, NULL, XCAST("version"), XCAST(vpninfo->version_string));
>         if (!node)
>                 goto bad;
>         if (!xmlNewProp(node, XCAST("who"), XCAST("vpn")))
> @@ -734,6 +734,14 @@ static xmlDocPtr xmlpost_new_query(struct openconnect_info *vpninfo, const char
>                     !xmlNewProp(node, XCAST("device-type"), XCAST(vpninfo->mobile_device_type)) ||
>                     !xmlNewProp(node, XCAST("unique-id"), XCAST(vpninfo->mobile_device_uniqueid)))
>                         goto bad;
> +               if (vpninfo->mobile_mac_address) {
> +                       node = xmlNewTextChild(root, NULL, XCAST("mac-address-list"), NULL);
> +                       if (!node)
> +                               goto bad;
> +                       child = xmlNewTextChild(node, NULL, XCAST("mac-address"), XCAST(vpninfo->mobile_mac_address));
> +                       if (!child)
> +                               goto bad;
> +               }
>         }
>
>         return doc;
> diff --git a/cstp.c b/cstp.c
> index 68c3d51..625c414 100644
> --- a/cstp.c
> +++ b/cstp.c
> @@ -179,7 +179,7 @@ static void append_mobile_headers(struct openconnect_info *vpninfo, struct oc_te
>  {
>         if (vpninfo->mobile_platform_version) {
>                 buf_append(buf, "X-AnyConnect-Identifier-ClientVersion: %s\r\n",
> -                          openconnect_version_str);
> +                          vpninfo->version_string);
>                 buf_append(buf, "X-AnyConnect-Identifier-Platform: %s\r\n",
>                            vpninfo->platname);
>                 buf_append(buf, "X-AnyConnect-Identifier-PlatformVersion: %s\r\n",
> diff --git a/env.sh b/env.sh
> new file mode 100644
> index 0000000..17faea0
> --- /dev/null
> +++ b/env.sh
> @@ -0,0 +1,60 @@
> +#
> +# This is entirely optional to provide better compatibility as
> +# this information may show in the ASA head-end output or can
> +# be used for CSD evaluation (e.g. if the wrong information is
> +# presented, the head-end may deny the connection).
> +#
> +# Source this script (provide password for 'sudo dmidecode')
> +# provide -E to sudo when launching openconnect to make sure
> +# the environment is preserved:
> +#
> +# The script obviously relies on some Linux tools to provide
> +# actual information. However, the variables could also be
> +# statically provided when pretending to be something else.
> +#
> +# Example:
> +#
> +# OC_DEVICE_TYPE="VMware, Inc. VMware Virtual Platform"
> +# OC_PLATFORM_VERSION="Linux 4.10.0-42-generic #46~16.04.1-Ubuntu SMP Mon Dec 4 15:57:59 UTC 2017 x86_64"
> +# OC_UNIQUE_ID="A1C043E19F166410ABC2C2BDC8C376DA4F7F03513FBE1DCB3A066F22C65C12B6"
> +# OC_MAC_ADDRESS="00-0c-29-0c-0e-57"
> +#
> +# - source env.sh
> +# - sudo -E openconnect ....
> +#
> +#set -x
> +
> +# get system information from DMI
> +DMI=$(sudo dmidecode | grep -A8 'System Information')
> +
> +# extract stuff we're interested in
> +MANUFACTURER=$(echo "$DMI" | grep 'Manufacturer' | cut -d: -f2)
> +PRODUCT=$(echo "$DMI" | grep 'Product Name' | cut -d: -f2)
> +SERIAL=$(echo "$DMI" | grep 'Serial Number' | cut -d: -f2)
> +UUID=$(echo "$DMI" | grep 'UUID' | cut -d: -f2)
> +
> +# synthesize / acquire device information
> +OC_DEVICE_TYPE="${MANUFACTURER## } ${PRODUCT## }"
> +OC_PLATFORM_VERSION=$(uname -srvp)
> +OC_UNIQUE_ID=$(echo $UUID$SERIAL | openssl sha256 | sed 's/^.* //' | tr [[:lower:]] [[:upper:]])
> +
> +# get the device that has the default route
> +GW_DEV=$(ip route | sed -nr '/^default/s/.* dev ([[:alnum:]]+) .*$/\1/p')
> +
> +# does it exist and is it different from tun?
> +# (if tunnel is running it potentially has the default route)
> +# if not, set it to all-zeroes
> +if [[ -n ${GW_DEV} && ! "${GW_DEV}" =~ ^tun[0-9]+$ ]]; then
> +       OC_MAC_ADDRESS=$(ip link show dev ${GW_DEV} | \
> +       sed -nr '2s/^.*ether (([0-9a-f]{2}(:?)){6}) .*$/\1/p' | \
> +       tr ':' '-')
> +else
> +       OC_MAC_ADDRESS="00-00-00-00-00-00"
> +fi
> +
> +# export the information used by OpenConnect
> +export OC_DEVICE_TYPE
> +export OC_PLATFORM_VERSION
> +export OC_UNIQUE_ID
> +export OC_MAC_ADDRESS
> +
> diff --git a/http.c b/http.c
> index 7ff3bf7..397141c 100644
> --- a/http.c
> +++ b/http.c
> @@ -1001,6 +1001,16 @@ char *openconnect_create_useragent(const char *base)
>         return uagent;
>  }
>
> +char *openconnect_create_version_string(void)
> +{
> +       char *version;
> +
> +       if (asprintf(&version, "%s", openconnect_version_str) < 0)
> +               return NULL;
> +
> +       return version;
> +}
> +
>  static int proxy_gets(struct openconnect_info *vpninfo, char *buf, size_t len)
>  {
>         int i = 0;
> diff --git a/library.c b/library.c
> index 3d13499..b26d938 100644
> --- a/library.c
> +++ b/library.c
> @@ -78,6 +78,7 @@ struct openconnect_info *openconnect_vpninfo_new(const char *useragent,
>         vpninfo->max_qlen = 10;
>         vpninfo->localname = strdup("localhost");
>         vpninfo->useragent = openconnect_create_useragent(useragent);
> +       vpninfo->version_string = openconnect_create_version_string();
>         vpninfo->validate_peer_cert = validate_peer_cert;
>         vpninfo->write_new_config = write_new_config;
>         vpninfo->process_auth_form = process_auth_form;
> @@ -276,11 +277,13 @@ int openconnect_set_reported_os(struct openconnect_info *vpninfo,
>  int openconnect_set_mobile_info(struct openconnect_info *vpninfo,
>                                 const char *mobile_platform_version,
>                                 const char *mobile_device_type,
> -                               const char *mobile_device_uniqueid)
> +                               const char *mobile_device_uniqueid,
> +                               const char *mobile_mac_address)
>  {
>         STRDUP(vpninfo->mobile_platform_version, mobile_platform_version);
>         STRDUP(vpninfo->mobile_device_type, mobile_device_type);
>         STRDUP(vpninfo->mobile_device_uniqueid, mobile_device_uniqueid);
> +       STRDUP(vpninfo->mobile_mac_address, mobile_mac_address);
>
>         return 0;
>  }
> diff --git a/main.c b/main.c
> index 379cf5d..1a95d49 100644
> --- a/main.c
> +++ b/main.c
> @@ -188,6 +188,7 @@ enum {
>         OPT_LOCAL_HOSTNAME,
>         OPT_PROTOCOL,
>         OPT_PASSTOS,
> +       OPT_VERSION,
>  };
>
>  #ifdef __sun__
> @@ -253,6 +254,7 @@ static const struct option long_options[] = {
>         OPTION("resolve", 1, OPT_RESOLVE),
>         OPTION("key-password-from-fsid", 0, OPT_KEY_PASSWORD_FROM_FSID),
>         OPTION("useragent", 1, OPT_USERAGENT),
> +       OPTION("version-string", 1, OPT_VERSION),
>         OPTION("local-hostname", 1, OPT_LOCAL_HOSTNAME),
>         OPTION("disable-ipv6", 0, OPT_DISABLE_IPV6),
>         OPTION("no-proxy", 0, OPT_NO_PROXY),
> @@ -875,6 +877,8 @@ static void usage(void)
>         printf("      --useragent=STRING          %s\n", _("HTTP header User-Agent: field"));
>         printf("      --local-hostname=STRING     %s\n", _("Local hostname to advertise to server"));
>         printf("      --os=STRING                 %s\n", _("OS type (linux,linux-64,win,...) to report"));
> +    printf("      --version-string=STRING     %s\n", _("reported version string during authentication"));
> +    printf("                                  (%s %s)\n", _("default:"), openconnect_version_str);
>
>  #ifndef _WIN32
>         printf("\n%s:\n", _("Trojan binary (CSD) execution"));
> @@ -1416,6 +1420,10 @@ int main(int argc, char **argv)
>                         free(vpninfo->useragent);
>                         vpninfo->useragent = dup_config_arg();
>                         break;
> +               case OPT_VERSION:
> +                       free(vpninfo->version_string);
> +                       vpninfo->version_string = dup_config_arg();
> +                       break;
>                 case OPT_LOCAL_HOSTNAME:
>                         openconnect_set_localname(vpninfo, config_arg);
>                         break;
> @@ -1454,7 +1462,62 @@ int main(int argc, char **argv)
>                                 openconnect_set_mobile_info(vpninfo,
>                                         xstrdup("1.0"),
>                                         dup_config_arg(),
> -                                       xstrdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
> +                                       xstrdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
> +                                       NULL);
> +                       }
> +
> +                       /* This is ONLY applied for linux-64 and mac-intel, but could be used for
> +                          other platforms, too.
> +
> +                          Read env variables for device information provided during authentication
> +                          this includes:
> +
> +                          - device type (from 'dmidecode'), e.g. 'VMware, Inc. VMware Virtual Platform'
> +                          - platform version (from 'uname -srvp'), e.g.
> +                           'Linux 3.19.0-61-generic #69~14.04.1-Ubuntu SMP Thu Jun 9 09:09:13 UTC 2016 x86_64'
> +                          - uuid (some 32 byte hex value)
> +                          - MAC address list (use first MAC address from interface which has default gateway)
> +
> +                          Sample output in <device-id> and <mac-address> elements:
> +                          (shortened and line-wrapped for readability)
> +
> +                               <?xml version="1.0" encoding="UTF-8"?>
> +                               <config-auth client="vpn" type="auth-reply">
> +                                       <version who="vpn">v7.07-lalala</version>
> +                                       <device-id device-type="VMware, Inc. VMware Virtual Platform"
> +                                         platform-version="Linux 3.19.0-61-generic #69~14.04.1-Ubuntu
> +                                         SMP Thu Jun 9 09:09:13 UTC 2016 x86_64"
> +                                         unique-id="AB92EE073BD690CA94A89E2...984701EEB1CC7C4C9666D5">
> +                                         linux-64
> +                                       </device-id>
> +                                       <mac-address-list>
> +                                               <mac-address>00-0c-29-1a-ee-36</mac-address>
> +                                       </mac-address-list>
> +                                       [...]
> +                               </config-auth>
> +
> +                          This is entirely optional to provide better compatibility as this information may show
> +                          in the ASA head-end output or can be used for CSD evaluation.
> +
> +                          sample script provided (env.sh), source script (provide password for 'sudo dmidecode')
> +                          provide -E to sudo to make sure environment is preserved
> +
> +                          - source env.sh
> +                          - sudo -E openconnect ....
> +                        */
> +
> +                       if (!strcmp(config_arg, "linux-64") || !strcmp(os, "mac-intel")) {
> +                               vpn_progress(vpninfo, PRG_INFO, _("providing device info\n"));
> +                               vpn_progress(vpninfo, PRG_INFO, _("OC_PLATFORM_VERSION [%s]\n"), getenv("OC_PLATFORM_VERSION"));
> +                               vpn_progress(vpninfo, PRG_INFO, _("OC_DEVICE_TYPE [%s]\n"), getenv("OC_DEVICE_TYPE"));
> +                               vpn_progress(vpninfo, PRG_INFO, _("OC_UNIQUE_ID [%s]\n"), getenv("OC_UNIQUE_ID"));
> +                               vpn_progress(vpninfo, PRG_INFO, _("OC_MAC_ADDRESS [%s]\n"), getenv("OC_MAC_ADDRESS"));
> +
> +                               openconnect_set_mobile_info(vpninfo,
> +                                       xstrdup(getenv("OC_PLATFORM_VERSION")),
> +                                       xstrdup(getenv("OC_DEVICE_TYPE")),
> +                                       xstrdup(getenv("OC_UNIQUE_ID")),
> +                                       xstrdup(getenv("OC_MAC_ADDRESS")));
>                         }
>                         break;
>                 case OPT_PASSTOS:
> diff --git a/openconnect-internal.h b/openconnect-internal.h
> index 729d301..766f76e 100644
> --- a/openconnect-internal.h
> +++ b/openconnect-internal.h
> @@ -389,6 +389,7 @@ struct openconnect_info {
>         char *mobile_platform_version;
>         char *mobile_device_type;
>         char *mobile_device_uniqueid;
> +       char *mobile_mac_address;
>         char *csd_token;
>         char *csd_ticket;
>         char *csd_stuburl;
> @@ -640,6 +641,7 @@ struct openconnect_info {
>
>         int is_dyndns; /* Attempt to redo DNS lookup on each CSTP reconnect */
>         char *useragent;
> +       char *version_string;  /* userdefined openconnect_version_str */
>
>         const char *quit_reason;
>
> @@ -1044,6 +1046,7 @@ void buf_append_xmlescaped(struct oc_text_buf *buf, const char *str);
>  int buf_error(struct oc_text_buf *buf);
>  int buf_free(struct oc_text_buf *buf);
>  char *openconnect_create_useragent(const char *base);
> +char *openconnect_create_version_string(void);
>  int process_proxy(struct openconnect_info *vpninfo, int ssl_sock);
>  int internal_parse_url(const char *url, char **res_proto, char **res_host,
>                        int *res_port, char **res_path, int default_port);
> diff --git a/openconnect.8.in b/openconnect.8.in
> index 1951183..1b19495 100644
> --- a/openconnect.8.in
> +++ b/openconnect.8.in
> @@ -64,6 +64,7 @@ openconnect \- Multi-protocol VPN client, for Cisco AnyConnect VPNs and others
>  .OP \-\-resolve host:ip
>  .OP \-\-servercert sha1
>  .OP \-\-useragent string
> +.OP \-\-version\-string string
>  .OP \-\-local-hostname string
>  .OP \-\-os string
>  .B [https://]\fIserver\fB[:\fIport\fB][/\fIgroup\fB]
> @@ -504,6 +505,12 @@ Use
>  as 'User\-Agent:' field value in HTTP header.
>  (e.g. \-\-useragent 'Cisco AnyConnect VPN Agent for Windows 2.2.0133')
>  .TP
> +.B \-\-version\-string=STRING
> +Use
> +.I STRING
> +as the software version reported to the head end.
> +(e.g. \-\-version\-string '2.2.0133')
> +.TP
>  .B \-\-local-hostname=STRING
>  Use
>  .I STRING
> @@ -523,6 +530,22 @@ applied to the VPN session.  If the gateway requires CSD, it will also cause
>  the corresponding CSD trojan binary to be downloaded, so you may need to use
>  .B \-\-csd\-wrapper
>  if this code is not executable on the local machine.
> +.SH ENVIRONMENT
> +When the following environment variables are present, their information is
> +sent during authentication to the head-end. This is entirely optional and
> +may provide better compatibility when CSD is in use.
> +.TP
> +.B OC_DEVICE_TYPE
> +the device type of the client, e.g. "VMware, Inc. VMware Virtual Platform"
> +.TP
> +.B OC_PLATFORM_VERSION
> +the exact version of the client's operating system, e.g. "Linux 4.10.0-42-generic #46~16.04.1-Ubuntu SMP Mon Dec 4 15:57:59 UTC 2017 x86_64"
> +.TP
> +.B OC_UNIQUE_ID
> +a unique 64 hex char long ID string representing the client, e.g. "A1C043E19F166410[...]DA4FCB3A066F22C65C12B6"
> +.TP
> +.B OC_MAC_ADDRESS
> +a MAC address identifying the client, e.g. "00-0c-29-0c-0e-57"
>  .SH SIGNALS
>  In the data phase of the connection, the following signals are handled:
>  .TP
> diff --git a/openconnect.h b/openconnect.h
> index 74a5124..43a4984 100644
> --- a/openconnect.h
> +++ b/openconnect.h
> @@ -509,7 +509,8 @@ int openconnect_set_reported_os(struct openconnect_info *, const char *os);
>  int openconnect_set_mobile_info(struct openconnect_info *vpninfo,
>                                 const char *mobile_platform_version,
>                                 const char *mobile_device_type,
> -                               const char *mobile_device_uniqueid);
> +                               const char *mobile_device_uniqueid,
> +                               const char *mobile_mac_address);
>  int openconnect_set_client_cert(struct openconnect_info *, const char *cert,
>                                 const char *sslkey);
>  const char *openconnect_get_ifname(struct openconnect_info *);
> --
> 2.18.0
>
>
> _______________________________________________
> openconnect-devel mailing list
> openconnect-devel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/openconnect-devel



-- 
Ralph Schmieder
Holtzstr. 2
76135 Karlsruhe
Germany
ralph.schmieder at gmail.com



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux