Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ssl2.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ssl2.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ssl2.h	(working copy)
@@ -0,0 +1,265 @@
+/* ssl/ssl2.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL2_H
+# define HEADER_SSL2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Protocol Version Codes */
+# define SSL2_VERSION            0x0002
+# define SSL2_VERSION_MAJOR      0x00
+# define SSL2_VERSION_MINOR      0x02
+/* #define SSL2_CLIENT_VERSION  0x0002 */
+/* #define SSL2_SERVER_VERSION  0x0002 */
+
+/* Protocol Message Codes */
+# define SSL2_MT_ERROR                   0
+# define SSL2_MT_CLIENT_HELLO            1
+# define SSL2_MT_CLIENT_MASTER_KEY       2
+# define SSL2_MT_CLIENT_FINISHED         3
+# define SSL2_MT_SERVER_HELLO            4
+# define SSL2_MT_SERVER_VERIFY           5
+# define SSL2_MT_SERVER_FINISHED         6
+# define SSL2_MT_REQUEST_CERTIFICATE     7
+# define SSL2_MT_CLIENT_CERTIFICATE      8
+
+/* Error Message Codes */
+# define SSL2_PE_UNDEFINED_ERROR         0x0000
+# define SSL2_PE_NO_CIPHER               0x0001
+# define SSL2_PE_NO_CERTIFICATE          0x0002
+# define SSL2_PE_BAD_CERTIFICATE         0x0004
+# define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
+
+/* Cipher Kind Values */
+# define SSL2_CK_NULL_WITH_MD5                   0x02000000/* v3 */
+# define SSL2_CK_RC4_128_WITH_MD5                0x02010080
+# define SSL2_CK_RC4_128_EXPORT40_WITH_MD5       0x02020080
+# define SSL2_CK_RC2_128_CBC_WITH_MD5            0x02030080
+# define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5   0x02040080
+# define SSL2_CK_IDEA_128_CBC_WITH_MD5           0x02050080
+# define SSL2_CK_DES_64_CBC_WITH_MD5             0x02060040
+# define SSL2_CK_DES_64_CBC_WITH_SHA             0x02060140/* v3 */
+# define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5       0x020700c0
+# define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA       0x020701c0/* v3 */
+# define SSL2_CK_RC4_64_WITH_MD5                 0x02080080/* MS hack */
+
+# define SSL2_CK_DES_64_CFB64_WITH_MD5_1         0x02ff0800/* SSLeay */
+# define SSL2_CK_NULL                            0x02ff0810/* SSLeay */
+
+# define SSL2_TXT_DES_64_CFB64_WITH_MD5_1        "DES-CFB-M1"
+# define SSL2_TXT_NULL_WITH_MD5                  "NULL-MD5"
+# define SSL2_TXT_RC4_128_WITH_MD5               "RC4-MD5"
+# define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5      "EXP-RC4-MD5"
+# define SSL2_TXT_RC2_128_CBC_WITH_MD5           "RC2-CBC-MD5"
+# define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5  "EXP-RC2-CBC-MD5"
+# define SSL2_TXT_IDEA_128_CBC_WITH_MD5          "IDEA-CBC-MD5"
+# define SSL2_TXT_DES_64_CBC_WITH_MD5            "DES-CBC-MD5"
+# define SSL2_TXT_DES_64_CBC_WITH_SHA            "DES-CBC-SHA"
+# define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5      "DES-CBC3-MD5"
+# define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA      "DES-CBC3-SHA"
+# define SSL2_TXT_RC4_64_WITH_MD5                "RC4-64-MD5"
+
+# define SSL2_TXT_NULL                           "NULL"
+
+/* Flags for the SSL_CIPHER.algorithm2 field */
+# define SSL2_CF_5_BYTE_ENC                      0x01
+# define SSL2_CF_8_BYTE_ENC                      0x02
+
+/* Certificate Type Codes */
+# define SSL2_CT_X509_CERTIFICATE                0x01
+
+/* Authentication Type Code */
+# define SSL2_AT_MD5_WITH_RSA_ENCRYPTION         0x01
+
+# define SSL2_MAX_SSL_SESSION_ID_LENGTH          32
+
+/* Upper/Lower Bounds */
+# define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS      256
+# ifdef OPENSSL_SYS_MPE
+#  define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER    29998u
+# else
+#  define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER    32767u
+                                                       /* 2^15-1 */
+# endif
+# define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER    16383/* 2^14-1 */
+
+# define SSL2_CHALLENGE_LENGTH   16
+/*
+ * #define SSL2_CHALLENGE_LENGTH 32
+ */
+# define SSL2_MIN_CHALLENGE_LENGTH       16
+# define SSL2_MAX_CHALLENGE_LENGTH       32
+# define SSL2_CONNECTION_ID_LENGTH       16
+# define SSL2_MAX_CONNECTION_ID_LENGTH   16
+# define SSL2_SSL_SESSION_ID_LENGTH      16
+# define SSL2_MAX_CERT_CHALLENGE_LENGTH  32
+# define SSL2_MIN_CERT_CHALLENGE_LENGTH  16
+# define SSL2_MAX_KEY_MATERIAL_LENGTH    24
+
+# ifndef HEADER_SSL_LOCL_H
+#  define  CERT           char
+# endif
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+typedef struct ssl2_state_st {
+    int three_byte_header;
+    int clear_text;             /* clear text */
+    int escape;                 /* not used in SSLv2 */
+    int ssl2_rollback;          /* used if SSLv23 rolled back to SSLv2 */
+    /*
+     * non-blocking io info, used to make sure the same args were passwd
+     */
+    unsigned int wnum;          /* number of bytes sent so far */
+    int wpend_tot;
+    const unsigned char *wpend_buf;
+    int wpend_off;              /* offset to data to write */
+    int wpend_len;              /* number of bytes passwd to write */
+    int wpend_ret;              /* number of bytes to return to caller */
+    /* buffer raw data */
+    int rbuf_left;
+    int rbuf_offs;
+    unsigned char *rbuf;
+    unsigned char *wbuf;
+    unsigned char *write_ptr;   /* used to point to the start due to 2/3 byte
+                                 * header. */
+    unsigned int padding;
+    unsigned int rlength;       /* passed to ssl2_enc */
+    int ract_data_length;       /* Set when things are encrypted. */
+    unsigned int wlength;       /* passed to ssl2_enc */
+    int wact_data_length;       /* Set when things are decrypted. */
+    unsigned char *ract_data;
+    unsigned char *wact_data;
+    unsigned char *mac_data;
+    unsigned char *read_key;
+    unsigned char *write_key;
+    /* Stuff specifically to do with this SSL session */
+    unsigned int challenge_length;
+    unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH];
+    unsigned int conn_id_length;
+    unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
+    unsigned int key_material_length;
+    unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH * 2];
+    unsigned long read_sequence;
+    unsigned long write_sequence;
+    struct {
+        unsigned int conn_id_length;
+        unsigned int cert_type;
+        unsigned int cert_length;
+        unsigned int csl;
+        unsigned int clear;
+        unsigned int enc;
+        unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH];
+        unsigned int cipher_spec_length;
+        unsigned int session_id_length;
+        unsigned int clen;
+        unsigned int rlen;
+    } tmp;
+} SSL2_STATE;
+
+# endif
+
+/* SSLv2 */
+/* client */
+# define SSL2_ST_SEND_CLIENT_HELLO_A             (0x10|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_HELLO_B             (0x11|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_HELLO_A              (0x20|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_HELLO_B              (0x21|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_MASTER_KEY_A        (0x30|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_MASTER_KEY_B        (0x31|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_FINISHED_A          (0x40|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_FINISHED_B          (0x41|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_CERTIFICATE_A       (0x50|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_CERTIFICATE_B       (0x51|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_CERTIFICATE_C       (0x52|SSL_ST_CONNECT)
+# define SSL2_ST_SEND_CLIENT_CERTIFICATE_D       (0x53|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_VERIFY_A             (0x60|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_VERIFY_B             (0x61|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_FINISHED_A           (0x70|SSL_ST_CONNECT)
+# define SSL2_ST_GET_SERVER_FINISHED_B           (0x71|SSL_ST_CONNECT)
+# define SSL2_ST_CLIENT_START_ENCRYPTION         (0x80|SSL_ST_CONNECT)
+# define SSL2_ST_X509_GET_CLIENT_CERTIFICATE     (0x90|SSL_ST_CONNECT)
+/* server */
+# define SSL2_ST_GET_CLIENT_HELLO_A              (0x10|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_HELLO_B              (0x11|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_HELLO_C              (0x12|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_HELLO_A             (0x20|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_HELLO_B             (0x21|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_MASTER_KEY_A         (0x30|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_MASTER_KEY_B         (0x31|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_VERIFY_A            (0x40|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_VERIFY_B            (0x41|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_VERIFY_C            (0x42|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_FINISHED_A           (0x50|SSL_ST_ACCEPT)
+# define SSL2_ST_GET_CLIENT_FINISHED_B           (0x51|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_FINISHED_A          (0x60|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_SERVER_FINISHED_B          (0x61|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_REQUEST_CERTIFICATE_A      (0x70|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_REQUEST_CERTIFICATE_B      (0x71|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_REQUEST_CERTIFICATE_C      (0x72|SSL_ST_ACCEPT)
+# define SSL2_ST_SEND_REQUEST_CERTIFICATE_D      (0x73|SSL_ST_ACCEPT)
+# define SSL2_ST_SERVER_START_ENCRYPTION         (0x80|SSL_ST_ACCEPT)
+# define SSL2_ST_X509_GET_SERVER_CERTIFICATE     (0x90|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ssl23.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ssl23.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ssl23.h	(working copy)
@@ -0,0 +1,84 @@
+/* ssl/ssl23.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL23_H
+# define HEADER_SSL23_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * client
+ */
+/* write to server */
+# define SSL23_ST_CW_CLNT_HELLO_A        (0x210|SSL_ST_CONNECT)
+# define SSL23_ST_CW_CLNT_HELLO_B        (0x211|SSL_ST_CONNECT)
+/* read from server */
+# define SSL23_ST_CR_SRVR_HELLO_A        (0x220|SSL_ST_CONNECT)
+# define SSL23_ST_CR_SRVR_HELLO_B        (0x221|SSL_ST_CONNECT)
+
+/* server */
+/* read from client */
+# define SSL23_ST_SR_CLNT_HELLO_A        (0x210|SSL_ST_ACCEPT)
+# define SSL23_ST_SR_CLNT_HELLO_B        (0x211|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ssl3.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ssl3.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ssl3.h	(working copy)
@@ -0,0 +1,774 @@
+/* ssl/ssl3.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_SSL3_H
+# define HEADER_SSL3_H
+
+# ifndef OPENSSL_NO_COMP
+#  include <openssl/comp.h>
+# endif
+# include <openssl/buffer.h>
+# include <openssl/evp.h>
+# include <openssl/ssl.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Signalling cipher suite value from RFC 5746
+ * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
+ */
+# define SSL3_CK_SCSV                            0x030000FF
+
+/*
+ * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
+ * (TLS_FALLBACK_SCSV)
+ */
+# define SSL3_CK_FALLBACK_SCSV                   0x03005600
+
+# define SSL3_CK_RSA_NULL_MD5                    0x03000001
+# define SSL3_CK_RSA_NULL_SHA                    0x03000002
+# define SSL3_CK_RSA_RC4_40_MD5                  0x03000003
+# define SSL3_CK_RSA_RC4_128_MD5                 0x03000004
+# define SSL3_CK_RSA_RC4_128_SHA                 0x03000005
+# define SSL3_CK_RSA_RC2_40_MD5                  0x03000006
+# define SSL3_CK_RSA_IDEA_128_SHA                0x03000007
+# define SSL3_CK_RSA_DES_40_CBC_SHA              0x03000008
+# define SSL3_CK_RSA_DES_64_CBC_SHA              0x03000009
+# define SSL3_CK_RSA_DES_192_CBC3_SHA            0x0300000A
+
+# define SSL3_CK_DH_DSS_DES_40_CBC_SHA           0x0300000B
+# define SSL3_CK_DH_DSS_DES_64_CBC_SHA           0x0300000C
+# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA         0x0300000D
+# define SSL3_CK_DH_RSA_DES_40_CBC_SHA           0x0300000E
+# define SSL3_CK_DH_RSA_DES_64_CBC_SHA           0x0300000F
+# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA         0x03000010
+
+# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA          0x03000011
+# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA          SSL3_CK_EDH_DSS_DES_40_CBC_SHA
+# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA          0x03000012
+# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA          SSL3_CK_EDH_DSS_DES_64_CBC_SHA
+# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA        0x03000013
+# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA        SSL3_CK_EDH_DSS_DES_192_CBC3_SHA
+# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA          0x03000014
+# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA          SSL3_CK_EDH_RSA_DES_40_CBC_SHA
+# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA          0x03000015
+# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA          SSL3_CK_EDH_RSA_DES_64_CBC_SHA
+# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA        0x03000016
+# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA        SSL3_CK_EDH_RSA_DES_192_CBC3_SHA
+
+# define SSL3_CK_ADH_RC4_40_MD5                  0x03000017
+# define SSL3_CK_ADH_RC4_128_MD5                 0x03000018
+# define SSL3_CK_ADH_DES_40_CBC_SHA              0x03000019
+# define SSL3_CK_ADH_DES_64_CBC_SHA              0x0300001A
+# define SSL3_CK_ADH_DES_192_CBC_SHA             0x0300001B
+
+# if 0
+#  define SSL3_CK_FZA_DMS_NULL_SHA                0x0300001C
+#  define SSL3_CK_FZA_DMS_FZA_SHA                 0x0300001D
+#  if 0                         /* Because it clashes with KRB5, is never
+                                 * used any more, and is safe to remove
+                                 * according to David Hopwood
+                                 * <david.hopwood@zetnet.co.uk> of the
+                                 * ietf-tls list */
+#   define SSL3_CK_FZA_DMS_RC4_SHA                 0x0300001E
+#  endif
+# endif
+
+/*
+ * VRS Additional Kerberos5 entries
+ */
+# define SSL3_CK_KRB5_DES_64_CBC_SHA             0x0300001E
+# define SSL3_CK_KRB5_DES_192_CBC3_SHA           0x0300001F
+# define SSL3_CK_KRB5_RC4_128_SHA                0x03000020
+# define SSL3_CK_KRB5_IDEA_128_CBC_SHA           0x03000021
+# define SSL3_CK_KRB5_DES_64_CBC_MD5             0x03000022
+# define SSL3_CK_KRB5_DES_192_CBC3_MD5           0x03000023
+# define SSL3_CK_KRB5_RC4_128_MD5                0x03000024
+# define SSL3_CK_KRB5_IDEA_128_CBC_MD5           0x03000025
+
+# define SSL3_CK_KRB5_DES_40_CBC_SHA             0x03000026
+# define SSL3_CK_KRB5_RC2_40_CBC_SHA             0x03000027
+# define SSL3_CK_KRB5_RC4_40_SHA                 0x03000028
+# define SSL3_CK_KRB5_DES_40_CBC_MD5             0x03000029
+# define SSL3_CK_KRB5_RC2_40_CBC_MD5             0x0300002A
+# define SSL3_CK_KRB5_RC4_40_MD5                 0x0300002B
+
+# define SSL3_TXT_RSA_NULL_MD5                   "NULL-MD5"
+# define SSL3_TXT_RSA_NULL_SHA                   "NULL-SHA"
+# define SSL3_TXT_RSA_RC4_40_MD5                 "EXP-RC4-MD5"
+# define SSL3_TXT_RSA_RC4_128_MD5                "RC4-MD5"
+# define SSL3_TXT_RSA_RC4_128_SHA                "RC4-SHA"
+# define SSL3_TXT_RSA_RC2_40_MD5                 "EXP-RC2-CBC-MD5"
+# define SSL3_TXT_RSA_IDEA_128_SHA               "IDEA-CBC-SHA"
+# define SSL3_TXT_RSA_DES_40_CBC_SHA             "EXP-DES-CBC-SHA"
+# define SSL3_TXT_RSA_DES_64_CBC_SHA             "DES-CBC-SHA"
+# define SSL3_TXT_RSA_DES_192_CBC3_SHA           "DES-CBC3-SHA"
+
+# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA          "EXP-DH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA          "DH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA        "DH-DSS-DES-CBC3-SHA"
+# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA          "EXP-DH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA          "DH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA        "DH-RSA-DES-CBC3-SHA"
+
+# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA         "EXP-DHE-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA         "DHE-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA       "DHE-DSS-DES-CBC3-SHA"
+# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA         "EXP-DHE-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA         "DHE-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA       "DHE-RSA-DES-CBC3-SHA"
+
+/*
+ * This next block of six "EDH" labels is for backward compatibility with
+ * older versions of OpenSSL.  New code should use the six "DHE" labels above
+ * instead:
+ */
+# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA         "EXP-EDH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA         "EDH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA       "EDH-DSS-DES-CBC3-SHA"
+# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA         "EXP-EDH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA         "EDH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA       "EDH-RSA-DES-CBC3-SHA"
+
+# define SSL3_TXT_ADH_RC4_40_MD5                 "EXP-ADH-RC4-MD5"
+# define SSL3_TXT_ADH_RC4_128_MD5                "ADH-RC4-MD5"
+# define SSL3_TXT_ADH_DES_40_CBC_SHA             "EXP-ADH-DES-CBC-SHA"
+# define SSL3_TXT_ADH_DES_64_CBC_SHA             "ADH-DES-CBC-SHA"
+# define SSL3_TXT_ADH_DES_192_CBC_SHA            "ADH-DES-CBC3-SHA"
+
+# if 0
+#  define SSL3_TXT_FZA_DMS_NULL_SHA               "FZA-NULL-SHA"
+#  define SSL3_TXT_FZA_DMS_FZA_SHA                "FZA-FZA-CBC-SHA"
+#  define SSL3_TXT_FZA_DMS_RC4_SHA                "FZA-RC4-SHA"
+# endif
+
+# define SSL3_TXT_KRB5_DES_64_CBC_SHA            "KRB5-DES-CBC-SHA"
+# define SSL3_TXT_KRB5_DES_192_CBC3_SHA          "KRB5-DES-CBC3-SHA"
+# define SSL3_TXT_KRB5_RC4_128_SHA               "KRB5-RC4-SHA"
+# define SSL3_TXT_KRB5_IDEA_128_CBC_SHA          "KRB5-IDEA-CBC-SHA"
+# define SSL3_TXT_KRB5_DES_64_CBC_MD5            "KRB5-DES-CBC-MD5"
+# define SSL3_TXT_KRB5_DES_192_CBC3_MD5          "KRB5-DES-CBC3-MD5"
+# define SSL3_TXT_KRB5_RC4_128_MD5               "KRB5-RC4-MD5"
+# define SSL3_TXT_KRB5_IDEA_128_CBC_MD5          "KRB5-IDEA-CBC-MD5"
+
+# define SSL3_TXT_KRB5_DES_40_CBC_SHA            "EXP-KRB5-DES-CBC-SHA"
+# define SSL3_TXT_KRB5_RC2_40_CBC_SHA            "EXP-KRB5-RC2-CBC-SHA"
+# define SSL3_TXT_KRB5_RC4_40_SHA                "EXP-KRB5-RC4-SHA"
+# define SSL3_TXT_KRB5_DES_40_CBC_MD5            "EXP-KRB5-DES-CBC-MD5"
+# define SSL3_TXT_KRB5_RC2_40_CBC_MD5            "EXP-KRB5-RC2-CBC-MD5"
+# define SSL3_TXT_KRB5_RC4_40_MD5                "EXP-KRB5-RC4-MD5"
+
+# define SSL3_SSL_SESSION_ID_LENGTH              32
+# define SSL3_MAX_SSL_SESSION_ID_LENGTH          32
+
+# define SSL3_MASTER_SECRET_SIZE                 48
+# define SSL3_RANDOM_SIZE                        32
+# define SSL3_SESSION_ID_SIZE                    32
+# define SSL3_RT_HEADER_LENGTH                   5
+
+# define SSL3_HM_HEADER_LENGTH                  4
+
+# ifndef SSL3_ALIGN_PAYLOAD
+ /*
+  * Some will argue that this increases memory footprint, but it's not
+  * actually true. Point is that malloc has to return at least 64-bit aligned
+  * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case.
+  * Suggested pre-gaping simply moves these wasted bytes from the end of
+  * allocated region to its front, but makes data payload aligned, which
+  * improves performance:-)
+  */
+#  define SSL3_ALIGN_PAYLOAD                     8
+# else
+#  if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0
+#   error "insane SSL3_ALIGN_PAYLOAD"
+#   undef SSL3_ALIGN_PAYLOAD
+#  endif
+# endif
+
+/*
+ * This is the maximum MAC (digest) size used by the SSL library. Currently
+ * maximum of 20 is used by SHA1, but we reserve for future extension for
+ * 512-bit hashes.
+ */
+
+# define SSL3_RT_MAX_MD_SIZE                     64
+
+/*
+ * Maximum block size used in all ciphersuites. Currently 16 for AES.
+ */
+
+# define SSL_RT_MAX_CIPHER_BLOCK_SIZE            16
+
+# define SSL3_RT_MAX_EXTRA                       (16384)
+
+/* Maximum plaintext length: defined by SSL/TLS standards */
+# define SSL3_RT_MAX_PLAIN_LENGTH                16384
+/* Maximum compression overhead: defined by SSL/TLS standards */
+# define SSL3_RT_MAX_COMPRESSED_OVERHEAD         1024
+
+/*
+ * The standards give a maximum encryption overhead of 1024 bytes. In
+ * practice the value is lower than this. The overhead is the maximum number
+ * of padding bytes (256) plus the mac size.
+ */
+# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD  (256 + SSL3_RT_MAX_MD_SIZE)
+
+/*
+ * OpenSSL currently only uses a padding length of at most one block so the
+ * send overhead is smaller.
+ */
+
+# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+                        (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE)
+
+/* If compression isn't used don't include the compression overhead */
+
+# ifdef OPENSSL_NO_COMP
+#  define SSL3_RT_MAX_COMPRESSED_LENGTH           SSL3_RT_MAX_PLAIN_LENGTH
+# else
+#  define SSL3_RT_MAX_COMPRESSED_LENGTH   \
+                (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
+# endif
+# define SSL3_RT_MAX_ENCRYPTED_LENGTH    \
+                (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
+# define SSL3_RT_MAX_PACKET_SIZE         \
+                (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+
+# define SSL3_MD_CLIENT_FINISHED_CONST   "\x43\x4C\x4E\x54"
+# define SSL3_MD_SERVER_FINISHED_CONST   "\x53\x52\x56\x52"
+
+# define SSL3_VERSION                    0x0300
+# define SSL3_VERSION_MAJOR              0x03
+# define SSL3_VERSION_MINOR              0x00
+
+# define SSL3_RT_CHANGE_CIPHER_SPEC      20
+# define SSL3_RT_ALERT                   21
+# define SSL3_RT_HANDSHAKE               22
+# define SSL3_RT_APPLICATION_DATA        23
+# define TLS1_RT_HEARTBEAT               24
+
+/* Pseudo content types to indicate additional parameters */
+# define TLS1_RT_CRYPTO                  0x1000
+# define TLS1_RT_CRYPTO_PREMASTER        (TLS1_RT_CRYPTO | 0x1)
+# define TLS1_RT_CRYPTO_CLIENT_RANDOM    (TLS1_RT_CRYPTO | 0x2)
+# define TLS1_RT_CRYPTO_SERVER_RANDOM    (TLS1_RT_CRYPTO | 0x3)
+# define TLS1_RT_CRYPTO_MASTER           (TLS1_RT_CRYPTO | 0x4)
+
+# define TLS1_RT_CRYPTO_READ             0x0000
+# define TLS1_RT_CRYPTO_WRITE            0x0100
+# define TLS1_RT_CRYPTO_MAC              (TLS1_RT_CRYPTO | 0x5)
+# define TLS1_RT_CRYPTO_KEY              (TLS1_RT_CRYPTO | 0x6)
+# define TLS1_RT_CRYPTO_IV               (TLS1_RT_CRYPTO | 0x7)
+# define TLS1_RT_CRYPTO_FIXED_IV         (TLS1_RT_CRYPTO | 0x8)
+
+/* Pseudo content type for SSL/TLS header info */
+# define SSL3_RT_HEADER                  0x100
+
+# define SSL3_AL_WARNING                 1
+# define SSL3_AL_FATAL                   2
+
+# define SSL3_AD_CLOSE_NOTIFY             0
+# define SSL3_AD_UNEXPECTED_MESSAGE      10/* fatal */
+# define SSL3_AD_BAD_RECORD_MAC          20/* fatal */
+# define SSL3_AD_DECOMPRESSION_FAILURE   30/* fatal */
+# define SSL3_AD_HANDSHAKE_FAILURE       40/* fatal */
+# define SSL3_AD_NO_CERTIFICATE          41
+# define SSL3_AD_BAD_CERTIFICATE         42
+# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43
+# define SSL3_AD_CERTIFICATE_REVOKED     44
+# define SSL3_AD_CERTIFICATE_EXPIRED     45
+# define SSL3_AD_CERTIFICATE_UNKNOWN     46
+# define SSL3_AD_ILLEGAL_PARAMETER       47/* fatal */
+
+# define TLS1_HB_REQUEST         1
+# define TLS1_HB_RESPONSE        2
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+typedef struct ssl3_record_st {
+    /* type of record */
+    /*
+     * r
+     */ int type;
+    /* How many bytes available */
+    /*
+     * rw
+     */ unsigned int length;
+    /* read/write offset into 'buf' */
+    /*
+     * r
+     */ unsigned int off;
+    /* pointer to the record data */
+    /*
+     * rw
+     */ unsigned char *data;
+    /* where the decode bytes are */
+    /*
+     * rw
+     */ unsigned char *input;
+    /* only used with decompression - malloc()ed */
+    /*
+     * r
+     */ unsigned char *comp;
+    /* epoch number, needed by DTLS1 */
+    /*
+     * r
+     */ unsigned long epoch;
+    /* sequence number, needed by DTLS1 */
+    /*
+     * r
+     */ unsigned char seq_num[8];
+} SSL3_RECORD;
+
+typedef struct ssl3_buffer_st {
+    /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */
+    unsigned char *buf;
+    /* buffer size */
+    size_t len;
+    /* where to 'copy from' */
+    int offset;
+    /* how many bytes left */
+    int left;
+} SSL3_BUFFER;
+
+# endif
+
+# define SSL3_CT_RSA_SIGN                        1
+# define SSL3_CT_DSS_SIGN                        2
+# define SSL3_CT_RSA_FIXED_DH                    3
+# define SSL3_CT_DSS_FIXED_DH                    4
+# define SSL3_CT_RSA_EPHEMERAL_DH                5
+# define SSL3_CT_DSS_EPHEMERAL_DH                6
+# define SSL3_CT_FORTEZZA_DMS                    20
+/*
+ * SSL3_CT_NUMBER is used to size arrays and it must be large enough to
+ * contain all of the cert types defined either for SSLv3 and TLSv1.
+ */
+# define SSL3_CT_NUMBER                  9
+
+# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS       0x0001
+# define SSL3_FLAGS_DELAY_CLIENT_FINISHED        0x0002
+# define SSL3_FLAGS_POP_BUFFER                   0x0004
+# define TLS1_FLAGS_TLS_PADDING_BUG              0x0008
+# define TLS1_FLAGS_SKIP_CERT_VERIFY             0x0010
+# define TLS1_FLAGS_KEEP_HANDSHAKE               0x0020
+/*
+ * Set when the handshake is ready to process peer's ChangeCipherSpec message.
+ * Cleared after the message has been processed.
+ */
+# define SSL3_FLAGS_CCS_OK                       0x0080
+
+/* SSL3_FLAGS_SGC_RESTART_DONE is no longer used */
+# define SSL3_FLAGS_SGC_RESTART_DONE             0x0040
+
+# ifndef OPENSSL_NO_SSL_INTERN
+
+typedef struct ssl3_state_st {
+    long flags;
+    int delay_buf_pop_ret;
+    unsigned char read_sequence[8];
+    int read_mac_secret_size;
+    unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
+    unsigned char write_sequence[8];
+    int write_mac_secret_size;
+    unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
+    unsigned char server_random[SSL3_RANDOM_SIZE];
+    unsigned char client_random[SSL3_RANDOM_SIZE];
+    /* flags for countermeasure against known-IV weakness */
+    int need_empty_fragments;
+    int empty_fragment_done;
+    /* The value of 'extra' when the buffers were initialized */
+    int init_extra;
+    SSL3_BUFFER rbuf;           /* read IO goes into here */
+    SSL3_BUFFER wbuf;           /* write IO goes into here */
+    SSL3_RECORD rrec;           /* each decoded record goes in here */
+    SSL3_RECORD wrec;           /* goes out from here */
+    /*
+     * storage for Alert/Handshake protocol data received but not yet
+     * processed by ssl3_read_bytes:
+     */
+    unsigned char alert_fragment[2];
+    unsigned int alert_fragment_len;
+    unsigned char handshake_fragment[4];
+    unsigned int handshake_fragment_len;
+    /* partial write - check the numbers match */
+    unsigned int wnum;          /* number of bytes sent so far */
+    int wpend_tot;              /* number bytes written */
+    int wpend_type;
+    int wpend_ret;              /* number of bytes submitted */
+    const unsigned char *wpend_buf;
+    /* used during startup, digest all incoming/outgoing packets */
+    BIO *handshake_buffer;
+    /*
+     * When set of handshake digests is determined, buffer is hashed and
+     * freed and MD_CTX-es for all required digests are stored in this array
+     */
+    EVP_MD_CTX **handshake_dgst;
+    /*
+     * Set whenever an expected ChangeCipherSpec message is processed.
+     * Unset when the peer's Finished message is received.
+     * Unexpected ChangeCipherSpec messages trigger a fatal alert.
+     */
+    int change_cipher_spec;
+    int warn_alert;
+    int fatal_alert;
+    /*
+     * we allow one fatal and one warning alert to be outstanding, send close
+     * alert via the warning alert
+     */
+    int alert_dispatch;
+    unsigned char send_alert[2];
+    /*
+     * This flag is set when we should renegotiate ASAP, basically when there
+     * is no more data in the read or write buffers
+     */
+    int renegotiate;
+    int total_renegotiations;
+    int num_renegotiations;
+    int in_read_app_data;
+    /*
+     * Opaque PRF input as used for the current handshake. These fields are
+     * used only if TLSEXT_TYPE_opaque_prf_input is defined (otherwise, they
+     * are merely present to improve binary compatibility)
+     */
+    void *client_opaque_prf_input;
+    size_t client_opaque_prf_input_len;
+    void *server_opaque_prf_input;
+    size_t server_opaque_prf_input_len;
+    struct {
+        /* actually only needs to be 16+20 */
+        unsigned char cert_verify_md[EVP_MAX_MD_SIZE * 2];
+        /* actually only need to be 16+20 for SSLv3 and 12 for TLS */
+        unsigned char finish_md[EVP_MAX_MD_SIZE * 2];
+        int finish_md_len;
+        unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2];
+        int peer_finish_md_len;
+        unsigned long message_size;
+        int message_type;
+        /* used to hold the new cipher we are going to use */
+        const SSL_CIPHER *new_cipher;
+#  ifndef OPENSSL_NO_DH
+        DH *dh;
+#  endif
+#  ifndef OPENSSL_NO_ECDH
+        EC_KEY *ecdh;           /* holds short lived ECDH key */
+#  endif
+        /* used when SSL_ST_FLUSH_DATA is entered */
+        int next_state;
+        int reuse_message;
+        /* used for certificate requests */
+        int cert_req;
+        int ctype_num;
+        char ctype[SSL3_CT_NUMBER];
+        STACK_OF(X509_NAME) *ca_names;
+        int use_rsa_tmp;
+        int key_block_length;
+        unsigned char *key_block;
+        const EVP_CIPHER *new_sym_enc;
+        const EVP_MD *new_hash;
+        int new_mac_pkey_type;
+        int new_mac_secret_size;
+#  ifndef OPENSSL_NO_COMP
+        const SSL_COMP *new_compression;
+#  else
+        char *new_compression;
+#  endif
+        int cert_request;
+    } tmp;
+
+    /* Connection binding to prevent renegotiation attacks */
+    unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
+    unsigned char previous_client_finished_len;
+    unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
+    unsigned char previous_server_finished_len;
+    int send_connection_binding; /* TODOEKR */
+
+#  ifndef OPENSSL_NO_NEXTPROTONEG
+    /*
+     * Set if we saw the Next Protocol Negotiation extension from our peer.
+     */
+    int next_proto_neg_seen;
+#  endif
+
+#  ifndef OPENSSL_NO_TLSEXT
+#   ifndef OPENSSL_NO_EC
+    /*
+     * This is set to true if we believe that this is a version of Safari
+     * running on OS X 10.6 or newer. We wish to know this because Safari on
+     * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support.
+     */
+    char is_probably_safari;
+#   endif                       /* !OPENSSL_NO_EC */
+
+    /*
+     * ALPN information (we are in the process of transitioning from NPN to
+     * ALPN.)
+     */
+
+    /*
+     * In a server these point to the selected ALPN protocol after the
+     * ClientHello has been processed. In a client these contain the protocol
+     * that the server selected once the ServerHello has been processed.
+     */
+    unsigned char *alpn_selected;
+    unsigned alpn_selected_len;
+#  endif                        /* OPENSSL_NO_TLSEXT */
+} SSL3_STATE;
+
+# endif
+
+/* SSLv3 */
+/*
+ * client
+ */
+/* extra state */
+# define SSL3_ST_CW_FLUSH                (0x100|SSL_ST_CONNECT)
+# ifndef OPENSSL_NO_SCTP
+#  define DTLS1_SCTP_ST_CW_WRITE_SOCK                     (0x310|SSL_ST_CONNECT)
+#  define DTLS1_SCTP_ST_CR_READ_SOCK                      (0x320|SSL_ST_CONNECT)
+# endif
+/* write to server */
+# define SSL3_ST_CW_CLNT_HELLO_A         (0x110|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CLNT_HELLO_B         (0x111|SSL_ST_CONNECT)
+/* read from server */
+# define SSL3_ST_CR_SRVR_HELLO_A         (0x120|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SRVR_HELLO_B         (0x121|SSL_ST_CONNECT)
+# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT)
+# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_A               (0x130|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_B               (0x131|SSL_ST_CONNECT)
+# define SSL3_ST_CR_KEY_EXCH_A           (0x140|SSL_ST_CONNECT)
+# define SSL3_ST_CR_KEY_EXCH_B           (0x141|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_REQ_A           (0x150|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_REQ_B           (0x151|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SRVR_DONE_A          (0x160|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SRVR_DONE_B          (0x161|SSL_ST_CONNECT)
+/* write to server */
+# define SSL3_ST_CW_CERT_A               (0x170|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_B               (0x171|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_C               (0x172|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_D               (0x173|SSL_ST_CONNECT)
+# define SSL3_ST_CW_KEY_EXCH_A           (0x180|SSL_ST_CONNECT)
+# define SSL3_ST_CW_KEY_EXCH_B           (0x181|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_VRFY_A          (0x190|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CERT_VRFY_B          (0x191|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CHANGE_A             (0x1A0|SSL_ST_CONNECT)
+# define SSL3_ST_CW_CHANGE_B             (0x1A1|SSL_ST_CONNECT)
+# ifndef OPENSSL_NO_NEXTPROTONEG
+#  define SSL3_ST_CW_NEXT_PROTO_A         (0x200|SSL_ST_CONNECT)
+#  define SSL3_ST_CW_NEXT_PROTO_B         (0x201|SSL_ST_CONNECT)
+# endif
+# define SSL3_ST_CW_FINISHED_A           (0x1B0|SSL_ST_CONNECT)
+# define SSL3_ST_CW_FINISHED_B           (0x1B1|SSL_ST_CONNECT)
+/* read from server */
+# define SSL3_ST_CR_CHANGE_A             (0x1C0|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CHANGE_B             (0x1C1|SSL_ST_CONNECT)
+# define SSL3_ST_CR_FINISHED_A           (0x1D0|SSL_ST_CONNECT)
+# define SSL3_ST_CR_FINISHED_B           (0x1D1|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SESSION_TICKET_A     (0x1E0|SSL_ST_CONNECT)
+# define SSL3_ST_CR_SESSION_TICKET_B     (0x1E1|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_STATUS_A        (0x1F0|SSL_ST_CONNECT)
+# define SSL3_ST_CR_CERT_STATUS_B        (0x1F1|SSL_ST_CONNECT)
+
+/* server */
+/* extra state */
+# define SSL3_ST_SW_FLUSH                (0x100|SSL_ST_ACCEPT)
+# ifndef OPENSSL_NO_SCTP
+#  define DTLS1_SCTP_ST_SW_WRITE_SOCK                     (0x310|SSL_ST_ACCEPT)
+#  define DTLS1_SCTP_ST_SR_READ_SOCK                      (0x320|SSL_ST_ACCEPT)
+# endif
+/* read from client */
+/* Do not change the number values, they do matter */
+# define SSL3_ST_SR_CLNT_HELLO_A         (0x110|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CLNT_HELLO_B         (0x111|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CLNT_HELLO_C         (0x112|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CLNT_HELLO_D         (0x115|SSL_ST_ACCEPT)
+/* write to client */
+# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
+# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_HELLO_REQ_A          (0x120|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_HELLO_REQ_B          (0x121|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_HELLO_REQ_C          (0x122|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SRVR_HELLO_A         (0x130|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SRVR_HELLO_B         (0x131|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_A               (0x140|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_B               (0x141|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_KEY_EXCH_A           (0x150|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_KEY_EXCH_B           (0x151|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_REQ_A           (0x160|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_REQ_B           (0x161|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SRVR_DONE_A          (0x170|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SRVR_DONE_B          (0x171|SSL_ST_ACCEPT)
+/* read from client */
+# define SSL3_ST_SR_CERT_A               (0x180|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CERT_B               (0x181|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_KEY_EXCH_A           (0x190|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_KEY_EXCH_B           (0x191|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CERT_VRFY_A          (0x1A0|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CERT_VRFY_B          (0x1A1|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CHANGE_A             (0x1B0|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_CHANGE_B             (0x1B1|SSL_ST_ACCEPT)
+# ifndef OPENSSL_NO_NEXTPROTONEG
+#  define SSL3_ST_SR_NEXT_PROTO_A         (0x210|SSL_ST_ACCEPT)
+#  define SSL3_ST_SR_NEXT_PROTO_B         (0x211|SSL_ST_ACCEPT)
+# endif
+# define SSL3_ST_SR_FINISHED_A           (0x1C0|SSL_ST_ACCEPT)
+# define SSL3_ST_SR_FINISHED_B           (0x1C1|SSL_ST_ACCEPT)
+/* write to client */
+# define SSL3_ST_SW_CHANGE_A             (0x1D0|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CHANGE_B             (0x1D1|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_FINISHED_A           (0x1E0|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_FINISHED_B           (0x1E1|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SESSION_TICKET_A     (0x1F0|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_SESSION_TICKET_B     (0x1F1|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_STATUS_A        (0x200|SSL_ST_ACCEPT)
+# define SSL3_ST_SW_CERT_STATUS_B        (0x201|SSL_ST_ACCEPT)
+
+# define SSL3_MT_HELLO_REQUEST                   0
+# define SSL3_MT_CLIENT_HELLO                    1
+# define SSL3_MT_SERVER_HELLO                    2
+# define SSL3_MT_NEWSESSION_TICKET               4
+# define SSL3_MT_CERTIFICATE                     11
+# define SSL3_MT_SERVER_KEY_EXCHANGE             12
+# define SSL3_MT_CERTIFICATE_REQUEST             13
+# define SSL3_MT_SERVER_DONE                     14
+# define SSL3_MT_CERTIFICATE_VERIFY              15
+# define SSL3_MT_CLIENT_KEY_EXCHANGE             16
+# define SSL3_MT_FINISHED                        20
+# define SSL3_MT_CERTIFICATE_STATUS              22
+# ifndef OPENSSL_NO_NEXTPROTONEG
+#  define SSL3_MT_NEXT_PROTO                      67
+# endif
+# define DTLS1_MT_HELLO_VERIFY_REQUEST    3
+
+# define SSL3_MT_CCS                             1
+
+/* These are used when changing over to a new cipher */
+# define SSL3_CC_READ            0x01
+# define SSL3_CC_WRITE           0x02
+# define SSL3_CC_CLIENT          0x10
+# define SSL3_CC_SERVER          0x20
+# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE)
+# define SSL3_CHANGE_CIPHER_SERVER_READ  (SSL3_CC_SERVER|SSL3_CC_READ)
+# define SSL3_CHANGE_CIPHER_CLIENT_READ  (SSL3_CC_CLIENT|SSL3_CC_READ)
+# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/stack.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/stack.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/stack.h	(working copy)
@@ -0,0 +1,107 @@
+/* crypto/stack/stack.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_STACK_H
+# define HEADER_STACK_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct stack_st {
+    int num;
+    char **data;
+    int sorted;
+    int num_alloc;
+    int (*comp) (const void *, const void *);
+} _STACK;                       /* Use STACK_OF(...) instead */
+
+# define M_sk_num(sk)            ((sk) ? (sk)->num:-1)
+# define M_sk_value(sk,n)        ((sk) ? (sk)->data[n] : NULL)
+
+int sk_num(const _STACK *);
+void *sk_value(const _STACK *, int);
+
+void *sk_set(_STACK *, int, void *);
+
+_STACK *sk_new(int (*cmp) (const void *, const void *));
+_STACK *sk_new_null(void);
+void sk_free(_STACK *);
+void sk_pop_free(_STACK *st, void (*func) (void *));
+_STACK *sk_deep_copy(_STACK *, void *(*)(void *), void (*)(void *));
+int sk_insert(_STACK *sk, void *data, int where);
+void *sk_delete(_STACK *st, int loc);
+void *sk_delete_ptr(_STACK *st, void *p);
+int sk_find(_STACK *st, void *data);
+int sk_find_ex(_STACK *st, void *data);
+int sk_push(_STACK *st, void *data);
+int sk_unshift(_STACK *st, void *data);
+void *sk_shift(_STACK *st);
+void *sk_pop(_STACK *st);
+void sk_zero(_STACK *st);
+int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *)))
+ (const void *, const void *);
+_STACK *sk_dup(_STACK *st);
+void sk_sort(_STACK *st);
+int sk_is_sorted(const _STACK *st);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/symhacks.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/symhacks.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/symhacks.h	(working copy)
@@ -0,0 +1,516 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SYMHACKS_H
+# define HEADER_SYMHACKS_H
+
+# include <openssl/e_os2.h>
+
+/*
+ * Hacks to solve the problem with linkers incapable of handling very long
+ * symbol names.  In the case of VMS, the limit is 31 characters on VMS for
+ * VAX.
+ */
+/*
+ * Note that this affects util/libeay.num and util/ssleay.num...  you may
+ * change those manually, but that's not recommended, as those files are
+ * controlled centrally and updated on Unix, and the central definition may
+ * disagree with yours, which in turn may come with shareable library
+ * incompatibilities.
+ */
+# ifdef OPENSSL_SYS_VMS
+
+/* Hack a long name in crypto/ex_data.c */
+#  undef CRYPTO_get_ex_data_implementation
+#  define CRYPTO_get_ex_data_implementation       CRYPTO_get_ex_data_impl
+#  undef CRYPTO_set_ex_data_implementation
+#  define CRYPTO_set_ex_data_implementation       CRYPTO_set_ex_data_impl
+
+/* Hack a long name in crypto/asn1/a_mbstr.c */
+#  undef ASN1_STRING_set_default_mask_asc
+#  define ASN1_STRING_set_default_mask_asc        ASN1_STRING_set_def_mask_asc
+
+#  if 0                         /* No longer needed, since safestack macro
+                                 * magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */
+#   undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#   define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO       i2d_ASN1_SET_OF_PKCS7_SIGINF
+#   undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#   define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO       d2i_ASN1_SET_OF_PKCS7_SIGINF
+#  endif
+
+#  if 0                         /* No longer needed, since safestack macro
+                                 * magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */
+#   undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO
+#   define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO        i2d_ASN1_SET_OF_PKCS7_RECINF
+#   undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO
+#   define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO        d2i_ASN1_SET_OF_PKCS7_RECINF
+#  endif
+
+#  if 0                         /* No longer needed, since safestack macro
+                                 * magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */
+#   undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION
+#   define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION      i2d_ASN1_SET_OF_ACC_DESC
+#   undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION
+#   define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION      d2i_ASN1_SET_OF_ACC_DESC
+#  endif
+
+/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */
+#  undef PEM_read_NETSCAPE_CERT_SEQUENCE
+#  define PEM_read_NETSCAPE_CERT_SEQUENCE         PEM_read_NS_CERT_SEQ
+#  undef PEM_write_NETSCAPE_CERT_SEQUENCE
+#  define PEM_write_NETSCAPE_CERT_SEQUENCE        PEM_write_NS_CERT_SEQ
+#  undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE
+#  define PEM_read_bio_NETSCAPE_CERT_SEQUENCE     PEM_read_bio_NS_CERT_SEQ
+#  undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE
+#  define PEM_write_bio_NETSCAPE_CERT_SEQUENCE    PEM_write_bio_NS_CERT_SEQ
+#  undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE
+#  define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ
+
+/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */
+#  undef PEM_read_PKCS8_PRIV_KEY_INFO
+#  define PEM_read_PKCS8_PRIV_KEY_INFO            PEM_read_P8_PRIV_KEY_INFO
+#  undef PEM_write_PKCS8_PRIV_KEY_INFO
+#  define PEM_write_PKCS8_PRIV_KEY_INFO           PEM_write_P8_PRIV_KEY_INFO
+#  undef PEM_read_bio_PKCS8_PRIV_KEY_INFO
+#  define PEM_read_bio_PKCS8_PRIV_KEY_INFO        PEM_read_bio_P8_PRIV_KEY_INFO
+#  undef PEM_write_bio_PKCS8_PRIV_KEY_INFO
+#  define PEM_write_bio_PKCS8_PRIV_KEY_INFO       PEM_write_bio_P8_PRIV_KEY_INFO
+#  undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO
+#  define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO    PEM_wrt_cb_bio_P8_PRIV_KEY_INFO
+
+/* Hack other PEM names */
+#  undef PEM_write_bio_PKCS8PrivateKey_nid
+#  define PEM_write_bio_PKCS8PrivateKey_nid       PEM_write_bio_PKCS8PrivKey_nid
+
+/* Hack some long X509 names */
+#  undef X509_REVOKED_get_ext_by_critical
+#  define X509_REVOKED_get_ext_by_critical        X509_REVOKED_get_ext_by_critic
+#  undef X509_policy_tree_get0_user_policies
+#  define X509_policy_tree_get0_user_policies     X509_pcy_tree_get0_usr_policies
+#  undef X509_policy_node_get0_qualifiers
+#  define X509_policy_node_get0_qualifiers        X509_pcy_node_get0_qualifiers
+#  undef X509_STORE_CTX_get_explicit_policy
+#  define X509_STORE_CTX_get_explicit_policy      X509_STORE_CTX_get_expl_policy
+#  undef X509_STORE_CTX_get0_current_issuer
+#  define X509_STORE_CTX_get0_current_issuer      X509_STORE_CTX_get0_cur_issuer
+
+/* Hack some long CRYPTO names */
+#  undef CRYPTO_set_dynlock_destroy_callback
+#  define CRYPTO_set_dynlock_destroy_callback     CRYPTO_set_dynlock_destroy_cb
+#  undef CRYPTO_set_dynlock_create_callback
+#  define CRYPTO_set_dynlock_create_callback      CRYPTO_set_dynlock_create_cb
+#  undef CRYPTO_set_dynlock_lock_callback
+#  define CRYPTO_set_dynlock_lock_callback        CRYPTO_set_dynlock_lock_cb
+#  undef CRYPTO_get_dynlock_lock_callback
+#  define CRYPTO_get_dynlock_lock_callback        CRYPTO_get_dynlock_lock_cb
+#  undef CRYPTO_get_dynlock_destroy_callback
+#  define CRYPTO_get_dynlock_destroy_callback     CRYPTO_get_dynlock_destroy_cb
+#  undef CRYPTO_get_dynlock_create_callback
+#  define CRYPTO_get_dynlock_create_callback      CRYPTO_get_dynlock_create_cb
+#  undef CRYPTO_set_locked_mem_ex_functions
+#  define CRYPTO_set_locked_mem_ex_functions      CRYPTO_set_locked_mem_ex_funcs
+#  undef CRYPTO_get_locked_mem_ex_functions
+#  define CRYPTO_get_locked_mem_ex_functions      CRYPTO_get_locked_mem_ex_funcs
+
+/* Hack some long SSL/TLS names */
+#  undef SSL_CTX_set_default_verify_paths
+#  define SSL_CTX_set_default_verify_paths        SSL_CTX_set_def_verify_paths
+#  undef SSL_get_ex_data_X509_STORE_CTX_idx
+#  define SSL_get_ex_data_X509_STORE_CTX_idx      SSL_get_ex_d_X509_STORE_CTX_idx
+#  undef SSL_add_file_cert_subjects_to_stack
+#  define SSL_add_file_cert_subjects_to_stack     SSL_add_file_cert_subjs_to_stk
+#  undef SSL_add_dir_cert_subjects_to_stack
+#  define SSL_add_dir_cert_subjects_to_stack      SSL_add_dir_cert_subjs_to_stk
+#  undef SSL_CTX_use_certificate_chain_file
+#  define SSL_CTX_use_certificate_chain_file      SSL_CTX_use_cert_chain_file
+#  undef SSL_CTX_set_cert_verify_callback
+#  define SSL_CTX_set_cert_verify_callback        SSL_CTX_set_cert_verify_cb
+#  undef SSL_CTX_set_default_passwd_cb_userdata
+#  define SSL_CTX_set_default_passwd_cb_userdata  SSL_CTX_set_def_passwd_cb_ud
+#  undef SSL_COMP_get_compression_methods
+#  define SSL_COMP_get_compression_methods        SSL_COMP_get_compress_methods
+#  undef SSL_COMP_set0_compression_methods
+#  define SSL_COMP_set0_compression_methods       SSL_COMP_set0_compress_methods
+#  undef SSL_COMP_free_compression_methods
+#  define SSL_COMP_free_compression_methods       SSL_COMP_free_compress_methods
+#  undef ssl_add_clienthello_renegotiate_ext
+#  define ssl_add_clienthello_renegotiate_ext     ssl_add_clienthello_reneg_ext
+#  undef ssl_add_serverhello_renegotiate_ext
+#  define ssl_add_serverhello_renegotiate_ext     ssl_add_serverhello_reneg_ext
+#  undef ssl_parse_clienthello_renegotiate_ext
+#  define ssl_parse_clienthello_renegotiate_ext   ssl_parse_clienthello_reneg_ext
+#  undef ssl_parse_serverhello_renegotiate_ext
+#  define ssl_parse_serverhello_renegotiate_ext   ssl_parse_serverhello_reneg_ext
+#  undef SSL_srp_server_param_with_username
+#  define SSL_srp_server_param_with_username      SSL_srp_server_param_with_un
+#  undef SSL_CTX_set_srp_client_pwd_callback
+#  define SSL_CTX_set_srp_client_pwd_callback     SSL_CTX_set_srp_client_pwd_cb
+#  undef SSL_CTX_set_srp_verify_param_callback
+#  define SSL_CTX_set_srp_verify_param_callback   SSL_CTX_set_srp_vfy_param_cb
+#  undef SSL_CTX_set_srp_username_callback
+#  define SSL_CTX_set_srp_username_callback       SSL_CTX_set_srp_un_cb
+#  undef ssl_add_clienthello_use_srtp_ext
+#  define ssl_add_clienthello_use_srtp_ext        ssl_add_clihello_use_srtp_ext
+#  undef ssl_add_serverhello_use_srtp_ext
+#  define ssl_add_serverhello_use_srtp_ext        ssl_add_serhello_use_srtp_ext
+#  undef ssl_parse_clienthello_use_srtp_ext
+#  define ssl_parse_clienthello_use_srtp_ext      ssl_parse_clihello_use_srtp_ext
+#  undef ssl_parse_serverhello_use_srtp_ext
+#  define ssl_parse_serverhello_use_srtp_ext      ssl_parse_serhello_use_srtp_ext
+#  undef SSL_CTX_set_next_protos_advertised_cb
+#  define SSL_CTX_set_next_protos_advertised_cb   SSL_CTX_set_next_protos_adv_cb
+#  undef SSL_CTX_set_next_proto_select_cb
+#  define SSL_CTX_set_next_proto_select_cb        SSL_CTX_set_next_proto_sel_cb
+
+#  undef tls1_send_server_supplemental_data
+#  define tls1_send_server_supplemental_data      tls1_send_server_suppl_data
+#  undef tls1_send_client_supplemental_data
+#  define tls1_send_client_supplemental_data      tls1_send_client_suppl_data
+#  undef tls1_get_server_supplemental_data
+#  define tls1_get_server_supplemental_data       tls1_get_server_suppl_data
+#  undef tls1_get_client_supplemental_data
+#  define tls1_get_client_supplemental_data       tls1_get_client_suppl_data
+
+#  undef ssl3_cbc_record_digest_supported
+#  define ssl3_cbc_record_digest_supported        ssl3_cbc_record_digest_support
+#  undef ssl_check_clienthello_tlsext_late
+#  define ssl_check_clienthello_tlsext_late       ssl_check_clihello_tlsext_late
+#  undef ssl_check_clienthello_tlsext_early
+#  define ssl_check_clienthello_tlsext_early      ssl_check_clihello_tlsext_early
+
+/* Hack some RSA long names */
+#  undef RSA_padding_check_PKCS1_OAEP_mgf1
+#  define RSA_padding_check_PKCS1_OAEP_mgf1       RSA_pad_check_PKCS1_OAEP_mgf1
+
+/* Hack some ENGINE long names */
+#  undef ENGINE_get_default_BN_mod_exp_crt
+#  define ENGINE_get_default_BN_mod_exp_crt       ENGINE_get_def_BN_mod_exp_crt
+#  undef ENGINE_set_default_BN_mod_exp_crt
+#  define ENGINE_set_default_BN_mod_exp_crt       ENGINE_set_def_BN_mod_exp_crt
+#  undef ENGINE_set_load_privkey_function
+#  define ENGINE_set_load_privkey_function        ENGINE_set_load_privkey_fn
+#  undef ENGINE_get_load_privkey_function
+#  define ENGINE_get_load_privkey_function        ENGINE_get_load_privkey_fn
+#  undef ENGINE_unregister_pkey_asn1_meths
+#  define ENGINE_unregister_pkey_asn1_meths       ENGINE_unreg_pkey_asn1_meths
+#  undef ENGINE_register_all_pkey_asn1_meths
+#  define ENGINE_register_all_pkey_asn1_meths     ENGINE_reg_all_pkey_asn1_meths
+#  undef ENGINE_set_default_pkey_asn1_meths
+#  define ENGINE_set_default_pkey_asn1_meths      ENGINE_set_def_pkey_asn1_meths
+#  undef ENGINE_get_pkey_asn1_meth_engine
+#  define ENGINE_get_pkey_asn1_meth_engine        ENGINE_get_pkey_asn1_meth_eng
+#  undef ENGINE_set_load_ssl_client_cert_function
+#  define ENGINE_set_load_ssl_client_cert_function \
+                                                ENGINE_set_ld_ssl_clnt_cert_fn
+#  undef ENGINE_get_ssl_client_cert_function
+#  define ENGINE_get_ssl_client_cert_function     ENGINE_get_ssl_client_cert_fn
+
+/* Hack some long OCSP names */
+#  undef OCSP_REQUEST_get_ext_by_critical
+#  define OCSP_REQUEST_get_ext_by_critical        OCSP_REQUEST_get_ext_by_crit
+#  undef OCSP_BASICRESP_get_ext_by_critical
+#  define OCSP_BASICRESP_get_ext_by_critical      OCSP_BASICRESP_get_ext_by_crit
+#  undef OCSP_SINGLERESP_get_ext_by_critical
+#  define OCSP_SINGLERESP_get_ext_by_critical     OCSP_SINGLERESP_get_ext_by_crit
+
+/* Hack some long DES names */
+#  undef _ossl_old_des_ede3_cfb64_encrypt
+#  define _ossl_old_des_ede3_cfb64_encrypt        _ossl_odes_ede3_cfb64_encrypt
+#  undef _ossl_old_des_ede3_ofb64_encrypt
+#  define _ossl_old_des_ede3_ofb64_encrypt        _ossl_odes_ede3_ofb64_encrypt
+
+/* Hack some long EVP names */
+#  undef OPENSSL_add_all_algorithms_noconf
+#  define OPENSSL_add_all_algorithms_noconf       OPENSSL_add_all_algo_noconf
+#  undef OPENSSL_add_all_algorithms_conf
+#  define OPENSSL_add_all_algorithms_conf         OPENSSL_add_all_algo_conf
+#  undef EVP_PKEY_meth_set_verify_recover
+#  define EVP_PKEY_meth_set_verify_recover        EVP_PKEY_meth_set_vrfy_recover
+
+/* Hack some long EC names */
+#  undef EC_GROUP_set_point_conversion_form
+#  define EC_GROUP_set_point_conversion_form      EC_GROUP_set_point_conv_form
+#  undef EC_GROUP_get_point_conversion_form
+#  define EC_GROUP_get_point_conversion_form      EC_GROUP_get_point_conv_form
+#  undef EC_GROUP_clear_free_all_extra_data
+#  define EC_GROUP_clear_free_all_extra_data      EC_GROUP_clr_free_all_xtra_data
+#  undef EC_KEY_set_public_key_affine_coordinates
+#  define EC_KEY_set_public_key_affine_coordinates \
+                                                EC_KEY_set_pub_key_aff_coords
+#  undef EC_POINT_set_Jprojective_coordinates_GFp
+#  define EC_POINT_set_Jprojective_coordinates_GFp \
+                                                EC_POINT_set_Jproj_coords_GFp
+#  undef EC_POINT_get_Jprojective_coordinates_GFp
+#  define EC_POINT_get_Jprojective_coordinates_GFp \
+                                                EC_POINT_get_Jproj_coords_GFp
+#  undef EC_POINT_set_affine_coordinates_GFp
+#  define EC_POINT_set_affine_coordinates_GFp     EC_POINT_set_affine_coords_GFp
+#  undef EC_POINT_get_affine_coordinates_GFp
+#  define EC_POINT_get_affine_coordinates_GFp     EC_POINT_get_affine_coords_GFp
+#  undef EC_POINT_set_compressed_coordinates_GFp
+#  define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp
+#  undef EC_POINT_set_affine_coordinates_GF2m
+#  define EC_POINT_set_affine_coordinates_GF2m    EC_POINT_set_affine_coords_GF2m
+#  undef EC_POINT_get_affine_coordinates_GF2m
+#  define EC_POINT_get_affine_coordinates_GF2m    EC_POINT_get_affine_coords_GF2m
+#  undef EC_POINT_set_compressed_coordinates_GF2m
+#  define EC_POINT_set_compressed_coordinates_GF2m \
+                                                EC_POINT_set_compr_coords_GF2m
+#  undef ec_GF2m_simple_group_clear_finish
+#  define ec_GF2m_simple_group_clear_finish       ec_GF2m_simple_grp_clr_finish
+#  undef ec_GF2m_simple_group_check_discriminant
+#  define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim
+#  undef ec_GF2m_simple_point_clear_finish
+#  define ec_GF2m_simple_point_clear_finish       ec_GF2m_simple_pt_clr_finish
+#  undef ec_GF2m_simple_point_set_to_infinity
+#  define ec_GF2m_simple_point_set_to_infinity    ec_GF2m_simple_pt_set_to_inf
+#  undef ec_GF2m_simple_points_make_affine
+#  define ec_GF2m_simple_points_make_affine       ec_GF2m_simple_pts_make_affine
+#  undef ec_GF2m_simple_point_set_affine_coordinates
+#  define ec_GF2m_simple_point_set_affine_coordinates \
+                                                ec_GF2m_smp_pt_set_af_coords
+#  undef ec_GF2m_simple_point_get_affine_coordinates
+#  define ec_GF2m_simple_point_get_affine_coordinates \
+                                                ec_GF2m_smp_pt_get_af_coords
+#  undef ec_GF2m_simple_set_compressed_coordinates
+#  define ec_GF2m_simple_set_compressed_coordinates \
+                                                ec_GF2m_smp_set_compr_coords
+#  undef ec_GFp_simple_group_set_curve_GFp
+#  define ec_GFp_simple_group_set_curve_GFp       ec_GFp_simple_grp_set_curve_GFp
+#  undef ec_GFp_simple_group_get_curve_GFp
+#  define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
+#  undef ec_GFp_simple_group_clear_finish
+#  define ec_GFp_simple_group_clear_finish        ec_GFp_simple_grp_clear_finish
+#  undef ec_GFp_simple_group_set_generator
+#  define ec_GFp_simple_group_set_generator       ec_GFp_simple_grp_set_generator
+#  undef ec_GFp_simple_group_get0_generator
+#  define ec_GFp_simple_group_get0_generator      ec_GFp_simple_grp_gt0_generator
+#  undef ec_GFp_simple_group_get_cofactor
+#  define ec_GFp_simple_group_get_cofactor        ec_GFp_simple_grp_get_cofactor
+#  undef ec_GFp_simple_point_clear_finish
+#  define ec_GFp_simple_point_clear_finish        ec_GFp_simple_pt_clear_finish
+#  undef ec_GFp_simple_point_set_to_infinity
+#  define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
+#  undef ec_GFp_simple_points_make_affine
+#  define ec_GFp_simple_points_make_affine        ec_GFp_simple_pts_make_affine
+#  undef ec_GFp_simple_set_Jprojective_coordinates_GFp
+#  define ec_GFp_simple_set_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_set_Jproj_coords_GFp
+#  undef ec_GFp_simple_get_Jprojective_coordinates_GFp
+#  define ec_GFp_simple_get_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_get_Jproj_coords_GFp
+#  undef ec_GFp_simple_point_set_affine_coordinates_GFp
+#  define ec_GFp_simple_point_set_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_set_af_coords_GFp
+#  undef ec_GFp_simple_point_get_affine_coordinates_GFp
+#  define ec_GFp_simple_point_get_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_get_af_coords_GFp
+#  undef ec_GFp_simple_set_compressed_coordinates_GFp
+#  define ec_GFp_simple_set_compressed_coordinates_GFp \
+                                                ec_GFp_smp_set_compr_coords_GFp
+#  undef ec_GFp_simple_point_set_affine_coordinates
+#  define ec_GFp_simple_point_set_affine_coordinates \
+                                                ec_GFp_smp_pt_set_af_coords
+#  undef ec_GFp_simple_point_get_affine_coordinates
+#  define ec_GFp_simple_point_get_affine_coordinates \
+                                                ec_GFp_smp_pt_get_af_coords
+#  undef ec_GFp_simple_set_compressed_coordinates
+#  define ec_GFp_simple_set_compressed_coordinates \
+                                                ec_GFp_smp_set_compr_coords
+#  undef ec_GFp_simple_group_check_discriminant
+#  define ec_GFp_simple_group_check_discriminant  ec_GFp_simple_grp_chk_discrim
+
+/* Hack som long STORE names */
+#  undef STORE_method_set_initialise_function
+#  define STORE_method_set_initialise_function    STORE_meth_set_initialise_fn
+#  undef STORE_method_set_cleanup_function
+#  define STORE_method_set_cleanup_function       STORE_meth_set_cleanup_fn
+#  undef STORE_method_set_generate_function
+#  define STORE_method_set_generate_function      STORE_meth_set_generate_fn
+#  undef STORE_method_set_modify_function
+#  define STORE_method_set_modify_function        STORE_meth_set_modify_fn
+#  undef STORE_method_set_revoke_function
+#  define STORE_method_set_revoke_function        STORE_meth_set_revoke_fn
+#  undef STORE_method_set_delete_function
+#  define STORE_method_set_delete_function        STORE_meth_set_delete_fn
+#  undef STORE_method_set_list_start_function
+#  define STORE_method_set_list_start_function    STORE_meth_set_list_start_fn
+#  undef STORE_method_set_list_next_function
+#  define STORE_method_set_list_next_function     STORE_meth_set_list_next_fn
+#  undef STORE_method_set_list_end_function
+#  define STORE_method_set_list_end_function      STORE_meth_set_list_end_fn
+#  undef STORE_method_set_update_store_function
+#  define STORE_method_set_update_store_function  STORE_meth_set_update_store_fn
+#  undef STORE_method_set_lock_store_function
+#  define STORE_method_set_lock_store_function    STORE_meth_set_lock_store_fn
+#  undef STORE_method_set_unlock_store_function
+#  define STORE_method_set_unlock_store_function  STORE_meth_set_unlock_store_fn
+#  undef STORE_method_get_initialise_function
+#  define STORE_method_get_initialise_function    STORE_meth_get_initialise_fn
+#  undef STORE_method_get_cleanup_function
+#  define STORE_method_get_cleanup_function       STORE_meth_get_cleanup_fn
+#  undef STORE_method_get_generate_function
+#  define STORE_method_get_generate_function      STORE_meth_get_generate_fn
+#  undef STORE_method_get_modify_function
+#  define STORE_method_get_modify_function        STORE_meth_get_modify_fn
+#  undef STORE_method_get_revoke_function
+#  define STORE_method_get_revoke_function        STORE_meth_get_revoke_fn
+#  undef STORE_method_get_delete_function
+#  define STORE_method_get_delete_function        STORE_meth_get_delete_fn
+#  undef STORE_method_get_list_start_function
+#  define STORE_method_get_list_start_function    STORE_meth_get_list_start_fn
+#  undef STORE_method_get_list_next_function
+#  define STORE_method_get_list_next_function     STORE_meth_get_list_next_fn
+#  undef STORE_method_get_list_end_function
+#  define STORE_method_get_list_end_function      STORE_meth_get_list_end_fn
+#  undef STORE_method_get_update_store_function
+#  define STORE_method_get_update_store_function  STORE_meth_get_update_store_fn
+#  undef STORE_method_get_lock_store_function
+#  define STORE_method_get_lock_store_function    STORE_meth_get_lock_store_fn
+#  undef STORE_method_get_unlock_store_function
+#  define STORE_method_get_unlock_store_function  STORE_meth_get_unlock_store_fn
+
+/* Hack some long TS names */
+#  undef TS_RESP_CTX_set_status_info_cond
+#  define TS_RESP_CTX_set_status_info_cond        TS_RESP_CTX_set_stat_info_cond
+#  undef TS_RESP_CTX_set_clock_precision_digits
+#  define TS_RESP_CTX_set_clock_precision_digits  TS_RESP_CTX_set_clk_prec_digits
+#  undef TS_CONF_set_clock_precision_digits
+#  define TS_CONF_set_clock_precision_digits      TS_CONF_set_clk_prec_digits
+
+/* Hack some long CMS names */
+#  undef CMS_RecipientInfo_ktri_get0_algs
+#  define CMS_RecipientInfo_ktri_get0_algs        CMS_RecipInfo_ktri_get0_algs
+#  undef CMS_RecipientInfo_ktri_get0_signer_id
+#  define CMS_RecipientInfo_ktri_get0_signer_id   CMS_RecipInfo_ktri_get0_sigr_id
+#  undef CMS_OtherRevocationInfoFormat_it
+#  define CMS_OtherRevocationInfoFormat_it        CMS_OtherRevocInfoFormat_it
+#  undef CMS_KeyAgreeRecipientIdentifier_it
+#  define CMS_KeyAgreeRecipientIdentifier_it      CMS_KeyAgreeRecipIdentifier_it
+#  undef CMS_OriginatorIdentifierOrKey_it
+#  define CMS_OriginatorIdentifierOrKey_it        CMS_OriginatorIdOrKey_it
+#  undef cms_SignerIdentifier_get0_signer_id
+#  define cms_SignerIdentifier_get0_signer_id     cms_SignerId_get0_signer_id
+#  undef CMS_RecipientInfo_kari_get0_orig_id
+#  define CMS_RecipientInfo_kari_get0_orig_id     CMS_RecipInfo_kari_get0_orig_id
+#  undef CMS_RecipientInfo_kari_get0_reks
+#  define CMS_RecipientInfo_kari_get0_reks        CMS_RecipInfo_kari_get0_reks
+#  undef CMS_RecipientEncryptedKey_cert_cmp
+#  define CMS_RecipientEncryptedKey_cert_cmp      CMS_RecipEncryptedKey_cert_cmp
+#  undef CMS_RecipientInfo_kari_set0_pkey
+#  define CMS_RecipientInfo_kari_set0_pkey        CMS_RecipInfo_kari_set0_pkey
+#  undef CMS_RecipientEncryptedKey_get0_id
+#  define CMS_RecipientEncryptedKey_get0_id       CMS_RecipEncryptedKey_get0_id
+#  undef CMS_RecipientInfo_kari_orig_id_cmp
+#  define CMS_RecipientInfo_kari_orig_id_cmp      CMS_RecipInfo_kari_orig_id_cmp
+
+/* Hack some long DTLS1 names */
+#  undef dtls1_retransmit_buffered_messages
+#  define dtls1_retransmit_buffered_messages      dtls1_retransmit_buffered_msgs
+
+/* Hack some long SRP names */
+#  undef SRP_generate_server_master_secret
+#  define SRP_generate_server_master_secret       SRP_gen_server_master_secret
+#  undef SRP_generate_client_master_secret
+#  define SRP_generate_client_master_secret       SRP_gen_client_master_secret
+
+/* Hack some long UI names */
+#  undef UI_method_get_prompt_constructor
+#  define UI_method_get_prompt_constructor        UI_method_get_prompt_constructr
+#  undef UI_method_set_prompt_constructor
+#  define UI_method_set_prompt_constructor        UI_method_set_prompt_constructr
+
+# endif                         /* defined OPENSSL_SYS_VMS */
+
+/* Case insensitive linking causes problems.... */
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
+#  undef ERR_load_CRYPTO_strings
+#  define ERR_load_CRYPTO_strings                 ERR_load_CRYPTOlib_strings
+#  undef OCSP_crlID_new
+#  define OCSP_crlID_new                          OCSP_crlID2_new
+
+#  undef d2i_ECPARAMETERS
+#  define d2i_ECPARAMETERS                        d2i_UC_ECPARAMETERS
+#  undef i2d_ECPARAMETERS
+#  define i2d_ECPARAMETERS                        i2d_UC_ECPARAMETERS
+#  undef d2i_ECPKPARAMETERS
+#  define d2i_ECPKPARAMETERS                      d2i_UC_ECPKPARAMETERS
+#  undef i2d_ECPKPARAMETERS
+#  define i2d_ECPKPARAMETERS                      i2d_UC_ECPKPARAMETERS
+
+/*
+ * These functions do not seem to exist! However, I'm paranoid... Original
+ * command in x509v3.h: These functions are being redefined in another
+ * directory, and clash when the linker is case-insensitive, so let's hide
+ * them a little, by giving them an extra 'o' at the beginning of the name...
+ */
+#  undef X509v3_cleanup_extensions
+#  define X509v3_cleanup_extensions               oX509v3_cleanup_extensions
+#  undef X509v3_add_extension
+#  define X509v3_add_extension                    oX509v3_add_extension
+#  undef X509v3_add_netscape_extensions
+#  define X509v3_add_netscape_extensions          oX509v3_add_netscape_extensions
+#  undef X509v3_add_standard_extensions
+#  define X509v3_add_standard_extensions          oX509v3_add_standard_extensions
+
+/* This one clashes with CMS_data_create */
+#  undef cms_Data_create
+#  define cms_Data_create                         priv_cms_Data_create
+
+# endif
+
+#endif                          /* ! defined HEADER_VMS_IDHACKS_H */
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/tls1.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/tls1.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/tls1.h	(working copy)
@@ -0,0 +1,810 @@
+/* ssl/tls1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifndef HEADER_TLS1_H
+# define HEADER_TLS1_H
+
+# include <openssl/buffer.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES    0
+
+# define TLS1_VERSION                    0x0301
+# define TLS1_1_VERSION                  0x0302
+# define TLS1_2_VERSION                  0x0303
+# define TLS_MAX_VERSION                 TLS1_2_VERSION
+
+# define TLS1_VERSION_MAJOR              0x03
+# define TLS1_VERSION_MINOR              0x01
+
+# define TLS1_1_VERSION_MAJOR            0x03
+# define TLS1_1_VERSION_MINOR            0x02
+
+# define TLS1_2_VERSION_MAJOR            0x03
+# define TLS1_2_VERSION_MINOR            0x03
+
+# define TLS1_get_version(s) \
+                ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0)
+
+# define TLS1_get_client_version(s) \
+                ((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0)
+
+# define TLS1_AD_DECRYPTION_FAILED       21
+# define TLS1_AD_RECORD_OVERFLOW         22
+# define TLS1_AD_UNKNOWN_CA              48/* fatal */
+# define TLS1_AD_ACCESS_DENIED           49/* fatal */
+# define TLS1_AD_DECODE_ERROR            50/* fatal */
+# define TLS1_AD_DECRYPT_ERROR           51
+# define TLS1_AD_EXPORT_RESTRICTION      60/* fatal */
+# define TLS1_AD_PROTOCOL_VERSION        70/* fatal */
+# define TLS1_AD_INSUFFICIENT_SECURITY   71/* fatal */
+# define TLS1_AD_INTERNAL_ERROR          80/* fatal */
+# define TLS1_AD_INAPPROPRIATE_FALLBACK  86/* fatal */
+# define TLS1_AD_USER_CANCELLED          90
+# define TLS1_AD_NO_RENEGOTIATION        100
+/* codes 110-114 are from RFC3546 */
+# define TLS1_AD_UNSUPPORTED_EXTENSION   110
+# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
+# define TLS1_AD_UNRECOGNIZED_NAME       112
+# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
+# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
+# define TLS1_AD_UNKNOWN_PSK_IDENTITY    115/* fatal */
+
+/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */
+# define TLSEXT_TYPE_server_name                 0
+# define TLSEXT_TYPE_max_fragment_length         1
+# define TLSEXT_TYPE_client_certificate_url      2
+# define TLSEXT_TYPE_trusted_ca_keys             3
+# define TLSEXT_TYPE_truncated_hmac              4
+# define TLSEXT_TYPE_status_request              5
+/* ExtensionType values from RFC4681 */
+# define TLSEXT_TYPE_user_mapping                6
+/* ExtensionType values from RFC5878 */
+# define TLSEXT_TYPE_client_authz                7
+# define TLSEXT_TYPE_server_authz                8
+/* ExtensionType values from RFC6091 */
+# define TLSEXT_TYPE_cert_type           9
+
+/* ExtensionType values from RFC4492 */
+# define TLSEXT_TYPE_elliptic_curves             10
+# define TLSEXT_TYPE_ec_point_formats            11
+
+/* ExtensionType value from RFC5054 */
+# define TLSEXT_TYPE_srp                         12
+
+/* ExtensionType values from RFC5246 */
+# define TLSEXT_TYPE_signature_algorithms        13
+
+/* ExtensionType value from RFC5764 */
+# define TLSEXT_TYPE_use_srtp    14
+
+/* ExtensionType value from RFC5620 */
+# define TLSEXT_TYPE_heartbeat   15
+
+/* ExtensionType value from RFC7301 */
+# define TLSEXT_TYPE_application_layer_protocol_negotiation 16
+
+/*
+ * ExtensionType value for TLS padding extension.
+ * http://tools.ietf.org/html/draft-agl-tls-padding
+ */
+# define TLSEXT_TYPE_padding     21
+
+/* ExtensionType value from RFC4507 */
+# define TLSEXT_TYPE_session_ticket              35
+
+/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */
+# if 0
+/*
+ * will have to be provided externally for now ,
+ * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183
+ * using whatever extension number you'd like to try
+ */
+#  define TLSEXT_TYPE_opaque_prf_input           ??
+# endif
+
+/* Temporary extension type */
+# define TLSEXT_TYPE_renegotiate                 0xff01
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+/* This is not an IANA defined extension number */
+#  define TLSEXT_TYPE_next_proto_neg              13172
+# endif
+
+/* NameType value from RFC3546 */
+# define TLSEXT_NAMETYPE_host_name 0
+/* status request value from RFC3546 */
+# define TLSEXT_STATUSTYPE_ocsp 1
+
+/* ECPointFormat values from RFC4492 */
+# define TLSEXT_ECPOINTFORMAT_first                      0
+# define TLSEXT_ECPOINTFORMAT_uncompressed               0
+# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime  1
+# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2  2
+# define TLSEXT_ECPOINTFORMAT_last                       2
+
+/* Signature and hash algorithms from RFC5246 */
+# define TLSEXT_signature_anonymous                      0
+# define TLSEXT_signature_rsa                            1
+# define TLSEXT_signature_dsa                            2
+# define TLSEXT_signature_ecdsa                          3
+
+/* Total number of different signature algorithms */
+# define TLSEXT_signature_num                            4
+
+# define TLSEXT_hash_none                                0
+# define TLSEXT_hash_md5                                 1
+# define TLSEXT_hash_sha1                                2
+# define TLSEXT_hash_sha224                              3
+# define TLSEXT_hash_sha256                              4
+# define TLSEXT_hash_sha384                              5
+# define TLSEXT_hash_sha512                              6
+
+/* Total number of different digest algorithms */
+
+# define TLSEXT_hash_num                                 7
+
+/* Flag set for unrecognised algorithms */
+# define TLSEXT_nid_unknown                              0x1000000
+
+/* ECC curves */
+
+# define TLSEXT_curve_P_256                              23
+# define TLSEXT_curve_P_384                              24
+
+# ifndef OPENSSL_NO_TLSEXT
+
+#  define TLSEXT_MAXLEN_host_name 255
+
+const char *SSL_get_servername(const SSL *s, const int type);
+int SSL_get_servername_type(const SSL *s);
+/*
+ * SSL_export_keying_material exports a value derived from the master secret,
+ * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
+ * optional context. (Since a zero length context is allowed, the |use_context|
+ * flag controls whether a context is included.) It returns 1 on success and
+ * zero otherwise.
+ */
+int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+                               const char *label, size_t llen,
+                               const unsigned char *p, size_t plen,
+                               int use_context);
+
+int SSL_get_sigalgs(SSL *s, int idx,
+                    int *psign, int *phash, int *psignandhash,
+                    unsigned char *rsig, unsigned char *rhash);
+
+int SSL_get_shared_sigalgs(SSL *s, int idx,
+                           int *psign, int *phash, int *psignandhash,
+                           unsigned char *rsig, unsigned char *rhash);
+
+int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain);
+
+#  define SSL_set_tlsext_host_name(s,name) \
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
+
+#  define SSL_set_tlsext_debug_callback(ssl, cb) \
+SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb)
+
+#  define SSL_set_tlsext_debug_arg(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg)
+
+#  define SSL_set_tlsext_status_type(ssl, type) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL)
+
+#  define SSL_get_tlsext_status_exts(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
+
+#  define SSL_set_tlsext_status_exts(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
+
+#  define SSL_get_tlsext_status_ids(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
+
+#  define SSL_set_tlsext_status_ids(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
+
+#  define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg)
+
+#  define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg)
+
+#  define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)
+
+#  define SSL_TLSEXT_ERR_OK 0
+#  define SSL_TLSEXT_ERR_ALERT_WARNING 1
+#  define SSL_TLSEXT_ERR_ALERT_FATAL 2
+#  define SSL_TLSEXT_ERR_NOACK 3
+
+#  define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
+SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)
+
+#  define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys))
+#  define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys))
+
+#  define SSL_CTX_set_tlsext_status_cb(ssl, cb) \
+SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb)
+
+#  define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
+SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)
+
+#  define SSL_set_tlsext_opaque_prf_input(s, src, len) \
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src)
+#  define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb)
+#  define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \
+SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg)
+
+#  define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
+SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
+
+#  ifndef OPENSSL_NO_HEARTBEATS
+#   define SSL_TLSEXT_HB_ENABLED                           0x01
+#   define SSL_TLSEXT_HB_DONT_SEND_REQUESTS        0x02
+#   define SSL_TLSEXT_HB_DONT_RECV_REQUESTS        0x04
+
+#   define SSL_get_tlsext_heartbeat_pending(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING,0,NULL)
+#   define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \
+        SSL_ctrl((ssl),SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL)
+#  endif
+# endif
+
+/* PSK ciphersuites from 4279 */
+# define TLS1_CK_PSK_WITH_RC4_128_SHA                    0x0300008A
+# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA               0x0300008B
+# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA                0x0300008C
+# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA                0x0300008D
+
+/*
+ * Additional TLS ciphersuites from expired Internet Draft
+ * draft-ietf-tls-56-bit-ciphersuites-01.txt (available if
+ * TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see s3_lib.c).  We
+ * actually treat them like SSL 3.0 ciphers, which we probably shouldn't.
+ * Note that the first two are actually not in the IDs.
+ */
+# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5          0x03000060/* not in
+                                                                    * ID */
+# define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5      0x03000061/* not in
+                                                                    * ID */
+# define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA         0x03000062
+# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA     0x03000063
+# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA          0x03000064
+# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA      0x03000065
+# define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA                0x03000066
+
+/* AES ciphersuites from RFC3268 */
+# define TLS1_CK_RSA_WITH_AES_128_SHA                    0x0300002F
+# define TLS1_CK_DH_DSS_WITH_AES_128_SHA                 0x03000030
+# define TLS1_CK_DH_RSA_WITH_AES_128_SHA                 0x03000031
+# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA                0x03000032
+# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA                0x03000033
+# define TLS1_CK_ADH_WITH_AES_128_SHA                    0x03000034
+
+# define TLS1_CK_RSA_WITH_AES_256_SHA                    0x03000035
+# define TLS1_CK_DH_DSS_WITH_AES_256_SHA                 0x03000036
+# define TLS1_CK_DH_RSA_WITH_AES_256_SHA                 0x03000037
+# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA                0x03000038
+# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA                0x03000039
+# define TLS1_CK_ADH_WITH_AES_256_SHA                    0x0300003A
+
+/* TLS v1.2 ciphersuites */
+# define TLS1_CK_RSA_WITH_NULL_SHA256                    0x0300003B
+# define TLS1_CK_RSA_WITH_AES_128_SHA256                 0x0300003C
+# define TLS1_CK_RSA_WITH_AES_256_SHA256                 0x0300003D
+# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256              0x0300003E
+# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256              0x0300003F
+# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256             0x03000040
+
+/* Camellia ciphersuites from RFC4132 */
+# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA           0x03000041
+# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA        0x03000042
+# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA        0x03000043
+# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA       0x03000044
+# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA       0x03000045
+# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA           0x03000046
+
+/* TLS v1.2 ciphersuites */
+# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256             0x03000067
+# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256              0x03000068
+# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256              0x03000069
+# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256             0x0300006A
+# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256             0x0300006B
+# define TLS1_CK_ADH_WITH_AES_128_SHA256                 0x0300006C
+# define TLS1_CK_ADH_WITH_AES_256_SHA256                 0x0300006D
+
+/* Camellia ciphersuites from RFC4132 */
+# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA           0x03000084
+# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA        0x03000085
+# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA        0x03000086
+# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA       0x03000087
+# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA       0x03000088
+# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA           0x03000089
+
+/* SEED ciphersuites from RFC4162 */
+# define TLS1_CK_RSA_WITH_SEED_SHA                       0x03000096
+# define TLS1_CK_DH_DSS_WITH_SEED_SHA                    0x03000097
+# define TLS1_CK_DH_RSA_WITH_SEED_SHA                    0x03000098
+# define TLS1_CK_DHE_DSS_WITH_SEED_SHA                   0x03000099
+# define TLS1_CK_DHE_RSA_WITH_SEED_SHA                   0x0300009A
+# define TLS1_CK_ADH_WITH_SEED_SHA                       0x0300009B
+
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256             0x0300009C
+# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384             0x0300009D
+# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256         0x0300009E
+# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384         0x0300009F
+# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256          0x030000A0
+# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384          0x030000A1
+# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256         0x030000A2
+# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384         0x030000A3
+# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256          0x030000A4
+# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384          0x030000A5
+# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256             0x030000A6
+# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384             0x030000A7
+
+/*
+ * ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in
+ * draft 13
+ */
+# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA                0x0300C001
+# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA             0x0300C002
+# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA        0x0300C003
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA         0x0300C004
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA         0x0300C005
+
+# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA               0x0300C006
+# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA            0x0300C007
+# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA       0x0300C008
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA        0x0300C009
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA        0x0300C00A
+
+# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA                  0x0300C00B
+# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA               0x0300C00C
+# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA          0x0300C00D
+# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA           0x0300C00E
+# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA           0x0300C00F
+
+# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA                 0x0300C010
+# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA              0x0300C011
+# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA         0x0300C012
+# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA          0x0300C013
+# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA          0x0300C014
+
+# define TLS1_CK_ECDH_anon_WITH_NULL_SHA                 0x0300C015
+# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA              0x0300C016
+# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA         0x0300C017
+# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA          0x0300C018
+# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA          0x0300C019
+
+/* SRP ciphersuites from RFC 5054 */
+# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA           0x0300C01A
+# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA       0x0300C01B
+# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA       0x0300C01C
+# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA            0x0300C01D
+# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA        0x0300C01E
+# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA        0x0300C01F
+# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA            0x0300C020
+# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA        0x0300C021
+# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA        0x0300C022
+
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256         0x0300C023
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384         0x0300C024
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256          0x0300C025
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384          0x0300C026
+# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256           0x0300C027
+# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384           0x0300C028
+# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256            0x0300C029
+# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384            0x0300C02A
+
+/* ECDH GCM based ciphersuites from RFC5289 */
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256     0x0300C02B
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384     0x0300C02C
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256      0x0300C02D
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384      0x0300C02E
+# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256       0x0300C02F
+# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384       0x0300C030
+# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256        0x0300C031
+# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384        0x0300C032
+
+/*
+ * XXX * Backward compatibility alert: + * Older versions of OpenSSL gave
+ * some DHE ciphers names with "EDH" + * instead of "DHE".  Going forward, we
+ * should be using DHE + * everywhere, though we may indefinitely maintain
+ * aliases for users + * or configurations that used "EDH" +
+ */
+# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5         "EXP1024-RC4-MD5"
+# define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5     "EXP1024-RC2-CBC-MD5"
+# define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA        "EXP1024-DES-CBC-SHA"
+# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA    "EXP1024-DHE-DSS-DES-CBC-SHA"
+# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA         "EXP1024-RC4-SHA"
+# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA     "EXP1024-DHE-DSS-RC4-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA               "DHE-DSS-RC4-SHA"
+
+/* AES ciphersuites from RFC3268 */
+# define TLS1_TXT_RSA_WITH_AES_128_SHA                   "AES128-SHA"
+# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA                "DH-DSS-AES128-SHA"
+# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA                "DH-RSA-AES128-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA               "DHE-DSS-AES128-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA               "DHE-RSA-AES128-SHA"
+# define TLS1_TXT_ADH_WITH_AES_128_SHA                   "ADH-AES128-SHA"
+
+# define TLS1_TXT_RSA_WITH_AES_256_SHA                   "AES256-SHA"
+# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA                "DH-DSS-AES256-SHA"
+# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA                "DH-RSA-AES256-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA               "DHE-DSS-AES256-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA               "DHE-RSA-AES256-SHA"
+# define TLS1_TXT_ADH_WITH_AES_256_SHA                   "ADH-AES256-SHA"
+
+/* ECC ciphersuites from RFC4492 */
+# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA               "ECDH-ECDSA-NULL-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA            "ECDH-ECDSA-RC4-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA       "ECDH-ECDSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA        "ECDH-ECDSA-AES128-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA        "ECDH-ECDSA-AES256-SHA"
+
+# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA              "ECDHE-ECDSA-NULL-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA           "ECDHE-ECDSA-RC4-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA      "ECDHE-ECDSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA       "ECDHE-ECDSA-AES128-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA       "ECDHE-ECDSA-AES256-SHA"
+
+# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA                 "ECDH-RSA-NULL-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA              "ECDH-RSA-RC4-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA         "ECDH-RSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA          "ECDH-RSA-AES128-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA          "ECDH-RSA-AES256-SHA"
+
+# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA                "ECDHE-RSA-NULL-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA             "ECDHE-RSA-RC4-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA        "ECDHE-RSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA         "ECDHE-RSA-AES128-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA         "ECDHE-RSA-AES256-SHA"
+
+# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA                "AECDH-NULL-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA             "AECDH-RC4-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA        "AECDH-DES-CBC3-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA         "AECDH-AES128-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA         "AECDH-AES256-SHA"
+
+/* PSK ciphersuites from RFC 4279 */
+# define TLS1_TXT_PSK_WITH_RC4_128_SHA                   "PSK-RC4-SHA"
+# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA              "PSK-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA               "PSK-AES128-CBC-SHA"
+# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA               "PSK-AES256-CBC-SHA"
+
+/* SRP ciphersuite from RFC 5054 */
+# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA          "SRP-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA      "SRP-RSA-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA      "SRP-DSS-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA           "SRP-AES-128-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA       "SRP-RSA-AES-128-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA       "SRP-DSS-AES-128-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA           "SRP-AES-256-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA       "SRP-RSA-AES-256-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA       "SRP-DSS-AES-256-CBC-SHA"
+
+/* Camellia ciphersuites from RFC4132 */
+# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA          "CAMELLIA128-SHA"
+# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA       "DH-DSS-CAMELLIA128-SHA"
+# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA       "DH-RSA-CAMELLIA128-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA      "DHE-DSS-CAMELLIA128-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA      "DHE-RSA-CAMELLIA128-SHA"
+# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA          "ADH-CAMELLIA128-SHA"
+
+# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA          "CAMELLIA256-SHA"
+# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA       "DH-DSS-CAMELLIA256-SHA"
+# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA       "DH-RSA-CAMELLIA256-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA      "DHE-DSS-CAMELLIA256-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA      "DHE-RSA-CAMELLIA256-SHA"
+# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA          "ADH-CAMELLIA256-SHA"
+
+/* SEED ciphersuites from RFC4162 */
+# define TLS1_TXT_RSA_WITH_SEED_SHA                      "SEED-SHA"
+# define TLS1_TXT_DH_DSS_WITH_SEED_SHA                   "DH-DSS-SEED-SHA"
+# define TLS1_TXT_DH_RSA_WITH_SEED_SHA                   "DH-RSA-SEED-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA                  "DHE-DSS-SEED-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA                  "DHE-RSA-SEED-SHA"
+# define TLS1_TXT_ADH_WITH_SEED_SHA                      "ADH-SEED-SHA"
+
+/* TLS v1.2 ciphersuites */
+# define TLS1_TXT_RSA_WITH_NULL_SHA256                   "NULL-SHA256"
+# define TLS1_TXT_RSA_WITH_AES_128_SHA256                "AES128-SHA256"
+# define TLS1_TXT_RSA_WITH_AES_256_SHA256                "AES256-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256             "DH-DSS-AES128-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256             "DH-RSA-AES128-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256            "DHE-DSS-AES128-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256            "DHE-RSA-AES128-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256             "DH-DSS-AES256-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256             "DH-RSA-AES256-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256            "DHE-DSS-AES256-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256            "DHE-RSA-AES256-SHA256"
+# define TLS1_TXT_ADH_WITH_AES_128_SHA256                "ADH-AES128-SHA256"
+# define TLS1_TXT_ADH_WITH_AES_256_SHA256                "ADH-AES256-SHA256"
+
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256            "AES128-GCM-SHA256"
+# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384            "AES256-GCM-SHA384"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256        "DHE-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384        "DHE-RSA-AES256-GCM-SHA384"
+# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256         "DH-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384         "DH-RSA-AES256-GCM-SHA384"
+# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256        "DHE-DSS-AES128-GCM-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384        "DHE-DSS-AES256-GCM-SHA384"
+# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256         "DH-DSS-AES128-GCM-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384         "DH-DSS-AES256-GCM-SHA384"
+# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256            "ADH-AES128-GCM-SHA256"
+# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384            "ADH-AES256-GCM-SHA384"
+
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256    "ECDHE-ECDSA-AES128-SHA256"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384    "ECDHE-ECDSA-AES256-SHA384"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256     "ECDH-ECDSA-AES128-SHA256"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384     "ECDH-ECDSA-AES256-SHA384"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256      "ECDHE-RSA-AES128-SHA256"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384      "ECDHE-RSA-AES256-SHA384"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256       "ECDH-RSA-AES128-SHA256"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384       "ECDH-RSA-AES256-SHA384"
+
+/* ECDH GCM based ciphersuites from RFC5289 */
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256    "ECDHE-ECDSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384    "ECDHE-ECDSA-AES256-GCM-SHA384"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256     "ECDH-ECDSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384     "ECDH-ECDSA-AES256-GCM-SHA384"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256      "ECDHE-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384      "ECDHE-RSA-AES256-GCM-SHA384"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256       "ECDH-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384       "ECDH-RSA-AES256-GCM-SHA384"
+
+# define TLS_CT_RSA_SIGN                 1
+# define TLS_CT_DSS_SIGN                 2
+# define TLS_CT_RSA_FIXED_DH             3
+# define TLS_CT_DSS_FIXED_DH             4
+# define TLS_CT_ECDSA_SIGN               64
+# define TLS_CT_RSA_FIXED_ECDH           65
+# define TLS_CT_ECDSA_FIXED_ECDH         66
+# define TLS_CT_GOST94_SIGN              21
+# define TLS_CT_GOST01_SIGN              22
+/*
+ * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
+ * comment there)
+ */
+# define TLS_CT_NUMBER                   9
+
+# define TLS1_FINISH_MAC_LENGTH          12
+
+# define TLS_MD_MAX_CONST_SIZE                   20
+# define TLS_MD_CLIENT_FINISH_CONST              "client finished"
+# define TLS_MD_CLIENT_FINISH_CONST_SIZE         15
+# define TLS_MD_SERVER_FINISH_CONST              "server finished"
+# define TLS_MD_SERVER_FINISH_CONST_SIZE         15
+# define TLS_MD_SERVER_WRITE_KEY_CONST           "server write key"
+# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE      16
+# define TLS_MD_KEY_EXPANSION_CONST              "key expansion"
+# define TLS_MD_KEY_EXPANSION_CONST_SIZE         13
+# define TLS_MD_CLIENT_WRITE_KEY_CONST           "client write key"
+# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE      16
+# define TLS_MD_SERVER_WRITE_KEY_CONST           "server write key"
+# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE      16
+# define TLS_MD_IV_BLOCK_CONST                   "IV block"
+# define TLS_MD_IV_BLOCK_CONST_SIZE              8
+# define TLS_MD_MASTER_SECRET_CONST              "master secret"
+# define TLS_MD_MASTER_SECRET_CONST_SIZE         13
+
+# ifdef CHARSET_EBCDIC
+#  undef TLS_MD_CLIENT_FINISH_CONST
+/*
+ * client finished
+ */
+#  define TLS_MD_CLIENT_FINISH_CONST    "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64"
+
+#  undef TLS_MD_SERVER_FINISH_CONST
+/*
+ * server finished
+ */
+#  define TLS_MD_SERVER_FINISH_CONST    "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64"
+
+#  undef TLS_MD_SERVER_WRITE_KEY_CONST
+/*
+ * server write key
+ */
+#  define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"
+
+#  undef TLS_MD_KEY_EXPANSION_CONST
+/*
+ * key expansion
+ */
+#  define TLS_MD_KEY_EXPANSION_CONST    "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e"
+
+#  undef TLS_MD_CLIENT_WRITE_KEY_CONST
+/*
+ * client write key
+ */
+#  define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"
+
+#  undef TLS_MD_SERVER_WRITE_KEY_CONST
+/*
+ * server write key
+ */
+#  define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"
+
+#  undef TLS_MD_IV_BLOCK_CONST
+/*
+ * IV block
+ */
+#  define TLS_MD_IV_BLOCK_CONST         "\x49\x56\x20\x62\x6c\x6f\x63\x6b"
+
+#  undef TLS_MD_MASTER_SECRET_CONST
+/*
+ * master secret
+ */
+#  define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
+# endif
+
+/* TLS Session Ticket extension struct */
+struct tls_session_ticket_ext_st {
+    unsigned short length;
+    void *data;
+};
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ts.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ts.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ts.h	(working copy)
@@ -0,0 +1,865 @@
+/* crypto/ts/ts.h */
+/*
+ * Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL project
+ * 2002, 2003, 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_TS_H
+# define HEADER_TS_H
+
+# include <openssl/opensslconf.h>
+# include <openssl/symhacks.h>
+# ifndef OPENSSL_NO_BUFFER
+#  include <openssl/buffer.h>
+# endif
+# ifndef OPENSSL_NO_EVP
+#  include <openssl/evp.h>
+# endif
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/stack.h>
+# include <openssl/asn1.h>
+# include <openssl/safestack.h>
+
+# ifndef OPENSSL_NO_RSA
+#  include <openssl/rsa.h>
+# endif
+
+# ifndef OPENSSL_NO_DSA
+#  include <openssl/dsa.h>
+# endif
+
+# ifndef OPENSSL_NO_DH
+#  include <openssl/dh.h>
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef WIN32
+/* Under Win32 this is defined in wincrypt.h */
+#  undef X509_NAME
+# endif
+
+# include <openssl/x509.h>
+# include <openssl/x509v3.h>
+
+/*-
+MessageImprint ::= SEQUENCE  {
+     hashAlgorithm                AlgorithmIdentifier,
+     hashedMessage                OCTET STRING  }
+*/
+
+typedef struct TS_msg_imprint_st {
+    X509_ALGOR *hash_algo;
+    ASN1_OCTET_STRING *hashed_msg;
+} TS_MSG_IMPRINT;
+
+/*-
+TimeStampReq ::= SEQUENCE  {
+   version                  INTEGER  { v1(1) },
+   messageImprint           MessageImprint,
+     --a hash algorithm OID and the hash value of the data to be
+     --time-stamped
+   reqPolicy                TSAPolicyId                OPTIONAL,
+   nonce                    INTEGER                    OPTIONAL,
+   certReq                  BOOLEAN                    DEFAULT FALSE,
+   extensions               [0] IMPLICIT Extensions    OPTIONAL  }
+*/
+
+typedef struct TS_req_st {
+    ASN1_INTEGER *version;
+    TS_MSG_IMPRINT *msg_imprint;
+    ASN1_OBJECT *policy_id;     /* OPTIONAL */
+    ASN1_INTEGER *nonce;        /* OPTIONAL */
+    ASN1_BOOLEAN cert_req;      /* DEFAULT FALSE */
+    STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */
+} TS_REQ;
+
+/*-
+Accuracy ::= SEQUENCE {
+                seconds        INTEGER           OPTIONAL,
+                millis     [0] INTEGER  (1..999) OPTIONAL,
+                micros     [1] INTEGER  (1..999) OPTIONAL  }
+*/
+
+typedef struct TS_accuracy_st {
+    ASN1_INTEGER *seconds;
+    ASN1_INTEGER *millis;
+    ASN1_INTEGER *micros;
+} TS_ACCURACY;
+
+/*-
+TSTInfo ::= SEQUENCE  {
+    version                      INTEGER  { v1(1) },
+    policy                       TSAPolicyId,
+    messageImprint               MessageImprint,
+      -- MUST have the same value as the similar field in
+      -- TimeStampReq
+    serialNumber                 INTEGER,
+     -- Time-Stamping users MUST be ready to accommodate integers
+     -- up to 160 bits.
+    genTime                      GeneralizedTime,
+    accuracy                     Accuracy                 OPTIONAL,
+    ordering                     BOOLEAN             DEFAULT FALSE,
+    nonce                        INTEGER                  OPTIONAL,
+      -- MUST be present if the similar field was present
+      -- in TimeStampReq.  In that case it MUST have the same value.
+    tsa                          [0] GeneralName          OPTIONAL,
+    extensions                   [1] IMPLICIT Extensions  OPTIONAL   }
+*/
+
+typedef struct TS_tst_info_st {
+    ASN1_INTEGER *version;
+    ASN1_OBJECT *policy_id;
+    TS_MSG_IMPRINT *msg_imprint;
+    ASN1_INTEGER *serial;
+    ASN1_GENERALIZEDTIME *time;
+    TS_ACCURACY *accuracy;
+    ASN1_BOOLEAN ordering;
+    ASN1_INTEGER *nonce;
+    GENERAL_NAME *tsa;
+    STACK_OF(X509_EXTENSION) *extensions;
+} TS_TST_INFO;
+
+/*-
+PKIStatusInfo ::= SEQUENCE {
+    status        PKIStatus,
+    statusString  PKIFreeText     OPTIONAL,
+    failInfo      PKIFailureInfo  OPTIONAL  }
+
+From RFC 1510 - section 3.1.1:
+PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
+        -- text encoded as UTF-8 String (note:  each UTF8String SHOULD
+        -- include an RFC 1766 language tag to indicate the language
+        -- of the contained text)
+*/
+
+/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */
+
+# define TS_STATUS_GRANTED                       0
+# define TS_STATUS_GRANTED_WITH_MODS             1
+# define TS_STATUS_REJECTION                     2
+# define TS_STATUS_WAITING                       3
+# define TS_STATUS_REVOCATION_WARNING            4
+# define TS_STATUS_REVOCATION_NOTIFICATION       5
+
+/*
+ * Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c
+ */
+
+# define TS_INFO_BAD_ALG                 0
+# define TS_INFO_BAD_REQUEST             2
+# define TS_INFO_BAD_DATA_FORMAT         5
+# define TS_INFO_TIME_NOT_AVAILABLE      14
+# define TS_INFO_UNACCEPTED_POLICY       15
+# define TS_INFO_UNACCEPTED_EXTENSION    16
+# define TS_INFO_ADD_INFO_NOT_AVAILABLE  17
+# define TS_INFO_SYSTEM_FAILURE          25
+
+typedef struct TS_status_info_st {
+    ASN1_INTEGER *status;
+    STACK_OF(ASN1_UTF8STRING) *text;
+    ASN1_BIT_STRING *failure_info;
+} TS_STATUS_INFO;
+
+DECLARE_STACK_OF(ASN1_UTF8STRING)
+DECLARE_ASN1_SET_OF(ASN1_UTF8STRING)
+
+/*-
+TimeStampResp ::= SEQUENCE  {
+     status                  PKIStatusInfo,
+     timeStampToken          TimeStampToken     OPTIONAL }
+*/
+
+typedef struct TS_resp_st {
+    TS_STATUS_INFO *status_info;
+    PKCS7 *token;
+    TS_TST_INFO *tst_info;
+} TS_RESP;
+
+/* The structure below would belong to the ESS component. */
+
+/*-
+IssuerSerial ::= SEQUENCE {
+        issuer                   GeneralNames,
+        serialNumber             CertificateSerialNumber
+        }
+*/
+
+typedef struct ESS_issuer_serial {
+    STACK_OF(GENERAL_NAME) *issuer;
+    ASN1_INTEGER *serial;
+} ESS_ISSUER_SERIAL;
+
+/*-
+ESSCertID ::=  SEQUENCE {
+        certHash                 Hash,
+        issuerSerial             IssuerSerial OPTIONAL
+}
+*/
+
+typedef struct ESS_cert_id {
+    ASN1_OCTET_STRING *hash;    /* Always SHA-1 digest. */
+    ESS_ISSUER_SERIAL *issuer_serial;
+} ESS_CERT_ID;
+
+DECLARE_STACK_OF(ESS_CERT_ID)
+DECLARE_ASN1_SET_OF(ESS_CERT_ID)
+
+/*-
+SigningCertificate ::=  SEQUENCE {
+       certs        SEQUENCE OF ESSCertID,
+       policies     SEQUENCE OF PolicyInformation OPTIONAL
+}
+*/
+
+typedef struct ESS_signing_cert {
+    STACK_OF(ESS_CERT_ID) *cert_ids;
+    STACK_OF(POLICYINFO) *policy_info;
+} ESS_SIGNING_CERT;
+
+TS_REQ *TS_REQ_new(void);
+void TS_REQ_free(TS_REQ *a);
+int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp);
+TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length);
+
+TS_REQ *TS_REQ_dup(TS_REQ *a);
+
+TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
+int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
+TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
+int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);
+
+TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void);
+void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
+int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
+                                   const unsigned char **pp, long length);
+
+TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);
+
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
+int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a);
+int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a);
+
+TS_RESP *TS_RESP_new(void);
+void TS_RESP_free(TS_RESP *a);
+int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
+TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
+TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
+TS_RESP *TS_RESP_dup(TS_RESP *a);
+
+TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
+int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
+TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a);
+int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a);
+
+TS_STATUS_INFO *TS_STATUS_INFO_new(void);
+void TS_STATUS_INFO_free(TS_STATUS_INFO *a);
+int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
+TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
+                                   const unsigned char **pp, long length);
+TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
+
+TS_TST_INFO *TS_TST_INFO_new(void);
+void TS_TST_INFO_free(TS_TST_INFO *a);
+int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
+TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
+                             long length);
+TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a);
+
+TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
+int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
+TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a);
+int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a);
+
+TS_ACCURACY *TS_ACCURACY_new(void);
+void TS_ACCURACY_free(TS_ACCURACY *a);
+int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
+TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
+                             long length);
+TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a);
+
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
+void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
+int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp);
+ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
+                                         const unsigned char **pp,
+                                         long length);
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);
+
+ESS_CERT_ID *ESS_CERT_ID_new(void);
+void ESS_CERT_ID_free(ESS_CERT_ID *a);
+int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
+ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
+                             long length);
+ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a);
+
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
+void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
+int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp);
+ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
+                                       const unsigned char **pp, long length);
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);
+
+void ERR_load_TS_strings(void);
+
+int TS_REQ_set_version(TS_REQ *a, long version);
+long TS_REQ_get_version(const TS_REQ *a);
+
+int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a);
+
+int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg);
+X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a);
+
+int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len);
+ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a);
+
+int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy);
+ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a);
+
+int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a);
+
+int TS_REQ_set_cert_req(TS_REQ *a, int cert_req);
+int TS_REQ_get_cert_req(const TS_REQ *a);
+
+STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a);
+void TS_REQ_ext_free(TS_REQ *a);
+int TS_REQ_get_ext_count(TS_REQ *a);
+int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos);
+int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos);
+int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos);
+X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc);
+X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc);
+int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc);
+void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx);
+
+/* Function declarations for TS_REQ defined in ts/ts_req_print.c */
+
+int TS_REQ_print_bio(BIO *bio, TS_REQ *a);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */
+
+int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info);
+TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a);
+
+/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
+void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info);
+PKCS7 *TS_RESP_get_token(TS_RESP *a);
+TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a);
+
+int TS_TST_INFO_set_version(TS_TST_INFO *a, long version);
+long TS_TST_INFO_get_version(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id);
+ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial);
+const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime);
+const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy);
+TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a);
+
+int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds);
+const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis);
+const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros);
+const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a);
+
+int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering);
+int TS_TST_INFO_get_ordering(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa);
+GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a);
+
+STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a);
+void TS_TST_INFO_ext_free(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_count(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos);
+int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos);
+int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos);
+X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc);
+X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc);
+int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc);
+void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx);
+
+/*
+ * Declarations related to response generation, defined in ts/ts_resp_sign.c.
+ */
+
+/* Optional flags for response generation. */
+
+/* Don't include the TSA name in response. */
+# define TS_TSA_NAME             0x01
+
+/* Set ordering to true in response. */
+# define TS_ORDERING             0x02
+
+/*
+ * Include the signer certificate and the other specified certificates in
+ * the ESS signing certificate attribute beside the PKCS7 signed data.
+ * Only the signer certificates is included by default.
+ */
+# define TS_ESS_CERT_ID_CHAIN    0x04
+
+/* Forward declaration. */
+struct TS_resp_ctx;
+
+/* This must return a unique number less than 160 bits long. */
+typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *);
+
+/*
+ * This must return the seconds and microseconds since Jan 1, 1970 in the sec
+ * and usec variables allocated by the caller. Return non-zero for success
+ * and zero for failure.
+ */
+typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec,
+                           long *usec);
+
+/*
+ * This must process the given extension. It can modify the TS_TST_INFO
+ * object of the context. Return values: !0 (processed), 0 (error, it must
+ * set the status info/failure info of the response).
+ */
+typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *,
+                                void *);
+
+typedef struct TS_resp_ctx {
+    X509 *signer_cert;
+    EVP_PKEY *signer_key;
+    STACK_OF(X509) *certs;      /* Certs to include in signed data. */
+    STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
+    ASN1_OBJECT *default_policy; /* It may appear in policies, too. */
+    STACK_OF(EVP_MD) *mds;      /* Acceptable message digests. */
+    ASN1_INTEGER *seconds;      /* accuracy, 0 means not specified. */
+    ASN1_INTEGER *millis;       /* accuracy, 0 means not specified. */
+    ASN1_INTEGER *micros;       /* accuracy, 0 means not specified. */
+    unsigned clock_precision_digits; /* fraction of seconds in time stamp
+                                      * token. */
+    unsigned flags;             /* Optional info, see values above. */
+    /* Callback functions. */
+    TS_serial_cb serial_cb;
+    void *serial_cb_data;       /* User data for serial_cb. */
+    TS_time_cb time_cb;
+    void *time_cb_data;         /* User data for time_cb. */
+    TS_extension_cb extension_cb;
+    void *extension_cb_data;    /* User data for extension_cb. */
+    /* These members are used only while creating the response. */
+    TS_REQ *request;
+    TS_RESP *response;
+    TS_TST_INFO *tst_info;
+} TS_RESP_CTX;
+
+DECLARE_STACK_OF(EVP_MD)
+DECLARE_ASN1_SET_OF(EVP_MD)
+
+/* Creates a response context that can be used for generating responses. */
+TS_RESP_CTX *TS_RESP_CTX_new(void);
+void TS_RESP_CTX_free(TS_RESP_CTX *ctx);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy);
+
+/* No additional certs are included in the response by default. */
+int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);
+
+/*
+ * Adds a new acceptable policy, only the default policy is accepted by
+ * default.
+ */
+int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy);
+
+/*
+ * Adds a new acceptable message digest. Note that no message digests are
+ * accepted by default. The md argument is shared with the caller.
+ */
+int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);
+
+/* Accuracy is not included by default. */
+int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
+                             int secs, int millis, int micros);
+
+/*
+ * Clock precision digits, i.e. the number of decimal digits: '0' means sec,
+ * '3' msec, '6' usec, and so on. Default is 0.
+ */
+int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
+                                           unsigned clock_precision_digits);
+/* At most we accept usec precision. */
+# define TS_MAX_CLOCK_PRECISION_DIGITS   6
+
+/* Maximum status message length */
+# define TS_MAX_STATUS_LENGTH   (1024 * 1024)
+
+/* No flags are set by default. */
+void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);
+
+/* Default callback always returns a constant. */
+void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data);
+
+/* Default callback uses the gettimeofday() and gmtime() system calls. */
+void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);
+
+/*
+ * Default callback rejects all extensions. The extension callback is called
+ * when the TS_TST_INFO object is already set up and not signed yet.
+ */
+/* FIXME: extension handling is not tested yet. */
+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
+                                  TS_extension_cb cb, void *data);
+
+/* The following methods can be used in the callbacks. */
+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
+                                int status, const char *text);
+
+/* Sets the status info only if it is still TS_STATUS_GRANTED. */
+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
+                                     int status, const char *text);
+
+int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);
+
+/* The get methods below can be used in the extension callback. */
+TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx);
+
+TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);
+
+/*
+ * Creates the signed TS_TST_INFO and puts it in TS_RESP.
+ * In case of errors it sets the status info properly.
+ * Returns NULL only in case of memory allocation/fatal error.
+ */
+TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);
+
+/*
+ * Declarations related to response verification,
+ * they are defined in ts/ts_resp_verify.c.
+ */
+
+int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
+                             X509_STORE *store, X509 **signer_out);
+
+/* Context structure for the generic verify method. */
+
+/* Verify the signer's certificate and the signature of the response. */
+# define TS_VFY_SIGNATURE        (1u << 0)
+/* Verify the version number of the response. */
+# define TS_VFY_VERSION          (1u << 1)
+/* Verify if the policy supplied by the user matches the policy of the TSA. */
+# define TS_VFY_POLICY           (1u << 2)
+/*
+ * Verify the message imprint provided by the user. This flag should not be
+ * specified with TS_VFY_DATA.
+ */
+# define TS_VFY_IMPRINT          (1u << 3)
+/*
+ * Verify the message imprint computed by the verify method from the user
+ * provided data and the MD algorithm of the response. This flag should not
+ * be specified with TS_VFY_IMPRINT.
+ */
+# define TS_VFY_DATA             (1u << 4)
+/* Verify the nonce value. */
+# define TS_VFY_NONCE            (1u << 5)
+/* Verify if the TSA name field matches the signer certificate. */
+# define TS_VFY_SIGNER           (1u << 6)
+/* Verify if the TSA name field equals to the user provided name. */
+# define TS_VFY_TSA_NAME         (1u << 7)
+
+/* You can use the following convenience constants. */
+# define TS_VFY_ALL_IMPRINT      (TS_VFY_SIGNATURE       \
+                                 | TS_VFY_VERSION       \
+                                 | TS_VFY_POLICY        \
+                                 | TS_VFY_IMPRINT       \
+                                 | TS_VFY_NONCE         \
+                                 | TS_VFY_SIGNER        \
+                                 | TS_VFY_TSA_NAME)
+# define TS_VFY_ALL_DATA         (TS_VFY_SIGNATURE       \
+                                 | TS_VFY_VERSION       \
+                                 | TS_VFY_POLICY        \
+                                 | TS_VFY_DATA          \
+                                 | TS_VFY_NONCE         \
+                                 | TS_VFY_SIGNER        \
+                                 | TS_VFY_TSA_NAME)
+
+typedef struct TS_verify_ctx {
+    /* Set this to the union of TS_VFY_... flags you want to carry out. */
+    unsigned flags;
+    /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
+    X509_STORE *store;
+    STACK_OF(X509) *certs;
+    /* Must be set only with TS_VFY_POLICY. */
+    ASN1_OBJECT *policy;
+    /*
+     * Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, the
+     * algorithm from the response is used.
+     */
+    X509_ALGOR *md_alg;
+    unsigned char *imprint;
+    unsigned imprint_len;
+    /* Must be set only with TS_VFY_DATA. */
+    BIO *data;
+    /* Must be set only with TS_VFY_TSA_NAME. */
+    ASN1_INTEGER *nonce;
+    /* Must be set only with TS_VFY_TSA_NAME. */
+    GENERAL_NAME *tsa_name;
+} TS_VERIFY_CTX;
+
+int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response);
+int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token);
+
+/*
+ * Declarations related to response verification context,
+ * they are defined in ts/ts_verify_ctx.c.
+ */
+
+/* Set all fields to zero. */
+TS_VERIFY_CTX *TS_VERIFY_CTX_new(void);
+void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);
+
+/*-
+ * If ctx is NULL, it allocates and returns a new object, otherwise
+ * it returns ctx. It initialises all the members as follows:
+ * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
+ * certs = NULL
+ * store = NULL
+ * policy = policy from the request or NULL if absent (in this case
+ *      TS_VFY_POLICY is cleared from flags as well)
+ * md_alg = MD algorithm from request
+ * imprint, imprint_len = imprint from request
+ * data = NULL
+ * nonce, nonce_len = nonce from the request or NULL if absent (in this case
+ *      TS_VFY_NONCE is cleared from flags as well)
+ * tsa_name = NULL
+ * Important: after calling this method TS_VFY_SIGNATURE should be added!
+ */
+TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */
+
+int TS_RESP_print_bio(BIO *bio, TS_RESP *a);
+int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a);
+int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a);
+
+/* Common utility functions defined in ts/ts_lib.c */
+
+int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num);
+int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj);
+int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions);
+int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg);
+int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg);
+
+/*
+ * Function declarations for handling configuration options, defined in
+ * ts/ts_conf.c
+ */
+
+X509 *TS_CONF_load_cert(const char *file);
+STACK_OF(X509) *TS_CONF_load_certs(const char *file);
+EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass);
+const char *TS_CONF_get_tsa_section(CONF *conf, const char *section);
+int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
+                       TS_RESP_CTX *ctx);
+int TS_CONF_set_crypto_device(CONF *conf, const char *section,
+                              const char *device);
+int TS_CONF_set_default_engine(const char *name);
+int TS_CONF_set_signer_cert(CONF *conf, const char *section,
+                            const char *cert, TS_RESP_CTX *ctx);
+int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
+                      TS_RESP_CTX *ctx);
+int TS_CONF_set_signer_key(CONF *conf, const char *section,
+                           const char *key, const char *pass,
+                           TS_RESP_CTX *ctx);
+int TS_CONF_set_def_policy(CONF *conf, const char *section,
+                           const char *policy, TS_RESP_CTX *ctx);
+int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
+                                       TS_RESP_CTX *ctx);
+int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
+                                  TS_RESP_CTX *ctx);
+
+/* -------------------------------------------------- */
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_TS_strings(void);
+
+/* Error codes for the TS functions. */
+
+/* Function codes. */
+# define TS_F_D2I_TS_RESP                                 147
+# define TS_F_DEF_SERIAL_CB                               110
+# define TS_F_DEF_TIME_CB                                 111
+# define TS_F_ESS_ADD_SIGNING_CERT                        112
+# define TS_F_ESS_CERT_ID_NEW_INIT                        113
+# define TS_F_ESS_SIGNING_CERT_NEW_INIT                   114
+# define TS_F_INT_TS_RESP_VERIFY_TOKEN                    149
+# define TS_F_PKCS7_TO_TS_TST_INFO                        148
+# define TS_F_TS_ACCURACY_SET_MICROS                      115
+# define TS_F_TS_ACCURACY_SET_MILLIS                      116
+# define TS_F_TS_ACCURACY_SET_SECONDS                     117
+# define TS_F_TS_CHECK_IMPRINTS                           100
+# define TS_F_TS_CHECK_NONCES                             101
+# define TS_F_TS_CHECK_POLICY                             102
+# define TS_F_TS_CHECK_SIGNING_CERTS                      103
+# define TS_F_TS_CHECK_STATUS_INFO                        104
+# define TS_F_TS_COMPUTE_IMPRINT                          145
+# define TS_F_TS_CONF_SET_DEFAULT_ENGINE                  146
+# define TS_F_TS_GET_STATUS_TEXT                          105
+# define TS_F_TS_MSG_IMPRINT_SET_ALGO                     118
+# define TS_F_TS_REQ_SET_MSG_IMPRINT                      119
+# define TS_F_TS_REQ_SET_NONCE                            120
+# define TS_F_TS_REQ_SET_POLICY_ID                        121
+# define TS_F_TS_RESP_CREATE_RESPONSE                     122
+# define TS_F_TS_RESP_CREATE_TST_INFO                     123
+# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO                124
+# define TS_F_TS_RESP_CTX_ADD_MD                          125
+# define TS_F_TS_RESP_CTX_ADD_POLICY                      126
+# define TS_F_TS_RESP_CTX_NEW                             127
+# define TS_F_TS_RESP_CTX_SET_ACCURACY                    128
+# define TS_F_TS_RESP_CTX_SET_CERTS                       129
+# define TS_F_TS_RESP_CTX_SET_DEF_POLICY                  130
+# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT                 131
+# define TS_F_TS_RESP_CTX_SET_STATUS_INFO                 132
+# define TS_F_TS_RESP_GET_POLICY                          133
+# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION          134
+# define TS_F_TS_RESP_SET_STATUS_INFO                     135
+# define TS_F_TS_RESP_SET_TST_INFO                        150
+# define TS_F_TS_RESP_SIGN                                136
+# define TS_F_TS_RESP_VERIFY_SIGNATURE                    106
+# define TS_F_TS_RESP_VERIFY_TOKEN                        107
+# define TS_F_TS_TST_INFO_SET_ACCURACY                    137
+# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT                 138
+# define TS_F_TS_TST_INFO_SET_NONCE                       139
+# define TS_F_TS_TST_INFO_SET_POLICY_ID                   140
+# define TS_F_TS_TST_INFO_SET_SERIAL                      141
+# define TS_F_TS_TST_INFO_SET_TIME                        142
+# define TS_F_TS_TST_INFO_SET_TSA                         143
+# define TS_F_TS_VERIFY                                   108
+# define TS_F_TS_VERIFY_CERT                              109
+# define TS_F_TS_VERIFY_CTX_NEW                           144
+
+/* Reason codes. */
+# define TS_R_BAD_PKCS7_TYPE                              132
+# define TS_R_BAD_TYPE                                    133
+# define TS_R_CERTIFICATE_VERIFY_ERROR                    100
+# define TS_R_COULD_NOT_SET_ENGINE                        127
+# define TS_R_COULD_NOT_SET_TIME                          115
+# define TS_R_D2I_TS_RESP_INT_FAILED                      128
+# define TS_R_DETACHED_CONTENT                            134
+# define TS_R_ESS_ADD_SIGNING_CERT_ERROR                  116
+# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR               101
+# define TS_R_INVALID_NULL_POINTER                        102
+# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE          117
+# define TS_R_MESSAGE_IMPRINT_MISMATCH                    103
+# define TS_R_NONCE_MISMATCH                              104
+# define TS_R_NONCE_NOT_RETURNED                          105
+# define TS_R_NO_CONTENT                                  106
+# define TS_R_NO_TIME_STAMP_TOKEN                         107
+# define TS_R_PKCS7_ADD_SIGNATURE_ERROR                   118
+# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR                 119
+# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED                 129
+# define TS_R_POLICY_MISMATCH                             108
+# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE      120
+# define TS_R_RESPONSE_SETUP_ERROR                        121
+# define TS_R_SIGNATURE_FAILURE                           109
+# define TS_R_THERE_MUST_BE_ONE_SIGNER                    110
+# define TS_R_TIME_SYSCALL_ERROR                          122
+# define TS_R_TOKEN_NOT_PRESENT                           130
+# define TS_R_TOKEN_PRESENT                               131
+# define TS_R_TSA_NAME_MISMATCH                           111
+# define TS_R_TSA_UNTRUSTED                               112
+# define TS_R_TST_INFO_SETUP_ERROR                        123
+# define TS_R_TS_DATASIGN                                 124
+# define TS_R_UNACCEPTABLE_POLICY                         125
+# define TS_R_UNSUPPORTED_MD_ALGORITHM                    126
+# define TS_R_UNSUPPORTED_VERSION                         113
+# define TS_R_WRONG_CONTENT_TYPE                          114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/txt_db.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/txt_db.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/txt_db.h	(working copy)
@@ -0,0 +1,112 @@
+/* crypto/txt_db/txt_db.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_TXT_DB_H
+# define HEADER_TXT_DB_H
+
+# include <openssl/opensslconf.h>
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/stack.h>
+# include <openssl/lhash.h>
+
+# define DB_ERROR_OK                     0
+# define DB_ERROR_MALLOC                 1
+# define DB_ERROR_INDEX_CLASH            2
+# define DB_ERROR_INDEX_OUT_OF_RANGE     3
+# define DB_ERROR_NO_INDEX               4
+# define DB_ERROR_INSERT_INDEX_CLASH     5
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef OPENSSL_STRING *OPENSSL_PSTRING;
+DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING)
+
+typedef struct txt_db_st {
+    int num_fields;
+    STACK_OF(OPENSSL_PSTRING) *data;
+    LHASH_OF(OPENSSL_STRING) **index;
+    int (**qual) (OPENSSL_STRING *);
+    long error;
+    long arg1;
+    long arg2;
+    OPENSSL_STRING *arg_row;
+} TXT_DB;
+
+# ifndef OPENSSL_NO_BIO
+TXT_DB *TXT_DB_read(BIO *in, int num);
+long TXT_DB_write(BIO *out, TXT_DB *db);
+# else
+TXT_DB *TXT_DB_read(char *in, int num);
+long TXT_DB_write(char *out, TXT_DB *db);
+# endif
+int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
+                        LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
+void TXT_DB_free(TXT_DB *db);
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
+                                    OPENSSL_STRING *value);
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ui.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ui.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ui.h	(working copy)
@@ -0,0 +1,415 @@
+/* crypto/ui/ui.h */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_H
+# define HEADER_UI_H
+
+# ifndef OPENSSL_NO_DEPRECATED
+#  include <openssl/crypto.h>
+# endif
+# include <openssl/safestack.h>
+# include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Declared already in ossl_typ.h */
+/* typedef struct ui_st UI; */
+/* typedef struct ui_method_st UI_METHOD; */
+
+/*
+ * All the following functions return -1 or NULL on error and in some cases
+ * (UI_process()) -2 if interrupted or in some other way cancelled. When
+ * everything is fine, they return 0, a positive value or a non-NULL pointer,
+ * all depending on their purpose.
+ */
+
+/* Creators and destructor.   */
+UI *UI_new(void);
+UI *UI_new_method(const UI_METHOD *method);
+void UI_free(UI *ui);
+
+/*-
+   The following functions are used to add strings to be printed and prompt
+   strings to prompt for data.  The names are UI_{add,dup}_<function>_string
+   and UI_{add,dup}_input_boolean.
+
+   UI_{add,dup}_<function>_string have the following meanings:
+        add     add a text or prompt string.  The pointers given to these
+                functions are used verbatim, no copying is done.
+        dup     make a copy of the text or prompt string, then add the copy
+                to the collection of strings in the user interface.
+        <function>
+                The function is a name for the functionality that the given
+                string shall be used for.  It can be one of:
+                        input   use the string as data prompt.
+                        verify  use the string as verification prompt.  This
+                                is used to verify a previous input.
+                        info    use the string for informational output.
+                        error   use the string for error output.
+   Honestly, there's currently no difference between info and error for the
+   moment.
+
+   UI_{add,dup}_input_boolean have the same semantics for "add" and "dup",
+   and are typically used when one wants to prompt for a yes/no response.
+
+   All of the functions in this group take a UI and a prompt string.
+   The string input and verify addition functions also take a flag argument,
+   a buffer for the result to end up with, a minimum input size and a maximum
+   input size (the result buffer MUST be large enough to be able to contain
+   the maximum number of characters).  Additionally, the verify addition
+   functions takes another buffer to compare the result against.
+   The boolean input functions take an action description string (which should
+   be safe to ignore if the expected user action is obvious, for example with
+   a dialog box with an OK button and a Cancel button), a string of acceptable
+   characters to mean OK and to mean Cancel.  The two last strings are checked
+   to make sure they don't have common characters.  Additionally, the same
+   flag argument as for the string input is taken, as well as a result buffer.
+   The result buffer is required to be at least one byte long.  Depending on
+   the answer, the first character from the OK or the Cancel character strings
+   will be stored in the first byte of the result buffer.  No NUL will be
+   added, so the result is *not* a string.
+
+   On success, the all return an index of the added information.  That index
+   is usefull when retrieving results with UI_get0_result(). */
+int UI_add_input_string(UI *ui, const char *prompt, int flags,
+                        char *result_buf, int minsize, int maxsize);
+int UI_dup_input_string(UI *ui, const char *prompt, int flags,
+                        char *result_buf, int minsize, int maxsize);
+int UI_add_verify_string(UI *ui, const char *prompt, int flags,
+                         char *result_buf, int minsize, int maxsize,
+                         const char *test_buf);
+int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
+                         char *result_buf, int minsize, int maxsize,
+                         const char *test_buf);
+int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+                         const char *ok_chars, const char *cancel_chars,
+                         int flags, char *result_buf);
+int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+                         const char *ok_chars, const char *cancel_chars,
+                         int flags, char *result_buf);
+int UI_add_info_string(UI *ui, const char *text);
+int UI_dup_info_string(UI *ui, const char *text);
+int UI_add_error_string(UI *ui, const char *text);
+int UI_dup_error_string(UI *ui, const char *text);
+
+/* These are the possible flags.  They can be or'ed together. */
+/* Use to have echoing of input */
+# define UI_INPUT_FLAG_ECHO              0x01
+/*
+ * Use a default password.  Where that password is found is completely up to
+ * the application, it might for example be in the user data set with
+ * UI_add_user_data().  It is not recommended to have more than one input in
+ * each UI being marked with this flag, or the application might get
+ * confused.
+ */
+# define UI_INPUT_FLAG_DEFAULT_PWD       0x02
+
+/*-
+ * The user of these routines may want to define flags of their own.  The core
+ * UI won't look at those, but will pass them on to the method routines.  They
+ * must use higher bits so they don't get confused with the UI bits above.
+ * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use.  A good
+ * example of use is this:
+ *
+ *    #define MY_UI_FLAG1       (0x01 << UI_INPUT_FLAG_USER_BASE)
+ *
+*/
+# define UI_INPUT_FLAG_USER_BASE 16
+
+/*-
+ * The following function helps construct a prompt.  object_desc is a
+ * textual short description of the object, for example "pass phrase",
+ * and object_name is the name of the object (might be a card name or
+ * a file name.
+ * The returned string shall always be allocated on the heap with
+ * OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
+ *
+ * If the ui_method doesn't contain a pointer to a user-defined prompt
+ * constructor, a default string is built, looking like this:
+ *
+ *       "Enter {object_desc} for {object_name}:"
+ *
+ * So, if object_desc has the value "pass phrase" and object_name has
+ * the value "foo.key", the resulting string is:
+ *
+ *       "Enter pass phrase for foo.key:"
+*/
+char *UI_construct_prompt(UI *ui_method,
+                          const char *object_desc, const char *object_name);
+
+/*
+ * The following function is used to store a pointer to user-specific data.
+ * Any previous such pointer will be returned and replaced.
+ *
+ * For callback purposes, this function makes a lot more sense than using
+ * ex_data, since the latter requires that different parts of OpenSSL or
+ * applications share the same ex_data index.
+ *
+ * Note that the UI_OpenSSL() method completely ignores the user data. Other
+ * methods may not, however.
+ */
+void *UI_add_user_data(UI *ui, void *user_data);
+/* We need a user data retrieving function as well.  */
+void *UI_get0_user_data(UI *ui);
+
+/* Return the result associated with a prompt given with the index i. */
+const char *UI_get0_result(UI *ui, int i);
+
+/* When all strings have been added, process the whole thing. */
+int UI_process(UI *ui);
+
+/*
+ * Give a user interface parametrised control commands.  This can be used to
+ * send down an integer, a data pointer or a function pointer, as well as be
+ * used to get information from a UI.
+ */
+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void));
+
+/* The commands */
+/*
+ * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the
+ * OpenSSL error stack before printing any info or added error messages and
+ * before any prompting.
+ */
+# define UI_CTRL_PRINT_ERRORS            1
+/*
+ * Check if a UI_process() is possible to do again with the same instance of
+ * a user interface.  This makes UI_ctrl() return 1 if it is redoable, and 0
+ * if not.
+ */
+# define UI_CTRL_IS_REDOABLE             2
+
+/* Some methods may use extra data */
+# define UI_set_app_data(s,arg)         UI_set_ex_data(s,0,arg)
+# define UI_get_app_data(s)             UI_get_ex_data(s,0)
+int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+                        CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int UI_set_ex_data(UI *r, int idx, void *arg);
+void *UI_get_ex_data(UI *r, int idx);
+
+/* Use specific methods instead of the built-in one */
+void UI_set_default_method(const UI_METHOD *meth);
+const UI_METHOD *UI_get_default_method(void);
+const UI_METHOD *UI_get_method(UI *ui);
+const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);
+
+/* The method with all the built-in thingies */
+UI_METHOD *UI_OpenSSL(void);
+
+/* ---------- For method writers ---------- */
+/*-
+   A method contains a number of functions that implement the low level
+   of the User Interface.  The functions are:
+
+        an opener       This function starts a session, maybe by opening
+                        a channel to a tty, or by opening a window.
+        a writer        This function is called to write a given string,
+                        maybe to the tty, maybe as a field label in a
+                        window.
+        a flusher       This function is called to flush everything that
+                        has been output so far.  It can be used to actually
+                        display a dialog box after it has been built.
+        a reader        This function is called to read a given prompt,
+                        maybe from the tty, maybe from a field in a
+                        window.  Note that it's called wth all string
+                        structures, not only the prompt ones, so it must
+                        check such things itself.
+        a closer        This function closes the session, maybe by closing
+                        the channel to the tty, or closing the window.
+
+   All these functions are expected to return:
+
+        0       on error.
+        1       on success.
+        -1      on out-of-band events, for example if some prompting has
+                been canceled (by pressing Ctrl-C, for example).  This is
+                only checked when returned by the flusher or the reader.
+
+   The way this is used, the opener is first called, then the writer for all
+   strings, then the flusher, then the reader for all strings and finally the
+   closer.  Note that if you want to prompt from a terminal or other command
+   line interface, the best is to have the reader also write the prompts
+   instead of having the writer do it.  If you want to prompt from a dialog
+   box, the writer can be used to build up the contents of the box, and the
+   flusher to actually display the box and run the event loop until all data
+   has been given, after which the reader only grabs the given data and puts
+   them back into the UI strings.
+
+   All method functions take a UI as argument.  Additionally, the writer and
+   the reader take a UI_STRING.
+*/
+
+/*
+ * The UI_STRING type is the data structure that contains all the needed info
+ * about a string or a prompt, including test data for a verification prompt.
+ */
+typedef struct ui_string_st UI_STRING;
+DECLARE_STACK_OF(UI_STRING)
+
+/*
+ * The different types of strings that are currently supported. This is only
+ * needed by method authors.
+ */
+enum UI_string_types {
+    UIT_NONE = 0,
+    UIT_PROMPT,                 /* Prompt for a string */
+    UIT_VERIFY,                 /* Prompt for a string and verify */
+    UIT_BOOLEAN,                /* Prompt for a yes/no response */
+    UIT_INFO,                   /* Send info to the user */
+    UIT_ERROR                   /* Send an error message to the user */
+};
+
+/* Create and manipulate methods */
+UI_METHOD *UI_create_method(char *name);
+void UI_destroy_method(UI_METHOD *ui_method);
+int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui));
+int UI_method_set_writer(UI_METHOD *method,
+                         int (*writer) (UI *ui, UI_STRING *uis));
+int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui));
+int UI_method_set_reader(UI_METHOD *method,
+                         int (*reader) (UI *ui, UI_STRING *uis));
+int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui));
+int UI_method_set_prompt_constructor(UI_METHOD *method,
+                                     char *(*prompt_constructor) (UI *ui,
+                                                                  const char
+                                                                  *object_desc,
+                                                                  const char
+                                                                  *object_name));
+int (*UI_method_get_opener(UI_METHOD *method)) (UI *);
+int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *);
+int (*UI_method_get_flusher(UI_METHOD *method)) (UI *);
+int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *);
+int (*UI_method_get_closer(UI_METHOD *method)) (UI *);
+char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
+                                                              const char *,
+                                                              const char *);
+
+/*
+ * The following functions are helpers for method writers to access relevant
+ * data from a UI_STRING.
+ */
+
+/* Return type of the UI_STRING */
+enum UI_string_types UI_get_string_type(UI_STRING *uis);
+/* Return input flags of the UI_STRING */
+int UI_get_input_flags(UI_STRING *uis);
+/* Return the actual string to output (the prompt, info or error) */
+const char *UI_get0_output_string(UI_STRING *uis);
+/*
+ * Return the optional action string to output (the boolean promtp
+ * instruction)
+ */
+const char *UI_get0_action_string(UI_STRING *uis);
+/* Return the result of a prompt */
+const char *UI_get0_result_string(UI_STRING *uis);
+/*
+ * Return the string to test the result against.  Only useful with verifies.
+ */
+const char *UI_get0_test_string(UI_STRING *uis);
+/* Return the required minimum size of the result */
+int UI_get_result_minsize(UI_STRING *uis);
+/* Return the required maximum size of the result */
+int UI_get_result_maxsize(UI_STRING *uis);
+/* Set the result of a UI_STRING. */
+int UI_set_result(UI *ui, UI_STRING *uis, const char *result);
+
+/* A couple of popular utility functions */
+int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
+                           int verify);
+int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
+                    int verify);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_UI_strings(void);
+
+/* Error codes for the UI functions. */
+
+/* Function codes. */
+# define UI_F_GENERAL_ALLOCATE_BOOLEAN                    108
+# define UI_F_GENERAL_ALLOCATE_PROMPT                     109
+# define UI_F_GENERAL_ALLOCATE_STRING                     100
+# define UI_F_UI_CTRL                                     111
+# define UI_F_UI_DUP_ERROR_STRING                         101
+# define UI_F_UI_DUP_INFO_STRING                          102
+# define UI_F_UI_DUP_INPUT_BOOLEAN                        110
+# define UI_F_UI_DUP_INPUT_STRING                         103
+# define UI_F_UI_DUP_VERIFY_STRING                        106
+# define UI_F_UI_GET0_RESULT                              107
+# define UI_F_UI_NEW_METHOD                               104
+# define UI_F_UI_SET_RESULT                               105
+
+/* Reason codes. */
+# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS             104
+# define UI_R_INDEX_TOO_LARGE                             102
+# define UI_R_INDEX_TOO_SMALL                             103
+# define UI_R_NO_RESULT_BUFFER                            105
+# define UI_R_RESULT_TOO_LARGE                            100
+# define UI_R_RESULT_TOO_SMALL                            101
+# define UI_R_UNKNOWN_CONTROL_COMMAND                     106
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ui_compat.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ui_compat.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/ui_compat.h	(working copy)
@@ -0,0 +1,88 @@
+/* crypto/ui/ui.h */
+/*
+ * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project
+ * 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_COMPAT_H
+# define HEADER_UI_COMPAT_H
+
+# include <openssl/opensslconf.h>
+# include <openssl/ui.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following functions were previously part of the DES section, and are
+ * provided here for backward compatibility reasons.
+ */
+
+# define des_read_pw_string(b,l,p,v) \
+        _ossl_old_des_read_pw_string((b),(l),(p),(v))
+# define des_read_pw(b,bf,s,p,v) \
+        _ossl_old_des_read_pw((b),(bf),(s),(p),(v))
+
+int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt,
+                                 int verify);
+int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt,
+                          int verify);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/whrlpool.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/whrlpool.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/whrlpool.h	(working copy)
@@ -0,0 +1,41 @@
+#ifndef HEADER_WHRLPOOL_H
+# define HEADER_WHRLPOOL_H
+
+# include <openssl/e_os2.h>
+# include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# define WHIRLPOOL_DIGEST_LENGTH (512/8)
+# define WHIRLPOOL_BBLOCK        512
+# define WHIRLPOOL_COUNTER       (256/8)
+
+typedef struct {
+    union {
+        unsigned char c[WHIRLPOOL_DIGEST_LENGTH];
+        /* double q is here to ensure 64-bit alignment */
+        double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)];
+    } H;
+    unsigned char data[WHIRLPOOL_BBLOCK / 8];
+    unsigned int bitoff;
+    size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)];
+} WHIRLPOOL_CTX;
+
+# ifndef OPENSSL_NO_WHIRLPOOL
+#  ifdef OPENSSL_FIPS
+int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c);
+#  endif
+int WHIRLPOOL_Init(WHIRLPOOL_CTX *c);
+int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes);
+void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits);
+int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c);
+unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md);
+# endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/x509.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/x509.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/x509.h	(working copy)
@@ -0,0 +1,1330 @@
+/* crypto/x509/x509.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_X509_H
+# define HEADER_X509_H
+
+# include <openssl/e_os2.h>
+# include <openssl/symhacks.h>
+# ifndef OPENSSL_NO_BUFFER
+#  include <openssl/buffer.h>
+# endif
+# ifndef OPENSSL_NO_EVP
+#  include <openssl/evp.h>
+# endif
+# ifndef OPENSSL_NO_BIO
+#  include <openssl/bio.h>
+# endif
+# include <openssl/stack.h>
+# include <openssl/asn1.h>
+# include <openssl/safestack.h>
+
+# ifndef OPENSSL_NO_EC
+#  include <openssl/ec.h>
+# endif
+
+# ifndef OPENSSL_NO_ECDSA
+#  include <openssl/ecdsa.h>
+# endif
+
+# ifndef OPENSSL_NO_ECDH
+#  include <openssl/ecdh.h>
+# endif
+
+# ifndef OPENSSL_NO_DEPRECATED
+#  ifndef OPENSSL_NO_RSA
+#   include <openssl/rsa.h>
+#  endif
+#  ifndef OPENSSL_NO_DSA
+#   include <openssl/dsa.h>
+#  endif
+#  ifndef OPENSSL_NO_DH
+#   include <openssl/dh.h>
+#  endif
+# endif
+
+# ifndef OPENSSL_NO_SHA
+#  include <openssl/sha.h>
+# endif
+# include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_SYS_WIN32
+/* Under Win32 these are defined in wincrypt.h */
+#  undef X509_NAME
+#  undef X509_CERT_PAIR
+#  undef X509_EXTENSIONS
+# endif
+
+# define X509_FILETYPE_PEM       1
+# define X509_FILETYPE_ASN1      2
+# define X509_FILETYPE_DEFAULT   3
+
+# define X509v3_KU_DIGITAL_SIGNATURE     0x0080
+# define X509v3_KU_NON_REPUDIATION       0x0040
+# define X509v3_KU_KEY_ENCIPHERMENT      0x0020
+# define X509v3_KU_DATA_ENCIPHERMENT     0x0010
+# define X509v3_KU_KEY_AGREEMENT         0x0008
+# define X509v3_KU_KEY_CERT_SIGN         0x0004
+# define X509v3_KU_CRL_SIGN              0x0002
+# define X509v3_KU_ENCIPHER_ONLY         0x0001
+# define X509v3_KU_DECIPHER_ONLY         0x8000
+# define X509v3_KU_UNDEF                 0xffff
+
+typedef struct X509_objects_st {
+    int nid;
+    int (*a2i) (void);
+    int (*i2a) (void);
+} X509_OBJECTS;
+
+struct X509_algor_st {
+    ASN1_OBJECT *algorithm;
+    ASN1_TYPE *parameter;
+} /* X509_ALGOR */ ;
+
+DECLARE_ASN1_SET_OF(X509_ALGOR)
+
+typedef STACK_OF(X509_ALGOR) X509_ALGORS;
+
+typedef struct X509_val_st {
+    ASN1_TIME *notBefore;
+    ASN1_TIME *notAfter;
+} X509_VAL;
+
+struct X509_pubkey_st {
+    X509_ALGOR *algor;
+    ASN1_BIT_STRING *public_key;
+    EVP_PKEY *pkey;
+};
+
+typedef struct X509_sig_st {
+    X509_ALGOR *algor;
+    ASN1_OCTET_STRING *digest;
+} X509_SIG;
+
+typedef struct X509_name_entry_st {
+    ASN1_OBJECT *object;
+    ASN1_STRING *value;
+    int set;
+    int size;                   /* temp variable */
+} X509_NAME_ENTRY;
+
+DECLARE_STACK_OF(X509_NAME_ENTRY)
+DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
+
+/* we always keep X509_NAMEs in 2 forms. */
+struct X509_name_st {
+    STACK_OF(X509_NAME_ENTRY) *entries;
+    int modified;               /* true if 'bytes' needs to be built */
+# ifndef OPENSSL_NO_BUFFER
+    BUF_MEM *bytes;
+# else
+    char *bytes;
+# endif
+/*      unsigned long hash; Keep the hash around for lookups */
+    unsigned char *canon_enc;
+    int canon_enclen;
+} /* X509_NAME */ ;
+
+DECLARE_STACK_OF(X509_NAME)
+
+# define X509_EX_V_NETSCAPE_HACK         0x8000
+# define X509_EX_V_INIT                  0x0001
+typedef struct X509_extension_st {
+    ASN1_OBJECT *object;
+    ASN1_BOOLEAN critical;
+    ASN1_OCTET_STRING *value;
+} X509_EXTENSION;
+
+typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
+
+DECLARE_STACK_OF(X509_EXTENSION)
+DECLARE_ASN1_SET_OF(X509_EXTENSION)
+
+/* a sequence of these are used */
+typedef struct x509_attributes_st {
+    ASN1_OBJECT *object;
+    int single;                 /* 0 for a set, 1 for a single item (which is
+                                 * wrong) */
+    union {
+        char *ptr;
+        /*
+         * 0
+         */ STACK_OF(ASN1_TYPE) *set;
+        /*
+         * 1
+         */ ASN1_TYPE *single;
+    } value;
+} X509_ATTRIBUTE;
+
+DECLARE_STACK_OF(X509_ATTRIBUTE)
+DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
+
+typedef struct X509_req_info_st {
+    ASN1_ENCODING enc;
+    ASN1_INTEGER *version;
+    X509_NAME *subject;
+    X509_PUBKEY *pubkey;
+    /*  d=2 hl=2 l=  0 cons: cont: 00 */
+    STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+} X509_REQ_INFO;
+
+typedef struct X509_req_st {
+    X509_REQ_INFO *req_info;
+    X509_ALGOR *sig_alg;
+    ASN1_BIT_STRING *signature;
+    int references;
+} X509_REQ;
+
+typedef struct x509_cinf_st {
+    ASN1_INTEGER *version;      /* [ 0 ] default of v1 */
+    ASN1_INTEGER *serialNumber;
+    X509_ALGOR *signature;
+    X509_NAME *issuer;
+    X509_VAL *validity;
+    X509_NAME *subject;
+    X509_PUBKEY *key;
+    ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
+    ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
+    STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
+    ASN1_ENCODING enc;
+} X509_CINF;
+
+/*
+ * This stuff is certificate "auxiliary info" it contains details which are
+ * useful in certificate stores and databases. When used this is tagged onto
+ * the end of the certificate itself
+ */
+
+typedef struct x509_cert_aux_st {
+    STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
+    STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
+    ASN1_UTF8STRING *alias;     /* "friendly name" */
+    ASN1_OCTET_STRING *keyid;   /* key id of private key */
+    STACK_OF(X509_ALGOR) *other; /* other unspecified info */
+} X509_CERT_AUX;
+
+struct x509_st {
+    X509_CINF *cert_info;
+    X509_ALGOR *sig_alg;
+    ASN1_BIT_STRING *signature;
+    int valid;
+    int references;
+    char *name;
+    CRYPTO_EX_DATA ex_data;
+    /* These contain copies of various extension values */
+    long ex_pathlen;
+    long ex_pcpathlen;
+    unsigned long ex_flags;
+    unsigned long ex_kusage;
+    unsigned long ex_xkusage;
+    unsigned long ex_nscert;
+    ASN1_OCTET_STRING *skid;
+    AUTHORITY_KEYID *akid;
+    X509_POLICY_CACHE *policy_cache;
+    STACK_OF(DIST_POINT) *crldp;
+    STACK_OF(GENERAL_NAME) *altname;
+    NAME_CONSTRAINTS *nc;
+# ifndef OPENSSL_NO_RFC3779
+    STACK_OF(IPAddressFamily) *rfc3779_addr;
+    struct ASIdentifiers_st *rfc3779_asid;
+# endif
+# ifndef OPENSSL_NO_SHA
+    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+# endif
+    X509_CERT_AUX *aux;
+} /* X509 */ ;
+
+DECLARE_STACK_OF(X509)
+DECLARE_ASN1_SET_OF(X509)
+
+/* This is used for a table of trust checking functions */
+
+typedef struct x509_trust_st {
+    int trust;
+    int flags;
+    int (*check_trust) (struct x509_trust_st *, X509 *, int);
+    char *name;
+    int arg1;
+    void *arg2;
+} X509_TRUST;
+
+DECLARE_STACK_OF(X509_TRUST)
+
+typedef struct x509_cert_pair_st {
+    X509 *forward;
+    X509 *reverse;
+} X509_CERT_PAIR;
+
+/* standard trust ids */
+
+# define X509_TRUST_DEFAULT      -1/* Only valid in purpose settings */
+
+# define X509_TRUST_COMPAT       1
+# define X509_TRUST_SSL_CLIENT   2
+# define X509_TRUST_SSL_SERVER   3
+# define X509_TRUST_EMAIL        4
+# define X509_TRUST_OBJECT_SIGN  5
+# define X509_TRUST_OCSP_SIGN    6
+# define X509_TRUST_OCSP_REQUEST 7
+# define X509_TRUST_TSA          8
+
+/* Keep these up to date! */
+# define X509_TRUST_MIN          1
+# define X509_TRUST_MAX          8
+
+/* trust_flags values */
+# define X509_TRUST_DYNAMIC      1
+# define X509_TRUST_DYNAMIC_NAME 2
+
+/* check_trust return codes */
+
+# define X509_TRUST_TRUSTED      1
+# define X509_TRUST_REJECTED     2
+# define X509_TRUST_UNTRUSTED    3
+
+/* Flags for X509_print_ex() */
+
+# define X509_FLAG_COMPAT                0
+# define X509_FLAG_NO_HEADER             1L
+# define X509_FLAG_NO_VERSION            (1L << 1)
+# define X509_FLAG_NO_SERIAL             (1L << 2)
+# define X509_FLAG_NO_SIGNAME            (1L << 3)
+# define X509_FLAG_NO_ISSUER             (1L << 4)
+# define X509_FLAG_NO_VALIDITY           (1L << 5)
+# define X509_FLAG_NO_SUBJECT            (1L << 6)
+# define X509_FLAG_NO_PUBKEY             (1L << 7)
+# define X509_FLAG_NO_EXTENSIONS         (1L << 8)
+# define X509_FLAG_NO_SIGDUMP            (1L << 9)
+# define X509_FLAG_NO_AUX                (1L << 10)
+# define X509_FLAG_NO_ATTRIBUTES         (1L << 11)
+# define X509_FLAG_NO_IDS                (1L << 12)
+
+/* Flags specific to X509_NAME_print_ex() */
+
+/* The field separator information */
+
+# define XN_FLAG_SEP_MASK        (0xf << 16)
+
+# define XN_FLAG_COMPAT          0/* Traditional SSLeay: use old
+                                   * X509_NAME_print */
+# define XN_FLAG_SEP_COMMA_PLUS  (1 << 16)/* RFC2253 ,+ */
+# define XN_FLAG_SEP_CPLUS_SPC   (2 << 16)/* ,+ spaced: more readable */
+# define XN_FLAG_SEP_SPLUS_SPC   (3 << 16)/* ;+ spaced */
+# define XN_FLAG_SEP_MULTILINE   (4 << 16)/* One line per field */
+
+# define XN_FLAG_DN_REV          (1 << 20)/* Reverse DN order */
+
+/* How the field name is shown */
+
+# define XN_FLAG_FN_MASK         (0x3 << 21)
+
+# define XN_FLAG_FN_SN           0/* Object short name */
+# define XN_FLAG_FN_LN           (1 << 21)/* Object long name */
+# define XN_FLAG_FN_OID          (2 << 21)/* Always use OIDs */
+# define XN_FLAG_FN_NONE         (3 << 21)/* No field names */
+
+# define XN_FLAG_SPC_EQ          (1 << 23)/* Put spaces round '=' */
+
+/*
+ * This determines if we dump fields we don't recognise: RFC2253 requires
+ * this.
+ */
+
+# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
+
+# define XN_FLAG_FN_ALIGN        (1 << 25)/* Align field names to 20
+                                           * characters */
+
+/* Complete set of RFC2253 flags */
+
+# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
+                        XN_FLAG_SEP_COMMA_PLUS | \
+                        XN_FLAG_DN_REV | \
+                        XN_FLAG_FN_SN | \
+                        XN_FLAG_DUMP_UNKNOWN_FIELDS)
+
+/* readable oneline form */
+
+# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
+                        ASN1_STRFLGS_ESC_QUOTE | \
+                        XN_FLAG_SEP_CPLUS_SPC | \
+                        XN_FLAG_SPC_EQ | \
+                        XN_FLAG_FN_SN)
+
+/* readable multiline form */
+
+# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
+                        ASN1_STRFLGS_ESC_MSB | \
+                        XN_FLAG_SEP_MULTILINE | \
+                        XN_FLAG_SPC_EQ | \
+                        XN_FLAG_FN_LN | \
+                        XN_FLAG_FN_ALIGN)
+
+struct x509_revoked_st {
+    ASN1_INTEGER *serialNumber;
+    ASN1_TIME *revocationDate;
+    STACK_OF(X509_EXTENSION) /* optional */ *extensions;
+    /* Set up if indirect CRL */
+    STACK_OF(GENERAL_NAME) *issuer;
+    /* Revocation reason */
+    int reason;
+    int sequence;               /* load sequence */
+};
+
+DECLARE_STACK_OF(X509_REVOKED)
+DECLARE_ASN1_SET_OF(X509_REVOKED)
+
+typedef struct X509_crl_info_st {
+    ASN1_INTEGER *version;
+    X509_ALGOR *sig_alg;
+    X509_NAME *issuer;
+    ASN1_TIME *lastUpdate;
+    ASN1_TIME *nextUpdate;
+    STACK_OF(X509_REVOKED) *revoked;
+    STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
+    ASN1_ENCODING enc;
+} X509_CRL_INFO;
+
+struct X509_crl_st {
+    /* actual signature */
+    X509_CRL_INFO *crl;
+    X509_ALGOR *sig_alg;
+    ASN1_BIT_STRING *signature;
+    int references;
+    int flags;
+    /* Copies of various extensions */
+    AUTHORITY_KEYID *akid;
+    ISSUING_DIST_POINT *idp;
+    /* Convenient breakdown of IDP */
+    int idp_flags;
+    int idp_reasons;
+    /* CRL and base CRL numbers for delta processing */
+    ASN1_INTEGER *crl_number;
+    ASN1_INTEGER *base_crl_number;
+# ifndef OPENSSL_NO_SHA
+    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+# endif
+    STACK_OF(GENERAL_NAMES) *issuers;
+    const X509_CRL_METHOD *meth;
+    void *meth_data;
+} /* X509_CRL */ ;
+
+DECLARE_STACK_OF(X509_CRL)
+DECLARE_ASN1_SET_OF(X509_CRL)
+
+typedef struct private_key_st {
+    int version;
+    /* The PKCS#8 data types */
+    X509_ALGOR *enc_algor;
+    ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
+    /* When decrypted, the following will not be NULL */
+    EVP_PKEY *dec_pkey;
+    /* used to encrypt and decrypt */
+    int key_length;
+    char *key_data;
+    int key_free;               /* true if we should auto free key_data */
+    /* expanded version of 'enc_algor' */
+    EVP_CIPHER_INFO cipher;
+    int references;
+} X509_PKEY;
+
+# ifndef OPENSSL_NO_EVP
+typedef struct X509_info_st {
+    X509 *x509;
+    X509_CRL *crl;
+    X509_PKEY *x_pkey;
+    EVP_CIPHER_INFO enc_cipher;
+    int enc_len;
+    char *enc_data;
+    int references;
+} X509_INFO;
+
+DECLARE_STACK_OF(X509_INFO)
+# endif
+
+/*
+ * The next 2 structures and their 8 routines were sent to me by Pat Richard
+ * <patr@x509.com> and are used to manipulate Netscapes spki structures -
+ * useful if you are writing a CA web page
+ */
+typedef struct Netscape_spkac_st {
+    X509_PUBKEY *pubkey;
+    ASN1_IA5STRING *challenge;  /* challenge sent in atlas >= PR2 */
+} NETSCAPE_SPKAC;
+
+typedef struct Netscape_spki_st {
+    NETSCAPE_SPKAC *spkac;      /* signed public key and challenge */
+    X509_ALGOR *sig_algor;
+    ASN1_BIT_STRING *signature;
+} NETSCAPE_SPKI;
+
+/* Netscape certificate sequence structure */
+typedef struct Netscape_certificate_sequence {
+    ASN1_OBJECT *type;
+    STACK_OF(X509) *certs;
+} NETSCAPE_CERT_SEQUENCE;
+
+/*- Unused (and iv length is wrong)
+typedef struct CBCParameter_st
+        {
+        unsigned char iv[8];
+        } CBC_PARAM;
+*/
+
+/* Password based encryption structure */
+
+typedef struct PBEPARAM_st {
+    ASN1_OCTET_STRING *salt;
+    ASN1_INTEGER *iter;
+} PBEPARAM;
+
+/* Password based encryption V2 structures */
+
+typedef struct PBE2PARAM_st {
+    X509_ALGOR *keyfunc;
+    X509_ALGOR *encryption;
+} PBE2PARAM;
+
+typedef struct PBKDF2PARAM_st {
+/* Usually OCTET STRING but could be anything */
+    ASN1_TYPE *salt;
+    ASN1_INTEGER *iter;
+    ASN1_INTEGER *keylength;
+    X509_ALGOR *prf;
+} PBKDF2PARAM;
+
+/* PKCS#8 private key info structure */
+
+struct pkcs8_priv_key_info_st {
+    /* Flag for various broken formats */
+    int broken;
+# define PKCS8_OK                0
+# define PKCS8_NO_OCTET          1
+# define PKCS8_EMBEDDED_PARAM    2
+# define PKCS8_NS_DB             3
+# define PKCS8_NEG_PRIVKEY       4
+    ASN1_INTEGER *version;
+    X509_ALGOR *pkeyalg;
+    /* Should be OCTET STRING but some are broken */
+    ASN1_TYPE *pkey;
+    STACK_OF(X509_ATTRIBUTE) *attributes;
+};
+
+#ifdef  __cplusplus
+}
+#endif
+
+# include <openssl/x509_vfy.h>
+# include <openssl/pkcs7.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define X509_EXT_PACK_UNKNOWN   1
+# define X509_EXT_PACK_STRING    2
+
+# define         X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
+/* #define      X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
+# define         X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
+# define         X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
+# define         X509_extract_key(x)     X509_get_pubkey(x)/*****/
+# define         X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
+# define         X509_REQ_get_subject_name(x) ((x)->req_info->subject)
+# define         X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
+# define         X509_name_cmp(a,b)      X509_NAME_cmp((a),(b))
+# define         X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
+
+# define         X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
+# define         X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
+# define         X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
+# define         X509_CRL_get_issuer(x) ((x)->crl->issuer)
+# define         X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
+                                     int (*crl_free) (X509_CRL *crl),
+                                     int (*crl_lookup) (X509_CRL *crl,
+                                                        X509_REVOKED **ret,
+                                                        ASN1_INTEGER *ser,
+                                                        X509_NAME *issuer),
+                                     int (*crl_verify) (X509_CRL *crl,
+                                                        EVP_PKEY *pk));
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
+void *X509_CRL_get_meth_data(X509_CRL *crl);
+
+/*
+ * This one is only used so that a binary form can output, as in
+ * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf)
+ */
+# define         X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
+
+const char *X509_verify_cert_error_string(long n);
+
+# ifndef OPENSSL_NO_EVP
+int X509_verify(X509 *a, EVP_PKEY *r);
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
+int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
+
+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len);
+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
+int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig);
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
+int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert);
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
+int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
+
+int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
+                       unsigned char *md, unsigned int *len);
+int X509_digest(const X509 *data, const EVP_MD *type,
+                unsigned char *md, unsigned int *len);
+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len);
+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len);
+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
+                     unsigned char *md, unsigned int *len);
+# endif
+
+# ifndef OPENSSL_NO_FP_API
+X509 *d2i_X509_fp(FILE *fp, X509 **x509);
+int i2d_X509_fp(FILE *fp, X509 *x509);
+X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
+int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
+int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req);
+#  ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
+int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa);
+RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
+int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa);
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
+int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa);
+#  endif
+#  ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+#  endif
+#  ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
+int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
+int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
+#  endif
+X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
+int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+                                                PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
+# endif
+
+# ifndef OPENSSL_NO_BIO
+X509 *d2i_X509_bio(BIO *bp, X509 **x509);
+int i2d_X509_bio(BIO *bp, X509 *x509);
+X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
+int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
+int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req);
+#  ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
+int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa);
+RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
+int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa);
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
+int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa);
+#  endif
+#  ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+#  endif
+#  ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
+int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
+int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
+#  endif
+X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
+int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+                                                 PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
+# endif
+
+X509 *X509_dup(X509 *x509);
+X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
+X509_CRL *X509_CRL_dup(X509_CRL *crl);
+X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev);
+X509_REQ *X509_REQ_dup(X509_REQ *req);
+X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
+                    void *pval);
+void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
+                     X509_ALGOR *algor);
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
+
+X509_NAME *X509_NAME_dup(X509_NAME *xn);
+X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+
+int X509_cmp_time(const ASN1_TIME *s, time_t *t);
+int X509_cmp_current_time(const ASN1_TIME *s);
+ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
+                            int offset_day, long offset_sec, time_t *t);
+ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);
+
+const char *X509_get_default_cert_area(void);
+const char *X509_get_default_cert_dir(void);
+const char *X509_get_default_cert_file(void);
+const char *X509_get_default_cert_dir_env(void);
+const char *X509_get_default_cert_file_env(void);
+const char *X509_get_default_private_dir(void);
+
+X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey);
+
+DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
+DECLARE_ASN1_FUNCTIONS(X509_VAL)
+
+DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key);
+int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp);
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
+# ifndef OPENSSL_NO_RSA
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
+# endif
+# ifndef OPENSSL_NO_DSA
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp);
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
+# endif
+# ifndef OPENSSL_NO_EC
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length);
+# endif
+
+DECLARE_ASN1_FUNCTIONS(X509_SIG)
+DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_REQ)
+
+DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
+
+DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME)
+
+int X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(X509_CINF)
+
+DECLARE_ASN1_FUNCTIONS(X509)
+DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
+
+int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int X509_set_ex_data(X509 *r, int idx, void *arg);
+void *X509_get_ex_data(X509 *r, int idx);
+int i2d_X509_AUX(X509 *a, unsigned char **pp);
+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length);
+
+int i2d_re_X509_tbs(X509 *x, unsigned char **pp);
+
+void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
+                         const X509 *x);
+int X509_get_signature_nid(const X509 *x);
+
+int X509_alias_set1(X509 *x, unsigned char *name, int len);
+int X509_keyid_set1(X509 *x, unsigned char *id, int len);
+unsigned char *X509_alias_get0(X509 *x, int *len);
+unsigned char *X509_keyid_get0(X509 *x, int *len);
+int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
+                                                                int);
+int X509_TRUST_set(int *t, int trust);
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
+void X509_trust_clear(X509 *x);
+void X509_reject_clear(X509 *x);
+
+DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
+DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_CRL)
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+                            X509_REVOKED **ret, ASN1_INTEGER *serial);
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
+
+X509_PKEY *X509_PKEY_new(void);
+void X509_PKEY_free(X509_PKEY *a);
+int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp);
+X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp,
+                         long length);
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
+
+# ifndef OPENSSL_NO_EVP
+X509_INFO *X509_INFO_new(void);
+void X509_INFO_free(X509_INFO *a);
+char *X509_NAME_oneline(X509_NAME *a, char *buf, int size);
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
+                ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey);
+
+int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
+                unsigned char *md, unsigned int *len);
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
+              X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+              char *data, EVP_PKEY *pkey, const EVP_MD *type);
+
+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
+                     unsigned char *md, unsigned int *len);
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                     ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey);
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data,
+                   EVP_PKEY *pkey, const EVP_MD *type);
+int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+                       void *asn, EVP_MD_CTX *ctx);
+# endif
+
+int X509_set_version(X509 *x, long version);
+int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
+ASN1_INTEGER *X509_get_serialNumber(X509 *x);
+int X509_set_issuer_name(X509 *x, X509_NAME *name);
+X509_NAME *X509_get_issuer_name(X509 *a);
+int X509_set_subject_name(X509 *x, X509_NAME *name);
+X509_NAME *X509_get_subject_name(X509 *a);
+int X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
+int X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
+int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
+EVP_PKEY *X509_get_pubkey(X509 *x);
+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);
+int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ );
+
+int X509_REQ_set_version(X509_REQ *x, long version);
+int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
+int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req);
+int X509_REQ_extension_nid(int nid);
+int *X509_REQ_get_extension_nids(void);
+void X509_REQ_set_extension_nids(int *nids);
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+                                int nid);
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+int X509_REQ_get_attr_count(const X509_REQ *req);
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos);
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+                             int lastpos);
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+                              const ASN1_OBJECT *obj, int type,
+                              const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+                              int nid, int type,
+                              const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+                              const char *attrname, int type,
+                              const unsigned char *bytes, int len);
+
+int X509_CRL_set_version(X509_CRL *x, long version);
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
+int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_sort(X509_CRL *crl);
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
+int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
+
+X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
+                        EVP_PKEY *skey, const EVP_MD *md, unsigned int flags);
+
+int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey);
+
+int X509_check_private_key(X509 *x509, EVP_PKEY *pkey);
+int X509_chain_check_suiteb(int *perror_depth,
+                            X509 *x, STACK_OF(X509) *chain,
+                            unsigned long flags);
+int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags);
+STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);
+
+int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
+unsigned long X509_issuer_and_serial_hash(X509 *a);
+
+int X509_issuer_name_cmp(const X509 *a, const X509 *b);
+unsigned long X509_issuer_name_hash(X509 *a);
+
+int X509_subject_name_cmp(const X509 *a, const X509 *b);
+unsigned long X509_subject_name_hash(X509 *x);
+
+# ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_name_hash_old(X509 *a);
+unsigned long X509_subject_name_hash_old(X509 *x);
+# endif
+
+int X509_cmp(const X509 *a, const X509 *b);
+int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+unsigned long X509_NAME_hash(X509_NAME *x);
+unsigned long X509_NAME_hash_old(X509_NAME *x);
+
+int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
+# ifndef OPENSSL_NO_FP_API
+int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
+                     unsigned long cflag);
+int X509_print_fp(FILE *bp, X509 *x);
+int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
+int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
+                          unsigned long flags);
+# endif
+
+# ifndef OPENSSL_NO_BIO
+int X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent,
+                       unsigned long flags);
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag,
+                  unsigned long cflag);
+int X509_print(BIO *bp, X509 *x);
+int X509_ocspid_print(BIO *bp, X509 *x);
+int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent);
+int X509_CRL_print(BIO *bp, X509_CRL *x);
+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag,
+                      unsigned long cflag);
+int X509_REQ_print(BIO *bp, X509_REQ *req);
+# endif
+
+int X509_NAME_entry_count(X509_NAME *name);
+int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len);
+int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+                              char *buf, int len);
+
+/*
+ * NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
+ * lastpos, search after that position on.
+ */
+int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos);
+int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+                               int lastpos);
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne,
+                        int loc, int set);
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+                               unsigned char *bytes, int len, int loc,
+                               int set);
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+                               unsigned char *bytes, int len, int loc,
+                               int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+                                               const char *field, int type,
+                                               const unsigned char *bytes,
+                                               int len);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+                                               int type, unsigned char *bytes,
+                                               int len);
+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+                               const unsigned char *bytes, int len, int loc,
+                               int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+                                               ASN1_OBJECT *obj, int type,
+                                               const unsigned char *bytes,
+                                               int len);
+int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj);
+int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+                             const unsigned char *bytes, int len);
+ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
+ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+
+int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+                          int nid, int lastpos);
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+                          ASN1_OBJECT *obj, int lastpos);
+int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+                               int crit, int lastpos);
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+                                         X509_EXTENSION *ex, int loc);
+
+int X509_get_ext_count(X509 *x);
+int X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
+int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos);
+int X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
+X509_EXTENSION *X509_get_ext(X509 *x, int loc);
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
+int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
+void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+                      unsigned long flags);
+
+int X509_CRL_get_ext_count(X509_CRL *x);
+int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
+int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos);
+int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
+X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
+int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
+void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+                          unsigned long flags);
+
+int X509_REVOKED_get_ext_count(X509_REVOKED *x);
+int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
+int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
+                                int lastpos);
+int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
+X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
+int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
+void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+                              unsigned long flags);
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
+                                             int nid, int crit,
+                                             ASN1_OCTET_STRING *data);
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+                                             ASN1_OBJECT *obj, int crit,
+                                             ASN1_OCTET_STRING *data);
+int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj);
+int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
+int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data);
+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
+int X509_EXTENSION_get_critical(X509_EXTENSION *ex);
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+                           int lastpos);
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
+                           ASN1_OBJECT *obj, int lastpos);
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+                                           X509_ATTRIBUTE *attr);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, const ASN1_OBJECT *obj,
+                                                  int type,
+                                                  const unsigned char *bytes,
+                                                  int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, int nid, int type,
+                                                  const unsigned char *bytes,
+                                                  int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, const char *attrname,
+                                                  int type,
+                                                  const unsigned char *bytes,
+                                                  int len);
+void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj,
+                              int lastpos, int type);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+                                             int atrtype, const void *data,
+                                             int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+                                             const ASN1_OBJECT *obj,
+                                             int atrtype, const void *data,
+                                             int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+                                             const char *atrname, int type,
+                                             const unsigned char *bytes,
+                                             int len);
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
+                             const void *data, int len);
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype,
+                               void *data);
+int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos);
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+                             int lastpos);
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+                              const ASN1_OBJECT *obj, int type,
+                              const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+                              int nid, int type,
+                              const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+                              const char *attrname, int type,
+                              const unsigned char *bytes, int len);
+
+int X509_verify_cert(X509_STORE_CTX *ctx);
+
+/* lookup a cert from a X509 STACK */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
+                                     ASN1_INTEGER *serial);
+X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(PBEPARAM)
+DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
+DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+                         const unsigned char *salt, int saltlen);
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+                          const unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+                           unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+                              unsigned char *salt, int saltlen,
+                              unsigned char *aiv, int prf_nid);
+
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+                             int prf_nid, int keylen);
+
+/* PKCS#8 utilities */
+
+DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
+PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+                    int version, int ptype, void *pval,
+                    unsigned char *penc, int penclen);
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+                    const unsigned char **pk, int *ppklen,
+                    X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8);
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+                           int ptype, void *pval,
+                           unsigned char *penc, int penclen);
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+                           const unsigned char **pk, int *ppklen,
+                           X509_ALGOR **pa, X509_PUBKEY *pub);
+
+int X509_check_trust(X509 *x, int id, int flags);
+int X509_TRUST_get_count(void);
+X509_TRUST *X509_TRUST_get0(int idx);
+int X509_TRUST_get_by_id(int id);
+int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
+                   char *name, int arg1, void *arg2);
+void X509_TRUST_cleanup(void);
+int X509_TRUST_get_flags(X509_TRUST *xp);
+char *X509_TRUST_get0_name(X509_TRUST *xp);
+int X509_TRUST_get_trust(X509_TRUST *xp);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+void ERR_load_X509_strings(void);
+
+/* Error codes for the X509 functions. */
+
+/* Function codes. */
+# define X509_F_ADD_CERT_DIR                              100
+# define X509_F_BY_FILE_CTRL                              101
+# define X509_F_CHECK_NAME_CONSTRAINTS                    106
+# define X509_F_CHECK_POLICY                              145
+# define X509_F_DIR_CTRL                                  102
+# define X509_F_GET_CERT_BY_SUBJECT                       103
+# define X509_F_NETSCAPE_SPKI_B64_DECODE                  129
+# define X509_F_NETSCAPE_SPKI_B64_ENCODE                  130
+# define X509_F_X509AT_ADD1_ATTR                          135
+# define X509_F_X509V3_ADD_EXT                            104
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID              136
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ              137
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT              140
+# define X509_F_X509_ATTRIBUTE_GET0_DATA                  139
+# define X509_F_X509_ATTRIBUTE_SET1_DATA                  138
+# define X509_F_X509_CHECK_PRIVATE_KEY                    128
+# define X509_F_X509_CRL_DIFF                             105
+# define X509_F_X509_CRL_PRINT_FP                         147
+# define X509_F_X509_EXTENSION_CREATE_BY_NID              108
+# define X509_F_X509_EXTENSION_CREATE_BY_OBJ              109
+# define X509_F_X509_GET_PUBKEY_PARAMETERS                110
+# define X509_F_X509_LOAD_CERT_CRL_FILE                   132
+# define X509_F_X509_LOAD_CERT_FILE                       111
+# define X509_F_X509_LOAD_CRL_FILE                        112
+# define X509_F_X509_NAME_ADD_ENTRY                       113
+# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID             114
+# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT             131
+# define X509_F_X509_NAME_ENTRY_SET_OBJECT                115
+# define X509_F_X509_NAME_ONELINE                         116
+# define X509_F_X509_NAME_PRINT                           117
+# define X509_F_X509_PRINT_EX_FP                          118
+# define X509_F_X509_PUBKEY_GET                           119
+# define X509_F_X509_PUBKEY_SET                           120
+# define X509_F_X509_REQ_CHECK_PRIVATE_KEY                144
+# define X509_F_X509_REQ_PRINT_EX                         121
+# define X509_F_X509_REQ_PRINT_FP                         122
+# define X509_F_X509_REQ_TO_X509                          123
+# define X509_F_X509_STORE_ADD_CERT                       124
+# define X509_F_X509_STORE_ADD_CRL                        125
+# define X509_F_X509_STORE_CTX_GET1_ISSUER                146
+# define X509_F_X509_STORE_CTX_INIT                       143
+# define X509_F_X509_STORE_CTX_NEW                        142
+# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT            134
+# define X509_F_X509_TO_X509_REQ                          126
+# define X509_F_X509_TRUST_ADD                            133
+# define X509_F_X509_TRUST_SET                            141
+# define X509_F_X509_VERIFY_CERT                          127
+
+/* Reason codes. */
+# define X509_R_AKID_MISMATCH                             110
+# define X509_R_BAD_X509_FILETYPE                         100
+# define X509_R_BASE64_DECODE_ERROR                       118
+# define X509_R_CANT_CHECK_DH_KEY                         114
+# define X509_R_CERT_ALREADY_IN_HASH_TABLE                101
+# define X509_R_CRL_ALREADY_DELTA                         127
+# define X509_R_CRL_VERIFY_FAILURE                        131
+# define X509_R_ERR_ASN1_LIB                              102
+# define X509_R_IDP_MISMATCH                              128
+# define X509_R_INVALID_DIRECTORY                         113
+# define X509_R_INVALID_FIELD_NAME                        119
+# define X509_R_INVALID_TRUST                             123
+# define X509_R_ISSUER_MISMATCH                           129
+# define X509_R_KEY_TYPE_MISMATCH                         115
+# define X509_R_KEY_VALUES_MISMATCH                       116
+# define X509_R_LOADING_CERT_DIR                          103
+# define X509_R_LOADING_DEFAULTS                          104
+# define X509_R_METHOD_NOT_SUPPORTED                      124
+# define X509_R_NAME_TOO_LONG                             134
+# define X509_R_NEWER_CRL_NOT_NEWER                       132
+# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY              105
+# define X509_R_NO_CRL_NUMBER                             130
+# define X509_R_PUBLIC_KEY_DECODE_ERROR                   125
+# define X509_R_PUBLIC_KEY_ENCODE_ERROR                   126
+# define X509_R_SHOULD_RETRY                              106
+# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN        107
+# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY            108
+# define X509_R_UNKNOWN_KEY_TYPE                          117
+# define X509_R_UNKNOWN_NID                               109
+# define X509_R_UNKNOWN_PURPOSE_ID                        121
+# define X509_R_UNKNOWN_TRUST_ID                          120
+# define X509_R_UNSUPPORTED_ALGORITHM                     111
+# define X509_R_WRONG_LOOKUP_TYPE                         112
+# define X509_R_WRONG_TYPE                                122
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/x509_vfy.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/x509_vfy.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/x509_vfy.h	(working copy)
@@ -0,0 +1,652 @@
+/* crypto/x509/x509_vfy.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_X509_H
+# include <openssl/x509.h>
+/*
+ * openssl/x509.h ends up #include-ing this file at about the only
+ * appropriate moment.
+ */
+#endif
+
+#ifndef HEADER_X509_VFY_H
+# define HEADER_X509_VFY_H
+
+# include <openssl/opensslconf.h>
+# ifndef OPENSSL_NO_LHASH
+#  include <openssl/lhash.h>
+# endif
+# include <openssl/bio.h>
+# include <openssl/crypto.h>
+# include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# if 0
+/* Outer object */
+typedef struct x509_hash_dir_st {
+    int num_dirs;
+    char **dirs;
+    int *dirs_type;
+    int num_dirs_alloced;
+} X509_HASH_DIR_CTX;
+# endif
+
+typedef struct x509_file_st {
+    int num_paths;              /* number of paths to files or directories */
+    int num_alloced;
+    char **paths;               /* the list of paths or directories */
+    int *path_type;
+} X509_CERT_FILE_CTX;
+
+/*******************************/
+/*-
+SSL_CTX -> X509_STORE
+                -> X509_LOOKUP
+                        ->X509_LOOKUP_METHOD
+                -> X509_LOOKUP
+                        ->X509_LOOKUP_METHOD
+
+SSL     -> X509_STORE_CTX
+                ->X509_STORE
+
+The X509_STORE holds the tables etc for verification stuff.
+A X509_STORE_CTX is used while validating a single certificate.
+The X509_STORE has X509_LOOKUPs for looking up certs.
+The X509_STORE then calls a function to actually verify the
+certificate chain.
+*/
+
+# define X509_LU_RETRY           -1
+# define X509_LU_FAIL            0
+# define X509_LU_X509            1
+# define X509_LU_CRL             2
+# define X509_LU_PKEY            3
+
+typedef struct x509_object_st {
+    /* one of the above types */
+    int type;
+    union {
+        char *ptr;
+        X509 *x509;
+        X509_CRL *crl;
+        EVP_PKEY *pkey;
+    } data;
+} X509_OBJECT;
+
+typedef struct x509_lookup_st X509_LOOKUP;
+
+DECLARE_STACK_OF(X509_LOOKUP)
+DECLARE_STACK_OF(X509_OBJECT)
+
+/* This is a static that defines the function interface */
+typedef struct x509_lookup_method_st {
+    const char *name;
+    int (*new_item) (X509_LOOKUP *ctx);
+    void (*free) (X509_LOOKUP *ctx);
+    int (*init) (X509_LOOKUP *ctx);
+    int (*shutdown) (X509_LOOKUP *ctx);
+    int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
+                 char **ret);
+    int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name,
+                           X509_OBJECT *ret);
+    int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name,
+                                 ASN1_INTEGER *serial, X509_OBJECT *ret);
+    int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type,
+                               unsigned char *bytes, int len,
+                               X509_OBJECT *ret);
+    int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len,
+                         X509_OBJECT *ret);
+} X509_LOOKUP_METHOD;
+
+typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID;
+
+/*
+ * This structure hold all parameters associated with a verify operation by
+ * including an X509_VERIFY_PARAM structure in related structures the
+ * parameters used can be customized
+ */
+
+typedef struct X509_VERIFY_PARAM_st {
+    char *name;
+    time_t check_time;          /* Time to use */
+    unsigned long inh_flags;    /* Inheritance flags */
+    unsigned long flags;        /* Various verify flags */
+    int purpose;                /* purpose to check untrusted certificates */
+    int trust;                  /* trust setting to check */
+    int depth;                  /* Verify depth */
+    STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
+    X509_VERIFY_PARAM_ID *id;   /* opaque ID data */
+} X509_VERIFY_PARAM;
+
+DECLARE_STACK_OF(X509_VERIFY_PARAM)
+
+/*
+ * This is used to hold everything.  It is used for all certificate
+ * validation.  Once we have a certificate chain, the 'verify' function is
+ * then called to actually check the cert chain.
+ */
+struct x509_store_st {
+    /* The following is a cache of trusted certs */
+    int cache;                  /* if true, stash any hits */
+    STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
+    /* These are external lookup methods */
+    STACK_OF(X509_LOOKUP) *get_cert_methods;
+    X509_VERIFY_PARAM *param;
+    /* Callbacks for various operations */
+    /* called to verify a certificate */
+    int (*verify) (X509_STORE_CTX *ctx);
+    /* error callback */
+    int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
+    /* get issuers cert from ctx */
+    int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+    /* check issued */
+    int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+    /* Check revocation status of chain */
+    int (*check_revocation) (X509_STORE_CTX *ctx);
+    /* retrieve CRL */
+    int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
+    /* Check CRL validity */
+    int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
+    /* Check certificate against CRL */
+    int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
+    STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    int (*cleanup) (X509_STORE_CTX *ctx);
+    CRYPTO_EX_DATA ex_data;
+    int references;
+} /* X509_STORE */ ;
+
+int X509_STORE_set_depth(X509_STORE *store, int depth);
+
+# define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
+# define X509_STORE_set_verify_func(ctx,func)    ((ctx)->verify=(func))
+
+/* This is the functions plus an instance of the local variables. */
+struct x509_lookup_st {
+    int init;                   /* have we been started */
+    int skip;                   /* don't use us. */
+    X509_LOOKUP_METHOD *method; /* the functions */
+    char *method_data;          /* method data */
+    X509_STORE *store_ctx;      /* who owns us */
+} /* X509_LOOKUP */ ;
+
+/*
+ * This is a used when verifying cert chains.  Since the gathering of the
+ * cert chain can take some time (and have to be 'retried', this needs to be
+ * kept and passed around.
+ */
+struct x509_store_ctx_st {      /* X509_STORE_CTX */
+    X509_STORE *ctx;
+    /* used when looking up certs */
+    int current_method;
+    /* The following are set by the caller */
+    /* The cert to check */
+    X509 *cert;
+    /* chain of X509s - untrusted - passed in */
+    STACK_OF(X509) *untrusted;
+    /* set of CRLs passed in */
+    STACK_OF(X509_CRL) *crls;
+    X509_VERIFY_PARAM *param;
+    /* Other info for use with get_issuer() */
+    void *other_ctx;
+    /* Callbacks for various operations */
+    /* called to verify a certificate */
+    int (*verify) (X509_STORE_CTX *ctx);
+    /* error callback */
+    int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
+    /* get issuers cert from ctx */
+    int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+    /* check issued */
+    int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+    /* Check revocation status of chain */
+    int (*check_revocation) (X509_STORE_CTX *ctx);
+    /* retrieve CRL */
+    int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
+    /* Check CRL validity */
+    int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
+    /* Check certificate against CRL */
+    int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
+    int (*check_policy) (X509_STORE_CTX *ctx);
+    STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    int (*cleanup) (X509_STORE_CTX *ctx);
+    /* The following is built up */
+    /* if 0, rebuild chain */
+    int valid;
+    /* index of last untrusted cert */
+    int last_untrusted;
+    /* chain of X509s - built up and trusted */
+    STACK_OF(X509) *chain;
+    /* Valid policy tree */
+    X509_POLICY_TREE *tree;
+    /* Require explicit policy value */
+    int explicit_policy;
+    /* When something goes wrong, this is why */
+    int error_depth;
+    int error;
+    X509 *current_cert;
+    /* cert currently being tested as valid issuer */
+    X509 *current_issuer;
+    /* current CRL */
+    X509_CRL *current_crl;
+    /* score of current CRL */
+    int current_crl_score;
+    /* Reason mask */
+    unsigned int current_reasons;
+    /* For CRL path validation: parent context */
+    X509_STORE_CTX *parent;
+    CRYPTO_EX_DATA ex_data;
+} /* X509_STORE_CTX */ ;
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
+
+# define X509_STORE_CTX_set_app_data(ctx,data) \
+        X509_STORE_CTX_set_ex_data(ctx,0,data)
+# define X509_STORE_CTX_get_app_data(ctx) \
+        X509_STORE_CTX_get_ex_data(ctx,0)
+
+# define X509_L_FILE_LOAD        1
+# define X509_L_ADD_DIR          2
+
+# define X509_LOOKUP_load_file(x,name,type) \
+                X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
+
+# define X509_LOOKUP_add_dir(x,name,type) \
+                X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
+
+# define         X509_V_OK                                       0
+# define         X509_V_ERR_UNSPECIFIED                          1
+
+# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT            2
+# define         X509_V_ERR_UNABLE_TO_GET_CRL                    3
+# define         X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     4
+# define         X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      5
+# define         X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6
+# define         X509_V_ERR_CERT_SIGNATURE_FAILURE               7
+# define         X509_V_ERR_CRL_SIGNATURE_FAILURE                8
+# define         X509_V_ERR_CERT_NOT_YET_VALID                   9
+# define         X509_V_ERR_CERT_HAS_EXPIRED                     10
+# define         X509_V_ERR_CRL_NOT_YET_VALID                    11
+# define         X509_V_ERR_CRL_HAS_EXPIRED                      12
+# define         X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       13
+# define         X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        14
+# define         X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       15
+# define         X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       16
+# define         X509_V_ERR_OUT_OF_MEM                           17
+# define         X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          18
+# define         X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN            19
+# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    20
+# define         X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      21
+# define         X509_V_ERR_CERT_CHAIN_TOO_LONG                  22
+# define         X509_V_ERR_CERT_REVOKED                         23
+# define         X509_V_ERR_INVALID_CA                           24
+# define         X509_V_ERR_PATH_LENGTH_EXCEEDED                 25
+# define         X509_V_ERR_INVALID_PURPOSE                      26
+# define         X509_V_ERR_CERT_UNTRUSTED                       27
+# define         X509_V_ERR_CERT_REJECTED                        28
+/* These are 'informational' when looking for issuer cert */
+# define         X509_V_ERR_SUBJECT_ISSUER_MISMATCH              29
+# define         X509_V_ERR_AKID_SKID_MISMATCH                   30
+# define         X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH          31
+# define         X509_V_ERR_KEYUSAGE_NO_CERTSIGN                 32
+
+# define         X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER             33
+# define         X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION         34
+# define         X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35
+# define         X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36
+# define         X509_V_ERR_INVALID_NON_CA                       37
+# define         X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38
+# define         X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39
+# define         X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40
+
+# define         X509_V_ERR_INVALID_EXTENSION                    41
+# define         X509_V_ERR_INVALID_POLICY_EXTENSION             42
+# define         X509_V_ERR_NO_EXPLICIT_POLICY                   43
+# define         X509_V_ERR_DIFFERENT_CRL_SCOPE                  44
+# define         X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE        45
+
+# define         X509_V_ERR_UNNESTED_RESOURCE                    46
+
+# define         X509_V_ERR_PERMITTED_VIOLATION                  47
+# define         X509_V_ERR_EXCLUDED_VIOLATION                   48
+# define         X509_V_ERR_SUBTREE_MINMAX                       49
+# define         X509_V_ERR_APPLICATION_VERIFICATION             50
+# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE          51
+# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX        52
+# define         X509_V_ERR_UNSUPPORTED_NAME_SYNTAX              53
+# define         X509_V_ERR_CRL_PATH_VALIDATION_ERROR            54
+
+/* Suite B mode algorithm violation */
+# define         X509_V_ERR_SUITE_B_INVALID_VERSION              56
+# define         X509_V_ERR_SUITE_B_INVALID_ALGORITHM            57
+# define         X509_V_ERR_SUITE_B_INVALID_CURVE                58
+# define         X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM  59
+# define         X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED              60
+# define         X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
+
+/* Host, email and IP check errors */
+# define         X509_V_ERR_HOSTNAME_MISMATCH                    62
+# define         X509_V_ERR_EMAIL_MISMATCH                       63
+# define         X509_V_ERR_IP_ADDRESS_MISMATCH                  64
+
+/* Caller error */
+# define         X509_V_ERR_INVALID_CALL                         65
+/* Issuer lookup error */
+# define         X509_V_ERR_STORE_LOOKUP                         66
+
+# define         X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION         67
+
+/* Certificate verify flags */
+
+/* Send issuer+subject checks to verify_cb */
+# define X509_V_FLAG_CB_ISSUER_CHECK             0x1
+/* Use check time instead of current time */
+# define X509_V_FLAG_USE_CHECK_TIME              0x2
+/* Lookup CRLs */
+# define X509_V_FLAG_CRL_CHECK                   0x4
+/* Lookup CRLs for whole chain */
+# define X509_V_FLAG_CRL_CHECK_ALL               0x8
+/* Ignore unhandled critical extensions */
+# define X509_V_FLAG_IGNORE_CRITICAL             0x10
+/* Disable workarounds for broken certificates */
+# define X509_V_FLAG_X509_STRICT                 0x20
+/* Enable proxy certificate validation */
+# define X509_V_FLAG_ALLOW_PROXY_CERTS           0x40
+/* Enable policy checking */
+# define X509_V_FLAG_POLICY_CHECK                0x80
+/* Policy variable require-explicit-policy */
+# define X509_V_FLAG_EXPLICIT_POLICY             0x100
+/* Policy variable inhibit-any-policy */
+# define X509_V_FLAG_INHIBIT_ANY                 0x200
+/* Policy variable inhibit-policy-mapping */
+# define X509_V_FLAG_INHIBIT_MAP                 0x400
+/* Notify callback that policy is OK */
+# define X509_V_FLAG_NOTIFY_POLICY               0x800
+/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
+# define X509_V_FLAG_EXTENDED_CRL_SUPPORT        0x1000
+/* Delta CRL support */
+# define X509_V_FLAG_USE_DELTAS                  0x2000
+/* Check selfsigned CA signature */
+# define X509_V_FLAG_CHECK_SS_SIGNATURE          0x4000
+/* Use trusted store first */
+# define X509_V_FLAG_TRUSTED_FIRST               0x8000
+/* Suite B 128 bit only mode: not normally used */
+# define X509_V_FLAG_SUITEB_128_LOS_ONLY         0x10000
+/* Suite B 192 bit only mode */
+# define X509_V_FLAG_SUITEB_192_LOS              0x20000
+/* Suite B 128 bit mode allowing 192 bit algorithms */
+# define X509_V_FLAG_SUITEB_128_LOS              0x30000
+
+/* Allow partial chains if at least one certificate is in trusted store */
+# define X509_V_FLAG_PARTIAL_CHAIN               0x80000
+/*
+ * If the initial chain is not trusted, do not attempt to build an alternative
+ * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag
+ * will force the behaviour to match that of previous versions.
+ */
+# define X509_V_FLAG_NO_ALT_CHAINS               0x100000
+
+# define X509_VP_FLAG_DEFAULT                    0x1
+# define X509_VP_FLAG_OVERWRITE                  0x2
+# define X509_VP_FLAG_RESET_FLAGS                0x4
+# define X509_VP_FLAG_LOCKED                     0x8
+# define X509_VP_FLAG_ONCE                       0x10
+
+/* Internal use: mask of policy related options */
+# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
+                                | X509_V_FLAG_EXPLICIT_POLICY \
+                                | X509_V_FLAG_INHIBIT_ANY \
+                                | X509_V_FLAG_INHIBIT_MAP)
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+                               X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
+                                             int type, X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
+                                        X509_OBJECT *x);
+void X509_OBJECT_up_ref_count(X509_OBJECT *a);
+void X509_OBJECT_free_contents(X509_OBJECT *a);
+X509_STORE *X509_STORE_new(void);
+void X509_STORE_free(X509_STORE *v);
+
+STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
+STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
+int X509_STORE_set_trust(X509_STORE *ctx, int trust);
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
+
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+                              int (*verify_cb) (int, X509_STORE_CTX *));
+
+void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
+                                   STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX
+                                                              *ctx,
+                                                              X509_NAME *nm));
+
+X509_STORE_CTX *X509_STORE_CTX_new(void);
+
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+                        X509 *x509, STACK_OF(X509) *chain);
+void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+
+X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
+
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
+
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
+                              X509_OBJECT *ret);
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+                     long argl, char **ret);
+
+# ifndef OPENSSL_NO_STDIO
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+# endif
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
+void X509_LOOKUP_free(X509_LOOKUP *ctx);
+int X509_LOOKUP_init(X509_LOOKUP *ctx);
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+                           X509_OBJECT *ret);
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+                                 ASN1_INTEGER *serial, X509_OBJECT *ret);
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+                               unsigned char *bytes, int len,
+                               X509_OBJECT *ret);
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
+                         X509_OBJECT *ret);
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
+
+# ifndef OPENSSL_NO_STDIO
+int X509_STORE_load_locations(X509_STORE *ctx,
+                              const char *file, const char *dir);
+int X509_STORE_set_default_paths(X509_STORE *ctx);
+# endif
+
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
+                                    CRYPTO_EX_new *new_func,
+                                    CRYPTO_EX_dup *dup_func,
+                                    CRYPTO_EX_free *free_func);
+int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data);
+void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx);
+int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s);
+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x);
+void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk);
+void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk);
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+                                   int purpose, int trust);
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+                             time_t t);
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+                                  int (*verify_cb) (int, X509_STORE_CTX *));
+
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
+
+/* X509_VERIFY_PARAM functions */
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
+                              const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
+                           const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param,
+                                unsigned long flags);
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+                                  unsigned long flags);
+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+                                  ASN1_OBJECT *policy);
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
+                                    STACK_OF(ASN1_OBJECT) *policies);
+
+int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
+                                const char *name, size_t namelen);
+int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
+                                const char *name, size_t namelen);
+void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
+                                     unsigned int flags);
+char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *);
+int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
+                                 const char *email, size_t emaillen);
+int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
+                              const unsigned char *ip, size_t iplen);
+int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param,
+                                  const char *ipasc);
+
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
+const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param);
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_get_count(void);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
+void X509_VERIFY_PARAM_table_cleanup(void);
+
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+                      STACK_OF(X509) *certs,
+                      STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags);
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree);
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
+X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
+                                               int i);
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
+                                                           X509_POLICY_TREE
+                                                           *tree);
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
+                                                                X509_POLICY_TREE
+                                                                *tree);
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level,
+                                              int i);
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
+
+STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
+                                                           X509_POLICY_NODE
+                                                           *node);
+const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
+                                                     *node);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/x509v3.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/x509v3.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/iOS/openssl/x509v3.h	(working copy)
@@ -0,0 +1,1055 @@
+/* x509v3.h */
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_X509V3_H
+# define HEADER_X509V3_H
+
+# include <openssl/bio.h>
+# include <openssl/x509.h>
+# include <openssl/conf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# ifdef OPENSSL_SYS_WIN32
+/* Under Win32 these are defined in wincrypt.h */
+#  undef X509_NAME
+#  undef X509_CERT_PAIR
+#  undef X509_EXTENSIONS
+# endif
+
+/* Forward reference */
+struct v3_ext_method;
+struct v3_ext_ctx;
+
+/* Useful typedefs */
+
+typedef void *(*X509V3_EXT_NEW)(void);
+typedef void (*X509V3_EXT_FREE) (void *);
+typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long);
+typedef int (*X509V3_EXT_I2D) (void *, unsigned char **);
+typedef STACK_OF(CONF_VALUE) *
+    (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext,
+                       STACK_OF(CONF_VALUE) *extlist);
+typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method,
+                                struct v3_ext_ctx *ctx,
+                                STACK_OF(CONF_VALUE) *values);
+typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method,
+                                void *ext);
+typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method,
+                                struct v3_ext_ctx *ctx, const char *str);
+typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext,
+                               BIO *out, int indent);
+typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method,
+                                struct v3_ext_ctx *ctx, const char *str);
+
+/* V3 extension structure */
+
+struct v3_ext_method {
+    int ext_nid;
+    int ext_flags;
+/* If this is set the following four fields are ignored */
+    ASN1_ITEM_EXP *it;
+/* Old style ASN1 calls */
+    X509V3_EXT_NEW ext_new;
+    X509V3_EXT_FREE ext_free;
+    X509V3_EXT_D2I d2i;
+    X509V3_EXT_I2D i2d;
+/* The following pair is used for string extensions */
+    X509V3_EXT_I2S i2s;
+    X509V3_EXT_S2I s2i;
+/* The following pair is used for multi-valued extensions */
+    X509V3_EXT_I2V i2v;
+    X509V3_EXT_V2I v2i;
+/* The following are used for raw extensions */
+    X509V3_EXT_I2R i2r;
+    X509V3_EXT_R2I r2i;
+    void *usr_data;             /* Any extension specific data */
+};
+
+typedef struct X509V3_CONF_METHOD_st {
+    char *(*get_string) (void *db, char *section, char *value);
+    STACK_OF(CONF_VALUE) *(*get_section) (void *db, char *section);
+    void (*free_string) (void *db, char *string);
+    void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section);
+} X509V3_CONF_METHOD;
+
+/* Context specific info */
+struct v3_ext_ctx {
+# define CTX_TEST 0x1
+    int flags;
+    X509 *issuer_cert;
+    X509 *subject_cert;
+    X509_REQ *subject_req;
+    X509_CRL *crl;
+    X509V3_CONF_METHOD *db_meth;
+    void *db;
+/* Maybe more here */
+};
+
+typedef struct v3_ext_method X509V3_EXT_METHOD;
+
+DECLARE_STACK_OF(X509V3_EXT_METHOD)
+
+/* ext_flags values */
+# define X509V3_EXT_DYNAMIC      0x1
+# define X509V3_EXT_CTX_DEP      0x2
+# define X509V3_EXT_MULTILINE    0x4
+
+typedef BIT_STRING_BITNAME ENUMERATED_NAMES;
+
+typedef struct BASIC_CONSTRAINTS_st {
+    int ca;
+    ASN1_INTEGER *pathlen;
+} BASIC_CONSTRAINTS;
+
+typedef struct PKEY_USAGE_PERIOD_st {
+    ASN1_GENERALIZEDTIME *notBefore;
+    ASN1_GENERALIZEDTIME *notAfter;
+} PKEY_USAGE_PERIOD;
+
+typedef struct otherName_st {
+    ASN1_OBJECT *type_id;
+    ASN1_TYPE *value;
+} OTHERNAME;
+
+typedef struct EDIPartyName_st {
+    ASN1_STRING *nameAssigner;
+    ASN1_STRING *partyName;
+} EDIPARTYNAME;
+
+typedef struct GENERAL_NAME_st {
+# define GEN_OTHERNAME   0
+# define GEN_EMAIL       1
+# define GEN_DNS         2
+# define GEN_X400        3
+# define GEN_DIRNAME     4
+# define GEN_EDIPARTY    5
+# define GEN_URI         6
+# define GEN_IPADD       7
+# define GEN_RID         8
+    int type;
+    union {
+        char *ptr;
+        OTHERNAME *otherName;   /* otherName */
+        ASN1_IA5STRING *rfc822Name;
+        ASN1_IA5STRING *dNSName;
+        ASN1_TYPE *x400Address;
+        X509_NAME *directoryName;
+        EDIPARTYNAME *ediPartyName;
+        ASN1_IA5STRING *uniformResourceIdentifier;
+        ASN1_OCTET_STRING *iPAddress;
+        ASN1_OBJECT *registeredID;
+        /* Old names */
+        ASN1_OCTET_STRING *ip;  /* iPAddress */
+        X509_NAME *dirn;        /* dirn */
+        ASN1_IA5STRING *ia5;    /* rfc822Name, dNSName,
+                                 * uniformResourceIdentifier */
+        ASN1_OBJECT *rid;       /* registeredID */
+        ASN1_TYPE *other;       /* x400Address */
+    } d;
+} GENERAL_NAME;
+
+typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
+
+typedef struct ACCESS_DESCRIPTION_st {
+    ASN1_OBJECT *method;
+    GENERAL_NAME *location;
+} ACCESS_DESCRIPTION;
+
+typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
+
+typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;
+
+DECLARE_STACK_OF(GENERAL_NAME)
+DECLARE_ASN1_SET_OF(GENERAL_NAME)
+
+DECLARE_STACK_OF(ACCESS_DESCRIPTION)
+DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION)
+
+typedef struct DIST_POINT_NAME_st {
+    int type;
+    union {
+        GENERAL_NAMES *fullname;
+        STACK_OF(X509_NAME_ENTRY) *relativename;
+    } name;
+/* If relativename then this contains the full distribution point name */
+    X509_NAME *dpname;
+} DIST_POINT_NAME;
+/* All existing reasons */
+# define CRLDP_ALL_REASONS       0x807f
+
+# define CRL_REASON_NONE                         -1
+# define CRL_REASON_UNSPECIFIED                  0
+# define CRL_REASON_KEY_COMPROMISE               1
+# define CRL_REASON_CA_COMPROMISE                2
+# define CRL_REASON_AFFILIATION_CHANGED          3
+# define CRL_REASON_SUPERSEDED                   4
+# define CRL_REASON_CESSATION_OF_OPERATION       5
+# define CRL_REASON_CERTIFICATE_HOLD             6
+# define CRL_REASON_REMOVE_FROM_CRL              8
+# define CRL_REASON_PRIVILEGE_WITHDRAWN          9
+# define CRL_REASON_AA_COMPROMISE                10
+
+struct DIST_POINT_st {
+    DIST_POINT_NAME *distpoint;
+    ASN1_BIT_STRING *reasons;
+    GENERAL_NAMES *CRLissuer;
+    int dp_reasons;
+};
+
+typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
+
+DECLARE_STACK_OF(DIST_POINT)
+DECLARE_ASN1_SET_OF(DIST_POINT)
+
+struct AUTHORITY_KEYID_st {
+    ASN1_OCTET_STRING *keyid;
+    GENERAL_NAMES *issuer;
+    ASN1_INTEGER *serial;
+};
+
+/* Strong extranet structures */
+
+typedef struct SXNET_ID_st {
+    ASN1_INTEGER *zone;
+    ASN1_OCTET_STRING *user;
+} SXNETID;
+
+DECLARE_STACK_OF(SXNETID)
+DECLARE_ASN1_SET_OF(SXNETID)
+
+typedef struct SXNET_st {
+    ASN1_INTEGER *version;
+    STACK_OF(SXNETID) *ids;
+} SXNET;
+
+typedef struct NOTICEREF_st {
+    ASN1_STRING *organization;
+    STACK_OF(ASN1_INTEGER) *noticenos;
+} NOTICEREF;
+
+typedef struct USERNOTICE_st {
+    NOTICEREF *noticeref;
+    ASN1_STRING *exptext;
+} USERNOTICE;
+
+typedef struct POLICYQUALINFO_st {
+    ASN1_OBJECT *pqualid;
+    union {
+        ASN1_IA5STRING *cpsuri;
+        USERNOTICE *usernotice;
+        ASN1_TYPE *other;
+    } d;
+} POLICYQUALINFO;
+
+DECLARE_STACK_OF(POLICYQUALINFO)
+DECLARE_ASN1_SET_OF(POLICYQUALINFO)
+
+typedef struct POLICYINFO_st {
+    ASN1_OBJECT *policyid;
+    STACK_OF(POLICYQUALINFO) *qualifiers;
+} POLICYINFO;
+
+typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;
+
+DECLARE_STACK_OF(POLICYINFO)
+DECLARE_ASN1_SET_OF(POLICYINFO)
+
+typedef struct POLICY_MAPPING_st {
+    ASN1_OBJECT *issuerDomainPolicy;
+    ASN1_OBJECT *subjectDomainPolicy;
+} POLICY_MAPPING;
+
+DECLARE_STACK_OF(POLICY_MAPPING)
+
+typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS;
+
+typedef struct GENERAL_SUBTREE_st {
+    GENERAL_NAME *base;
+    ASN1_INTEGER *minimum;
+    ASN1_INTEGER *maximum;
+} GENERAL_SUBTREE;
+
+DECLARE_STACK_OF(GENERAL_SUBTREE)
+
+struct NAME_CONSTRAINTS_st {
+    STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
+    STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
+};
+
+typedef struct POLICY_CONSTRAINTS_st {
+    ASN1_INTEGER *requireExplicitPolicy;
+    ASN1_INTEGER *inhibitPolicyMapping;
+} POLICY_CONSTRAINTS;
+
+/* Proxy certificate structures, see RFC 3820 */
+typedef struct PROXY_POLICY_st {
+    ASN1_OBJECT *policyLanguage;
+    ASN1_OCTET_STRING *policy;
+} PROXY_POLICY;
+
+typedef struct PROXY_CERT_INFO_EXTENSION_st {
+    ASN1_INTEGER *pcPathLengthConstraint;
+    PROXY_POLICY *proxyPolicy;
+} PROXY_CERT_INFO_EXTENSION;
+
+DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
+DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
+
+struct ISSUING_DIST_POINT_st {
+    DIST_POINT_NAME *distpoint;
+    int onlyuser;
+    int onlyCA;
+    ASN1_BIT_STRING *onlysomereasons;
+    int indirectCRL;
+    int onlyattr;
+};
+
+/* Values in idp_flags field */
+/* IDP present */
+# define IDP_PRESENT     0x1
+/* IDP values inconsistent */
+# define IDP_INVALID     0x2
+/* onlyuser true */
+# define IDP_ONLYUSER    0x4
+/* onlyCA true */
+# define IDP_ONLYCA      0x8
+/* onlyattr true */
+# define IDP_ONLYATTR    0x10
+/* indirectCRL true */
+# define IDP_INDIRECT    0x20
+/* onlysomereasons present */
+# define IDP_REASONS     0x40
+
+# define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
+",name:", val->name, ",value:", val->value);
+
+# define X509V3_set_ctx_test(ctx) \
+                        X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
+# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL;
+
+# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \
+                        0,0,0,0, \
+                        0,0, \
+                        (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \
+                        (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \
+                        NULL, NULL, \
+                        table}
+
+# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \
+                        0,0,0,0, \
+                        (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \
+                        (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \
+                        0,0,0,0, \
+                        NULL}
+
+# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+/* X509_PURPOSE stuff */
+
+# define EXFLAG_BCONS            0x1
+# define EXFLAG_KUSAGE           0x2
+# define EXFLAG_XKUSAGE          0x4
+# define EXFLAG_NSCERT           0x8
+
+# define EXFLAG_CA               0x10
+/* Really self issued not necessarily self signed */
+# define EXFLAG_SI               0x20
+# define EXFLAG_V1               0x40
+# define EXFLAG_INVALID          0x80
+# define EXFLAG_SET              0x100
+# define EXFLAG_CRITICAL         0x200
+# define EXFLAG_PROXY            0x400
+
+# define EXFLAG_INVALID_POLICY   0x800
+# define EXFLAG_FRESHEST         0x1000
+/* Self signed */
+# define EXFLAG_SS               0x2000
+
+# define KU_DIGITAL_SIGNATURE    0x0080
+# define KU_NON_REPUDIATION      0x0040
+# define KU_KEY_ENCIPHERMENT     0x0020
+# define KU_DATA_ENCIPHERMENT    0x0010
+# define KU_KEY_AGREEMENT        0x0008
+# define KU_KEY_CERT_SIGN        0x0004
+# define KU_CRL_SIGN             0x0002
+# define KU_ENCIPHER_ONLY        0x0001
+# define KU_DECIPHER_ONLY        0x8000
+
+# define NS_SSL_CLIENT           0x80
+# define NS_SSL_SERVER           0x40
+# define NS_SMIME                0x20
+# define NS_OBJSIGN              0x10
+# define NS_SSL_CA               0x04
+# define NS_SMIME_CA             0x02
+# define NS_OBJSIGN_CA           0x01
+# define NS_ANY_CA               (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA)
+
+# define XKU_SSL_SERVER          0x1
+# define XKU_SSL_CLIENT          0x2
+# define XKU_SMIME               0x4
+# define XKU_CODE_SIGN           0x8
+# define XKU_SGC                 0x10
+# define XKU_OCSP_SIGN           0x20
+# define XKU_TIMESTAMP           0x40
+# define XKU_DVCS                0x80
+# define XKU_ANYEKU              0x100
+
+# define X509_PURPOSE_DYNAMIC    0x1
+# define X509_PURPOSE_DYNAMIC_NAME       0x2
+
+typedef struct x509_purpose_st {
+    int purpose;
+    int trust;                  /* Default trust ID */
+    int flags;
+    int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int);
+    char *name;
+    char *sname;
+    void *usr_data;
+} X509_PURPOSE;
+
+# define X509_PURPOSE_SSL_CLIENT         1
+# define X509_PURPOSE_SSL_SERVER         2
+# define X509_PURPOSE_NS_SSL_SERVER      3
+# define X509_PURPOSE_SMIME_SIGN         4
+# define X509_PURPOSE_SMIME_ENCRYPT      5
+# define X509_PURPOSE_CRL_SIGN           6
+# define X509_PURPOSE_ANY                7
+# define X509_PURPOSE_OCSP_HELPER        8
+# define X509_PURPOSE_TIMESTAMP_SIGN     9
+
+# define X509_PURPOSE_MIN                1
+# define X509_PURPOSE_MAX                9
+
+/* Flags for X509V3_EXT_print() */
+
+# define X509V3_EXT_UNKNOWN_MASK         (0xfL << 16)
+/* Return error for unknown extensions */
+# define X509V3_EXT_DEFAULT              0
+/* Print error for unknown extensions */
+# define X509V3_EXT_ERROR_UNKNOWN        (1L << 16)
+/* ASN1 parse unknown extensions */
+# define X509V3_EXT_PARSE_UNKNOWN        (2L << 16)
+/* BIO_dump unknown extensions */
+# define X509V3_EXT_DUMP_UNKNOWN         (3L << 16)
+
+/* Flags for X509V3_add1_i2d */
+
+# define X509V3_ADD_OP_MASK              0xfL
+# define X509V3_ADD_DEFAULT              0L
+# define X509V3_ADD_APPEND               1L
+# define X509V3_ADD_REPLACE              2L
+# define X509V3_ADD_REPLACE_EXISTING     3L
+# define X509V3_ADD_KEEP_EXISTING        4L
+# define X509V3_ADD_DELETE               5L
+# define X509V3_ADD_SILENT               0x10
+
+DECLARE_STACK_OF(X509_PURPOSE)
+
+DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
+
+DECLARE_ASN1_FUNCTIONS(SXNET)
+DECLARE_ASN1_FUNCTIONS(SXNETID)
+
+int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen);
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
+                       int userlen);
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user,
+                         int userlen);
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone);
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone);
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone);
+
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)
+
+DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
+
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+                                     X509V3_CTX *ctx,
+                                     STACK_OF(CONF_VALUE) *nval);
+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+                                          ASN1_BIT_STRING *bits,
+                                          STACK_OF(CONF_VALUE) *extlist);
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
+                                       GENERAL_NAME *gen,
+                                       STACK_OF(CONF_VALUE) *ret);
+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+                                        GENERAL_NAMES *gen,
+                                        STACK_OF(CONF_VALUE) *extlist);
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+
+DECLARE_ASN1_FUNCTIONS(OTHERNAME)
+DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+                                ASN1_OBJECT *oid, ASN1_TYPE *value);
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
+                                ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+                            ASN1_OCTET_STRING *ia5);
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+                                         X509V3_CTX *ctx, char *str);
+
+DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a);
+
+DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
+DECLARE_ASN1_FUNCTIONS(POLICYINFO)
+DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO)
+DECLARE_ASN1_FUNCTIONS(USERNOTICE)
+DECLARE_ASN1_FUNCTIONS(NOTICEREF)
+
+DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
+DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
+
+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
+
+DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
+
+DECLARE_ASN1_ITEM(POLICY_MAPPING)
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
+DECLARE_ASN1_ITEM(POLICY_MAPPINGS)
+
+DECLARE_ASN1_ITEM(GENERAL_SUBTREE)
+DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
+
+DECLARE_ASN1_ITEM(NAME_CONSTRAINTS)
+DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
+DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
+
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+                               const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, int gen_type, char *value,
+                               int is_nc);
+
+# ifdef HEADER_CONF_H
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, CONF_VALUE *cnf);
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+                                  const X509V3_EXT_METHOD *method,
+                                  X509V3_CTX *ctx, CONF_VALUE *cnf,
+                                  int is_nc);
+void X509V3_conf_free(CONF_VALUE *val);
+
+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+                                     char *value);
+X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
+                                 char *value);
+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
+                            STACK_OF(X509_EXTENSION) **sk);
+int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+                         X509 *cert);
+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+                             X509_REQ *req);
+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
+                             X509_CRL *crl);
+
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
+                                    X509V3_CTX *ctx, int ext_nid,
+                                    char *value);
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                                char *name, char *value);
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                        char *section, X509 *cert);
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                            char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                            char *section, X509_CRL *crl);
+
+int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+                             STACK_OF(CONF_VALUE) **extlist);
+int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
+int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
+# endif
+
+char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
+STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section);
+void X509V3_string_free(X509V3_CTX *ctx, char *str);
+void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
+                    X509_REQ *req, X509_CRL *crl, int flags);
+
+int X509V3_add_value(const char *name, const char *value,
+                     STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+                           STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+                          STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+                         STACK_OF(CONF_VALUE) **extlist);
+char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
+ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
+char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth,
+                                ASN1_ENUMERATED *aint);
+int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
+int X509V3_EXT_add_alias(int nid_to, int nid_from);
+void X509V3_EXT_cleanup(void);
+
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
+int X509V3_add_standard_extensions(void);
+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
+void *X509V3_EXT_d2i(X509_EXTENSION *ext);
+void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
+                     int *idx);
+int X509V3_EXT_free(int nid, void *ext_data);
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
+                    int crit, unsigned long flags);
+
+char *hex_to_string(const unsigned char *buffer, long len);
+unsigned char *string_to_hex(const char *str, long *len);
+int name_cmp(const char *name, const char *cmp);
+
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+                        int ml);
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
+                     int indent);
+int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
+
+int X509V3_extensions_print(BIO *out, char *title,
+                            STACK_OF(X509_EXTENSION) *exts,
+                            unsigned long flag, int indent);
+
+int X509_check_ca(X509 *x);
+int X509_check_purpose(X509 *x, int id, int ca);
+int X509_supported_extension(X509_EXTENSION *ex);
+int X509_PURPOSE_set(int *p, int purpose);
+int X509_check_issued(X509 *issuer, X509 *subject);
+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
+int X509_PURPOSE_get_count(void);
+X509_PURPOSE *X509_PURPOSE_get0(int idx);
+int X509_PURPOSE_get_by_sname(char *sname);
+int X509_PURPOSE_get_by_id(int id);
+int X509_PURPOSE_add(int id, int trust, int flags,
+                     int (*ck) (const X509_PURPOSE *, const X509 *, int),
+                     char *name, char *sname, void *arg);
+char *X509_PURPOSE_get0_name(X509_PURPOSE *xp);
+char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp);
+int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
+void X509_PURPOSE_cleanup(void);
+int X509_PURPOSE_get_id(X509_PURPOSE *);
+
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
+/* Flags for X509_check_* functions */
+
+/*
+ * Always check subject name for host match even if subject alt names present
+ */
+# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT    0x1
+/* Disable wildcard matching for dnsName fields and common name. */
+# define X509_CHECK_FLAG_NO_WILDCARDS    0x2
+/* Wildcards must not match a partial label. */
+# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4
+/* Allow (non-partial) wildcards to match multiple labels. */
+# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8
+/* Constraint verifier subdomain patterns to match a single labels. */
+# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10
+/*
+ * Match reference identifiers starting with "." to any sub-domain.
+ * This is a non-public flag, turned on implicitly when the subject
+ * reference identity is a DNS name.
+ */
+# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000
+
+int X509_check_host(X509 *x, const char *chk, size_t chklen,
+                    unsigned int flags, char **peername);
+int X509_check_email(X509 *x, const char *chk, size_t chklen,
+                     unsigned int flags);
+int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
+                  unsigned int flags);
+int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags);
+
+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
+int a2i_ipadd(unsigned char *ipout, const char *ipasc);
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
+                             unsigned long chtype);
+
+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
+DECLARE_STACK_OF(X509_POLICY_NODE)
+
+# ifndef OPENSSL_NO_RFC3779
+
+typedef struct ASRange_st {
+    ASN1_INTEGER *min, *max;
+} ASRange;
+
+#  define ASIdOrRange_id          0
+#  define ASIdOrRange_range       1
+
+typedef struct ASIdOrRange_st {
+    int type;
+    union {
+        ASN1_INTEGER *id;
+        ASRange *range;
+    } u;
+} ASIdOrRange;
+
+typedef STACK_OF(ASIdOrRange) ASIdOrRanges;
+DECLARE_STACK_OF(ASIdOrRange)
+
+#  define ASIdentifierChoice_inherit              0
+#  define ASIdentifierChoice_asIdsOrRanges        1
+
+typedef struct ASIdentifierChoice_st {
+    int type;
+    union {
+        ASN1_NULL *inherit;
+        ASIdOrRanges *asIdsOrRanges;
+    } u;
+} ASIdentifierChoice;
+
+typedef struct ASIdentifiers_st {
+    ASIdentifierChoice *asnum, *rdi;
+} ASIdentifiers;
+
+DECLARE_ASN1_FUNCTIONS(ASRange)
+DECLARE_ASN1_FUNCTIONS(ASIdOrRange)
+DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice)
+DECLARE_ASN1_FUNCTIONS(ASIdentifiers)
+
+typedef struct IPAddressRange_st {
+    ASN1_BIT_STRING *min, *max;
+} IPAddressRange;
+
+#  define IPAddressOrRange_addressPrefix  0
+#  define IPAddressOrRange_addressRange   1
+
+typedef struct IPAddressOrRange_st {
+    int type;
+    union {
+        ASN1_BIT_STRING *addressPrefix;
+        IPAddressRange *addressRange;
+    } u;
+} IPAddressOrRange;
+
+typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges;
+DECLARE_STACK_OF(IPAddressOrRange)
+
+#  define IPAddressChoice_inherit                 0
+#  define IPAddressChoice_addressesOrRanges       1
+
+typedef struct IPAddressChoice_st {
+    int type;
+    union {
+        ASN1_NULL *inherit;
+        IPAddressOrRanges *addressesOrRanges;
+    } u;
+} IPAddressChoice;
+
+typedef struct IPAddressFamily_st {
+    ASN1_OCTET_STRING *addressFamily;
+    IPAddressChoice *ipAddressChoice;
+} IPAddressFamily;
+
+typedef STACK_OF(IPAddressFamily) IPAddrBlocks;
+DECLARE_STACK_OF(IPAddressFamily)
+
+DECLARE_ASN1_FUNCTIONS(IPAddressRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressOrRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressChoice)
+DECLARE_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * API tag for elements of the ASIdentifer SEQUENCE.
+ */
+#  define V3_ASID_ASNUM   0
+#  define V3_ASID_RDI     1
+
+/*
+ * AFI values, assigned by IANA.  It'd be nice to make the AFI
+ * handling code totally generic, but there are too many little things
+ * that would need to be defined for other address families for it to
+ * be worth the trouble.
+ */
+#  define IANA_AFI_IPV4   1
+#  define IANA_AFI_IPV6   2
+
+/*
+ * Utilities to construct and extract values from RFC3779 extensions,
+ * since some of the encodings (particularly for IP address prefixes
+ * and ranges) are a bit tedious to work with directly.
+ */
+int v3_asid_add_inherit(ASIdentifiers *asid, int which);
+int v3_asid_add_id_or_range(ASIdentifiers *asid, int which,
+                            ASN1_INTEGER *min, ASN1_INTEGER *max);
+int v3_addr_add_inherit(IPAddrBlocks *addr,
+                        const unsigned afi, const unsigned *safi);
+int v3_addr_add_prefix(IPAddrBlocks *addr,
+                       const unsigned afi, const unsigned *safi,
+                       unsigned char *a, const int prefixlen);
+int v3_addr_add_range(IPAddrBlocks *addr,
+                      const unsigned afi, const unsigned *safi,
+                      unsigned char *min, unsigned char *max);
+unsigned v3_addr_get_afi(const IPAddressFamily *f);
+int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi,
+                      unsigned char *min, unsigned char *max,
+                      const int length);
+
+/*
+ * Canonical forms.
+ */
+int v3_asid_is_canonical(ASIdentifiers *asid);
+int v3_addr_is_canonical(IPAddrBlocks *addr);
+int v3_asid_canonize(ASIdentifiers *asid);
+int v3_addr_canonize(IPAddrBlocks *addr);
+
+/*
+ * Tests for inheritance and containment.
+ */
+int v3_asid_inherits(ASIdentifiers *asid);
+int v3_addr_inherits(IPAddrBlocks *addr);
+int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b);
+int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b);
+
+/*
+ * Check whether RFC 3779 extensions nest properly in chains.
+ */
+int v3_asid_validate_path(X509_STORE_CTX *);
+int v3_addr_validate_path(X509_STORE_CTX *);
+int v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+                                  ASIdentifiers *ext, int allow_inheritance);
+int v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+                                  IPAddrBlocks *ext, int allow_inheritance);
+
+# endif                         /* OPENSSL_NO_RFC3779 */
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_X509V3_strings(void);
+
+/* Error codes for the X509V3 functions. */
+
+/* Function codes. */
+# define X509V3_F_A2I_GENERAL_NAME                        164
+# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE             161
+# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL         162
+# define X509V3_F_COPY_EMAIL                              122
+# define X509V3_F_COPY_ISSUER                             123
+# define X509V3_F_DO_DIRNAME                              144
+# define X509V3_F_DO_EXT_CONF                             124
+# define X509V3_F_DO_EXT_I2D                              135
+# define X509V3_F_DO_EXT_NCONF                            151
+# define X509V3_F_DO_I2V_NAME_CONSTRAINTS                 148
+# define X509V3_F_GNAMES_FROM_SECTNAME                    156
+# define X509V3_F_HEX_TO_STRING                           111
+# define X509V3_F_I2S_ASN1_ENUMERATED                     121
+# define X509V3_F_I2S_ASN1_IA5STRING                      149
+# define X509V3_F_I2S_ASN1_INTEGER                        120
+# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS               138
+# define X509V3_F_NOTICE_SECTION                          132
+# define X509V3_F_NREF_NOS                                133
+# define X509V3_F_POLICY_SECTION                          131
+# define X509V3_F_PROCESS_PCI_VALUE                       150
+# define X509V3_F_R2I_CERTPOL                             130
+# define X509V3_F_R2I_PCI                                 155
+# define X509V3_F_S2I_ASN1_IA5STRING                      100
+# define X509V3_F_S2I_ASN1_INTEGER                        108
+# define X509V3_F_S2I_ASN1_OCTET_STRING                   112
+# define X509V3_F_S2I_ASN1_SKEY_ID                        114
+# define X509V3_F_S2I_SKEY_ID                             115
+# define X509V3_F_SET_DIST_POINT_NAME                     158
+# define X509V3_F_STRING_TO_HEX                           113
+# define X509V3_F_SXNET_ADD_ID_ASC                        125
+# define X509V3_F_SXNET_ADD_ID_INTEGER                    126
+# define X509V3_F_SXNET_ADD_ID_ULONG                      127
+# define X509V3_F_SXNET_GET_ID_ASC                        128
+# define X509V3_F_SXNET_GET_ID_ULONG                      129
+# define X509V3_F_V2I_ASIDENTIFIERS                       163
+# define X509V3_F_V2I_ASN1_BIT_STRING                     101
+# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS               139
+# define X509V3_F_V2I_AUTHORITY_KEYID                     119
+# define X509V3_F_V2I_BASIC_CONSTRAINTS                   102
+# define X509V3_F_V2I_CRLD                                134
+# define X509V3_F_V2I_EXTENDED_KEY_USAGE                  103
+# define X509V3_F_V2I_GENERAL_NAMES                       118
+# define X509V3_F_V2I_GENERAL_NAME_EX                     117
+# define X509V3_F_V2I_IDP                                 157
+# define X509V3_F_V2I_IPADDRBLOCKS                        159
+# define X509V3_F_V2I_ISSUER_ALT                          153
+# define X509V3_F_V2I_NAME_CONSTRAINTS                    147
+# define X509V3_F_V2I_POLICY_CONSTRAINTS                  146
+# define X509V3_F_V2I_POLICY_MAPPINGS                     145
+# define X509V3_F_V2I_SUBJECT_ALT                         154
+# define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL          160
+# define X509V3_F_V3_GENERIC_EXTENSION                    116
+# define X509V3_F_X509V3_ADD1_I2D                         140
+# define X509V3_F_X509V3_ADD_VALUE                        105
+# define X509V3_F_X509V3_EXT_ADD                          104
+# define X509V3_F_X509V3_EXT_ADD_ALIAS                    106
+# define X509V3_F_X509V3_EXT_CONF                         107
+# define X509V3_F_X509V3_EXT_FREE                         165
+# define X509V3_F_X509V3_EXT_I2D                          136
+# define X509V3_F_X509V3_EXT_NCONF                        152
+# define X509V3_F_X509V3_GET_SECTION                      142
+# define X509V3_F_X509V3_GET_STRING                       143
+# define X509V3_F_X509V3_GET_VALUE_BOOL                   110
+# define X509V3_F_X509V3_PARSE_LIST                       109
+# define X509V3_F_X509_PURPOSE_ADD                        137
+# define X509V3_F_X509_PURPOSE_SET                        141
+
+/* Reason codes. */
+# define X509V3_R_BAD_IP_ADDRESS                          118
+# define X509V3_R_BAD_OBJECT                              119
+# define X509V3_R_BN_DEC2BN_ERROR                         100
+# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR                101
+# define X509V3_R_CANNOT_FIND_FREE_FUNCTION               168
+# define X509V3_R_DIRNAME_ERROR                           149
+# define X509V3_R_DISTPOINT_ALREADY_SET                   160
+# define X509V3_R_DUPLICATE_ZONE_ID                       133
+# define X509V3_R_ERROR_CONVERTING_ZONE                   131
+# define X509V3_R_ERROR_CREATING_EXTENSION                144
+# define X509V3_R_ERROR_IN_EXTENSION                      128
+# define X509V3_R_EXPECTED_A_SECTION_NAME                 137
+# define X509V3_R_EXTENSION_EXISTS                        145
+# define X509V3_R_EXTENSION_NAME_ERROR                    115
+# define X509V3_R_EXTENSION_NOT_FOUND                     102
+# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED         103
+# define X509V3_R_EXTENSION_VALUE_ERROR                   116
+# define X509V3_R_ILLEGAL_EMPTY_EXTENSION                 151
+# define X509V3_R_ILLEGAL_HEX_DIGIT                       113
+# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG             152
+# define X509V3_R_INVALID_ASNUMBER                        162
+# define X509V3_R_INVALID_ASRANGE                         163
+# define X509V3_R_INVALID_BOOLEAN_STRING                  104
+# define X509V3_R_INVALID_EXTENSION_STRING                105
+# define X509V3_R_INVALID_INHERITANCE                     165
+# define X509V3_R_INVALID_IPADDRESS                       166
+# define X509V3_R_INVALID_MULTIPLE_RDNS                   161
+# define X509V3_R_INVALID_NAME                            106
+# define X509V3_R_INVALID_NULL_ARGUMENT                   107
+# define X509V3_R_INVALID_NULL_NAME                       108
+# define X509V3_R_INVALID_NULL_VALUE                      109
+# define X509V3_R_INVALID_NUMBER                          140
+# define X509V3_R_INVALID_NUMBERS                         141
+# define X509V3_R_INVALID_OBJECT_IDENTIFIER               110
+# define X509V3_R_INVALID_OPTION                          138
+# define X509V3_R_INVALID_POLICY_IDENTIFIER               134
+# define X509V3_R_INVALID_PROXY_POLICY_SETTING            153
+# define X509V3_R_INVALID_PURPOSE                         146
+# define X509V3_R_INVALID_SAFI                            164
+# define X509V3_R_INVALID_SECTION                         135
+# define X509V3_R_INVALID_SYNTAX                          143
+# define X509V3_R_ISSUER_DECODE_ERROR                     126
+# define X509V3_R_MISSING_VALUE                           124
+# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS           142
+# define X509V3_R_NO_CONFIG_DATABASE                      136
+# define X509V3_R_NO_ISSUER_CERTIFICATE                   121
+# define X509V3_R_NO_ISSUER_DETAILS                       127
+# define X509V3_R_NO_POLICY_IDENTIFIER                    139
+# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED   154
+# define X509V3_R_NO_PUBLIC_KEY                           114
+# define X509V3_R_NO_SUBJECT_DETAILS                      125
+# define X509V3_R_ODD_NUMBER_OF_DIGITS                    112
+# define X509V3_R_OPERATION_NOT_DEFINED                   148
+# define X509V3_R_OTHERNAME_ERROR                         147
+# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED         155
+# define X509V3_R_POLICY_PATH_LENGTH                      156
+# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED      157
+# define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED   158
+# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
+# define X509V3_R_SECTION_NOT_FOUND                       150
+# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS            122
+# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID              123
+# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT             111
+# define X509V3_R_UNKNOWN_EXTENSION                       129
+# define X509V3_R_UNKNOWN_EXTENSION_NAME                  130
+# define X509V3_R_UNKNOWN_OPTION                          120
+# define X509V3_R_UNSUPPORTED_OPTION                      117
+# define X509V3_R_UNSUPPORTED_TYPE                        167
+# define X509V3_R_USER_TOO_LONG                           132
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/osal.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/osal.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/osal.h	(working copy)
@@ -0,0 +1,211 @@
+#pragma once
+
+#include <stdint.h>
+#include <time.h>
+
+#define INVALID_FD  (-1)
+
+#ifdef _WINDLL
+#define ARRAYAPI_DECL __declspec(dllexport)
+#else
+#define ARRAYAPI_DECL
+#endif
+
+#if defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <thr/threads.h>    /* only visual studio 2012+ is supported */
+
+typedef int ssize_t;
+
+typedef HANDLE sema_t;
+
+struct timespec {
+    time_t tv_sec;      /* Seconds.  */
+    long   tv_nsec;     /* Nanoseconds.  */
+};
+
+#elif defined(__linux__)
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+typedef int (*thrd_start_t)(void*);
+
+typedef pthread_cond_t  cnd_t;
+typedef pthread_t       thrd_t;
+typedef pthread_mutex_t mtx_t;
+typedef sem_t           sema_t;
+
+#elif defined(__APPLE__)
+#include <mach/mach_init.h>
+#include <mach/task.h>
+#include <mach/sync_policy.h>
+#include <mach/mach_error.h>
+#include <mach/clock_types.h>
+#include <mach/semaphore.h>
+#include <pthread.h>
+
+typedef int (*thrd_start_t)(void*);
+
+typedef pthread_cond_t  cnd_t;
+typedef pthread_t       thrd_t;
+typedef pthread_mutex_t mtx_t;
+typedef semaphore_t     sema_t;
+
+#else
+
+#error Not supported on this platform.
+#endif
+
+#ifndef _WIN32
+enum {
+    mtx_plain     = 0,
+    mtx_try,
+    mtx_timed,
+    mtx_recursive 
+};
+
+enum {
+    thrd_success = 0, 
+    thrd_timeout,    
+    thrd_error,      
+    thrd_busy,      
+    thrd_nomem     
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _WIN32
+int    thrd_create(thrd_t *thr, thrd_start_t func, void *arg);
+thrd_t thrd_current(void);
+int    thrd_detach(thrd_t thr);
+void   thrd_exit(int result);
+int    thrd_join(thrd_t thr, int *res);
+int    thrd_equal(thrd_t thr0, thrd_t thr1);
+void   thrd_yield();
+
+void   mtx_destroy(mtx_t *mtx); 
+int    mtx_init(mtx_t *mtx, int type);
+int    mtx_lock(mtx_t *mtx);
+int    mtx_timedlock(mtx_t *mtx, const struct timespec *ts);
+int    mtx_trylock(mtx_t *mtx);
+int    mtx_unlock(mtx_t *mtx);
+
+int    cnd_broadcast(cnd_t *cond);
+void   cnd_destroy(cnd_t *cond);
+int    cnd_init(cnd_t *cond);
+int    cnd_signal(cnd_t *cond);
+int    cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
+int    cnd_wait(cnd_t *cond, mtx_t *mtx);
+
+int    sema_init(sema_t *sem, unsigned int value);
+int    sema_post(sema_t *sem);
+int    sema_wait(sema_t *sem);
+int    sema_trywait(sema_t *sem);
+int    sema_timedwait(sema_t *sem, const struct timespec *abs_timeout, unsigned int *ms);
+int    sema_destroy (sema_t *sem);
+int    sema_is_valid(sema_t *sem);
+int    sema_set_invalid(sema_t *sem);
+
+int    thrd_is_null(thrd_t thr);
+void   thrd_set_null(thrd_t *thr);
+int    thrd_is_running(thrd_t thr);
+int    thrd_timedjoin(thrd_t *thr, unsigned int seconds);
+
+void   thrd_set_name(const char* name);
+
+#else
+
+#define thrd_timeout thrd_timedout
+
+#define snprintf _snprintf
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+
+ARRAYAPI_DECL int	 pipe(int fds[2]);
+ARRAYAPI_DECL char*  strcasestr(const char *s, const char *find);
+
+ARRAYAPI_DECL int    sema_init(sema_t *sem, unsigned int value);
+ARRAYAPI_DECL int    sema_post(sema_t *sem);
+ARRAYAPI_DECL int    sema_wait(sema_t *sem);
+ARRAYAPI_DECL int    sema_trywait(sema_t *sem);
+ARRAYAPI_DECL int    sema_timedwait(sema_t *sem, const struct timespec *ts, unsigned int *ms);
+ARRAYAPI_DECL int    sema_destroy(sema_t *sem);
+ARRAYAPI_DECL int    sema_is_valid(sema_t *sem);
+ARRAYAPI_DECL int    sema_set_invalid(sema_t *sem);
+
+ARRAYAPI_DECL int    thrd_is_null(thrd_t thr);
+ARRAYAPI_DECL void   thrd_set_null(thrd_t *thr);
+ARRAYAPI_DECL int    thrd_is_running(thrd_t thr);
+ARRAYAPI_DECL int    thrd_timedjoin(thrd_t *thr, unsigned int seconds);
+
+ARRAYAPI_DECL int    gettimeofday(struct timeval *tv, struct timezone *tz);
+ARRAYAPI_DECL int    win_errno();
+ARRAYAPI_DECL char*  win_strerror(int error);
+ARRAYAPI_DECL void   winsock_init();
+
+ARRAYAPI_DECL void   thrd_set_name(const char* name);
+#endif
+
+void get_timespec(struct timespec *ts);
+long timespec_diff_to_ms(struct timespec *end, struct timespec *begin);
+void timespec_add(struct timespec *ts, unsigned int timeout_ms);
+int  is_app_tcp_port(unsigned short port, int *result);
+int  is_app_udp_port(unsigned short port, int *result);
+
+
+#ifdef _WIN32
+#ifdef _USING_V110_SDK71_ /* Visual Studio 2012 - Windows XP (v110_xp) */
+#define atomic_uint64_add(x, y) ((*x) += y)
+#else
+#define atomic_uint64_add(x, y) InterlockedExchangeAdd64(x, y)
+#endif
+#else
+#ifndef __ANDROID__
+/*#define atomic_uint64_add(x, y)  __sync_fetch_and_add(x,y)*/
+#define atomic_uint64_add(x, y)  ((*x) += y)
+#else
+/* OSAtomicCompareAndSwap64 OSAtomicCompareAndSwap64Barrier */
+#define atomic_uint64_add(x, y)  ((*x) += y)
+#endif
+#endif
+
+#ifdef _MSC_VER
+#define tls_storage __declspec(thread)
+#else
+#define tls_storage	__thread
+#endif
+
+#ifndef _WIN32
+#define close_socket(x) close(x)
+#define os_errno errno
+#define os_strerror(x) strerror(x)
+#else
+int win_errno();
+char *win_strerror(int error);
+#define close_socket(x) closesocket(x)
+#define os_errno win_errno()
+#define os_strerror(x) win_strerror(x)
+#endif
+
+#define container_of(address, type, field) ((type *)( (char*)(address) - (char*)(&((type *)0)->field)))
+
+ARRAYAPI_DECL void sleep_sec(unsigned int sec);
+
+ARRAYAPI_DECL int get_local_address(uint32_t *addrs, uint8_t max_count);
+
+ARRAYAPI_DECL int get_local_mac_address(uint8_t *mac,int sock);
+
+#ifdef _WIN32
+ARRAYAPI_DECL int GetVirtualAdapterMAC(BYTE mac[6]);
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/uuid.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/uuid.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/uuid.h	(working copy)
@@ -0,0 +1,103 @@
+/*
+ * Public include file for the UUID library
+ *
+ * Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, and the entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * %End-Header%
+ */
+
+#ifndef _UUID_UUID_H
+#define _UUID_UUID_H
+
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
+#include <time.h>
+
+typedef unsigned char uuid_t[16];
+
+/* UUID Variant definitions */
+#define UUID_VARIANT_NCS 	0
+#define UUID_VARIANT_DCE 	1
+#define UUID_VARIANT_MICROSOFT	2
+#define UUID_VARIANT_OTHER	3
+
+/* UUID Type definitions */
+#define UUID_TYPE_DCE_TIME   1
+#define UUID_TYPE_DCE_RANDOM 4
+
+/* Allow UUID constants to be defined */
+#ifdef __GNUC__
+#define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \
+	static const uuid_t name __attribute__ ((unused)) = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15}
+#else
+#define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \
+	static const uuid_t name = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15}
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* clear.c */
+void uuid_clear(uuid_t uu);
+
+/* compare.c */
+int uuid_compare(const uuid_t uu1, const uuid_t uu2);
+
+/* copy.c */
+void uuid_copy(uuid_t dst, const uuid_t src);
+
+/* gen_uuid.c */
+void uuid_generate(uuid_t out);
+void uuid_generate_random(uuid_t out);
+void uuid_generate_time(uuid_t out);
+
+/* isnull.c */
+int uuid_is_null(const uuid_t uu);
+
+/* parse.c */
+int uuid_parse(const char *in, uuid_t uu);
+
+/* unparse.c */
+void uuid_unparse(const uuid_t uu, char *out);
+void uuid_unparse_lower(const uuid_t uu, char *out);
+void uuid_unparse_upper(const uuid_t uu, char *out);
+
+/* uuid_time.c */
+time_t uuid_time(const uuid_t uu, struct timeval *ret_tv);
+int uuid_type(const uuid_t uu);
+int uuid_variant(const uuid_t uu);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _UUID_UUID_H */
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/vpn_error.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/vpn_error.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/vpn_error.h	(working copy)
@@ -0,0 +1,118 @@
+#pragma once
+
+#undef  ERR_SUCCESS
+#define ERR_SUCCESS 					0
+#define ERR_FAILURE						1
+#define ERR_SSL_READ 					2
+#define ERR_SSL_WRITE 					3
+#define ERR_SSL_CONN 					4
+#define ERR_SSL_CLIENT_CERT				5
+#define ERR_SESS_INVALID				6
+#define ERR_SESS_TIMEOUT				7
+#define ERR_MEM_ALLOC					8
+#define ERR_SOCK_CREATE					9
+#define ERR_SOCK_ACCEPT					10
+#define ERR_SOCK_RECV					11
+#define ERR_SOCK_CLOSE					12
+#define ERR_SOCK_BIND					13
+#define ERR_SOCK_LISTEN					14
+#define ERR_SOCK_SEND					15
+#define ERR_SOCK_CONN					16
+#define ERR_ITEM_NOT_FOUND				17
+#define ERR_PARSE_COOKIE				18
+#define ERR_HTTP_NOT_REDIR				19
+#define ERR_HTTP_NO_LOCATION			20
+#define ERR_CONTROL_SOCK_BIND			21
+#define ERR_APP_CONN_LIMIT				22
+#define ERR_BUF_SIZE					23
+#define ERR_UNKNOWN_HOST				24
+#define ERR_STILL_RUNNING				25
+#define ERR_NOT_RUNNING					26
+#define ERR_THREAD_JOIN					27
+#define ERR_THREAD_CREATE				28
+#define ERR_SOCK_SELECT					29
+#define ERR_SERVER_CONFIG				30
+#define ERR_SESS_SECOND_LOGIN			31
+#define ERR_CERT_PASS					32
+#define ERR_CERT_PARSE					33
+#define ERR_CERT_FILE_READ				34
+#define ERR_CTL_SOCK_CONN				35
+#define ERR_CTL_SOCK_SEND				36
+#define ERR_WRONG_USER_PASS				37
+#define ERR_GET_AAA_METHOD				38
+#define ERR_CONFIG_L3VPN				39
+#define ERR_GET_L3VPN_CONFIG			40
+#define ERR_INTERRUPTED					41
+#define ERR_PARAM_INVALID               42
+#define ERR_TUN_CREATE		            43
+#define ERR_TUN_CONFIG		            44
+#define ERR_SETUP_UDP					45
+#define ERR_UDP_SEND					46
+#define ERR_UDP_RECV					47
+#define ERR_TUN_DOWN                    48
+#define ERR_SERVER_AG                   49
+#define ERR_SERVER_NO_RESP		        50
+#define ERR_CLIENT_SECURITY		        51
+#define ERR_CHOOSE_METHOD               52
+#define ERR_UNSUPPORT_METHOD            53
+#define ERR_SHUTDOWN_SOCKET             54
+#define ERR_HTTP_PROXY_START_FAILED     55
+#define ERR_SOCK_PROXY_START_FAILED     56
+#define ERR_HTTP_PROXY_STOP_FAILED      57
+#define ERR_SOCK_PROXY_STOP_FAILED      58
+#define ERR_HTTP_SOCK_PROXY_STOP_FAILED 59
+#define ERR_CALLBACK_FAILED             60
+#define ERR_DEVID_APPROVE_PENDING       61
+#define ERR_DEVID_APPROVE_DENY          62
+#define ERR_DEVID_USER_LIMIT            63
+#define ERR_DEVID_DEV_LIMIT             64
+#define ERR_DEVID_UNREG	                65
+#define ERR_CREATE_SESSION              66
+#define ERR_CERT_NO                     67
+#define ERR_CERT_INVALID_SIGNTURE       68
+#define ERR_CERT_UNTRUSTED              69
+#define ERR_CERT_EXPIRED                70
+#define ERR_CERT_INVALID                71
+#define ERR_CERT_REVOKED                72
+#define ERR_CERT_SERVER_NO              73
+#define ERR_CERT_SERVER_INVALID_SIGN    74
+#define ERR_CERT_SERVER_UNTRUSTED       75
+#define ERR_CERT_SERVER_EXPIRED         76
+#define ERR_CERT_SERVER_INVALID         77
+#define ERR_CERT_SERVER_REVOKED         78
+#define ERR_CHANGE_PASSWORD             79
+#define ERR_AUTHORIZE_FAILED            80
+#define ERR_CONNECT_TIMEOUT             81
+#define ERR_PROXY_AUTH                  82
+#define ERR_SMS_GET_PHONE               83
+#define ERR_SMS_SEND                    84
+#define ERR_SMS_TOO_MANY_RETRY          85
+#define ERR_IPC                         86
+#define ERR_HWID_DENY                   87
+#define ERR_HWID_PENDING                88
+#define ERR_CS_DOWNLOAD                 89
+#define ERR_FILE_WRITE                  90
+#define ERR_FILE_OPEN                   91
+#define ERR_FILE_READ                   92
+#define ERR_DD_CLIENT_VERIFY_FAIL       93
+#define ERR_CLIENT_SECURITY_FAIL        94
+#define ERR_CLIENT_NEED_UPDATE          95
+#define ERR_HTTP_NO_POST_URL            96
+#define ERR_HTTP_NO_REALM               97
+#define ERR_GET_LOGIN_RESP_FAILED       98
+#define ERR_POST_START_RESP_FAILED      99
+#define ERR_HTTP_NO_CSRF                100
+#define ERR_HTTP_NO_DYNAMIC_DATA        101
+#define ERR_GET_GRID_RESP_FAILED        102
+#define ERR_POST_GRID_RESP_FAILED       103
+#define ERR_GET_BASE64_RESP_FAILED      104
+#define ERR_HTTP_NO_SECGRID             105
+#define ERR_DECODE_FAILED               106
+#define ERR_POST_SECGRID_RESP_FAILED    107
+#define ERR_NOT_SYFERLOCK_AUTH_SITE     108
+#define ERR_NAME_ADDR_NUM_MISMATCH      109
+#define ERR_INVALID_IP_ADDRESS          110
+#define ERR_INVALID_DOMAIN_NAME         111
+#define ERR_USER_LOCKED                 112
+#define ERR_NEED_SDK_LICENSE            113
+#define ERR_MAX                         114
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/xtun.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/xtun.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/ArrayL3VPN/include/xtun.h	(working copy)
@@ -0,0 +1,102 @@
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32
+#include <ras.h>
+typedef intptr_t ssize_t;
+#endif
+
+#pragma pack(push, 1)
+
+typedef struct {
+    char          ifname[16];
+    unsigned int  flags;
+
+#ifdef _WIN32
+
+    char          devname[256];
+    HANDLE        device;      
+    int           sstp_client;   
+    uint32_t      gateway;
+    uint32_t      ip;
+    uint32_t      netmask;
+    uint32_t      dns;
+    uint32_t      dns2;
+    uint32_t      wins;
+    uint32_t      wins2;
+    uint32_t      if_metric;
+    uint16_t      mtu;
+    char          sstp_entry[32];    
+    char          searchdomain[RAS_MaxDnsSuffix];
+	char          ipv6[128];
+	char          maskv6[128];
+	char          gatewayv6[128];
+	char          dnsv6[128];
+	char          dns2v6[128];
+	uint32_t      netmaskv6prefix;
+#endif
+
+} xtun_opt_t;
+
+#pragma pack(pop)
+
+#define XTUN_FLAG_TUNNEL_SPLIT                 0x00000001  /* split tunnel */
+#define XTUN_FLAG_TUNNEL_FULL                  0x00000002  /* full tunnel */
+#define XTUN_FLAG_WIN_TYPE_SSTP                0x00000004  /* use win vpn-sstp device */
+#define XTUN_FLAG_WIN_TYPE_DEV                 0x00000008  /* use custome adapter device */
+#define XTUN_FLAG_SSTP_IF_METRIC               0x00000010  /* set explicit if metirc */
+#define XTUN_FLAG_SSTP_DISABLE_SMB_CLIENT      0x00000020  /* set explicit if metirc */
+#define XTUN_FLAG_SSTP_DISABLE_SMB_SERVER      0x00000040  /* set explicit if metirc */
+#define XTUN_FLAG_SSTP_DISABLE_NBTOVERIP       0x00000080  /* set explicit if metirc */
+
+#define XTUN_SSTP_DEFAULT_ENTRY                "Array Networks SSL VPN"
+
+#define XTUN_SSTP_MTU_DEFAULT                  1400
+#pragma pack(push, 1)
+typedef struct {
+    unsigned char ip_hl:4, ip_v:4;
+    unsigned char ip_tos;
+    unsigned short int ip_len;
+    unsigned short int ip_id;
+    unsigned short int ip_off;
+    unsigned char ip_ttl;
+    unsigned char ip_p;
+    unsigned short int ip_sum;
+    unsigned int ip_src;
+    unsigned int ip_dst;
+} iphead;
+#pragma pack(pop)
+#define IPV6_PACKET(buf)  (((iphead*)(buf))->ip_v) == 0x6
+
+#ifdef _WINDLL
+#define ARRAYAPI_DECL __declspec(dllexport)
+#else
+#define ARRAYAPI_DECL
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define xtun_init(opt)          (void)memset(opt, 0, sizeof(xtun_opt_t))
+#define xtun_get_if_name(opt)    (const char*)((opt)->ifname)
+
+    ARRAYAPI_DECL int xtun_open(xtun_opt_t *opt);
+    ARRAYAPI_DECL int xtun_close(int fd);
+    ARRAYAPI_DECL ssize_t xtun_read(int fd, char *buf, size_t len);
+    ARRAYAPI_DECL ssize_t xtun_write(int fd, const char *buf, size_t len);
+
+#ifdef _WIN32
+    ARRAYAPI_DECL int xtun_get_if_index(int *index);
+    ARRAYAPI_DECL int xtun_get_if_metric(int index, int *metric);
+    ARRAYAPI_DECL int xtun_wait_ready(int timeout);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/CertificateManager.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/CertificateManager.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/CertificateManager.h	(working copy)
@@ -0,0 +1,56 @@
+//
+//  CertificateManager.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/7/26.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "vpn_error.h"
+
+typedef enum {
+    OK,
+    ERROR_UNKNOWN,
+    ERROR_ALLOCATE_MEMORY_FAILED,
+    ERROR_CERT_INVALID_SIGNTURE = ERR_CERT_INVALID_SIGNTURE,
+    ERROR_CERT_UNTRUSTED = ERR_CERT_UNTRUSTED,
+    ERROR_CERT_INVALID = ERR_CERT_INVALID,
+    ERROR_CERT_EXPIRED = ERR_CERT_EXPIRED,
+    ERROR_FILE_NOT_FOUND,
+    ERROR_PASSWORD_WRONG
+} CERT_STATUS;
+
+@interface Certificate : NSObject <NSCoding>
+@property (nonatomic, strong) NSString *name;
+@property (nonatomic, strong) NSString *subjectCN;
+@property (nonatomic, strong) NSString *alias;
+@property (nonatomic, strong) NSString *path;
+@property (nonatomic, strong) NSString *expireTime;
+@property (nonatomic, strong) NSString *issuer;
+@property (nonatomic, strong) NSString *password;
+@property (nonatomic) NSInteger status;
+
+- (Certificate *)initWithP12Path:(NSString *)path pass:(NSString *)pass;
+
+@end
+
+@interface CertificateManager : NSObject
+
+@property (nonatomic, strong) NSMutableDictionary *certificates;
+
++ (CertificateManager *)sharedInstance;
+- (void)save;
+
+- (Certificate *)certificateWithName:(NSString *)name;
+
+- (NSString *)certsDirectory;
+- (void)addCertWithData:(NSData *)data name:(NSString *)name pass:(NSString *)pass;
+
+- (void)removeCertForName:(NSString *)name;
+- (void)addCert:(Certificate *)cert withName:(NSString *)name;
+- (void)setStatus:(NSInteger)statues ForCert:(NSString *)name;
+
+- (BOOL)updateCertName:(NSString *)certName withNewName:(NSString *)newName;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/CertificateManager.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/CertificateManager.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/CertificateManager.m	(working copy)
@@ -0,0 +1,451 @@
+//
+//  CertificateManager.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/7/26.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <openssl/pkcs12.h>
+#import <openssl/err.h>
+#import <openssl/x509.h>
+#import <Security/Security.h>
+#import "ANLogger.h"
+#import "CertificateManager.h"
+
+static time_t getTimeFromASN1(const ASN1_TIME * aTime) {
+    time_t lResult = 0;
+    char lBuffer[24];
+    char * pBuffer = lBuffer;
+    
+    size_t lTimeLength = aTime->length;
+    char * pString = (char *)aTime->data;
+    
+    if (aTime->type == V_ASN1_UTCTIME) {
+        if ((lTimeLength < 11) || (lTimeLength > 17))
+        {
+            return 0;
+        }
+        
+        memcpy(pBuffer, pString, 10);
+        pBuffer += 10;
+        pString += 10;
+    } else {
+        if (lTimeLength < 13) {
+            return 0;
+        }
+        
+        memcpy(pBuffer, pString, 12);
+        pBuffer += 12;
+        pString += 12;
+    }
+    
+    if ((*pString == 'Z') || (*pString == '-') || (*pString == '+')) {
+        *(pBuffer++) = '0';
+        *(pBuffer++) = '0';
+    } else {
+        *(pBuffer++) = *(pString++);
+        *(pBuffer++) = *(pString++);
+        // Skip any fractional seconds...
+        if (*pString == '.') {
+            pString++;
+            while ((*pString >= '0') && (*pString <= '9')) {
+                pString++;
+            }
+        }
+    }
+    
+    *(pBuffer++) = 'Z';
+    *(pBuffer++) = '\0';
+    
+    time_t lSecondsFromUCT;
+    if (*pString == 'Z') {
+        lSecondsFromUCT = 0;
+    } else {
+        if ((*pString != '+') && (pString[5] != '-')) {
+            return 0;
+        }
+        
+        lSecondsFromUCT = ((pString[1]-'0') * 10 + (pString[2]-'0')) * 60;
+        lSecondsFromUCT += (pString[3]-'0') * 10 + (pString[4]-'0');
+        if (*pString == '-') {
+            lSecondsFromUCT = -lSecondsFromUCT;
+        }
+    }
+    
+    struct tm lTime;
+    lTime.tm_sec  = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
+    lTime.tm_min  = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
+    lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
+    lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
+    lTime.tm_mon  = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
+    lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
+    if (lTime.tm_year < 50) {
+        lTime.tm_year += 100; // RFC 2459
+    }
+    lTime.tm_wday = 0;
+    lTime.tm_yday = 0;
+    lTime.tm_isdst = 0;  // No DST adjustment requested
+    
+    lResult = mktime(&lTime);
+    if ((time_t)-1 != lResult) {
+        if (0 != lTime.tm_isdst)
+        {
+            lResult -= 3600;  // mktime may adjust for DST  (OS dependent)
+        }
+        lResult += lSecondsFromUCT;
+    } else {
+        lResult = 0;
+    }
+    
+    return lResult;
+}
+
+static NSString *getTimeStringFromASN1(ASN1_TIME *time) {
+    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
+    [formatter setDateFormat:@"MM/dd/YYYY"];
+    time_t tm = getTimeFromASN1(time);
+    NSDate *expireDate = [NSDate dateWithTimeIntervalSince1970:tm];
+    
+    return [formatter stringFromDate:expireDate];
+}
+
+int get_certificate_info(const char *cert_filepath, const char *password, Certificate *cert);
+int parse_cert_file(const char *cert_filepath, const char *password, X509 **x509);
+
+@interface Certificate()
+
+@property (nonatomic, strong) NSNumber *stu;
+@property (nonatomic, strong) NSString *filename;
+
+@end
+
+@implementation Certificate
+
+@synthesize subjectCN;
+@synthesize issuer;
+@synthesize expireTime;
+@synthesize path = _path;
+@synthesize alias;
+@synthesize password = _password;
+@synthesize name;
+@synthesize stu;
+@synthesize filename;
+
+- (id)initWithCoder:(NSCoder *)aDecoder {
+    self = [super init];
+    if (self != nil) {
+        self.name = [aDecoder decodeObjectForKey:@"name"];
+        self.subjectCN = [aDecoder decodeObjectForKey:@"subjectCN"];
+        self.issuer = [aDecoder decodeObjectForKey:@"issuer"];
+        self.path = [aDecoder decodeObjectForKey:@"path"];
+        self.password = [aDecoder decodeObjectForKey:@"password"];
+        self.expireTime = [aDecoder decodeObjectForKey:@"expireTime"];
+        self.stu = [aDecoder decodeObjectForKey:@"stu"];
+        self.status = [self.stu integerValue];
+        self.filename = [aDecoder decodeObjectForKey:@"filename"];
+    }
+    
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder {
+    [aCoder encodeObject:self.name forKey:@"name"];
+    [aCoder encodeObject:self.subjectCN forKey:@"subjectCN"];
+    [aCoder encodeObject:self.issuer forKey:@"issuer"];
+    [aCoder encodeObject:self.path forKey:@"path"];
+    [aCoder encodeObject:self.password forKey:@"password"];
+    [aCoder encodeObject:self.expireTime forKey:@"expireTime"];
+    self.stu = [[NSNumber alloc] initWithInteger:self.status];
+    [aCoder encodeObject:self.stu forKey:@"stu"];
+    [aCoder encodeObject:self.filename forKey:@"filename"];
+}
+
+int get_certificate_info(const char *cert_filepath, const char *password, Certificate *cert) {
+    X509 *x509data;
+    
+    NSInteger status = parse_cert_file(cert_filepath,password,&x509data);
+    if(status != OK) {
+        return (int)status;
+    }
+    
+    char issuer_name[1024];
+    char subject_name[1024];
+    
+    X509_NAME_oneline(X509_get_issuer_name(x509data), issuer_name, sizeof(issuer_name));
+    X509_NAME_oneline(X509_get_subject_name(x509data), subject_name, sizeof(subject_name));
+    
+    ANDebug(@"Issuer  name: %s", issuer_name);
+    ANDebug(@"Subject name: %s", subject_name);
+    ANDebug(@"Validity from: %s", x509data->cert_info->validity->notBefore->data);
+    ANDebug(@"Validity till: %s", x509data->cert_info->validity->notAfter->data);
+    
+    char issuer_cn[256] = {0};
+    char subject_cn[256] = {0};
+    X509_NAME_get_text_by_NID(X509_get_issuer_name(x509data), NID_commonName, issuer_cn,256);
+    X509_NAME_get_text_by_NID(X509_get_subject_name(x509data), NID_commonName, subject_cn,256);
+    ANDebug(@"Issuer  cn: %s", issuer_cn);
+    ANDebug(@"Subject cn: %s", subject_cn);
+    
+    cert.expireTime = getTimeStringFromASN1(x509data->cert_info->validity->notAfter);
+    cert.subjectCN = [NSString stringWithUTF8String:subject_cn];
+    cert.issuer = [NSString stringWithUTF8String:issuer_cn];
+    
+    return OK;
+}
+
+int parse_cert_file(const char *cert_filepath, const char *password, X509 **x509) {
+    BIO *cert = NULL;
+    PKCS12 *p12;
+    
+    SSLeay_add_all_algorithms();
+    ERR_load_crypto_strings();
+    
+    if ((cert=BIO_new(BIO_s_file())) == NULL) {
+        ANError(@"failed to init BIO");
+        
+        return ERROR_UNKNOWN;
+    }
+    
+    if (BIO_read_filename(cert, cert_filepath) <= 0) {
+        ANError(@"failed to read cert file %s", cert_filepath);
+        
+        BIO_free(cert);
+        
+        return ERROR_FILE_NOT_FOUND;
+    }
+    
+    p12 = d2i_PKCS12_bio(cert, NULL);
+    if (p12 == NULL) {
+        ANError(@"failed to read cert file  %s as PKCS12", cert_filepath);
+        
+        BIO_free(cert);
+        
+        return ERROR_CERT_INVALID;
+    }
+    
+    if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) {
+        ANError(@"password is not needed\n");
+    } else {
+        int pass_len = (int)strlen(password);
+        if (!PKCS12_verify_mac(p12, password, pass_len)) {
+            
+            ANError(@"PKCS12_verify_mac failed, error: %d, %s", (int)ERR_get_error(), ERR_error_string(ERR_get_error(), NULL));
+            ANError(@"Certificate password is wrong.");
+            
+            PKCS12_free(p12);
+            BIO_free(cert);
+            
+            return ERROR_PASSWORD_WRONG;
+        }
+    }
+    
+    EVP_PKEY *pkey;
+    if(!PKCS12_parse(p12, password, &pkey, x509, NULL)) {
+        ANError(@"Cert parse failed, error: %d, %s", (int)ERR_get_error(), ERR_error_string(ERR_get_error(), NULL));
+        
+        PKCS12_free(p12);
+        BIO_free(cert);
+        
+        return ERROR_CERT_INVALID;
+    }
+    
+    PKCS12_free(p12);
+    BIO_free(cert);
+    
+    return OK;
+}
+
+- (Certificate *)initWithP12Path:(NSString *)path pass:(NSString *)pass {
+    self = [super init];
+    if (self) {
+        self.path = path;
+        self.password = pass;
+        self.filename = [path lastPathComponent];
+        
+        self.status = get_certificate_info([path UTF8String], [pass UTF8String], self);
+        if (self.status != OK) {
+            self = nil;
+        };
+    }
+    
+    return  self;
+}
+
+- (NSString *)path {
+    return [[[CertificateManager sharedInstance] certsDirectory] stringByAppendingPathComponent:self.filename];
+}
+
+OSStatus extractIdentityAndTrust(CFDataRef inPKCS12Data,
+                                 SecIdentityRef *outIdentity,
+                                 SecTrustRef *outTrust,
+                                 CFStringRef keyPassword) {
+    OSStatus securityError = errSecSuccess;
+    
+    const void *keys[] = { kSecImportExportPassphrase };
+    const void *values[] = { keyPassword };
+    CFDictionaryRef optionsDictionary = NULL;
+    
+    optionsDictionary = CFDictionaryCreate(
+                                           NULL, keys,
+                                           values, (keyPassword ? 1 : 0),
+                                           NULL, NULL);
+    
+    CFArrayRef items = NULL;
+    securityError = SecPKCS12Import(inPKCS12Data,
+                                    optionsDictionary,
+                                    &items);
+    
+    if (securityError == 0) {
+        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
+        const void *tempIdentity = NULL;
+        tempIdentity = CFDictionaryGetValue (myIdentityAndTrust,
+                                             kSecImportItemIdentity);
+        CFRetain(tempIdentity);
+        *outIdentity = (SecIdentityRef)tempIdentity;
+        const void *tempTrust = NULL;
+        tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
+        
+        CFRetain(tempTrust);
+        *outTrust = (SecTrustRef)tempTrust;
+    }
+    
+    if (optionsDictionary) {
+        CFRelease(optionsDictionary);
+    }
+    
+    if (items) {
+        CFRelease(items);
+    }
+    
+    return securityError;
+}
+
+NSString *copySummaryString(SecIdentityRef identity) {
+    SecCertificateRef myReturnedCertificate = NULL;
+    OSStatus status = SecIdentityCopyCertificate (identity,
+                                                  &myReturnedCertificate);
+    
+    if (status) {
+        ANError(@"SecIdentityCopyCertificate failed.");
+        
+        return NULL;
+    }
+    
+    CFStringRef certSummary = SecCertificateCopySubjectSummary(myReturnedCertificate);
+    
+    NSString* summaryString = [[NSString alloc] initWithString:(__bridge NSString *)certSummary];
+    
+    CFRelease(certSummary);
+    
+    return summaryString;
+}
+
+@end
+
+@implementation CertificateManager
+
+@synthesize certificates;
+
+- (void)save {
+    NSData *arch = [NSKeyedArchiver archivedDataWithRootObject:self.certificates];
+    [[NSUserDefaults standardUserDefaults] setObject:arch forKey:@"certificate"];
+    [[NSUserDefaults standardUserDefaults] synchronize];
+}
+
++ (CertificateManager *)sharedInstance {
+    static CertificateManager * instance;
+    
+    @synchronized([CertificateManager class]) {
+        if(instance == nil){
+            instance = [[CertificateManager alloc] init];
+            
+            NSData * data = [[NSUserDefaults standardUserDefaults] objectForKey:@"certificate"];
+            instance.certificates = [NSKeyedUnarchiver unarchiveObjectWithData:data];
+            if (instance.certificates == nil) {
+                instance.certificates = [[NSMutableDictionary alloc] initWithCapacity:3];
+            }
+            
+            NSFileManager *fileManager = [NSFileManager defaultManager];
+            
+            BOOL isDir;
+            BOOL ret = [fileManager fileExistsAtPath:[instance certsDirectory] isDirectory:&isDir];
+            
+            if (!ret || !isDir) {
+                [fileManager createDirectoryAtPath:[instance certsDirectory] withIntermediateDirectories:YES attributes:nil error:nil];
+            }
+        }
+    }
+    
+    return instance;
+}
+
+- (void)dealloc {
+    [[NSUserDefaults standardUserDefaults] setObject:self.certificates forKey:@"certificate"];
+    [[NSUserDefaults standardUserDefaults] synchronize];
+}
+
+- (NSString *)certsDirectory {
+    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+    NSString *documentsDirectory = [paths objectAtIndex:0];
+    NSString *dir = [documentsDirectory stringByAppendingPathComponent:@"certs"];
+    
+    return dir;
+}
+
+- (void)addCertWithData:(NSData *)data name:(NSString *)name pass:(NSString *)pass {
+    ANInfo(@"Install PKCS12 %@", name);
+    
+    NSString *certpath = [[self certsDirectory] stringByAppendingPathComponent:name];
+    [data writeToFile:certpath atomically:YES];
+}
+
+- (void)addCert:(Certificate *)cert withName:(NSString *)name {
+    ANInfo(@"Add PKCS12 %@", name);
+    
+    [self.certificates setValue:cert forKey:name];
+    [self save];
+}
+
+- (void)removeCertForName:(NSString *)name {
+    ANInfo(@"Delete PKCS12 %@", name);
+    
+    [self.certificates removeObjectForKey:name];
+    [self save];
+}
+
+- (void)setStatus:(NSInteger)status ForCert:(NSString *)name {
+    Certificate *cert = [self.certificates objectForKey:name];
+    if (cert) {
+        cert.status = status;
+    }
+}
+
+- (Certificate *)certificateWithName:(NSString *)name {
+    return [self.certificates objectForKey:name];
+}
+
+- (BOOL)updateCertName:(NSString *)certName withNewName:(NSString *)newName {
+    if (!certName || certName.length < 1 || !newName || newName.length < 1) {
+        ANError(@"Invalid parameter for updating cert name.");
+        return NO;
+    }
+    
+    if ([certName isEqualToString:newName]) {
+        ANInfo(@"Cert name \"%@\" has not changed.", certName);
+        return NO;
+    }
+    
+    Certificate *certificate = [self certificateWithName:certName];
+    if (!certificate) {
+        ANError(@"Certificate named \"%@\" has not been found.", certName);
+        return NO;
+    }
+    
+    [self addCert:certificate withName:newName];
+    [self removeCertForName:certName];
+    
+    return YES;
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/ClientSecurity.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/ClientSecurity.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/ClientSecurity.h	(working copy)
@@ -0,0 +1,28 @@
+//
+//  ClientSecurity.h
+//  MobileNow
+//
+//  Created by wangxy on 16/5/17.
+//  Copyright © 2016年 ArrayNetworks. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface DeviceInfo : NSObject
+
+@property (nonatomic, strong) NSString *name;
+@property (nonatomic, strong) NSString *securityInput;
+
+- (DeviceInfo *)init;
+
+@end
+
+@interface ClientSecurity : NSObject
+
+@property (nonatomic, strong) NSMutableArray *devices;
+
+- (ClientSecurity *)initWithXMLString:(NSString *)xml;
+- (BOOL)startParse;
+- (NSString *)deviceDataForSecurityInput;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/ClientSecurity.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/ClientSecurity.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/ClientSecurity.m	(working copy)
@@ -0,0 +1,108 @@
+//
+//  ClientSecurity.m
+//  MobileNow
+//
+//  Created by wangxy on 16/5/17.
+//  Copyright © 2016年 ArrayNetworks. All rights reserved.
+//
+
+#import "ANLogger.h"
+#import "ClientSecurity.h"
+
+#pragma mark - Device information
+@implementation DeviceInfo
+
+- (DeviceInfo *)init {
+    self = [super init];
+    if (self) {
+        self.name = nil;
+        self.securityInput = nil;
+    }
+    return self;
+}
+
+@end
+
+#pragma mark - Client Security
+@interface ClientSecurity () <NSXMLParserDelegate>
+
+typedef enum {
+    kDeviceNone = 0,
+    kDeviceOnlyOne = 1,
+    kDeviceMore = 2
+} DeviceCounts;
+
+@property (nonatomic, strong) NSXMLParser *parser;
+
+@end
+
+@implementation ClientSecurity
+
+- (ClientSecurity *)initWithXMLString:(NSString *)xml {
+    self = [super init];
+    if (self) {
+        self.devices = [NSMutableArray arrayWithCapacity:1];
+        self.parser = [[NSXMLParser alloc] initWithData:[xml dataUsingEncoding:NSUTF8StringEncoding]];
+        self.parser.delegate = self;
+    }
+    return self;
+}
+
+- (BOOL)startParse {
+    return [self.parser parse];
+}
+
+- (NSString *)deviceDataForSecurityInput {
+    NSInteger totalDevices = [[self devices] count];
+    if (totalDevices == kDeviceNone) {
+        ANError(@"No device info found in client security.");
+        return nil;
+    }
+    
+    /**
+     *  If only 'Default' device is set, use its query string of 'data' from
+     *  'SuccessURL' as input data to response to server. If any other devices
+     *  is set, take the first non-default device's data field as response to
+     *  server.
+     */
+    if (totalDevices == kDeviceOnlyOne) {
+        DeviceInfo *device =  [self.devices objectAtIndex:0];
+        ANDebug(@"Client security has only one device named \"%@\".", device.name);
+        return device.securityInput;
+    } else if (totalDevices >= kDeviceMore) {
+        DeviceInfo *device = [self.devices objectAtIndex:1];
+        if ([device.name isEqualToString:@"Default"]) {
+            device = [self.devices objectAtIndex:0];
+        }
+        ANDebug(@"Client security has %zi devices, \"%@\" is selected.", totalDevices, device.name);
+        return device.securityInput;
+    }
+    return nil;
+}
+
+#pragma mark - NSXMLParserDelegate
+- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
+    NSLog(@"Start parse element named: %@.", elementName);
+    if ([elementName isEqualToString:@"Device"]) {
+        if (attributeDict == nil) {
+            ANWarn(@"[%s] Incorrect xml without attributes.", __FUNCTION__);
+            return;
+        }
+        NSString *successURL = [attributeDict objectForKey:@"SuccessURL"];
+        if (successURL == nil) {
+            ANDebug(@"[%s] No success URL found in the attributes.", __FUNCTION__);
+            return;
+        }
+        DeviceInfo *device = [[DeviceInfo alloc] init];
+        device.name = [attributeDict objectForKey:@"Name"];
+        device.securityInput = [[NSURL URLWithString:successURL].query substringFromIndex:[@"data=" length]];
+        [self.devices addObject:device];
+    }
+}
+
+- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
+    ANError(@"Error occurs when parsing xml for client security. %@", parseError);
+    [self.devices removeAllObjects];
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/XMLAnalysis.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/XMLAnalysis.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/XMLAnalysis.h	(working copy)
@@ -0,0 +1,31 @@
+//
+//  XMLAnalysis.h
+//  MotionProPlus
+//
+//  Created by YJoo on 2022/1/25.
+//  Copyright © 2022 Array Networks. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+enum {
+    XMLReaderOptionsProcessNamespaces           = 1 << 0, // Specifies whether the receiver reports the namespace and the qualified name of an element.
+    XMLReaderOptionsReportNamespacePrefixes     = 1 << 1, // Specifies whether the receiver reports the scope of namespace declarations.
+    XMLReaderOptionsResolveExternalEntities     = 1 << 2, // Specifies whether the receiver reports declarations of external entities.
+};
+typedef NSUInteger XMLReaderOptions;
+
+@interface XMLAnalysis : NSObject <NSXMLParserDelegate>
+
+@property (nonatomic, copy) NSString *information;
+
+- (id)init;
+-(NSDictionary *)dictionaryForXMLData:(NSData *)data ;
+-(NSDictionary *)dictionaryForXMLString:(NSString *)string ;
+-(BOOL) supportSecurity: (NSString *) XMLString;
+
+@end
+
+NS_ASSUME_NONNULL_END
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/XMLAnalysis.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/XMLAnalysis.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ClientSecurity/XMLAnalysis.m	(working copy)
@@ -0,0 +1,340 @@
+//
+//  XMLAnalysis.m
+//  MotionProPlus
+//
+//  Created by YJoo on 2022/1/25.
+//  Copyright © 2022 Array Networks. All rights reserved.
+//
+
+#import "XMLAnalysis.h"
+
+#import <UIKit/UIDevice.h>
+
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "XMLReader requires ARC support."
+#endif
+
+NSString *const kXMLReaderTextNodeKey        = @"text";
+NSString *const kXMLReaderAttributePrefix    = @"@";
+
+@interface XMLAnalysis ()
+
+@property (nonatomic, strong) NSMutableArray *dictionaryStack;
+@property (nonatomic, strong) NSMutableString *textInProgress;
+@property (nonatomic, strong) NSError *errorPointer;
+@property (nonatomic, assign) BOOL securityResult;
+
+@property (nonatomic, strong) NSMutableArray *osArr;
+@property (nonatomic, strong) NSMutableArray *ipArr;
+
+
+@end
+
+
+@implementation XMLAnalysis
+
+#pragma mark - Public methods
+
+
+-(BOOL) supportSecurity: (NSString *) XMLString
+{
+    NSDictionary *xmlDic = [self dictionaryForXMLString:XMLString];
+    return [self deviceDataForSecurityCondition:xmlDic];
+}
+
+
+-(NSDictionary *)dictionaryForXMLData:(NSData *)data
+{
+    XMLAnalysis *reader = [[XMLAnalysis alloc] init];
+    NSDictionary *rootDictionary = [reader objectWithData:data options:0];
+    return rootDictionary;
+}
+
+-(NSDictionary *)dictionaryForXMLString:(NSString *)string
+{
+    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
+    return [self dictionaryForXMLData:data];
+}
+
+#pragma mark - Parsing
+
+- (id)init
+{
+    self = [super init];
+    if (self)
+    {
+        
+    }
+    return self;
+}
+
+- (NSDictionary *)objectWithData:(NSData *)data options:(XMLReaderOptions)options
+{
+    // Clear out any old data
+    self.dictionaryStack = [[NSMutableArray alloc] init];
+    self.textInProgress = [[NSMutableString alloc] init];
+    
+    // Initialize the stack with a fresh dictionary
+    [self.dictionaryStack addObject:[NSMutableDictionary dictionary]];
+    
+    // Parse the XML
+    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
+    
+    [parser setShouldProcessNamespaces:(options & XMLReaderOptionsProcessNamespaces)];
+    [parser setShouldReportNamespacePrefixes:(options & XMLReaderOptionsReportNamespacePrefixes)];
+    [parser setShouldResolveExternalEntities:(options & XMLReaderOptionsResolveExternalEntities)];
+    
+    parser.delegate = self;
+    BOOL success = [parser parse];
+    
+    // Return the stack's root dictionary on success
+    if (success)
+    {
+        NSDictionary *resultDict = [self.dictionaryStack objectAtIndex:0];
+        return resultDict;
+    }
+    
+    return nil;
+}
+
+
+#pragma mark -  NSXMLParserDelegate methods
+
+- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
+{
+    // Get the dictionary for the current level in the stack
+    NSMutableDictionary *parentDict = [self.dictionaryStack lastObject];
+
+    // Create the child dictionary for the new element, and initilaize it with the attributes
+    NSMutableDictionary *childDict = [NSMutableDictionary dictionary];
+    [childDict addEntriesFromDictionary:attributeDict];
+    
+    // If there's already an item for this key, it means we need to create an array
+    id existingValue = [parentDict objectForKey:elementName];
+    if (existingValue)
+    {
+        NSMutableArray *array = nil;
+        if ([existingValue isKindOfClass:[NSMutableArray class]])
+        {
+            // The array exists, so use it
+            array = (NSMutableArray *) existingValue;
+        }
+        else
+        {
+            // Create an array if it doesn't exist
+            array = [NSMutableArray array];
+            [array addObject:existingValue];
+
+            // Replace the child dictionary with an array of children dictionaries
+            [parentDict setObject:array forKey:elementName];
+        }
+        
+        // Add the new child dictionary to the array
+        [array addObject:childDict];
+    }
+    else
+    {
+        // No existing value, so update the dictionary
+        [parentDict setObject:childDict forKey:elementName];
+    }
+    
+    // Update the stack
+    [self.dictionaryStack addObject:childDict];
+}
+
+- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
+{
+    // Update the parent dict with text info
+    NSMutableDictionary *dictInProgress = [self.dictionaryStack lastObject];
+    
+    // Set the text property
+    if ([self.textInProgress length] > 0)
+    {
+        // trim after concatenating
+        NSString *trimmedString = [self.textInProgress stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+        [dictInProgress setObject:[trimmedString mutableCopy] forKey:kXMLReaderTextNodeKey];
+
+        // Reset the text
+        self.textInProgress = [[NSMutableString alloc] init];
+    }
+    
+    // Pop the current dict
+    [self.dictionaryStack removeLastObject];
+}
+
+- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
+{
+    // Build the text value
+    [self.textInProgress appendString:string];
+}
+
+- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
+{
+    // Set the error pointer to the parser's error object
+    self.errorPointer = parseError;
+}
+
+-(BOOL) deviceDataForSecurityCondition: (NSDictionary *) xmlDic
+{
+    if (xmlDic.count < 1){
+        
+        return YES;
+    }
+    
+    _securityResult = YES;
+    _osArr = [NSMutableArray arrayWithCapacity:0];
+    _ipArr = [NSMutableArray arrayWithCapacity:0];
+    
+    NSDictionary *arrayConfig = [xmlDic objectForKey:@"ArrayConfig"];
+    NSDictionary *deviceClassDic = [arrayConfig objectForKey:@"DeviceClass"];
+    NSArray *deviceArr = [self dictionaryForArray:deviceClassDic andKey:@"Device"];
+    
+    for (int i = 0; i < deviceArr.count; i++){
+        
+        NSDictionary *deviceDic = [deviceArr objectAtIndex:i];
+        NSArray *switchConditionArr = [self dictionaryForArray:deviceDic andKey:@"SwitchCondition"];
+        
+        for (int j = 0; j < switchConditionArr.count; j++) {
+            
+            NSDictionary *switchConditionDic = [switchConditionArr objectAtIndex:j];
+            
+            NSString *switchType = [switchConditionDic objectForKey:@"Type"];
+            if ([switchType isEqualToString:@"OS"]){
+                
+                [_osArr addObject:[switchConditionDic objectForKey:@"OSName"]];
+            }else if ([switchType isEqualToString:@"IPAddress"]){
+                
+                [_ipArr addObject:[switchConditionDic objectForKey:@"IP"]];
+            }
+        }
+    }
+    
+    NSArray *devices = [self dictionaryForArray:arrayConfig andKey:@"Device"];
+    for (int i = 0; i < devices.count; i++){
+            
+        NSDictionary *devicesDic = [devices objectAtIndex:i];
+        
+        NSString *HI = [devicesDic objectForKey:@"HI"];
+        if (![HI isEqualToString:@"true"]){
+            
+            continue;
+        }
+        
+
+        NSDictionary *hostIntegrity = [devicesDic objectForKey:@"HostIntegrity"];
+        NSArray *ruleSet = [self dictionaryForArray:hostIntegrity andKey:@"RuleSet"];
+        
+        for (int j = 0; j < ruleSet.count; j++){
+            
+            NSDictionary *ruleSetDic = [ruleSet objectAtIndex:j];
+            NSString *enabled = [ruleSetDic objectForKey:@"Enabled"];
+            if (ruleSetDic.count < 1 || [enabled isEqualToString:@"false"]){
+                
+                continue;
+            }
+            
+            
+            NSArray *ruleZone = [self dictionaryForArray:ruleSetDic andKey:@"RuleZone"];
+            if (ruleZone.count < 1){
+                
+                continue;
+            }
+                
+            for (int k = 0; k < ruleZone.count; k++){
+                
+                NSDictionary *ruleZoneDic = [ruleZone objectAtIndex:k];
+                if ([[ruleZoneDic objectForKey:@"Enabled"] isEqualToString:@"false"]){
+                    
+                    continue;
+                }
+                
+                NSDictionary *ruleDefinition = [ruleZoneDic objectForKey:@"RuleDefinition"];
+                if (ruleDefinition.count < 1){
+                    
+                    continue;
+                }
+                
+                NSString *ruleZoneType = [ruleZoneDic objectForKey:@"Type"];
+                if ([ruleZoneType isEqualToString:@"os"]){
+                
+                    [_osArr addObject:[ruleDefinition objectForKey:@"OSName"]];
+                }
+            }
+        }
+    }
+    
+    //system os version
+    if (_osArr.count > 0){
+        
+        _securityResult = [self judgeOSVersion:_osArr];
+    }
+    
+    //ip address
+    if (_ipArr.count > 0){}
+    
+    return _securityResult;
+}
+
+#pragma mark - system os version
+-(BOOL) judgeOSVersion: (NSMutableArray *) ruleArr
+{
+    for (int i = 0; i < ruleArr.count; i++){
+        
+        NSString *oSName = [ruleArr objectAtIndex:i];
+        self.information = NSLocalizedString(@"The local system does not pass the Client Security check, The detailed check results are as follows:\nOperating system rules checking fail", nil);
+        
+        BOOL isiOS = [oSName containsString:@"ios"];
+#if TAGERT_OS_IPHONE
+        if (isiOS){
+            
+            oSName = [oSName substringWithRange:NSMakeRange(3, 2)];
+            
+            NSString *systemVersion = [UIDevice currentDevice].systemVersion;
+            systemVersion = [systemVersion substringToIndex:2];
+            _securityResult = [systemVersion isEqualToString:oSName];
+        }
+#endif
+        if (_securityResult && isiOS){
+            
+            return _securityResult;
+        }
+    }
+    
+    return _securityResult;
+}
+
+
+#pragma mark - ip address
+-(BOOL)judgeIPAddress: (NSMutableArray *) ruleArr
+{
+    return YES;
+}
+
+
+-(NSArray *) dictionaryForArray: (NSDictionary *) dic andKey: (NSString *) key
+{
+    if (dic.count < 1){
+        
+        return nil;
+    }
+    
+    NSArray *array = [dic objectForKey:key];
+    if (!array){
+        
+        return nil;
+    }
+    
+    NSMutableArray *finalArr = [NSMutableArray arrayWithCapacity:0];
+    if (![array isKindOfClass:[NSMutableArray class]]){
+        
+        [finalArr addObject:array];
+        return finalArr.copy;
+    }
+    
+    return array;
+}
+
+
+@end
+
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ConfigurationManager.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ConfigurationManager.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ConfigurationManager.h	(working copy)
@@ -0,0 +1,141 @@
+//
+//  ConfigurationManager.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/5/8.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#pragma mark - XML Tags
+
+#define TAG_HOST            @"Host"
+#define TAG_WEBAPPS         @"WebApps"
+#define TAG_WEBAPP          @"WebApp"
+#define TAG_WebAcls         @"WebAcls"
+#define TAG_NATIVEAPPS      @"NativeApps"
+#define TAG_NATIVEAPP       @"NativeApp"
+#define TAG_MOBILEAPP       @"MobileApp"
+#define TAG_PACKAGE         @"Package"
+#define TAG_APPDESC         @"AppDesc"
+#define TAG_PORTAL          @"Portal"
+#define TAG_TABPAGE         @"TabPage"
+#define TAG_TABPAGE_WEB     @"web"
+#define TAG_TABPAGE_APP     @"application"
+#define TAG_TABPAGE_DESKTOP @"desktop"
+#define TAG_VPNPOLICY       @"vpnpolicy"
+#define TAG_DYNAMICACL      @"acldynamic"
+#define TAG_CHANGE_LDB_PASSWORD     @"changeldbpassword"
+#define TAG_CHANGE_LDAP_PASSWORD    @"changeldappassword"
+
+#define TAG_ExtMDM          @"ExternalMDM"
+
+// For MotionPro Desktop
+#define TAG_ARP             @"ARP"
+#define TAG_ARP_SETTINGS    @"Settings"
+#define TAG_ARP_HOSTS       @"Hosts"
+#define TAG_ARP_APPS        @"Apps"
+#define TAG_ARP_APP         @"App"
+#define TAG_ARP_SESSINFO    @"SessInfo"
+#define TAG_ARP_PORT        @"RDPPort"
+#define TAG_ARP_INSTANCE    @"Instance"
+#define TAG_ARP_PROVIDERID  @"ProviderID"
+#define TAG_ARP_PROVIDER    @"Provider"
+
+// For MotionPro Desktop Settings
+#define TAG_ARP_SETTINGS_DOMAIN     @"domain"
+#define TAG_ARP_SETTINGS_POWERMNG   @"powermng"
+#define TAG_ARP_SETTINGS_CUSTOMDEST @"customdest"
+
+#define TAG_ARP_SETTINGS_BITMAPCACHE    @"bitmapcache"
+#define TAG_ARP_SETTINGS_DESKTOPWALL    @"desktopwall"
+#define TAG_ARP_SETTINGS_FULLWINDOWDRAG @"fullwindowdrag"
+#define TAG_ARP_SETTINGS_MENUANIM       @"menuanim"
+#define TAG_ARP_SETTINGS_THEMES         @"themes"
+#define TAG_ARP_SETTINGS_SSO            @"sso"
+#define TAG_ARP_SETTINGS_VENDOR_NEC     @"jp-rdp"
+
+
+// For Pub Apps
+#define ARP_APP_NAME        @"Name"
+#define ARP_APP_LOC         @"Loc"
+#define ARP_APP_DIR         @"Dir"
+
+#define ATR_DESC            @"Desc"
+#define ATR_FOLDER          @"Folder"
+#define ATR_WEBAPP_ID       @"ID"
+#define ATR_NATIVEAPP_NAME  @"Name"
+#define ATR_NATIVEAPP_OS    @"OS"
+#define ATR_NATIVEAPP_TYPE  @"Type"
+#define ATR_NATIVEAPP_PARA  @"Para"
+#define ATR_NATIVEAPP_CUSTOM_ICON_URL   @"Icon"
+
+// for MDM
+#define ATR_EXT_MDM_PUSH_IP         @"push_ip"
+#define ATR_EXT_MDM_PUSH_PORT       @"push_port"
+#define ATR_EXT_MDM_SERVICE_URL     @"service_url"
+
+#define ATR_MOBILE_LOCALTIONTYPE    @"LocationType"
+#define ATR_MOBILE_CATEGORY         @"Category"
+#define ATR_MOBILE_ICONURL          @"IconURL"
+#define ATR_MOBILE_APPID            @"AppID"
+#define ATR_MOBILE_SCHEMES          @"Schemes"
+
+#define ATR_PKG_VERSIONNAME         @"VersionName"
+#define ATR_PKG_VERSIONCODE         @"VersionCode"
+#define ATR_PKG_FILESIZE            @"FileSize"
+#define ATR_PKG_FILEURL             @"FileURL"
+#define ATR_PKG_CREATETIME          @"CreateTime"
+#define ATR_PKG_DEVICETYPE          @"DeviceType"
+
+#define ATR_APPDESC_DESC            @"Description"
+
+#define NATIVEAPP_TYPE_BUILDIN      @"built-in app"
+#define NATIVEAPP_TYPE_THIRD        @"third party app"
+
+#define ENC_DEC_KEY "%^UNR#%^UEB$%@$"
+
+@protocol ConfigurationParseProtocol <NSObject>
+
+- (void)configureWithXMLString:(NSString *)string;
+
+@end
+
+#pragma mark - Portal Configuration
+@interface PortalTabsConfiguration : NSObject <ConfigurationParseProtocol>
+
+@property (nonatomic) BOOL isWebAppConfigured;  // Decide whether web app tab to show.
+@property (nonatomic) BOOL isNativeAppConfigured;
+@property (nonatomic) BOOL isDesktopConfigured;
+
+@end
+
+#pragma mark - Dynamic ACL Configuration
+@interface DynamicACLConfiguration : NSObject <ConfigurationParseProtocol>
+
+@property (nonatomic) BOOL isDynamicACLEnabled;
+@property (nonatomic, assign) NSInteger VPNPolicy;
+
+@end
+
+#pragma mark - Change Password Configuraion
+@interface ChangePaswordConfiguration : NSObject <ConfigurationParseProtocol>
+
+@property (nonatomic) BOOL isLocalDBEnabled;
+@property (nonatomic) BOOL isLDAPEnabled;
+
+@end
+
+#pragma mark - Configuration Manager
+@interface ConfigurationManager : NSObject
+
+@property (nonatomic, strong) PortalTabsConfiguration *portalTabs;
+@property (nonatomic, strong) DynamicACLConfiguration *dynamicACL;
+@property (nonatomic, strong) ChangePaswordConfiguration *changePassword;
+
++ (instancetype)sharedInstance;
+
+- (void)parseConfigurations;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ConfigurationManager.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ConfigurationManager.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/ConfigurationManager.m	(working copy)
@@ -0,0 +1,101 @@
+//
+//  ConfigureManager.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/5/8.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "ANLogger.h"
+#import "XMLParser.h"
+#import "AAAManager.h"
+#import "ConfigurationManager.h"
+
+#pragma mark - Portal Configuration
+@implementation PortalTabsConfiguration
+
+- (void)configureWithXMLString:(NSString *)string {
+    NSString *webConfiguredString = [XMLParser parseXMLString:string
+                                                         tags:@[TAG_HOST, TAG_PORTAL, TAG_TABPAGE, TAG_TABPAGE_WEB]];
+    NSString *nativeConfiguredString = [XMLParser parseXMLString:string
+                                                            tags:@[TAG_HOST, TAG_PORTAL, TAG_TABPAGE, TAG_TABPAGE_APP]];
+    NSString *desktopConfiguredString = [XMLParser parseXMLString:string
+                                                             tags:@[TAG_HOST, TAG_PORTAL, TAG_TABPAGE, TAG_TABPAGE_DESKTOP]];
+    if (webConfiguredString) {
+        self.isWebAppConfigured = ![webConfiguredString boolValue];
+    }
+    if (nativeConfiguredString) {
+        self.isNativeAppConfigured = ![nativeConfiguredString boolValue];
+    }
+    if (desktopConfiguredString) {
+        self.isDesktopConfigured = ![desktopConfiguredString boolValue];
+    }
+}
+
+@end
+
+@implementation DynamicACLConfiguration
+
+- (void)configureWithXMLString:(NSString *)string {
+    NSString *VPNPolicyString = [XMLParser parseXMLString:string
+                                                     tags:@[TAG_HOST, TAG_PORTAL, TAG_VPNPOLICY]];
+    NSString *dynamicACLString = [XMLParser parseXMLString:string
+                                                      tags:@[TAG_HOST, TAG_PORTAL, TAG_DYNAMICACL]];
+    if (VPNPolicyString) {
+        self.VPNPolicy = [VPNPolicyString integerValue];
+    }
+    if (dynamicACLString) {
+        self.isDynamicACLEnabled = [dynamicACLString boolValue];
+    }
+}
+
+@end
+
+@implementation ChangePaswordConfiguration
+
+- (void)configureWithXMLString:(NSString *)string {
+    NSString *localDBString = [XMLParser parseXMLString:string
+                                                   tags:@[TAG_HOST, TAG_PORTAL, TAG_CHANGE_LDB_PASSWORD]];
+    NSString *ldapString = [XMLParser parseXMLString:string
+                                                tags:@[TAG_HOST, TAG_PORTAL, TAG_CHANGE_LDAP_PASSWORD]];
+    if (localDBString) {
+        self.isLocalDBEnabled = [localDBString boolValue];
+    }
+    if (ldapString) {
+        self.isLDAPEnabled = [ldapString boolValue];
+    }
+}
+
+@end
+
+#pragma mark - Configuration Manager
+@implementation ConfigurationManager
+
++ (instancetype)sharedInstance {
+    static ConfigurationManager *instance;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        instance = [[ConfigurationManager alloc] init];
+    });
+    
+    return instance;
+}
+
+- (void)parseConfigurations {
+    NSString *resource = [AAAManager sharedInstance].resources;
+    
+    NSString *rootName = [XMLParser getRootNodeNameWithXMLString:resource];
+    if (![rootName isEqualToString:TAG_HOST]) {
+        return;
+    }
+    
+    self.portalTabs = [[PortalTabsConfiguration alloc] init];
+    self.dynamicACL = [[DynamicACLConfiguration alloc] init];
+    self.changePassword = [[ChangePaswordConfiguration alloc] init];
+    
+    [self.portalTabs configureWithXMLString:resource];
+    [self.dynamicACL configureWithXMLString:resource];
+    [self.changePassword configureWithXMLString:resource];
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDHelper.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDHelper.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDHelper.h	(working copy)
@@ -0,0 +1,34 @@
+//
+//  DDHelper.h
+//  MobileNow
+//
+//  Created by zhangqq on 14-5-15.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#if TARGET_OS_IPHONE
+#import <UIKit/UIKit.h>
+#elif TARGET_OS_MAC
+#import <AppKit/AppKit.h>
+#endif
+#import "ResourceItem.h"
+
+@class HostItem;
+@class PubAppItem;
+
+@interface DDHelper : NSObject
+
++ (HostPowerState)queryHostPowerStatus:(HostItem *)host;
++ (void)wakeUpHost:(HostItem *)host withCallback:(void(^)(HostPowerState))callback;
+
++ (NSString *)resolveDomain:(HostItem *)host;
++ (NSDictionary *)fetchAppInfo:(PubAppItem *)app;
+#if TARGET_OS_IPHONE
++ (UIImage *)fetchAppIcon:(PubAppItem *)app;
+#elif TARGET_OS_MAC
++ (NSImage *)fetchAppIcon:(PubAppItem *)app;
+#endif
++ (NSString *)fetchSsoUsername;
++ (NSString *)fetchSsoPassword;
++ (NSDictionary *)fetchVMViewInfo:(HostItem *)host;
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDHelper.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDHelper.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDHelper.m	(working copy)
@@ -0,0 +1,446 @@
+//
+//  DDHelper.m
+//  MobileNow
+//
+//  Created by zhangqq on 14-5-15.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import <arpa/inet.h>
+
+#import "DDHelper.h"
+#import "DDSdkWrapper.h"
+#import "AAAManager.h"
+#import "HostItem.h"
+#import "PubAppItem.h"
+#import "XMLParser.h"
+
+#import "ANLogger.h"
+#import "GeneralTool.h"
+
+static void freeHostInfo(DD_host_info *info);
+
+#pragma mark - DDHelperSession
+/**
+ *  DDHelper Session
+ *  Hold Session when waking up remote host
+ */
+@interface DDHelperSession : NSObject
+@property (nonatomic) DD_host_info *info;
+@property (nonatomic, strong) NSString *session;
+@property (nonatomic, strong) void(^callback)(HostPowerState);
+@end
+
+static const CGFloat WOLCheckWakeUpStateInterval = 10.0;
+
+@implementation DDHelperSession
+- (void)dealloc
+{
+    if (self.info) {
+        freeHostInfo(self.info);
+    }
+}
+@end
+
+#pragma mark - DDHelper
+
+@implementation DDHelper
+
+static char *copyString(const char *string)
+{
+    size_t length;
+    char *newString;
+    
+    if (string == NULL) {
+        length = 0;
+        newString = malloc(length + 1);
+        newString[length] = 0;
+    } else {
+        length = strlen(string);
+        newString = malloc(length + 1);
+        
+        memcpy(newString, string, length);
+        newString[length] = 0;
+    }
+    return newString;
+}
+
+static DD_host_info *createHostInfo(HostItem *hostItem)
+{
+    DD_host_info *info = malloc(sizeof(DD_host_info));
+    memset(info, sizeof(DD_host_info), 0);
+    
+    AAAManager *manager = [AAAManager sharedInstance];
+
+    info->objid = copyString([hostItem.serverIP UTF8String]?: [hostItem.server UTF8String]);
+
+    info->uname = copyString([[GeneralTool encodeURL:manager.account.userName ] UTF8String]?: "");
+    info->vhost = copyString([manager.account.vsHost UTF8String]);
+    info->vport = copyString([manager.account.vsPort UTF8String]);
+    info->pid = copyString([manager.account.passWord UTF8String]);
+    info->instid = copyString([hostItem.instance UTF8String]);
+    info->port = copyString([hostItem.port UTF8String]);
+    info->deskid = copyString([hostItem.ID UTF8String]?: "");
+    
+    info->prov = copyString([hostItem.provider UTF8String]?: "");
+    info->provid = copyString([hostItem.providerID UTF8String]?: "");
+    
+    return info;
+}
+
+static void freeHostInfo(DD_host_info *info)
+{
+    free((void*)info->objid);
+    free((void*)info->uname);
+    free((void*)info->vhost);
+    free((void*)info->vport);
+    free((void*)info->pid);
+    free((void*)info->instid);
+    free((void*)info->port);
+    free((void*)info->deskid);
+    free((void*)info->prov);
+    free((void*)info->provid);
+    
+    free((void*)info);
+}
+
+static NSString *getHostStateSession(DD_host_info *info)
+{
+    char *xml;
+    int length = get_host_power_state_session(info, &xml);
+    
+    if (length <= 0) {
+        ANDebug(@"Fail to get http response.");
+        return nil;
+    }
+    
+    NSString *xmlString = [NSString stringWithUTF8String:xml];
+    NSArray *results = [XMLParser parseXMLString:xmlString tags:@[@"ARP", @"StateSess"] attributes:@[@"ID"]];
+    if (!results || results.count == 0) {
+        ANError(@"Fail to parse http reponse.");
+        return nil;
+    }
+    
+    // <?xml version="1.0"?><ARP><StateSess ID="2"/></ARP>
+    
+    NSString *session = results[0][@"ID"];
+    if (!session) {
+        ANError(@"Fail to get power session.");
+        return nil;
+    }
+    
+    return session;
+}
+
+static NSInteger getHostState(DD_host_info *info, NSDictionary **vdiInfo)
+{
+    char *xml;
+    int length = get_host_power_state(info, &xml);
+    
+    if (length <= 0) {
+        ANDebug(@"Fail to get http response.");
+        return 0;
+    }
+    
+    ANInfo(@"Got XML response: %s", xml);
+    
+    NSString *xmlString = [NSString stringWithUTF8String:xml];
+    NSArray *results = [XMLParser parseXMLString:xmlString
+                                            tags:@[@"ARP", @"StateSess"]
+                                      attributes:@[@"ID", @"State", @"VDIUser", @"VDIPwd", @"VDIDomain", @"Host"]];
+    if (!results || results.count == 0) {
+        ANError(@"Fail to parse http reponse.");
+        return 0;
+    }
+    
+    // <?xml version="1.0"?><ARP><StateSess ID="2" State="1" VDIUser="" VDIPwd="XXXX" VDIDomain="" Host=""/></ARP>
+    
+    NSString *state = results[0][@"State"];
+    if (!state) {
+        ANDebug(@"Fail to get power session.");
+        return 0;
+    }
+    
+    if (vdiInfo != nil) {
+        *vdiInfo = results[0];
+    }
+    
+    return [state integerValue];
+}
+
+static NSString *wakeUpHost(DD_host_info *info)
+{
+    char *xml;
+    int length = wake_up_host(info, &xml);
+    
+    if (length <= 0) {
+        ANError(@"Fail to get http response.");
+        return nil;
+    }
+    
+    NSString *xmlString = [NSString stringWithUTF8String:xml];
+    NSArray *results = [XMLParser parseXMLString:xmlString
+                                            tags:@[@"ARP", @"StateSess"]
+                                      attributes:@[@"ID"]];
+    if (!results || results.count == 0) {
+        ANError(@"Fail to get power session.");
+        return nil;
+    }
+    
+    // <?xml version="1.0"?><ARP><StateSess ID="2"/></ARP>
+    
+    NSString *session = results[0][@"ID"];
+    if (!session) {
+        ANError(@"Fail to get power session.");
+        return nil;
+    }
+    
+    return session;
+}
+
+static NSString *getHostByName(NSString *domain)
+{
+    char *ip;
+    int length = get_host_by_name([domain UTF8String], &ip);
+    if (length <= 0) {
+        ANError(@"Fail to get http response");
+        return nil;
+    }
+    
+    NSString *address = [NSString stringWithCString:ip encoding:NSUTF8StringEncoding];
+    free(ip);
+    
+    return address;
+}
+
+static NSDictionary *getAppInfo(PubAppItem *app)
+{
+    AAAManager *manager = [AAAManager sharedInstance];
+
+    const char *app_id = [app.ID UTF8String];
+    const char *vhost = [manager.account.vsHost UTF8String];
+    const char *vport = [manager.account.vsPort UTF8String];
+    
+    char *info;
+    
+    int length = get_pub_app_host_info(app_id, vhost, vport, &info);
+    
+    if (length <= 0) {
+        ANDebug(@"Fail to get http response.");
+        return nil;
+    }
+    
+    NSString *xml = [NSString stringWithCString:info encoding:NSUTF8StringEncoding];
+    free(info);
+    
+    NSString *port = nil;
+    NSArray *results = [XMLParser parseXMLString:xml
+                                            tags:@[@"ARP", @"Server"]
+                                      attributes:@[@"Port"]];
+    if (results && results.count > 0) {
+        port = results[0][@"Port"];
+    }
+    
+    // <?xml version="1.0"?><ARP><Server Port="3389">10.8.22.172</Server></ARP>
+    
+    NSString *server = [XMLParser parseXMLString:xml tags:@[@"ARP", @"Server"]];
+
+    if (server.length == 0 || !port) {
+        ANDebug(@"Fail to get pub app host and port.");
+        return nil;
+    }
+    
+    return @{@"server": server, @"port": port};
+}
+
+
+static UIImage *getAppIcon(PubAppItem *app)
+
+{
+    AAAManager *manager = [AAAManager sharedInstance];
+    const char *app_id = [app.ID UTF8String];
+    const char *vhost = [manager.account.vsHost UTF8String];
+    const char *vport = [manager.account.vsPort UTF8String];
+    
+    uint8_t *icon;
+    
+    int length = get_pub_app_icon(app_id, vhost, vport, &icon);
+    if (length <= 0) {
+        ANError(@"Fail to get http response.");
+        return nil;
+    }
+    
+    NSData *data = [NSData dataWithBytes:icon length:length];
+    free(icon);
+    
+
+    return [UIImage imageWithData:data];
+
+}
+
+static NSString *getSsoUsername(void)
+{
+    char *username;
+    int length = get_sso_username(&username);
+    if (length <= 0) {
+        ANError(@"Fail to get http response");
+        return [AAAManager sharedInstance].account.userName;
+    }
+    
+    NSString *ssoUsername = [NSString stringWithCString:username encoding:NSUTF8StringEncoding];
+    free(username);
+    
+    return ssoUsername;
+}
+
+static NSString *getSsoPassword(void)
+{
+    char *password;
+    int length = get_sso_password(&password);
+    if (length <= 0) {
+        ANError(@"Fail to get http response.");
+        return [AAAManager sharedInstance].account.passWord;
+    }
+    
+    NSString *ssoPassword = [NSString stringWithCString:password encoding:NSUTF8StringEncoding];
+    free(password);
+    
+    return ssoPassword;
+}
+
++ (HostPowerState)queryHostPowerStatus:(HostItem *)hostItem
+{
+    DD_host_info *info = createHostInfo(hostItem);
+    
+    NSString *session = getHostStateSession(info);
+    if (!session) {
+        freeHostInfo(info);
+        return HostPowerStateUnknow;
+    }
+    
+    info->sessid = [session UTF8String];
+    
+    HostPowerState state = getHostState(info, nil);
+    freeHostInfo(info);
+    
+    if (state < HostPowerStateUnknow || state > HostPowerStateWakingFailed) {
+        return HostPowerStateUnknow;
+    }
+    
+    return state;
+}
+
++ (void)queryHostPowerStatusRepeatly:(NSTimer *)timer
+{
+    DDHelperSession *session = timer.userInfo;
+    if (!session) {
+        return;
+    }
+    
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        HostPowerState state = getHostState(session.info, nil);
+        
+        if (state != HostPowerStateWaking) {
+            // Not waking, return;
+            session.callback(state);
+            return;
+        }
+        
+        // Waking, query 10s latter.
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [NSTimer scheduledTimerWithTimeInterval:WOLCheckWakeUpStateInterval
+                                             target:[self class]
+                                           selector:@selector(queryHostPowerStatusRepeatly:)
+                                           userInfo:session
+                                            repeats:NO];
+        });
+    });
+}
+
++ (void)wakeUpHost:(HostItem *)hostItem withCallback:(void(^)(HostPowerState))callback;
+{
+    DD_host_info *info = createHostInfo(hostItem);
+    
+    NSString *session = wakeUpHost(info);
+    if (!session) {
+        freeHostInfo(info);
+        callback(HostPowerStateWakingFailed);
+        return;
+    }
+    
+    info->sessid = [session UTF8String];
+    NSInteger state = getHostState(info, nil);
+    
+    if (state != HostPowerStateWaking) {
+        callback(state);
+        freeHostInfo(info);
+        return;
+    }
+    
+    DDHelperSession *helperSession = [[DDHelperSession alloc] init];
+    helperSession.info = info;
+    helperSession.callback = callback;
+    helperSession.session = session;
+    
+    dispatch_async(dispatch_get_main_queue(), ^{
+        [NSTimer scheduledTimerWithTimeInterval:WOLCheckWakeUpStateInterval
+                                         target:[self class]
+                                       selector:@selector(queryHostPowerStatusRepeatly:)
+                                       userInfo:helperSession
+                                        repeats:NO];
+    });
+    
+}
+
++ (NSString *)resolveDomain:(HostItem *)host
+{
+    return getHostByName(host.server);
+}
+
++ (NSDictionary *)fetchAppInfo:(PubAppItem *)app
+{
+    return getAppInfo(app);
+}
+
+
++ (UIImage *)fetchAppIcon:(PubAppItem *)app
+
+{
+    return getAppIcon(app);
+}
+
++ (NSString *)fetchSsoUsername
+{
+    return getSsoUsername();
+}
+
++ (NSString *)fetchSsoPassword
+{
+    return getSsoPassword();
+}
+
++ (NSDictionary *)fetchVMViewInfo:(HostItem *)host
+{
+    NSDictionary *vdiInfo = nil;
+    DD_host_info *info = createHostInfo(host);
+    
+    // Set objid to host ID.
+    
+    free((void*)info->objid);
+    info->objid = copyString([[GeneralTool encodeURL:host.ID] UTF8String]?: "");
+    
+    NSString *session = getHostStateSession(info);
+    if (!session) {
+        freeHostInfo(info);
+        return HostPowerStateUnknow;
+    }
+    
+    info->sessid = [session UTF8String];
+    
+    getHostState(info, &vdiInfo);
+    freeHostInfo(info);
+
+    return vdiInfo;
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDSdkWrapper.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDSdkWrapper.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDSdkWrapper.h	(working copy)
@@ -0,0 +1,117 @@
+//
+//  DDSdkWrapper.h
+//  MobileNow
+//
+//  Created by zhangqq on 14-5-13.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#ifndef MobileNow_DDSdkWrapper_h
+#define MobileNow_DDSdkWrapper_h
+
+#include <stdint.h>
+
+#pragma mark - WOL
+
+typedef struct {
+    const char *sessid;
+    const char *objid;
+    const char *uname;
+    const char *pid;
+    const char *provid;
+    const char *prov;
+    const char *instid;
+    const char *port;
+    const char *vhost;
+    const char *vport;
+    const char *deskid;
+} DD_host_info;
+
+/**
+ *  Get host power state session
+ *
+ *  @param info    host information
+ *  @param session result xml string, such as  <?xml version="1.0"?><ARP><StateSess ID="2"/></ARP>
+ *
+ *  @return xml string length, -1 is failed.
+ */
+int get_host_power_state_session(DD_host_info *info, char **session);
+
+/**
+ *  Get host power state
+ *
+ *  @param info  host information
+ *  @param state result xml string, such as <?xml version="1.0"?><ARP><StateSess ID="2" State="1" VDIUser="" VDIPwd="XXXX" VDIDomain="" Host=""/></ARP>
+ *
+ *  @return xml string length, -1 is failed.
+ */
+int get_host_power_state(DD_host_info *info, char **state);
+
+/**
+ *  Wake up host
+ *
+ *  @param info    host information
+ *  @param session result xml string, such as  <?xml version="1.0"?><ARP><StateSess ID="2"/></ARP>
+ *
+ *  @return xml string length, -1 is failed.
+ */
+int wake_up_host(DD_host_info *info, char **session);
+
+#pragma mark - Pub App
+
+/**
+ *  Get pub app icon
+ *
+ *  @param app_id pub app id
+ *  @param vhost  virtual site host
+ *  @param vport  virtual site port
+ *  @param icon   result icon
+ *
+ *  @return icon size
+ */
+int get_pub_app_icon(const char *app_id, const char *vhost, const char *vport, uint8_t **icon);
+
+/**
+ *  Get pub app host and port
+ *
+ *  @param app_id pub app id
+ *  @param vhost  virtual site host
+ *  @param vport  virtual site port
+ *  @param info   result xml, <?xml version="1.0"?><ARP><Server Port="3389">10.8.22.172</Server></ARP>
+ *
+ *  @return xml length
+ */
+int get_pub_app_host_info(const char *app_id, const char *vhost, const char *vport, char **info);
+
+
+#pragma mark - Domain and SSO
+
+/**
+ *  Resolve domain name
+ *
+ *  @param domain domain
+ *  @param ip     result ip address
+ *
+ *  @return ip length
+ */
+int get_host_by_name(const char *domain, char **ip);
+
+/**
+ *  Get sso username
+ *
+ *  @param username the gotted username
+ *
+ *  @return username length
+ */
+int get_sso_username(char **username);
+
+/**
+ *  Get sso password
+ *
+ *  @param password the gotted password
+ *
+ *  @return password length
+ */
+int get_sso_password(char **password);
+
+#endif
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDSdkWrapper.c
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDSdkWrapper.c	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DDSdkWrapper.c	(working copy)
@@ -0,0 +1,424 @@
+//
+//  DdSdkWrapper.c
+//  MobileNow
+//
+//  Created by zhangqq on 14-5-13.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#include <stdio.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "DDSdkWrapper.h"
+#include "arrayapi.h"
+#include "vpn_error.h"
+
+// Resolve domain
+int get_host_by_name(const char *domain, char **ip)
+{
+    vpn_vsite_conn_t conn = NULL;
+    int ret = 0;
+    uint32_t ip_int = 0;
+    int length = 0;
+    
+    *ip = NULL;
+    
+    ret = array_vpn_tcs_connect(&conn);
+    if(ret != ERR_SUCCESS)
+    {
+        return -1;
+    }
+    
+    ret = array_vpn_resolve_host(conn, domain, &ip_int);
+    if (ret != ERR_SUCCESS) {
+        array_vpn_tcs_close(conn);
+        return -1;
+    }
+    
+    array_vpn_tcs_close(conn);
+    
+    struct in_addr ip_addr;
+    ip_addr.s_addr = ip_int;
+    
+    char *string = inet_ntoa(ip_addr);
+    if (string == NULL || string[0] == 0) {
+        return -1;
+    }
+    
+    length = (int)strlen(string);
+    
+    *ip = malloc(length+1);
+    memcpy(*ip, string, length);
+    (*ip)[length] = 0;
+    
+    return length;
+    
+}
+
+
+#define DEFAULT_BUF_SIZE 8192
+
+static char * const GET_APP_INFO_HEADER = "GET /prx/000/http/localhost:9090/query/%s?_appid=%s HTTP/1.1\r\n\r\n";
+
+static int send_http_request(char *header, char **buffer)
+{
+    vpn_vsite_conn_t connection = NULL;
+    int ret = 0;
+    char *response = NULL;
+    uint32_t length;
+    
+    *buffer = NULL;
+    
+    ret = array_vpn_vsite_connect(&connection);
+    
+    if (ret != ERR_SUCCESS) {
+        *buffer = NULL;
+        return -1;
+    }
+    
+    response = (char *)malloc(DEFAULT_BUF_SIZE);
+    memset(response, 0, DEFAULT_BUF_SIZE);
+    
+    length = DEFAULT_BUF_SIZE - 1;
+    
+    ret = array_vpn_vsite_request(connection, header, response, &length);
+    
+    if (ret == ERR_BUF_SIZE) {
+        free(response);
+        response = malloc(length);
+        ret = array_vpn_vsite_request(connection, header, response, &length);
+    }
+    
+    if (ret != ERR_SUCCESS) {
+        free(response);
+        return -1;
+    }
+    
+    array_vpn_vsite_close(connection);
+    
+    *buffer = response;
+    return length;
+}
+
+static int request_app_info(const char *url, const char *app_id, const char *vhost, const char *vport, void **buffer)
+{
+    int length;
+    
+    size_t header_length = strlen(url) + strlen(app_id) + 256;
+    char *header = malloc(header_length);
+    
+    snprintf(header, header_length, GET_APP_INFO_HEADER, url, app_id);
+
+    length = send_http_request(header, (char **)buffer);
+    free(header);
+    
+    return length;
+}
+
+static void *parse_http_body(const char *response)
+{
+    char *body;
+    char *content_length = strstr(response, "Content-Length: ");
+    if (content_length && content_length[0] == '0') {
+        return NULL;
+    }
+    
+    body = strstr(response, "\r\n\r\n");
+    if (!body) {
+        return NULL;
+    }
+    
+    body += 4;
+    return body;
+}
+
+static int get_xml_string_copy(const char *string, char **xml)
+{
+    int length = 0;
+    char *start = strstr(string, "<?xml version");
+    
+    *xml = NULL;
+    
+    if (!start) {
+        return -1;
+    }
+    
+    length = (int)(strlen(string) - (start - string));
+    if (length <= 0) {
+        return length;
+    }
+    
+    *xml = malloc(length + 1);
+    memcpy(*xml, start, length);
+    (*xml)[length] = 0;
+    
+    return length;
+}
+
+// Get pub app icon
+int get_pub_app_icon(const char *app_id, const char *vhost, const char *vport, uint8_t **icon)
+{
+    void *buffer;
+    void *body;
+    int length = 0;
+    
+    *icon = NULL;
+    
+    length = request_app_info("appicon", app_id, vhost, vport, &buffer);
+    if (length <= 0) {
+        return 0;
+    }
+    
+    body = parse_http_body(buffer);
+    if (!body) {
+        free(buffer);
+        return 0;
+    }
+    
+    length = (int)(length - (body - buffer));
+    if (length == 0) {
+        free(buffer);
+        return 0;
+    }
+    
+    *icon = malloc(length);
+    memcpy(*icon, body, length);
+    
+    free(buffer);
+    
+    return length;
+}
+
+int get_pub_app_host_info(const char *app_id, const char *vhost, const char *vport, char **info)
+{
+    void *buffer;
+    int length;
+    
+    *info = NULL;
+    
+    length = request_app_info("appserver", app_id, vhost, vport, &buffer);
+    if (length <= 0) {
+        return -1;
+    }
+    
+    length = get_xml_string_copy(buffer, info);
+    
+    free(buffer);
+    
+    return length;
+}
+
+#define MAX_SSO_INFO_LEN 255
+
+// MS RD client doesn't support password, so just get username.
+int get_sso_username(char **sso_username)
+{
+    vpn_vsite_conn_t conn = NULL;
+    int ret = 0;
+    char *password = NULL;
+    char *username = NULL;
+    uint32_t usernameLength = MAX_SSO_INFO_LEN;
+    uint32_t passwordLength = MAX_SSO_INFO_LEN;
+    int length = 0;
+    
+    username = NULL;
+    password = NULL;
+    *sso_username = NULL;
+    
+    ret = array_vpn_vsite_connect(&conn);
+    if(ret != ERR_SUCCESS)
+    {
+        return -1;
+    }
+    
+    username = malloc(MAX_SSO_INFO_LEN+1);
+    memset(username, 0, MAX_SSO_INFO_LEN+1);
+    
+    password = malloc(MAX_SSO_INFO_LEN+1);
+    memset(password, 0, MAX_SSO_INFO_LEN+1);
+    
+    // TODO: 255 may be not long enouth.
+    ret = array_vpn_get_sso_info(conn, username, &usernameLength, password, &passwordLength);
+    
+    // Free password
+    free(password);
+    
+    if (ret != ERR_SUCCESS) {
+        array_vpn_vsite_close(conn);
+        free(username);
+        // Return current username
+        return -1;
+    }
+    
+    array_vpn_vsite_close(conn);
+    
+    if (username[0] == 0) {
+        free(username);
+        return 0;
+    }
+    
+    length = (int)strlen(username);
+    *sso_username = username;
+    
+    return length;
+}
+
+// MS RD client doesn't support password, so just get username.
+int get_sso_password(char **sso_password)
+{
+    vpn_vsite_conn_t conn = NULL;
+    int ret = 0;
+    char *password = NULL;
+    char *username = NULL;
+    uint32_t usernameLength = MAX_SSO_INFO_LEN;
+    uint32_t passwordLength = MAX_SSO_INFO_LEN;
+    int length = 0;
+    
+    username = NULL;
+    password = NULL;
+    *sso_password = NULL;
+    
+    ret = array_vpn_vsite_connect(&conn);
+    if(ret != ERR_SUCCESS)
+    {
+        return -1;
+    }
+    
+    username = malloc(MAX_SSO_INFO_LEN+1);
+    memset(username, 0, MAX_SSO_INFO_LEN+1);
+    
+    password = malloc(MAX_SSO_INFO_LEN+1);
+    memset(password, 0, MAX_SSO_INFO_LEN+1);
+    
+    // TODO: 255 may be not long enouth.
+    ret = array_vpn_get_sso_info(conn, username, &usernameLength, password, &passwordLength);
+    
+    // Free password
+    free(username);
+    
+    if (ret != ERR_SUCCESS) {
+        array_vpn_vsite_close(conn);
+        free(password);
+        // Return current username
+        return -1;
+    }
+    
+    array_vpn_vsite_close(conn);
+    
+    if (password[0] == 0) {
+        free(password);
+        return 0;
+    }
+    
+    length = (int)strlen(password);
+    *sso_password = password;
+    
+    return length;
+}
+
+static char * const GET_HOST_STATE_SESSION_URL = ""
+"GET /prx/000/http/localhost:9090/object/newstatesess?"
+"_instid=%s"
+"&_objid=%s"
+"&_uname=%s"
+"&_provid=%s"
+" HTTP/1.1\r\n\r\n";
+
+int get_host_power_state_session(DD_host_info *info, char **session)
+{
+    char *buffer;
+    size_t header_length = strlen(info->objid) + strlen(info->uname) + strlen(info->provid) + strlen(info->instid) + 256;
+    char *header = malloc(header_length);
+    int length = 0;
+    
+    snprintf(header, header_length, GET_HOST_STATE_SESSION_URL, info->instid, info->objid, info->uname, info->provid);
+    
+    if (send_http_request(header, &buffer) <= 0) {
+        free(header);
+        return -1;
+    }
+    
+    length = get_xml_string_copy(buffer, session);
+    
+    free(header);
+    free(buffer);
+    
+    return length;
+}
+
+static char * const GET_HOST_STATE_URL = ""
+"GET /prx/000/http/localhost:9090/query/avail?"
+"_sessid=%s"
+"&_objid=%s"
+"&_provid=%s"
+"&_prov=%s"
+"&_instid=%s"
+"&_uname=%s"
+"&_pid=%s"
+"&_port=%s"
+"&_deskid=%s"
+" HTTP/1.1\r\n\r\n";
+
+int get_host_power_state(DD_host_info *info, char **state)
+{
+    char *buffer;
+    int length = 0;
+    size_t header_length = strlen(info->sessid) + strlen(info->uname) + strlen(info->provid) + strlen(info->prov)
+                           + strlen(info->instid) + strlen(info->pid) + strlen(info->port) + strlen(info->deskid) + strlen(info->objid) + 256;
+    
+    printf("Header length is %ld\n", header_length);
+    
+    char *header = malloc(header_length);
+    
+    snprintf(header, header_length, GET_HOST_STATE_URL, info->sessid, info->objid, info->provid,
+             info->prov, info->instid, info->uname, info->pid, info->port, info->deskid);
+    
+    if (send_http_request(header, &buffer) <= 0) {
+        free(header);
+        return -1;
+    }
+    length = get_xml_string_copy(buffer, state);
+    
+    free(header);
+    free(buffer);
+    
+    return length;
+}
+
+static char * const WAKE_UP_HOST_URL = ""
+"GET /prx/000/http/localhost:9090/object/powerup?"
+"_objid=%s"
+"&_prov=%s"
+"&_instid=%s"
+"&_uname=%s"
+" HTTP/1.1\r\n\r\n";
+
+int wake_up_host(DD_host_info *info, char **session)
+{
+    char *buffer;
+    int length = 0;
+    
+    size_t header_length = strlen(info->uname) + strlen(info->prov) + strlen(info->instid) + strlen(info->deskid) + 256;
+    
+    char *header = malloc(header_length);
+    
+    snprintf(header, header_length, WAKE_UP_HOST_URL, info->deskid, info->prov, info->instid, info->uname);
+    
+    if (send_http_request(header, &buffer) <= 0) {
+        free(header);
+        return -1;
+    }
+    
+    length = get_xml_string_copy(buffer, session);
+    
+    free(header);
+    free(buffer);
+    
+    if (length <= 0) {
+        return -1;
+    }
+    
+    return length;
+}
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DynamicAclSender.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DynamicAclSender.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DynamicAclSender.h	(working copy)
@@ -0,0 +1,15 @@
+//
+//  DynamicAclSender.h
+//  MobileNow
+//
+//  Created by zhangqq on 14-5-9.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface DynamicAclSender : NSObject
+
++ (BOOL)createTCPPermitACL:(NSString *)ip port:(NSInteger)port;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DynamicAclSender.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DynamicAclSender.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/DynamicAclSender.m	(working copy)
@@ -0,0 +1,101 @@
+//
+//  DynamicAclSender.m
+//  MobileNow
+//
+//  Created by zhangqq on 14-5-9.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import "DynamicAclSender.h"
+#import "UDPHelper.h"
+#import "ANLogger.h"
+
+NSString* createAclMessage(NSString *ip, NSInteger port, BOOL permit, NSInteger priority);
+NSData* packAclRequestMessage(NSString *aclString);
+
+@implementation DynamicAclSender
+
+static NSString * const ACL_FORMAT_TCP_DENY = @"%d IP TCP:%@:%zi DENY";
+static NSString * const ACL_FORMAT_TCP_PERMIT = @"%d IP TCP:%@:%zi PERMIT";
+
+#define DEFAULT_ACL_PRIORITY 10
+#define ACL_DESTINATION_IP   @"2.255.255.252"
+#define ACL_DESTINATION_PORT 1314
+
+struct AclRequestMessage {
+    uint8_t ID;
+    uint8_t sequence;
+    uint8_t operation;
+    uint8_t encryptedMethod;
+    uint16_t aclRuleLength;
+    char acl[0];
+};
+
+struct AclResponseMessage {
+    uint8_t ID;
+    uint8_t sequence;
+    uint8_t operation;
+    uint8_t result;
+};
+
+typedef NS_ENUM(NSInteger, AclResponseResult) {
+    AclResponseResultSuccess = 0,
+    AclResponseResultDeny,
+    AclResponseResultFormatError,
+    AclResponseResultEncryptError,
+    AclResponseResultSystemError,
+    AclResponseResultAclExist,
+};
+
+NSData* packAclRequestMessage(NSString *aclString) {
+    uint16_t len = (uint16_t)aclString.length;
+    const char *acl = [aclString UTF8String];
+    
+    uint32_t totalLength = sizeof(struct AclRequestMessage)+len;
+    struct AclRequestMessage *message = malloc(totalLength);
+    if (!message) {
+        return nil;
+    }
+    
+    uint16_t aclLength = len;
+    
+    message->ID = 1;
+    message->sequence = 1;
+    message->operation = 1;
+    message->encryptedMethod = 0;
+    message->aclRuleLength = HTONS(aclLength);
+    
+    memcpy(message->acl, acl, len);
+    
+    NSData *data = [NSData dataWithBytes:message length:totalLength];
+    free(message);
+    
+    return data;
+}
+
++ (BOOL)createTCPPermitACL:(NSString *)ip port:(NSInteger)port
+{
+    NSString *acl = [NSString stringWithFormat:ACL_FORMAT_TCP_PERMIT, DEFAULT_ACL_PRIORITY, ip, port];
+    NSData *aclData = packAclRequestMessage(acl);
+    
+    NSLog(@"ACL length is %zi", aclData.length);
+    
+    NSData *response = [UDPHelper sendSyncPacketTo:@"2.255.255.252" port:1314 withMessage:aclData];
+    NSLog(@"response is %@", response);
+    
+    if (!response || response.length==0) {
+        return NO;
+    }
+    
+    const struct AclResponseMessage *message = response.bytes;
+    
+    ANDebug(@"Create ACL result %d", message->result);
+    
+    if (message->result == AclResponseResultSuccess
+        || message->result == AclResponseResultAclExist) {
+        return YES;
+    } else {
+        return NO;
+    }
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/FolderItem.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/FolderItem.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/FolderItem.h	(working copy)
@@ -0,0 +1,24 @@
+//
+//  FolderItem.h
+//  MobileNow
+//
+//  Created by zorro on 14-4-24.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import "ResourceItem.h"
+#import "ConfigurationManager.h"
+
+@interface FolderItem : ResourceItem
+
+@property (nonatomic, strong, readonly) NSMutableDictionary *resourceItems;
+
+- (void)addResourceItem:(ResourceItem *)item forPath:(NSString *)path;
+
+@end
+
+@interface DesktopSetting : NSObject
+
+@property (nonatomic, strong) NSMutableDictionary *settings;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/FolderItem.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/FolderItem.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/FolderItem.m	(working copy)
@@ -0,0 +1,95 @@
+//
+//  FolderItem.m
+//  MobileNow
+//
+//  Created by zorro on 14-4-24.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import "XMLParser.h"
+#import "AppManager.h"
+#import "FolderItem.h"
+#import "PubAppItem.h"
+#import "GCustomItem.h"
+
+#pragma mark - Folder Item
+@implementation FolderItem
+
+- (instancetype)init
+{
+    self = [super init];
+    if (self) {
+        _resourceItems = [[NSMutableDictionary alloc] init];
+    }
+    
+    return self;
+}
+
+- (NSString *)ID
+{
+    return self.name;
+}
+
+- (NSString *)desc
+{
+    return self.name;
+}
+
+- (NSString *)description
+{
+    return self.name;
+}
+
+- (instancetype)folderForPath:(NSString *)path
+{
+    FolderItem *currentFolder = self;
+    NSArray *paths = [path pathComponents];
+    
+    for (NSString *name in paths) {
+        if ([name isEqualToString:@"/"]) {
+            continue;
+        }
+        
+        FolderItem *tmpFolder = [currentFolder.resourceItems valueForKey:name];
+        if (!tmpFolder) {
+            // Create a new folder
+            tmpFolder = [[FolderItem alloc] init];
+            tmpFolder.name = name;
+            currentFolder.resourceItems[name] = tmpFolder;
+        }
+        currentFolder = tmpFolder;
+    }
+    
+    return currentFolder;
+}
+
+- (void)addResourceItem:(ResourceItem *)item forPath:(NSString *)path
+{
+    if (!item.ID) {
+        NSLog(@"Item doesn't have an ID");
+        return;
+    }
+    
+    if ([item.desc rangeOfString:@"pc_only"].location == NSNotFound) {
+        FolderItem *folder = [self folderForPath:path];
+        folder.resourceItems[item.ID] = item;
+    }
+}
+
+@end
+
+#pragma mark - Desktop Setting
+@implementation DesktopSetting
+
+@synthesize settings = _settings;
+
+- (NSMutableDictionary *)settings
+{
+    if (!_settings) {
+        _settings = [[NSMutableDictionary alloc] init];
+    }
+    
+    return _settings;
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/GCustomItem.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/GCustomItem.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/GCustomItem.h	(working copy)
@@ -0,0 +1,13 @@
+//
+//  GCustomItem.h
+//  MobileNow
+//
+//  Created by zhangqq on 14-5-28.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import "HostItem.h"
+
+@interface GCustomItem : HostItem
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/GCustomItem.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/GCustomItem.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/GCustomItem.m	(working copy)
@@ -0,0 +1,77 @@
+//
+//  GCustomItem.m
+//  MobileNow
+//
+//  Created by zhangqq on 14-5-28.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import "GCustomItem.h"
+#import "DDHelper.h"
+#import "ANLogger.h"
+#import "DynamicAclSender.h"
+#import "ArrayVPNManager.h"
+#import "ConfigurationManager.h"
+#import "AAAManager.h"
+
+@implementation GCustomItem
+
+- (void)prepare
+{
+    __weak GCustomItem *wSelf = self;
+    static NSString *session;
+    
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        __strong GCustomItem *sSelf = wSelf;
+        if (!sSelf) {
+            return;
+        }
+        
+        // Resolve domain
+        if (!sSelf.serverIP) {
+            sSelf.status = ResourceStatusResolvingDomain;
+            sSelf.serverIP = [DDHelper resolveDomain:sSelf];
+            if (!sSelf.serverIP) {
+                ANError(@"Cannot resolve the domain name.");
+                sSelf.status = ResourceStatusFailed;
+                return;
+            }
+        }
+        
+        if (![session isEqualToString:[AAAManager sharedInstance].sessCookie]) {
+            session = [AAAManager sharedInstance].sessCookie;
+        }
+        
+        // Dynamic ACL
+        ArrayVPNStatus sslvpnStatus = [ArrayVPNManager sharedInstance].vpnStatus;
+        BOOL portalEnabledAclDynamic = [ConfigurationManager sharedInstance].dynamicACL.isDynamicACLEnabled;
+        
+        if (portalEnabledAclDynamic && sslvpnStatus == ArrayVPNConnected) {
+            BOOL aclResult = NO;
+            int retry = 3;
+            
+            sSelf.status = ResourceStatusCreatingAcl;
+            
+            ANInfo(@"Create dynamic ACL: tcp %@ %@ permit.", sSelf.serverIP, sSelf.port);
+            
+            while (retry--) {
+                aclResult = [DynamicAclSender createTCPPermitACL:sSelf.serverIP port:[sSelf.port integerValue] ];
+                
+                if (aclResult) {
+                    break;
+                }
+            }
+            
+            if (!aclResult) {
+                sSelf.status = ResourceStatusCreatingAclFailed;
+                ANError(@"Fail to create ACL.");
+                return;
+            }
+        }
+        
+        sSelf.status = ResourceStatusReady;
+        
+    });
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/HostItem.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/HostItem.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/HostItem.h	(working copy)
@@ -0,0 +1,34 @@
+//
+//  HostItem.h
+//  MobileNow
+//
+//  Created by zorro on 14-4-24.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#if TARGET_OS_IPHONE
+#import <UIKit/UIKit.h>
+#elif TARGET_OS_MAC
+#import <AppKit/AppKit.h>
+#endif
+#import "ResourceItem.h"
+
+@interface HostItem : ResourceItem
+
+@property (nonatomic, strong) NSString *ssoUsername;
+@property (nonatomic, strong) NSString *ssoPassword;
+@property (nonatomic, strong) NSString *port;
+@property (nonatomic, strong) NSString *domain;
+@property (nonatomic, strong) NSString *server;
+@property (nonatomic, strong) NSString *serverIP;
+@property (nonatomic, strong) NSString *instance;
+@property (nonatomic, strong) NSString *provider;
+@property (nonatomic, strong) NSString *providerID;
+
+@property (nonatomic) NSInteger powerMng;
+@property (nonatomic) HostPowerState powerState;
+@property (nonatomic, strong) NSURL *urlVendorNEC;
+
+- (void)wakeUp;
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/HostItem.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/HostItem.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/HostItem.m	(working copy)
@@ -0,0 +1,353 @@
+//
+//  HostItem.m
+//  MobileNow
+//
+//  Created by zorro on 14-4-24.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#include <arpa/inet.h>
+
+#import "HostItem.h"
+#import "ANLogger.h"
+#import "AAAManager.h"
+#import "ArrayVPNManager.h"
+#import "ConfigurationManager.h"
+
+#import "DynamicAclSender.h"
+#import "DDHelper.h"
+#import "GeneralTool.h"
+#import "AppManager.h"
+#import "ArrayVPNWrapper.h"
+#import "RDCrypto.h"
+
+BOOL isValidIpAddress(const char *ipAddress);
+NSString *resolveDomain(const NSString *domain);
+
+BOOL isValidIpAddress(const char *ipAddress)
+{
+    if (!ipAddress) {
+        return NO;
+    }
+    
+    struct sockaddr_in sa;
+    int result = inet_pton(AF_INET, ipAddress, &(sa.sin_addr));
+    return result != 0;
+}
+
+@interface HostItem()
+@property (nonatomic, strong) NSString *filePath;
+@end
+
+@implementation HostItem
+
+- (UIImage *)icon
+{
+    return [UIImage imageNamed:@"desktop_30.png"];
+}
+
+
+
+- (NSString *)ssoPassword
+{
+    if (!_ssoPassword) {
+        _ssoPassword = @"";
+    }
+    
+    return _ssoPassword;
+}
+
+- (NSString *)ssoUsername
+{
+    if (!_ssoUsername) {
+        _ssoUsername = @"";
+    }
+    
+    return _ssoUsername;
+}
+
+- (void)completeInit
+{
+    if (!self.port) {
+        self.port = @"3389";
+    }
+    
+    if (!self.instance) {
+        self.instance = @"";
+    }
+    
+    if (isValidIpAddress([self.server UTF8String])) {
+        self.serverIP = self.server;
+    }
+    
+    if (!self.desc || self.desc.length == 0) {
+        self.desc = self.name;
+    }
+    
+    NSDictionary *desktopSettings = [AppManager sharedInstance].desktopSettings.settings;
+    if (!self.domain) {
+        self.domain = desktopSettings[@"domain"];
+    }
+    self.instance = desktopSettings[@"instance"];
+    self.powerMng = [desktopSettings[@"powermng"] integerValue];
+    
+    self.status = ResourceStatusInited;
+}
+
+- (void)prepare
+{
+    static NSString *globalSsoUsername;
+    static NSString *session;
+    
+    __weak HostItem *wSelf = self;
+    
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        __strong HostItem *sSelf = wSelf;
+        if (!sSelf) {
+            return;
+        }
+        
+        // VMView doesn't need to resolve ip address.
+        BOOL isVMView = ([self.provider isEqualToString:@"VMView"] || [self.provider isEqualToString:@"XenDesktop"]);
+        
+        if (!sSelf.serverIP && !isVMView) {
+            sSelf.status = ResourceStatusResolvingDomain;
+            sSelf.serverIP = [DDHelper resolveDomain:sSelf];
+            if (!sSelf.serverIP || [sSelf.serverIP isEqualToString:@"0.0.0.0"]) {
+                ANError(@"Cannot resolve the domain name");
+                sSelf.status = ResourceStatusResolveHostNameFailed;
+                // Set it to nil.
+                sSelf.serverIP = nil;
+                //return;
+            }
+        }
+        
+        if (![session isEqualToString:[AAAManager sharedInstance].sessCookie]) {
+            globalSsoUsername = nil;
+            session = [AAAManager sharedInstance].sessCookie;
+        }
+        
+        NSDictionary *desktopSettings = [AppManager sharedInstance].desktopSettings.settings;
+        NSString *enableSSO = desktopSettings[@"sso"];
+        
+        if ([enableSSO isEqualToString:@"0"]) {
+            sSelf.ssoUsername = @"";
+            sSelf.domain = @"";
+            sSelf.ssoPassword = @"";
+        } else {
+            if (!sSelf.ssoUsername || sSelf.ssoUsername.length==0) {
+                if (globalSsoUsername) {
+                    sSelf.ssoUsername = globalSsoUsername;
+                } else {
+                    sSelf.status = ResourceStatusGettingSSO;
+                    globalSsoUsername = [DDHelper fetchSsoUsername];
+                    sSelf.ssoUsername = globalSsoUsername;
+                }
+            }
+            
+            if (!sSelf.ssoPassword || sSelf.ssoPassword.length == 0) {
+                sSelf.status = ResourceStatusGettingSSO;
+                sSelf.ssoPassword = [DDHelper fetchSsoPassword];
+            }
+        }
+        if (isVMView) {
+            NSDictionary *info = [DDHelper fetchVMViewInfo:sSelf];
+            if (info) {
+                sSelf.ssoUsername = info[@"VDIUser"];
+                sSelf.domain = info[@"VDIDomain"];
+                //sSelf.serverIP = info[@"Host"];
+                sSelf.powerState = [info[@"State"] integerValue];
+            
+                NSArray *host = [info[@"Host"] componentsSeparatedByString:@":"];
+                
+                sSelf.serverIP = host[0];
+                if (host.count == 2) {
+                    sSelf.port = host[1];
+                }
+                
+                if (!sSelf.serverIP || sSelf.serverIP.length == 0) {
+                    //Failed
+                    sSelf.status = ResourceStatusFailed;
+                    return;
+                }
+            } else {
+                ANError(@"Fail to get VMView info.");
+                sSelf.status = ResourceStatusFailed;
+                return;
+            }
+        }
+        
+        ANDebug(@"Get sso username %@", sSelf.ssoUsername);
+        
+        BOOL checkPowerState = YES;
+        
+        if (sSelf.powerMng != 1 && !isVMView) {
+            // Power management is off and is not VMView.
+            // Treate it as power up.
+            checkPowerState = NO;
+        }
+        
+        if (sSelf.powerState == HostPowerStateWaking) {
+            if (sSelf.status != ResourceStatusPowerWaking) {
+                sSelf.status = ResourceStatusPowerWaking;
+            }
+            return;
+        } else if (checkPowerState && sSelf.powerState != HostPowerStateUp) {
+            // Query host power state.
+            sSelf.status = ResourceStatusGettingPowerState;
+            
+            sSelf.powerState = [DDHelper queryHostPowerStatus:sSelf];
+            ANDebug(@"Host power state is %ld", (long)sSelf.powerState);
+
+            if (sSelf.powerState == HostPowerStateDown
+                || sSelf.powerState == HostPowerStateUnknow
+                || sSelf.powerState == HostPowerStateWakingFailed) {
+                sSelf.status = ResourceStatusPowerDown;
+                return;
+            } else if (sSelf.powerState == HostPowerStateWaking) {
+                sSelf.status = ResourceStatusPowerWaking;
+                return;
+            }
+        }
+        
+        // Dynamic ACL
+        ArrayVPNStatus sslvpnStatus = [ArrayVPNManager sharedInstance].vpnStatus;
+        BOOL portalEnabledAclDynamic = [ConfigurationManager sharedInstance].dynamicACL.isDynamicACLEnabled;
+        
+        if (portalEnabledAclDynamic && sslvpnStatus == ArrayVPNConnected) {
+            BOOL aclResult = NO;
+            int retry = 3;
+            
+            sSelf.status = ResourceStatusCreatingAcl;
+            
+            ANInfo(@"Creating dynamic ACL: tcp %@ %@ permit", sSelf.serverIP, sSelf.port);
+            
+            while (retry--) {
+                aclResult = [DynamicAclSender createTCPPermitACL:sSelf.serverIP port:[sSelf.port integerValue] ];
+                
+                if (aclResult) {
+                    break;
+                }
+            }
+            
+            if (!aclResult) {
+                sSelf.status = ResourceStatusCreatingAclFailed;
+                ANWarn(@"Failed to create dynamic ACL");
+                return;
+            } else {
+                ANInfo(@"Dynamic ACL is created successfully");
+            }
+        }
+        
+        sSelf.status = ResourceStatusReady;
+    });
+}
+
+- (NSString *)rdpFilePath
+{
+    NSString *tmpDirectory = NSTemporaryDirectory();
+    NSString *rdpFileName = [NSString stringWithFormat:@"%@.rdp", self.ID];
+    return [tmpDirectory stringByAppendingPathComponent:rdpFileName];
+}
+
+static NSString * const RDP_URL_TEMPLATE = @"rdp://"
+"full%%20address=s%%3A%@%%3A%@"
+"&remoteapplicationmode=i%%3A0"
+"&username=s%%3A%@"
+"&domain=s%%3A%@"
+"&disable%%20wallpaper=i%%3A%@"
+"&disable%%20themes=i%%3A%@"
+"&disable%%20menu%%20anims=i%%3A%@"
+"&disable%%20full%%20window%%20drag=i%%3A%@"
+"&drivestoredirect=s%%3A*"
+"&audiomode=i%%3A%d"
+"&server%%20port=i%%3A%@";
+
+- (NSURL *)url
+{
+    if (!self.serverIP) {
+        return nil;
+    }
+    
+    NSDictionary *settings = [AppManager sharedInstance].desktopSettings.settings;
+    
+    NSString *name = [GeneralTool encodeURL:self.ssoUsername];
+    /*if (self.domain && self.domain.length > 0) {
+        name = [NSString stringWithFormat:@"%@\\%@", self.domain, self.ssoUsername];
+        name = [GeneralTool encodeURL:name];
+    }*/
+    
+    NSString *urlString = [NSString stringWithFormat:RDP_URL_TEMPLATE,
+                           self.serverIP,
+                           self.port,
+                           name,
+                           self.domain ? [GeneralTool encodeURL:self.domain] : @"",
+                           settings[@"desktopwall"],
+                           settings[@"themes"],
+                           settings[@"menuanim"],
+                           settings[@"fullwindowdrag"],
+                           (int)[[NSUserDefaults standardUserDefaults] integerForKey:@"desktop_audio_mode"],
+                           self.port];
+    
+    return [NSURL URLWithString:urlString];
+}
+
+- (NSURL *)urlVendorNEC
+{
+    if (!self.serverIP) {
+        return nil;
+    }
+    
+    NSMutableString *rdString = [NSMutableString stringWithCapacity:0];
+    
+    NSString *encryptedHost;
+    if (self.port && ![self.port isEqualToString:@"3389"]) {
+        encryptedHost = [RDCrypto encryptString:[NSString stringWithFormat:@"ip=%@:%@", self.serverIP, self.port]];
+    } else {
+        encryptedHost = [RDCrypto encryptString:[NSString stringWithFormat:@"ip=%@", self.serverIP]];
+    }
+    [rdString appendString:@"RD://?"];
+    [rdString appendString:encryptedHost];
+    
+    if (self.ssoUsername) {
+        NSString *encryptedUsername = [RDCrypto encryptString:[NSString stringWithFormat:@"user=%@", self.ssoUsername]];
+        [rdString appendString:@"&"];
+        [rdString appendString:encryptedUsername];
+    }
+    if (self.ssoPassword) {
+        NSString *encryptedPassword = [RDCrypto encryptString:[NSString stringWithFormat:@"password=%@", self.ssoPassword]];
+        [rdString appendString:@"&"];
+        [rdString appendString:encryptedPassword];
+    }
+    if (self.domain) {
+        NSString *encryptedDomain = [RDCrypto encryptString:[NSString stringWithFormat:@"domain=%@", self.domain]];
+        [rdString appendString:@"&"];
+        [rdString appendString:encryptedDomain];
+    }
+    
+    return [NSURL URLWithString:rdString];
+}
+
+- (void)wakeUp
+{
+    __weak HostItem *wSelf = self;
+    self.status = ResourceStatusPowerWaking;
+    
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        [DDHelper wakeUpHost:self withCallback:^(HostPowerState state) {
+            __strong HostItem *sSelf = wSelf;
+            if (!sSelf) {
+                return;
+            }
+            sSelf.powerState = state;
+            
+            if (state == HostPowerStateUp) {
+                sSelf.status = ResourceStatusWaked;
+                [sSelf prepare];
+            } else {
+                sSelf.status = ResourceStatusWakeFailed;
+            }
+        }];
+    });
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/PubAppItem.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/PubAppItem.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/PubAppItem.h	(working copy)
@@ -0,0 +1,15 @@
+//
+//  PubAppItem.h
+//  MobileNow
+//
+//  Created by zorro on 14-4-25.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import "HostItem.h"
+
+@interface PubAppItem : HostItem
+@property (nonatomic, strong) NSString *location;
+@property (nonatomic, strong) NSString *directory;
+@property (nonatomic) BOOL useV11;
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/PubAppItem.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/PubAppItem.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/PubAppItem.m	(working copy)
@@ -0,0 +1,243 @@
+//
+//  PubAppItem.m
+//  MobileNow
+//
+//  Created by zorro on 14-4-25.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import "PubAppItem.h"
+#import "vpn_error.h"
+#import "arrayapi.h"
+#import "XMLParser.h"
+#import "AAAManager.h"
+#import "ANLogger.h"
+#import "DDHelper.h"
+#import "AppManager.h"
+#import "GeneralTool.h"
+
+@interface PubAppItem()
+{
+
+    UIImage *_icon;
+
+}
+@end
+
+@implementation PubAppItem
+
+static NSString * const RDP_URL_TEMPLATE = @"rdp://"
+"full%%20address=s%%3A%@%%3A%@"
+"&alternate%%20shell=s%%3A%@"
+"&remoteapplicationmode=i%%3A1"
+"&remoteapplicationprogram=s%%3A%@"
+"&shell%%20working%%20directory=s%%3A%@"
+"&username=s%%3A%@"
+"&domain=s%%3A%@"
+"&disable%%20wallpaper=i%%3A%@"
+"&disable%%20themes=i%%3A%@"
+"&disable%%20menu%%20anims=i%%3A%@"
+"&disable%%20full%%20window%%20drag=i%%3A%@"
+"&drivestoredirect=s%%3A*"
+"&audiomode=i%%3A%d"
+"&server%%20port=i%%3A%@";
+
+#define  MAX_VALUE_LEN                256
+#define  LAUNCH_LOCATION_IE           @"iexplore.exe"
+#define  LAUNCH_LOCATION_HTTP         @"http:"
+
+#define  LAUNCH_LOCATION_XTBG         @"http://172.27.63.104"
+#define  LAUNCH_LOCATION_EAS          @"http://192.168.11.62:6888/easportal"
+#define  LAUNCH_LOCATION_TA           @"http://172.27.63.101/trustWeb"
+#define  LAUNCH_LOCATION_TCMP         @"http://172.27.63.109/tcmp"
+#define  LAUNCH_LOCATION_LEARNING     @"http://192.168.11.114:8081/learning"
+#define  LAUNCH_LOCATION_XWH          @"http://192.168.80.205:8013"
+#define  LAUNCH_LOCATION_JDK3         @"C:\\Program Files (x86)\\Kingdee\\K3ERP\\kdmain.exe"
+
+#define  LAUNCH_CMD_XTBG              @"C:\\arrayagent\\ssoagent_xtbg.exe"
+#define  LAUNCH_CMD_EAS               @"C:\\arrayagent\\ssoagent_eas.exe"
+#define  LAUNCH_CMD_TA                @"C:\\arrayagent\\ssoagent_ta.exe"
+#define  LAUNCH_CMD_TCMP              @"C:\\arrayagent\\ssoagent_tcmp.exe"
+#define  LAUNCH_CMD_LEARNING          @"C:\\arrayagent\\ssoagent_learning.exe"
+#define  LAUNCH_CMD_XWH               @"C:\\arrayagent\\ssoagent_xwh.exe"
+#define  LAUNCH_CMD_JDK3              @"C:\\arrayagent\\ssoagent_jdk3.exe"
+
+#define  LAUNCH_CMD_V11               @"C:\\arrayagent\\service\\%@\\ssoagent_v11.exe"
+#define  RDP_USERNAME_V11             @"zrtremoteapp"
+
+int SECRETKEY[] = { 0x3ef5, 0x5e78, 0x1afd, 0x24ef, 0x969d, 0x15ff, 0xef12, 0xdaef, 0x54d9, 0xe8d2,
+        0x33df, 0x72d4, 0xd3d3, 0x666d, 0x5aa5, 0x895d, 0x1e39, 0x9981, 0x99d3, 0xa4d9,
+        0x6980, 0x3289, 0x654,  0x9e8d, 0x6536, 0x4589, 0x27dd, 0x2890, 0x2929, 0x303a,
+        0x313d, 0x32aa};
+
+- (NSString *)encodePassword:(NSString *)password {
+    const char *pOldPwd = [password UTF8String];
+    if (pOldPwd == NULL || strlen(pOldPwd) == 0) {
+        return nil;
+    }
+    
+    char sBuf[4 * MAX_VALUE_LEN + 1];
+    memset(sBuf, 0, 4*MAX_VALUE_LEN+1);
+    int i, j;
+    for (i = 0, j = 0; i < strlen(pOldPwd); i ++) {
+        sprintf( &sBuf[4*i], "%04x", (pOldPwd[i] ^ SECRETKEY[j ++])&0xffff );
+        if (j == 32) {
+            j = 0;
+        }
+    }
+    
+    return [NSString stringWithUTF8String:sBuf];
+}
+
+- (BOOL)postRequest:(int)action url:(NSString *)location {
+    NSString *request = [NSString stringWithFormat:@"%@:60202/action=%d@@@@@@uname=%@@@@@@@session=%@@@@@@@url=%@", self.serverIP, action, self.ssoUsername, [self encodePassword:self.ssoPassword], location];
+    ANInfo(@"post request:%@", request);
+    char resp[4096] = {0};
+    array_vpn_get_response([request UTF8String], resp, 4096);
+    ANInfo(@"postRequest:Get resp finished:%s", resp);
+    
+    NSString *nsResp= [[NSString alloc] initWithUTF8String:resp];
+    if ([nsResp containsString:@"this is ok"]) {
+        return YES;
+    }
+    return NO;
+}
+
+- (NSString *)getLaunchCmdv10:(NSString *)launchCMD {
+    if ([launchCMD containsString:LAUNCH_LOCATION_IE] && [launchCMD containsString:LAUNCH_LOCATION_HTTP]) {
+        if ([launchCMD containsString:LAUNCH_LOCATION_XTBG]) {
+            launchCMD = LAUNCH_CMD_XTBG;
+        } else if ([launchCMD containsString:LAUNCH_LOCATION_EAS]) {
+            launchCMD = LAUNCH_CMD_EAS;
+        } else if ([launchCMD containsString:LAUNCH_LOCATION_TA]) {
+            launchCMD = LAUNCH_CMD_TA;
+        } else if ([launchCMD containsString:LAUNCH_LOCATION_TCMP]) {
+            launchCMD = LAUNCH_CMD_TCMP;
+        } else if ([launchCMD containsString:LAUNCH_LOCATION_LEARNING]) {
+            launchCMD = LAUNCH_CMD_LEARNING;
+        } else if ([launchCMD containsString:LAUNCH_LOCATION_XWH]) {
+            launchCMD = LAUNCH_CMD_XWH;
+        } else {
+            NSRange range = [launchCMD rangeOfString:LAUNCH_LOCATION_HTTP];
+            if (range.length > 0) {
+                launchCMD = [launchCMD substringToIndex:range.location];
+            }
+        }
+    } else if ([launchCMD containsString:LAUNCH_LOCATION_JDK3]) {
+        launchCMD = LAUNCH_CMD_JDK3;
+    }
+    
+    return launchCMD;
+}
+
+- (NSString *)getLaunchCmdv11:(NSString *)launchCMD {
+    int action = 0;
+    NSString *cmd = launchCMD;
+    NSString *result = [NSString stringWithFormat:LAUNCH_CMD_V11, self.ssoUsername];
+    
+    if ([cmd containsString:LAUNCH_LOCATION_IE] && [cmd containsString:LAUNCH_LOCATION_HTTP]) {
+        action = 1;
+        NSRange range = [cmd rangeOfString:LAUNCH_LOCATION_HTTP];
+        if (range.length > 0) {
+            cmd = [cmd substringFromIndex:range.location];
+        }
+    } else if ([cmd containsString:@" "]) {
+        action = 2;
+    }
+    if(![self postRequest:action url:cmd]) {
+        ANInfo(@"post request failed, use version 1.1 failed. change to version 1.0");
+        self.useV11 = NO;
+        result = [self getLaunchCmdv10:launchCMD];
+    }
+    
+    return result;
+}
+
+- (NSURL *)url
+{
+    self.useV11 = YES;
+    if (!self.serverIP) {
+        return nil;
+    }
+    
+    NSDictionary *settings = [AppManager sharedInstance].desktopSettings.settings;
+
+    NSString *launchCMD = [self getLaunchCmdv11:self.location];
+    NSString *name = RDP_USERNAME_V11;
+    if (!self.useV11) {
+        name = [GeneralTool encodeURL:self.ssoUsername];
+    } else {
+        self.domain = @"";
+    }
+    
+    NSString *urlString = [NSString stringWithFormat:RDP_URL_TEMPLATE,
+                           self.serverIP,
+                           self.port,
+                           [GeneralTool encodeURL: launchCMD],
+                           [GeneralTool encodeURL: launchCMD],
+                           [GeneralTool encodeURL: self.directory],
+                           name,
+                           self.domain ? [GeneralTool encodeURL:self.domain] : @"",
+                           settings[@"desktopwall"],
+                           settings[@"themes"],
+                           settings[@"menuanim"],
+                           settings[@"fullwindowdrag"],
+                           (int)[[NSUserDefaults standardUserDefaults] integerForKey:@"desktop_audio_mode"],
+                           self.port];
+    ANInfo(@"url string=%@", urlString);
+    return [NSURL URLWithString:urlString];
+}
+
+- (void)completeInit
+{
+    [super completeInit];
+    __weak PubAppItem *wSelf = self;
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        __strong PubAppItem *sSelf = wSelf;
+        
+        if (!sSelf) {
+            return;
+        }
+        sSelf->_icon = [DDHelper fetchAppIcon:self];
+    });
+}
+
+- (void)prepare
+{
+    __weak PubAppItem *wSelf = self;
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        __strong PubAppItem *sSelf = wSelf;
+
+        if (!sSelf) {
+            return;
+        }
+        
+        if (!self.port || !self.server) {
+            self.status = ResourceStatusGettingServer;
+            
+            NSDictionary *info = [DDHelper fetchAppInfo:sSelf];
+            if (!info) {
+                self.status = ResourceStatusFailed;
+                ANError(@"Fail to get the host and port");
+                return;
+            }
+            
+            sSelf.server = info[@"server"];
+            sSelf.port = info[@"port"];
+        }
+        
+        [super prepare];
+    });
+}
+
+- (UIImage *)icon
+{
+    if (_icon) {
+        return _icon;
+    }
+    
+    return [super icon];
+}
+
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/RDCrypto/RDCrypto.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/RDCrypto/RDCrypto.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/RDCrypto/RDCrypto.h	(working copy)
@@ -0,0 +1,16 @@
+//
+//  RDCrypto.h
+//  RDCrypto
+//
+//  Created by NECST_1SW_3SG_1 on 2012/12/04.
+//  Copyright (c) 2012年 NECST_1SW_3SG_1. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface RDCrypto : NSObject
+
++ (NSString *)encryptString:(NSString *)input;
++ (NSString *)decryptString:(NSString *)input;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/RDCrypto/RDCrypto.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/RDCrypto/RDCrypto.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/RDCrypto/RDCrypto.m	(working copy)
@@ -0,0 +1,83 @@
+//
+//  RDCrypto.m
+//  RDCrypto
+//
+//  Created by NECST_1SW_3SG_1 on 2012/12/04.
+//  Copyright (c) 2012年 NECST_1SW_3SG_1. All rights reserved.
+//
+
+#import "RDCrypto.h"
+#import "Base64.h"
+#import <CommonCrypto/CommonCrypto.h>
+
+@implementation RDCrypto
+
+NSString *keyString = @"jsdnv823un4iqndfu3nfuqpqia013da";
+
++ (NSString *)encryptString:(NSString *)input
+{
+    const void *vKey = (const void *)[keyString UTF8String];
+    const void *vInput = (const void *)[input UTF8String];
+    size_t inputStringBufferSize = strlen(vInput);
+    
+    CCCryptorStatus cryptoStatus;
+    uint8_t *bufferPtr = NULL;
+    size_t bufferPtrSize = 0;
+    size_t encryptedSize = 0;
+    
+    bufferPtrSize = (inputStringBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
+    bufferPtr = malloc(bufferPtrSize * sizeof(uint8_t));
+    memset((void *)bufferPtr, 0x0, bufferPtrSize);
+    
+    cryptoStatus = CCCrypt(kCCEncrypt,
+                           kCCAlgorithmDES,
+                           kCCOptionPKCS7Padding | kCCOptionECBMode,
+                           vKey,
+                           kCCKeySizeDES,
+                           NULL,
+                           vInput,
+                           inputStringBufferSize,
+                           (void *)bufferPtr,
+                           bufferPtrSize,
+                           &encryptedSize);
+    
+    NSString *result;
+    NSData *data = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)encryptedSize];
+    
+    result = [data base64EncodedString];
+    return result;
+}
+
++ (NSString *)decryptString:(NSString *)input
+{
+    NSData *encryptData = [NSData dataWithBase64EncodedString:input];
+    const void *vKey = (const void *)[keyString UTF8String];
+    const void *vInput = (const void *)[encryptData bytes];
+    size_t inputStringBufferSize = [encryptData length];
+    
+    CCCryptorStatus cryptoStatus;
+    uint8_t *bufferPtr = NULL;
+    size_t bufferPtrSize = 0;
+    size_t decryptedSize = 0;
+    
+    bufferPtrSize = (inputStringBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
+    bufferPtr = malloc(bufferPtrSize * sizeof(uint8_t));
+    memset((void *)bufferPtr, 0x0, bufferPtrSize);
+
+    cryptoStatus = CCCrypt(kCCDecrypt,
+                           kCCAlgorithmDES,
+                           kCCOptionPKCS7Padding | kCCOptionECBMode,
+                           vKey,
+                           kCCKeySizeDES,
+                           NULL,
+                           vInput,
+                           inputStringBufferSize,
+                           (void *)bufferPtr,
+                           bufferPtrSize,
+                           &decryptedSize);
+    NSString *result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)decryptedSize]
+                                             encoding:NSUTF8StringEncoding];
+    return result;
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/ResourceItem.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/ResourceItem.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/ResourceItem.h	(working copy)
@@ -0,0 +1,67 @@
+//
+//  ResourceItem.h
+//  MobileNow
+//
+//  Created by zorro on 14-4-24.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import <TargetConditionals.h>
+
+#if TARGET_OS_IPHONE
+#import <UIKit/UIKit.h>
+#elif TARGET_OS_MAC
+#import <AppKit/AppKit.h>
+#endif
+#import "GDataXMLNode.h"
+
+typedef NS_ENUM(NSInteger, ResourceStatus) {
+    // Normal steps
+    ResourceStatusInited = 0,
+    ResourceStatusGettingSSO,
+    ResourceStatusGettingServer,
+    ResourceStatusResolvingDomain,
+    
+    ResourceStatusGettingPowerState,
+    ResourceStatusPowerWaking,
+    
+    ResourceStatusCreatingAcl,
+    
+    // Ready
+    ResourceStatusReady,
+    ResourceStatusWaked,
+    
+    // Failed
+    ResourceStatusFailed,
+    ResourceStatusPowerDown,
+    ResourceStatusWakeFailed,
+    ResourceStatusCreatingAclFailed,
+    ResourceStatusResolveHostNameFailed,
+};
+
+typedef NS_ENUM(NSInteger, HostPowerState) {
+    HostPowerStateUnknow = 0,
+    HostPowerStateDown,
+    HostPowerStateWaking,
+    HostPowerStateUp,
+    HostPowerStateWakingFailed,
+};
+
+@interface ResourceItem : NSObject
+
+@property (nonatomic, strong) NSString *ID;
+@property (nonatomic, strong) NSString *name;
+@property (nonatomic, strong) NSString *desc;
+@property (nonatomic, strong) NSURL *url;
+#if TARGET_OS_IPHONE
+@property (nonatomic, strong) UIImage  *icon;
+#elif TARGET_OS_MAC
+@property (nonatomic, strong) NSImage  *icon;
+#endif
+
+@property (atomic) ResourceStatus status;
+
+- (void)completeInit;
+- (void)prepare;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/ResourceItem.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/ResourceItem.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Desktops/ResourceItem.m	(working copy)
@@ -0,0 +1,36 @@
+//
+//  ResourceItem.m
+//  MobileNow
+//
+//  Created by zorro on 14-4-24.
+//  Copyright (c) 2014年 ArrayNetworks. All rights reserved.
+//
+
+#import "ResourceItem.h"
+
+@implementation ResourceItem
+
+- (void)prepare
+{
+    return;
+}
+
+- (void)completeInit
+{
+    return;
+}
+
+- (NSString *)description
+{
+    return _desc;
+}
+
+
+- (UIImage *)icon
+{
+    // Default icon
+    return [UIImage imageNamed:@"folder_30.png"];
+}
+
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/DetectHostManager.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/DetectHostManager.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/DetectHostManager.h	(working copy)
@@ -0,0 +1,44 @@
+//
+//  DetectHostManager.h
+//  MacTunnel
+//
+//  Created by wangxy on 2021/1/15.
+//  Copyright © 2021 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#define MAX_DETECT_HOST   32
+@interface HostInfo : NSObject
+
+@property (nonatomic,     ) NSInteger valid;
+@property (nonatomic,     ) NSInteger iRTTBest;
+@property (nonatomic,     ) NSInteger iRTT2;
+@property (nonatomic,     ) NSInteger iRTT3;
+@property (nonatomic, copy) NSString *port;
+@property (nonatomic, copy) NSString *host;
+@property (nonatomic, copy) NSString *ipBest;
+@property (nonatomic, copy) NSString *ip2;
+@property (nonatomic, copy) NSString *ip3;
+@property (nonatomic, copy) NSString *alias;
+@end
+
+@interface DetectHostManager : NSObject
+
+@property (nonatomic, strong) HostInfo *bestHost;
+@property (nonatomic, strong) NSArray *allHostArray;
+@property (nonatomic) BOOL getAllTime;
+@property (nonatomic) NSInteger loopTimes;
+@property (nonatomic) NSInteger loopInterval;
+@property (nonatomic, strong) NSMutableArray *allHostInfo;
+
+
++ (DetectHostManager *)sharedInstance;
+- (void)setDetectHostValue:(NSString *)allHost withAllConnTime:(BOOL)getAllTime withLoopTimes:(NSInteger)loopTimes withLoopInterval:(NSInteger)loopInterval;
+- (void)setConnTimewithHost:(NSString *)host ip:(NSString *)ip time:(NSInteger)time ip2:(NSString *)ip2 time2:(NSInteger)time2 ip3:(NSString *)ip3 time3:(NSInteger)time3;
+- (void)startDetect;
+- (void)detectThread:(HostInfo *)param;
+- (HostInfo *)GetHostInfoPerHost:(NSString *)hostString;
+
+@end
+
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/DetectHostManager.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/DetectHostManager.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/DetectHostManager.m	(working copy)
@@ -0,0 +1,203 @@
+//
+//  DetectHostManager.m
+//  MacTunnel
+//
+//  Created by wangxy on 2021/1/15.
+//  Copyright © 2021 wangxy. All rights reserved.
+//
+#import "DetectHostManager.h"
+#import "ANLogger.h"
+#import "arrayapi.h"
+
+@implementation HostInfo
+
+@end
+
+@implementation DetectHostManager
+
+@synthesize bestHost = _bestHost;
+@synthesize allHostArray = _allHostArray;
+@synthesize getAllTime = _getAllTime;
+@synthesize loopTimes = _loopTimes;
+@synthesize loopInterval = _loopInterval;
+@synthesize allHostInfo = _allHostInfo;
+
++ (DetectHostManager *)sharedInstance
+{
+    static DetectHostManager * instance;
+    @synchronized([DetectHostManager class]) {
+        if(instance == nil){
+            instance = [[DetectHostManager alloc] init];
+        }
+    }
+    return instance;
+}
+
+- (void)setDetectHostValue:(NSString *)allHost withAllConnTime:(BOOL)getAllTime withLoopTimes:(NSInteger)loopTimes withLoopInterval:(NSInteger)loopInterval
+{
+    _allHostArray = [allHost componentsSeparatedByString:@";"];
+    _getAllTime = getAllTime;
+    _loopTimes = loopTimes;
+    _loopInterval = loopInterval;
+    
+    _bestHost = [[HostInfo alloc] init];
+    _bestHost.iRTTBest = -1;
+    _bestHost.iRTT2 = -1;
+    _bestHost.iRTT3 = -1;
+    _bestHost.valid = 0;
+}
+
+- (void)detectThread:(HostInfo *)param
+{
+    int port = [param.port intValue];
+    if (param.host == nil || [param.host length] <= 0 || port <= 0) {
+        return;
+    }
+    
+    char chIPAdd[256] = {0}, chIPAdd2[256] = {0}, chIPAdd3[256] = {0};
+    int iRTT2 = INVALID_CONN_TIME, iRTT3 = INVALID_CONN_TIME;
+    int iTime = array_vpn_getHostConnTime2([param.host UTF8String], port, chIPAdd, &iRTT2, chIPAdd2, &iRTT3, chIPAdd3);
+    [self setConnTimewithHost:param.host ip:[[NSString alloc] initWithCString:chIPAdd encoding:NSUTF8StringEncoding] time:iTime ip2:[[NSString alloc] initWithCString:chIPAdd2 encoding:NSUTF8StringEncoding] time2:iRTT2 ip3:[[NSString alloc] initWithCString:chIPAdd3 encoding:NSUTF8StringEncoding] time3:iRTT3];
+    ANInfo(@"detectThread: host:%@, connect time=%d, ip=%s", [[NSThread currentThread] name], iTime, chIPAdd);
+}
+
+- (void)setConnTimewithHost:(NSString *)host ip:(NSString *)ip time:(NSInteger)time ip2:(NSString *)ip2 time2:(NSInteger)time2 ip3:(NSString *)ip3 time3:(NSInteger)time3
+{
+    if (host == nil) {
+        return;
+    }
+    
+    for(int i = 0; i < _allHostArray.count; i++) {
+        if (i >= MAX_DETECT_HOST) {
+            ANInfo(@"DetectHost, ignore the host if host number is more than %d.", MAX_DETECT_HOST);
+            break;
+        }
+        HostInfo *hostInfo = [_allHostInfo objectAtIndex:i];
+        if(host && [hostInfo.host length] > 0 && [host isEqualToString:hostInfo.host] && [hostInfo.ipBest length] <= 0) {
+            hostInfo.iRTTBest = time;
+            hostInfo.iRTT2 = time2;
+            hostInfo.iRTT3 = time3;
+            hostInfo.ipBest = ip;
+            hostInfo.ip2 = ip2;
+            hostInfo.ip3 = ip3;
+            break;
+        }
+    }
+}
+
+- (void)startDetect
+{
+    ANInfo(@"DetectHost: get best host start...");
+    _allHostInfo = [[NSMutableArray alloc] initWithCapacity:MAX_DETECT_HOST];
+    
+    for (int i = 0; i < MAX_DETECT_HOST; i++) {
+        HostInfo *hostInfo = [[HostInfo alloc] init];
+        hostInfo.iRTTBest = -1;
+        hostInfo.iRTT2 = -1;
+        hostInfo.iRTT3 = -1;
+        hostInfo.valid = 0;
+        NSValue *value = [NSValue valueWithBytes:&hostInfo objCType:@encode(HostInfo)];
+        [_allHostInfo addObject:value];
+    }
+    for (int i = 0; i < _allHostArray.count; i ++) {
+        if (i >= MAX_DETECT_HOST) {
+            ANInfo(@"DetectHost, ignore the host if host number is more than %d.", MAX_DETECT_HOST);
+            break;
+        }
+        NSString *host = [_allHostArray objectAtIndex:i];
+        ANInfo(@"Detect host index=%d, host=%@.", i, host);
+        if ([host length] > 0) {
+            HostInfo *hostInfo = [self GetHostInfoPerHost:[_allHostArray objectAtIndex:i]];
+            [_allHostInfo replaceObjectAtIndex:i withObject:hostInfo];
+        }
+    }
+    
+    ANInfo(@"DetectHost, before start all of the thread");
+    NSInteger threadNum = 0;
+    for (int i = 0; i < _allHostArray.count; i ++) {
+        if (i >= MAX_DETECT_HOST) {
+            ANInfo(@"DetectHost, ignore the host if host number is more than %d.", MAX_DETECT_HOST);
+            break;
+        }
+        HostInfo *hostInfo = [_allHostInfo objectAtIndex:i];
+        if (hostInfo.valid == 1 && [hostInfo.host length] > 0) {
+            threadNum ++;
+            NSThread *Thread = [[NSThread alloc] initWithTarget:self selector:@selector(detectThread:) object:hostInfo];
+            [Thread setName:hostInfo.host];
+            [Thread start];
+        }
+    }
+    ANInfo(@"DetectHost, finish start all of the thread, thread num=%ld", (long)threadNum);
+    
+    int iTimes = 0;
+    while (iTimes < _loopTimes) {
+        
+        if(_bestHost.valid == 0) {
+            for (int i = 0; i < _allHostArray.count; i ++) {
+                HostInfo *hostInfo = [_allHostInfo objectAtIndex:i];
+                if (hostInfo.iRTTBest > 0) {
+                    _bestHost.iRTTBest = hostInfo.iRTTBest;
+                    _bestHost.iRTT2 = hostInfo.iRTT2;
+                    _bestHost.iRTT3 = hostInfo.iRTT3;
+                    _bestHost.port = hostInfo.port;
+                    _bestHost.valid = 1;
+                    _bestHost.host = hostInfo.host;
+                    _bestHost.alias = hostInfo.alias;
+                    _bestHost.ipBest = hostInfo.ipBest;
+                    _bestHost.ip2 = hostInfo.ip2;
+                    _bestHost.ip3 = hostInfo.ip3;
+                    ANInfo(@"Get the best conn time(%ld ms), stop for loop.", (long)_bestHost.iRTTBest);
+                    break;
+                }
+            }
+        }
+        
+        if (_bestHost.valid == 1) {
+            ANInfo(@"detecting finished, no need wait all of the thread, best host:%@. conn time:%ld, exit thread.", _bestHost.host, (long)_bestHost.iRTTBest);
+            break;
+        }
+        
+        [NSThread sleepForTimeInterval:0.01 * _loopInterval];
+        iTimes ++;
+    }
+}
+
+- (HostInfo *)GetHostInfoPerHost:(NSString *)hostString
+{
+    HostInfo *hostInfo = [[HostInfo alloc] init];
+    hostInfo.iRTTBest = -1;
+    hostInfo.iRTT2 = -1;
+    hostInfo.iRTT3 = -1;
+
+    if ([hostString length] <= 0) {
+        return hostInfo;
+    }
+    ANInfo(@"GetHostInfoPerHost=%@", hostString);
+
+    NSString *host = @"", *alias = @"", *port = @"443", *tmp = @"";
+
+    host = [hostString rangeOfString:@"/"].location == NSNotFound ? hostString : [[hostString componentsSeparatedByString:@"/"] firstObject];
+    tmp = [hostString rangeOfString:@":"].location == NSNotFound ? @"" : [[hostString componentsSeparatedByString:@":"] lastObject];
+    if ([tmp length] > 0) {
+        port = tmp;
+    }
+    tmp = [hostString rangeOfString:@"/"].location == NSNotFound ? @"" : [[hostString componentsSeparatedByString:@"/"] lastObject];
+    alias = [tmp rangeOfString:@":"].location == NSNotFound ? tmp : [[tmp componentsSeparatedByString:@":"] firstObject];
+    
+    if ([host length] > 0) {
+        hostInfo.valid = 1;
+    }
+
+    hostInfo.host = host;
+    hostInfo.alias = alias;
+    hostInfo.ipBest = @"";
+    hostInfo.ip2 = @"";
+    hostInfo.ip3 = @"";
+    hostInfo.port = port;
+
+    return hostInfo;
+}
+
+
+@end
+
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.h	(working copy)
@@ -0,0 +1,84 @@
+//
+//  GatewayManager.h
+//  MobileNow
+//
+//  Created by array on 2/10/14.
+//  Copyright (c) 2014 MobileNow. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+typedef NS_ENUM(NSInteger, AuthType) {
+    kAuthTypeInvalid = -1,
+    kAuthTypeRegular,
+    kAuthTypeCertificate,
+    kAuthTypeSMS,
+    kAUthTypeSyferlock
+};
+
+@interface Gateway : NSObject
+
+@property (nonatomic, copy) NSString *title;
+@property (nonatomic, copy) NSString *url; /*url maybe: host/alias*/
+@property (nonatomic, copy) NSString *host;
+@property (nonatomic, copy) NSString *bestHost;
+@property (nonatomic, copy) NSString *alias;
+@property (nonatomic, copy) NSString *port;
+@property (nonatomic, copy) NSString *username;
+@property (nonatomic, copy) NSString *certname;
+@property (nonatomic, copy) NSDate   *lastAccessedDate;
+@property (nonatomic,     ) AuthType authType;
+@property (nonatomic, copy) NSString *methodName;
+@property (nonatomic,     ) NSInteger reconnectCounts;
+@property (nonatomic,     ) NSInteger reconnectTime;
+@property (nonatomic      ) BOOL      isSavePasswordEnabled;
+@property (nonatomic,     ) BOOL      isProxyEnabled;
+@property (nonatomic, copy) NSString *proxyHost;
+@property (nonatomic, copy) NSString *proxyUsername;
+@property (nonatomic, copy) NSString *proxyPassword;
+@property (nonatomic,     ) BOOL      isSaveProxyPaswordEnabled;
+@property (nonatomic,     ) BOOL      isSecureTunnelEnabled;
+@property (nonatomic,     ) BOOL      isShowLoginDialogEnabled;
+@property (nonatomic,     ) BOOL      isWebSSOEnabled;
+@property (nonatomic,     ) BOOL      isSyferLockEnabled;
+@property (nonatomic,     ) BOOL      isWebAuthEnabled;
+@property (nonatomic, assign) BOOL    isGestureEnabled; //开启手势校验
+@property (nonatomic, assign) BOOL    isFaceOrTouchIDEnabled;   //开启面部或指纹校验
+@property (nonatomic, copy) NSString *customDnsList;
+@property (nonatomic, assign) BOOL    isRadiusPWD;   //only save Static pass,did not support Biometric authentication
+
+@end
+
+extern NSString * const GATEWAY_FILE_NAME;
+
+@interface GatewayManager : NSObject
+
+@property (nonatomic, readonly) NSString *filePath;
+@property (nonatomic, readonly) NSString *lastClientVersion;
+@property (nonatomic, readonly) NSString *clientDownloadURL;
+
+- (NSInteger)numberOfGateways;
+- (Gateway *)gatewayAtIndex:(NSUInteger)index;
+
+- (void)addGateway:(Gateway *)gateway;
+- (void)updateGateway:(Gateway *)gateway atIndex:(NSUInteger)index;
+- (void)updateGateway:(Gateway *)newGateway;
+- (void)deleteGatewayAtIndex:(NSUInteger)index;
+- (void)deleteGateway:(Gateway *)gateway;
+- (void)didAccessGatewayAtIndex:(NSUInteger)index;
+
+- (NSInteger)indexOfUrl:(NSString *)url andport:(NSString *) port;
+- (Gateway *)gatewayOfUrl:(NSString *)url andport:(NSString *) port;
+
+- (NSInteger)indexOfTitle:(NSString *)title;
+- (Gateway *)gatewayOfTitle:(NSString *)title;
+- (BOOL)isGatewayExist:(NSString *)title;
+- (NSString *)getLastClientVersion;
+- (NSString *)getClientDownloadURL;
+
+- (void)reloadGateways;
+
++ (GatewayManager *)sharedInstance;
+
+//Passwords
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.h.iqiyi
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.h.iqiyi	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.h.iqiyi	(working copy)
@@ -0,0 +1,83 @@
+//
+//  GatewayManager.h
+//  MobileNow
+//
+//  Created by array on 2/10/14.
+//  Copyright (c) 2014 MobileNow. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+typedef NS_ENUM(NSInteger, AuthType) {
+    kAuthTypeInvalid = -1,
+    kAuthTypeRegular,
+    kAuthTypeCertificate,
+    kAuthTypeSMS,
+    kAUthTypeSyferlock
+};
+
+@interface Gateway : NSObject
+
+@property (nonatomic, copy) NSString *title;
+@property (nonatomic, copy) NSString *url; /*url maybe: host/alias*/
+@property (nonatomic, copy) NSString *host;
+@property (nonatomic, copy) NSString *bestHost;
+@property (nonatomic, copy) NSString *alias;
+@property (nonatomic, copy) NSString *port;
+@property (nonatomic, copy) NSString *username;
+@property (nonatomic, copy) NSString *certname;
+@property (nonatomic, copy) NSDate   *lastAccessedDate;
+@property (nonatomic,     ) AuthType authType;
+@property (nonatomic, copy) NSString *methodName;
+@property (nonatomic,     ) NSInteger reconnectCounts;
+@property (nonatomic,     ) NSInteger reconnectTime;
+@property (nonatomic      ) BOOL      isSavePasswordEnabled;
+@property (nonatomic,     ) BOOL      isProxyEnabled;
+@property (nonatomic, copy) NSString *proxyHost;
+@property (nonatomic, copy) NSString *proxyUsername;
+@property (nonatomic, copy) NSString *proxyPassword;
+@property (nonatomic,     ) BOOL      isSaveProxyPaswordEnabled;
+@property (nonatomic,     ) BOOL      isSecureTunnelEnabled;
+@property (nonatomic,     ) BOOL      isShowLoginDialogEnabled;
+@property (nonatomic,     ) BOOL      isWebSSOEnabled;
+@property (nonatomic,     ) BOOL      isSyferLockEnabled;
+@property (nonatomic,     ) BOOL      isWebAuthEnabled;
+@property (nonatomic, assign) BOOL    isGestureEnabled; //开启手势校验
+@property (nonatomic, assign) BOOL    isFaceOrTouchIDEnabled;   //开启面部或指纹校验
+@property (nonatomic, copy) NSString *customDnsList;
+
+@end
+
+extern NSString * const GATEWAY_FILE_NAME;
+
+@interface GatewayManager : NSObject
+
+@property (nonatomic, readonly) NSString *filePath;
+@property (nonatomic, readonly) NSString *lastClientVersion;
+@property (nonatomic, readonly) NSString *clientDownloadURL;
+
+- (NSInteger)numberOfGateways;
+- (Gateway *)gatewayAtIndex:(NSUInteger)index;
+
+- (void)addGateway:(Gateway *)gateway;
+- (void)updateGateway:(Gateway *)gateway atIndex:(NSUInteger)index;
+- (void)updateGateway:(Gateway *)newGateway;
+- (void)deleteGatewayAtIndex:(NSUInteger)index;
+- (void)deleteGateway:(Gateway *)gateway;
+- (void)didAccessGatewayAtIndex:(NSUInteger)index;
+
+- (NSInteger)indexOfUrl:(NSString *)url andport:(NSString *) port;
+- (Gateway *)gatewayOfUrl:(NSString *)url andport:(NSString *) port;
+
+- (NSInteger)indexOfTitle:(NSString *)title;
+- (Gateway *)gatewayOfTitle:(NSString *)title;
+- (BOOL)isGatewayExist:(NSString *)title;
+- (NSString *)getLastClientVersion;
+- (NSString *)getClientDownloadURL;
+
+- (void)reloadGateways;
+
++ (GatewayManager *)sharedInstance;
+
+//Passwords
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.h.zrt
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.h.zrt	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.h.zrt	(working copy)
@@ -0,0 +1,84 @@
+//
+//  GatewayManager.h
+//  MobileNow
+//
+//  Created by array on 2/10/14.
+//  Copyright (c) 2014 MobileNow. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+typedef NS_ENUM(NSInteger, AuthType) {
+    kAuthTypeInvalid = -1,
+    kAuthTypeRegular,
+    kAuthTypeCertificate,
+    kAuthTypeSMS,
+    kAUthTypeSyferlock
+};
+
+@interface Gateway : NSObject
+
+@property (nonatomic, copy) NSString *title;
+@property (nonatomic, copy) NSString *url; /*url maybe: host/alias*/
+@property (nonatomic, copy) NSString *host;
+@property (nonatomic, copy) NSString *bestHost;
+@property (nonatomic, copy) NSString *alias;
+@property (nonatomic, copy) NSString *port;
+@property (nonatomic, copy) NSString *username;
+@property (nonatomic, copy) NSString *certname;
+@property (nonatomic, copy) NSDate   *lastAccessedDate;
+@property (nonatomic,     ) AuthType authType;
+@property (nonatomic, copy) NSString *methodName;
+@property (nonatomic,     ) NSInteger reconnectCounts;
+@property (nonatomic,     ) NSInteger reconnectTime;
+@property (nonatomic      ) BOOL      isSavePasswordEnabled;
+@property (nonatomic,     ) BOOL      isProxyEnabled;
+@property (nonatomic, copy) NSString *proxyHost;
+@property (nonatomic, copy) NSString *proxyUsername;
+@property (nonatomic, copy) NSString *proxyPassword;
+@property (nonatomic,     ) BOOL      isSaveProxyPaswordEnabled;
+@property (nonatomic,     ) BOOL      isSecureTunnelEnabled;
+@property (nonatomic,     ) BOOL      isShowLoginDialogEnabled;
+@property (nonatomic,     ) BOOL      isWebSSOEnabled;
+@property (nonatomic,     ) BOOL      isSyferLockEnabled;
+@property (nonatomic,     ) BOOL      isWebAuthEnabled;
+@property (nonatomic, assign) BOOL    isGestureEnabled; //开启手势校验
+@property (nonatomic, assign) BOOL    isFaceOrTouchIDEnabled;   //开启面部或指纹校验
+@property (nonatomic, copy) NSString *customDnsList;
+
+@end
+
+extern NSString * const GATEWAY_FILE_NAME;
+
+@interface GatewayManager : NSObject
+
+@property (nonatomic, readonly) NSString *filePath;
+@property (nonatomic, readonly) NSString *lastClientVersion;
+@property (nonatomic, readonly) NSString *clientDownloadURL;
+
+- (NSInteger)numberOfGateways;
+- (Gateway *)gatewayAtIndex:(NSUInteger)index;
+
+- (void)addGateway:(Gateway *)gateway;
+- (void)updateGateway:(Gateway *)gateway atIndex:(NSUInteger)index;
+- (void)updateGateway:(Gateway *)newGateway;
+- (void)deleteGatewayAtIndex:(NSUInteger)index;
+- (void)deleteGateway:(Gateway *)gateway;
+- (void)didAccessGatewayAtIndex:(NSUInteger)index;
+- (void)addInitGateway;
+
+- (NSInteger)indexOfUrl:(NSString *)url andport:(NSString *) port;
+- (Gateway *)gatewayOfUrl:(NSString *)url andport:(NSString *) port;
+
+- (NSInteger)indexOfTitle:(NSString *)title;
+- (Gateway *)gatewayOfTitle:(NSString *)title;
+- (BOOL)isGatewayExist:(NSString *)title;
+- (NSString *)getLastClientVersion;
+- (NSString *)getClientDownloadURL;
+
+- (void)reloadGateways;
+
++ (GatewayManager *)sharedInstance;
+
+//Passwords
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.m	(working copy)
@@ -0,0 +1,496 @@
+//
+//  GatewayManager.m
+//  MobileNow
+//
+//  Created by array on 2/10/14.
+//  Copyright (c) 2014 MobileNow. All rights reserved.
+//
+
+#import "GatewayManager.h"
+#import "NSString+AES256.h"
+#import "ANLogger.h"
+#import "ANKeychain.h"
+#import "arrayapi.h"
+
+#define INIT_CONFIG_URL  ""
+static NSString * const kEncryptKey = @"jkajiofpiejqw4i3qu8weji4sa4f890l34";
+
+@interface Gateway()
+
+- (NSDictionary *)archive;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+
+@end
+
+#define GATEWAY_KEY_TITLE        @"title"
+#define GATEWAY_KEY_URL          @"url"
+#define GATEWAY_KEY_HOST         @"host"
+#define GATEWAT_KEY_BEST_HOST    @"besthost"
+#define GATEWAY_KEY_ALIAS        @"alias"
+#define GATEWAY_KEY_USERNAME     @"username"
+#define GATEWAY_KEY_PORT         @"port"
+#define GATEWAY_KEY_CERTNAME     @"certname"
+#define GATEWAY_KEY_LASTACCESS   @"lastAccessedDate"
+#define GATEWAY_KEY_AUTH_TYPE    @"authType"
+#define GATEWAY_KEY_METHOD_NAME  @"methodName"
+#define GATEWAY_KEY_RECONNECT_COUNTS    @"reconnectCounts"
+#define GATEWAY_KEY_RECONNECT_TIME      @"reconnectTime"
+#define GATEWAY_KEY_PROXY_ENABLED       @"proxyEnabled"
+#define GATEWAY_KEY_PROXY_HOST          @"proxyHost"
+#define GATEWAY_KEY_PROXY_USERNAME      @"proxyUsername"
+#define GATEWAY_KEY_PROXY_PASSWORD      @"proxyPassword"
+#define GATEWAY_KEY_WEB_SSO_ENABLED     @"webSSOEnabled"
+#define GATEWAY_KEY_SYFERLOCKENABLED    @"syferLocakEnabled"
+#define GATEWAY_KEY_SAVEPASSWORDENABLED @"savePasswordEnabled"
+#define GATEWAY_KEY_SAVEPROXYPASSWORDENABLED    @"saveProxyPasswordEnabled"
+#define GATEWAY_KEY_SHOW_LOGIN_DIALOG           @"showLoginDialog"
+#define GATEWAY_KEY_SECURE_TUNNEL_ENABLED       @"ipsecEnabled"  // To compatible with v1.0.
+#define GATEWAY_KEY_WEBAUTH_ENABLED             @"webAuthEnabled"
+#define GATEWAY_KEY_GESTURE_ENABLED             @"gestureEnabled"
+#define GATEWAY_KEY_FACE_TOUCHID_ENABLED        @"faceOrTouchIDEnabled"
+#define GATEWAY_KEY_RADIUS_PWD                  @"radiusPwd"
+
+// MPP v1.0 global setting keys
+#define GATEWAY_KEY_SAVEPASSWORDENABLED_V1    @"save_password"
+#define GATEWAY_KEY_WEB_SSO_ENABLED_V1        @"enable_SSO"
+#define GATEWAY_KEY_SHOW_LOGIN_DIALOG_V1      @"disable_login_dialog"
+
+#define GATEWAY_KEY_CUSTOM_DNS_LIST @"customDnsList"
+
+@implementation Gateway
+
+- (NSDictionary *)archive
+{
+    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:19];
+    
+    if (_title) dict[GATEWAY_KEY_TITLE] = _title;
+    if (_url) dict[GATEWAY_KEY_URL] = _url;
+    if (_host) dict[GATEWAY_KEY_HOST] = _host;
+    if (_bestHost) dict[GATEWAT_KEY_BEST_HOST] = _bestHost;
+    if (_alias) dict[GATEWAY_KEY_ALIAS] = _alias;
+    if (_port) dict[GATEWAY_KEY_PORT] = _port;
+    if (_username) dict[GATEWAY_KEY_USERNAME] = _username;
+    if (_certname) dict[GATEWAY_KEY_CERTNAME] = _certname;
+    if (_lastAccessedDate) dict[GATEWAY_KEY_LASTACCESS] = _lastAccessedDate;
+    dict[GATEWAY_KEY_AUTH_TYPE] = @(_authType);
+    if (_methodName) dict[GATEWAY_KEY_METHOD_NAME] = _methodName;
+    dict[GATEWAY_KEY_RECONNECT_COUNTS] = @(_reconnectCounts);
+    dict[GATEWAY_KEY_RECONNECT_TIME] = @(_reconnectTime);
+    dict[GATEWAY_KEY_PROXY_ENABLED] = @(_isProxyEnabled);
+    dict[GATEWAY_KEY_SAVEPASSWORDENABLED] = @(_isSavePasswordEnabled);
+    if (_proxyHost) dict[GATEWAY_KEY_PROXY_HOST] = _proxyHost;
+    if (_proxyUsername) dict[GATEWAY_KEY_PROXY_USERNAME] = _proxyUsername;
+    if (_proxyPassword) dict[GATEWAY_KEY_PROXY_PASSWORD] = [_proxyPassword aes256_encrypt:kEncryptKey];
+    dict[GATEWAY_KEY_SAVEPROXYPASSWORDENABLED] = @(_isSaveProxyPaswordEnabled);
+    dict[GATEWAY_KEY_WEB_SSO_ENABLED] = @(_isWebSSOEnabled);
+    dict[GATEWAY_KEY_SYFERLOCKENABLED] = @(_isSyferLockEnabled);
+    dict[GATEWAY_KEY_SHOW_LOGIN_DIALOG] = @(_isShowLoginDialogEnabled);
+    dict[GATEWAY_KEY_SECURE_TUNNEL_ENABLED] = @(_isSecureTunnelEnabled);
+    dict[GATEWAY_KEY_WEBAUTH_ENABLED] = @(_isWebAuthEnabled);
+    dict[GATEWAY_KEY_GESTURE_ENABLED] = @(_isGestureEnabled);
+    dict[GATEWAY_KEY_FACE_TOUCHID_ENABLED] = @(_isFaceOrTouchIDEnabled);
+    dict[GATEWAY_KEY_RADIUS_PWD] = @(_isRadiusPWD);
+    if (_customDnsList) dict[GATEWAY_KEY_CUSTOM_DNS_LIST] = _customDnsList;
+    
+    return dict;
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)dict
+{
+    self = [super init];
+    if (self) {
+        _title = dict[GATEWAY_KEY_TITLE];
+        _url = dict[GATEWAY_KEY_URL];
+        _host = dict[GATEWAY_KEY_HOST]?dict[GATEWAY_KEY_HOST]:_url;
+        _bestHost = dict[GATEWAT_KEY_BEST_HOST];
+        _alias = dict[GATEWAY_KEY_ALIAS];
+        _port = dict[GATEWAY_KEY_PORT];
+        _username = dict[GATEWAY_KEY_USERNAME];
+        _certname = dict[GATEWAY_KEY_CERTNAME];
+        _lastAccessedDate = dict[GATEWAY_KEY_LASTACCESS];
+        _customDnsList = dict[GATEWAY_KEY_CUSTOM_DNS_LIST];
+        if (dict[GATEWAY_KEY_AUTH_TYPE] == nil) {
+            _authType = kAuthTypeRegular;
+        } else {
+            _authType = [dict[GATEWAY_KEY_AUTH_TYPE] integerValue];
+        }
+        _methodName = dict[GATEWAY_KEY_METHOD_NAME];
+        if (dict[GATEWAY_KEY_RECONNECT_COUNTS] == nil) {
+            _reconnectCounts = 0;
+        } else {
+            _reconnectCounts = [dict[GATEWAY_KEY_RECONNECT_COUNTS] integerValue];
+        }
+        if (dict[GATEWAY_KEY_RECONNECT_TIME] == nil) {
+            _reconnectTime = 300;
+        } else {
+            _reconnectTime = [dict[GATEWAY_KEY_RECONNECT_TIME] integerValue];
+        }
+        if (dict[GATEWAY_KEY_PROXY_ENABLED] == nil) {
+            _isProxyEnabled = NO;
+        } else {
+            _isProxyEnabled = [dict[GATEWAY_KEY_PROXY_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SAVEPASSWORDENABLED] == nil) {
+            // It must compitable with MPP 1.x. This configuration is a global variable in MPP 1.x.
+            _isSavePasswordEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:GATEWAY_KEY_SAVEPASSWORDENABLED_V1];
+        } else {
+            _isSavePasswordEnabled = [dict[GATEWAY_KEY_SAVEPASSWORDENABLED] boolValue];
+        }
+        _proxyHost = dict[GATEWAY_KEY_PROXY_HOST];
+        _proxyUsername = dict[GATEWAY_KEY_PROXY_USERNAME];
+        if (dict[GATEWAY_KEY_PROXY_PASSWORD]) {
+            NSString *password = dict[GATEWAY_KEY_PROXY_PASSWORD];
+            _proxyPassword = [password aes256_decrypt:kEncryptKey];
+        }
+        if (dict[GATEWAY_KEY_SAVEPROXYPASSWORDENABLED] == nil) {
+            _isSaveProxyPaswordEnabled = NO;
+        } else {
+            _isSaveProxyPaswordEnabled = [dict[GATEWAY_KEY_SAVEPROXYPASSWORDENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_WEB_SSO_ENABLED] == nil) {
+            _isWebSSOEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:GATEWAY_KEY_WEB_SSO_ENABLED_V1];
+        } else {
+            _isWebSSOEnabled = [dict[GATEWAY_KEY_WEB_SSO_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SYFERLOCKENABLED] == nil) {
+            _isSyferLockEnabled = NO;
+        } else {
+            _isSyferLockEnabled = [dict[GATEWAY_KEY_SYFERLOCKENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SHOW_LOGIN_DIALOG] == nil) {
+            _isShowLoginDialogEnabled = ![[NSUserDefaults standardUserDefaults] boolForKey:GATEWAY_KEY_SHOW_LOGIN_DIALOG_V1];
+        } else {
+            _isShowLoginDialogEnabled = [dict[GATEWAY_KEY_SHOW_LOGIN_DIALOG] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SECURE_TUNNEL_ENABLED] == nil) {
+            _isSecureTunnelEnabled = YES;
+        } else {
+            _isSecureTunnelEnabled = [dict[GATEWAY_KEY_SECURE_TUNNEL_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_WEBAUTH_ENABLED] == nil) {
+            _isWebAuthEnabled = NO;
+        } else {
+            _isWebAuthEnabled = [dict[GATEWAY_KEY_WEBAUTH_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_GESTURE_ENABLED] == nil) {
+            _isGestureEnabled = NO;
+        } else {
+            _isGestureEnabled = [dict[GATEWAY_KEY_GESTURE_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_FACE_TOUCHID_ENABLED] == nil) {
+            _isFaceOrTouchIDEnabled = NO;
+        } else {
+            _isFaceOrTouchIDEnabled = [dict[GATEWAY_KEY_FACE_TOUCHID_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_RADIUS_PWD] == nil) {
+            _isRadiusPWD = NO;
+        } else {
+            _isRadiusPWD = [dict[GATEWAY_KEY_RADIUS_PWD] boolValue];
+        }
+    }
+    
+    return self;
+}
+
+@end
+
+#pragma mark - Gateway Manager
+
+//For forward compatibility, the file still named Accounts.plist.
+NSString * const GATEWAY_FILE_NAME = @"Accounts.plist";
+
+#define GATEWAY_DEFAULT_PORT    @"443"
+
+@interface GatewayManager()
+{
+    NSMutableArray *_gateways;
+}
+@end
+
+@implementation GatewayManager
+
+@synthesize filePath = _filePath;
+@synthesize lastClientVersion = _lastClientVersion;
+@synthesize clientDownloadURL = _clientDownloadURL;
+
+- (NSString *)filePath {
+    if (!_filePath) {
+        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+        NSString *documentsDirectory = [paths objectAtIndex:0];
+        
+        _filePath = [documentsDirectory stringByAppendingPathComponent:GATEWAY_FILE_NAME];
+    }
+    
+    return _filePath;
+}
+
+- (BOOL)URLInitGateway
+{
+    if(strlen(INIT_CONFIG_URL) <= 0) {
+        return NO;
+    }
+    motionpro_config_t motionpro_config;
+    memset(&motionpro_config, 0, sizeof(motionpro_config_t));
+    array_vpn_get_motionpro_config_byurl(INIT_CONFIG_URL, DD_DEV_TYPE_IPHONE, &motionpro_config);
+    ANInfo(@"URLInitGateway, profile number=%d", motionpro_config.profilenum);
+    if(motionpro_config.profilenum > 0) {
+        [self deleteAllGateways];
+        _gateways = [[NSMutableArray alloc] init];
+    } else {
+        ANError(@"URLInitGateway, init gateway failed.");
+        return NO;
+    }
+    
+    for (int i = 0; i < motionpro_config.profilenum; i ++)
+    {
+        Gateway *newGateway = [[Gateway alloc] init];
+        newGateway.title = [NSString stringWithUTF8String:motionpro_config.profile[i].name];
+        newGateway.url = [NSString stringWithUTF8String:motionpro_config.profile[i].host];
+        newGateway.host = [NSString stringWithUTF8String:motionpro_config.profile[i].host];
+        newGateway.alias = [NSString stringWithUTF8String:motionpro_config.profile[i].alias];
+        newGateway.port = [NSString stringWithFormat:@"%d",motionpro_config.profile[i].port];
+        newGateway.username = [NSString stringWithUTF8String:motionpro_config.profile[i].username];
+        newGateway.isWebSSOEnabled = NO;
+        newGateway.isSyferLockEnabled = NO;
+        newGateway.isSavePasswordEnabled = NO;
+        newGateway.isShowLoginDialogEnabled = YES;
+        newGateway.isSecureTunnelEnabled = YES;
+        newGateway.isWebAuthEnabled = NO;
+        newGateway.certname = @"";
+        
+        [self addGateway:newGateway];
+    }
+    _lastClientVersion = [NSString stringWithUTF8String:motionpro_config.version];
+    _clientDownloadURL = [NSString stringWithUTF8String:motionpro_config.downloadurl];
+    
+    return YES;
+}
+
+- (void)gatewaysInit
+{
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    NSMutableArray *savedGateways = [NSMutableArray arrayWithContentsOfFile: self.filePath];
+    _gateways = [[NSMutableArray alloc] init];
+    
+    if (![fileManager fileExistsAtPath: self.filePath])
+    {
+        [fileManager changeCurrentDirectoryPath:[self.filePath stringByExpandingTildeInPath]];
+        NSData *null = [[NSData alloc] init];
+        [fileManager createFileAtPath:self.filePath contents:null attributes:nil];
+        
+        if(![[NSFileManager defaultManager] fileExistsAtPath:self.filePath])
+        {
+            ANWarn(@"%@ does not exist", self.filePath);
+        }
+        else
+        {
+            if ([self URLInitGateway])  return;
+        }
+    }
+    else
+    {
+        if ([self URLInitGateway])  return;
+    }
+
+    if (savedGateways) {
+        [savedGateways enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+            Gateway *gateway = [[Gateway alloc] initWithDictionary:obj];
+            [_gateways addObject:gateway];
+        }];
+    }
+}
+
+- (id)init
+{
+    self = [super init];
+    if(self) {
+        [self gatewaysInit];
+    }
+    
+    return self;
+}
+
+- (void)synToFile
+{
+    NSMutableArray *allGateways = [[NSMutableArray alloc] initWithCapacity:3];
+    
+    [_gateways enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+        [allGateways addObject:[(Gateway *)obj archive]];
+    }];
+    
+    [allGateways writeToFile:self.filePath atomically:YES];
+}
+
+- (NSInteger)numberOfGateways
+{
+    return _gateways.count;
+}
+
+- (Gateway *)gatewayAtIndex:(NSUInteger)index
+{
+    if (index >= _gateways.count || _gateways.count == 0) {
+        return nil;
+    }
+    
+    return _gateways[index];
+}
+
+- (void)addGateway:(Gateway *)gateway
+{
+    [_gateways addObject:gateway];
+    [self synToFile];
+}
+
+- (void)updateGateway:(Gateway *)gateway atIndex:(NSUInteger)index
+{
+    if (index > _gateways.count) {
+        return;
+    }
+    
+    _gateways[index] = gateway;
+    [self synToFile];
+}
+
+- (void)updateGateway:(Gateway *)newGateway
+{
+    for (NSInteger index = 0; index < _gateways.count; index++) {
+        Gateway *gateway = [_gateways objectAtIndex:index];
+        if ([gateway.url isEqualToString:newGateway.url] && [gateway.port isEqualToString:newGateway.port]) {
+            _gateways[index] = newGateway;
+            [self synToFile];
+        }
+    }
+}
+
+- (void)deleteGatewayAtIndex:(NSUInteger)index
+{
+    if (index > _gateways.count) {
+        return;
+    }
+
+    [_gateways removeObjectAtIndex:index];
+    [self synToFile];
+}
+
+- (void)deleteGateway:(Gateway *)gateway
+{
+    for (NSInteger index = 0; index < _gateways.count; index++) {
+        Gateway *iter = [_gateways objectAtIndex:index];
+        if ([iter.title isEqualToString:gateway.title]) {
+            [_gateways removeObjectAtIndex:index];
+            [self synToFile];
+            return;
+        }
+    }
+}
+
+- (void)didAccessGatewayAtIndex:(NSUInteger)index
+{
+    if (index > _gateways.count) {
+        return;
+    }
+    
+    Gateway *gateway = _gateways[index];
+
+    if (!gateway) {
+        ANDebug(@"Gateway at index: %zi not found", index);
+        return;
+    }
+
+    gateway.lastAccessedDate = [NSDate date];
+    [self synToFile];
+}
+
+- (NSInteger)indexOfUrl:(NSString *)url andport:(NSString *) port
+{
+    NSInteger index = -1;
+    for (Gateway *gateway in _gateways) {
+        index++;
+        
+        if ([url isEqualToString:gateway.url] && [port isEqualToString:gateway.port]) {
+            return index;
+        }
+    }
+    
+    return NSNotFound;
+}
+
+- (Gateway *)gatewayOfUrl:(NSString *)url andport:(NSString *) port
+{
+    NSInteger index = -1;
+    for (Gateway *gateway in _gateways) {
+        index++;
+        
+        if ([url isEqualToString:gateway.url] && [port isEqualToString:gateway.port]) {
+            return gateway;
+        }
+    }
+    
+    return nil;
+}
+
+- (NSInteger)indexOfTitle:(NSString *)title
+{
+    NSInteger index = -1;
+    for (Gateway *gateway in _gateways) {
+        index++;
+        
+        if ([title isEqualToString:gateway.title]) {
+            return index;
+        }
+    }
+    
+    return NSNotFound;
+}
+
+- (Gateway *)gatewayOfTitle:(NSString *)title
+{
+    for (Gateway *gateway in _gateways) {
+        if ([gateway.title isEqualToString:title]) {
+            return gateway;
+        }
+    }
+    
+    return nil;
+}
+
+- (BOOL)isGatewayExist:(NSString *)title
+{
+    return [self gatewayOfTitle:title] != nil ? YES : NO;
+}
+
+- (NSString *)getLastClientVersion
+{
+    return _lastClientVersion;
+}
+
+- (NSString *)getClientDownloadURL
+{
+    return _clientDownloadURL;
+}
+
+- (void)deleteAllGateways
+{
+    if (_gateways) {
+        [_gateways removeAllObjects];
+        _gateways = nil;
+    }
+}
+
+- (void)reloadGateways
+{
+    [self deleteAllGateways];
+    [self gatewaysInit];
+}
+
++ (GatewayManager *)sharedInstance
+{
+    static GatewayManager * instance;
+    @synchronized([GatewayManager class]) {
+        if(instance == nil){
+            instance = [[GatewayManager alloc] init];
+        }
+    }
+    return instance;
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.m.iqiyi
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.m.iqiyi	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.m.iqiyi	(working copy)
@@ -0,0 +1,489 @@
+//
+//  GatewayManager.m
+//  MobileNow
+//
+//  Created by array on 2/10/14.
+//  Copyright (c) 2014 MobileNow. All rights reserved.
+//
+
+#import "GatewayManager.h"
+#import "NSString+AES256.h"
+#import "ANLogger.h"
+#import "ANKeychain.h"
+#import "arrayapi.h"
+
+#define INIT_CONFIG_URL  "https://iqiyi.cn/zentrys"
+static NSString * const kEncryptKey = @"jkajiofpiejqw4i3qu8weji4sa4f890l34";
+
+@interface Gateway()
+
+- (NSDictionary *)archive;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+
+@end
+
+#define GATEWAY_KEY_TITLE        @"title"
+#define GATEWAY_KEY_URL          @"url"
+#define GATEWAY_KEY_HOST         @"host"
+#define GATEWAT_KEY_BEST_HOST    @"besthost"
+#define GATEWAY_KEY_ALIAS        @"alias"
+#define GATEWAY_KEY_USERNAME     @"username"
+#define GATEWAY_KEY_PORT         @"port"
+#define GATEWAY_KEY_CERTNAME     @"certname"
+#define GATEWAY_KEY_LASTACCESS   @"lastAccessedDate"
+#define GATEWAY_KEY_AUTH_TYPE    @"authType"
+#define GATEWAY_KEY_METHOD_NAME  @"methodName"
+#define GATEWAY_KEY_RECONNECT_COUNTS    @"reconnectCounts"
+#define GATEWAY_KEY_RECONNECT_TIME      @"reconnectTime"
+#define GATEWAY_KEY_PROXY_ENABLED       @"proxyEnabled"
+#define GATEWAY_KEY_PROXY_HOST          @"proxyHost"
+#define GATEWAY_KEY_PROXY_USERNAME      @"proxyUsername"
+#define GATEWAY_KEY_PROXY_PASSWORD      @"proxyPassword"
+#define GATEWAY_KEY_WEB_SSO_ENABLED     @"webSSOEnabled"
+#define GATEWAY_KEY_SYFERLOCKENABLED    @"syferLocakEnabled"
+#define GATEWAY_KEY_SAVEPASSWORDENABLED @"savePasswordEnabled"
+#define GATEWAY_KEY_SAVEPROXYPASSWORDENABLED    @"saveProxyPasswordEnabled"
+#define GATEWAY_KEY_SHOW_LOGIN_DIALOG           @"showLoginDialog"
+#define GATEWAY_KEY_SECURE_TUNNEL_ENABLED       @"ipsecEnabled"  // To compatible with v1.0.
+#define GATEWAY_KEY_WEBAUTH_ENABLED             @"webAuthEnabled"
+#define GATEWAY_KEY_GESTURE_ENABLED             @"gestureEnabled"
+#define GATEWAY_KEY_FACE_TOUCHID_ENABLED        @"faceOrTouchIDEnabled"
+
+// MPP v1.0 global setting keys
+#define GATEWAY_KEY_SAVEPASSWORDENABLED_V1    @"save_password"
+#define GATEWAY_KEY_WEB_SSO_ENABLED_V1        @"enable_SSO"
+#define GATEWAY_KEY_SHOW_LOGIN_DIALOG_V1      @"disable_login_dialog"
+
+#define GATEWAY_KEY_CUSTOM_DNS_LIST @"customDnsList"
+
+@implementation Gateway
+
+- (NSDictionary *)archive
+{
+    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:19];
+    
+    if (_title) dict[GATEWAY_KEY_TITLE] = _title;
+    if (_url) dict[GATEWAY_KEY_URL] = _url;
+    if (_host) dict[GATEWAY_KEY_HOST] = _host;
+    if (_bestHost) dict[GATEWAT_KEY_BEST_HOST] = _bestHost;
+    if (_alias) dict[GATEWAY_KEY_ALIAS] = _alias;
+    if (_port) dict[GATEWAY_KEY_PORT] = _port;
+    if (_username) dict[GATEWAY_KEY_USERNAME] = _username;
+    if (_certname) dict[GATEWAY_KEY_CERTNAME] = _certname;
+    if (_lastAccessedDate) dict[GATEWAY_KEY_LASTACCESS] = _lastAccessedDate;
+    dict[GATEWAY_KEY_AUTH_TYPE] = @(_authType);
+    if (_methodName) dict[GATEWAY_KEY_METHOD_NAME] = _methodName;
+    dict[GATEWAY_KEY_RECONNECT_COUNTS] = @(_reconnectCounts);
+    dict[GATEWAY_KEY_RECONNECT_TIME] = @(_reconnectTime);
+    dict[GATEWAY_KEY_PROXY_ENABLED] = @(_isProxyEnabled);
+    dict[GATEWAY_KEY_SAVEPASSWORDENABLED] = @(_isSavePasswordEnabled);
+    if (_proxyHost) dict[GATEWAY_KEY_PROXY_HOST] = _proxyHost;
+    if (_proxyUsername) dict[GATEWAY_KEY_PROXY_USERNAME] = _proxyUsername;
+    if (_proxyPassword) dict[GATEWAY_KEY_PROXY_PASSWORD] = [_proxyPassword aes256_encrypt:kEncryptKey];
+    dict[GATEWAY_KEY_SAVEPROXYPASSWORDENABLED] = @(_isSaveProxyPaswordEnabled);
+    dict[GATEWAY_KEY_WEB_SSO_ENABLED] = @(_isWebSSOEnabled);
+    dict[GATEWAY_KEY_SYFERLOCKENABLED] = @(_isSyferLockEnabled);
+    dict[GATEWAY_KEY_SHOW_LOGIN_DIALOG] = @(_isShowLoginDialogEnabled);
+    dict[GATEWAY_KEY_SECURE_TUNNEL_ENABLED] = @(_isSecureTunnelEnabled);
+    dict[GATEWAY_KEY_WEBAUTH_ENABLED] = @(_isWebAuthEnabled);
+    dict[GATEWAY_KEY_GESTURE_ENABLED] = @(_isGestureEnabled);
+    dict[GATEWAY_KEY_FACE_TOUCHID_ENABLED] = @(_isFaceOrTouchIDEnabled);
+    if (_customDnsList) dict[GATEWAY_KEY_CUSTOM_DNS_LIST] = _customDnsList;
+    
+    return dict;
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)dict
+{
+    self = [super init];
+    if (self) {
+        _title = dict[GATEWAY_KEY_TITLE];
+        _url = dict[GATEWAY_KEY_URL];
+        _host = dict[GATEWAY_KEY_HOST]?dict[GATEWAY_KEY_HOST]:_url;
+        _bestHost = dict[GATEWAT_KEY_BEST_HOST];
+        _alias = dict[GATEWAY_KEY_ALIAS];
+        _port = dict[GATEWAY_KEY_PORT];
+        _username = dict[GATEWAY_KEY_USERNAME];
+        _certname = dict[GATEWAY_KEY_CERTNAME];
+        _lastAccessedDate = dict[GATEWAY_KEY_LASTACCESS];
+        _customDnsList = dict[GATEWAY_KEY_CUSTOM_DNS_LIST];
+        if (dict[GATEWAY_KEY_AUTH_TYPE] == nil) {
+            _authType = kAuthTypeRegular;
+        } else {
+            _authType = [dict[GATEWAY_KEY_AUTH_TYPE] integerValue];
+        }
+        _methodName = dict[GATEWAY_KEY_METHOD_NAME];
+        if (dict[GATEWAY_KEY_RECONNECT_COUNTS] == nil) {
+            _reconnectCounts = 0;
+        } else {
+            _reconnectCounts = [dict[GATEWAY_KEY_RECONNECT_COUNTS] integerValue];
+        }
+        if (dict[GATEWAY_KEY_RECONNECT_TIME] == nil) {
+            _reconnectTime = 300;
+        } else {
+            _reconnectTime = [dict[GATEWAY_KEY_RECONNECT_TIME] integerValue];
+        }
+        if (dict[GATEWAY_KEY_PROXY_ENABLED] == nil) {
+            _isProxyEnabled = NO;
+        } else {
+            _isProxyEnabled = [dict[GATEWAY_KEY_PROXY_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SAVEPASSWORDENABLED] == nil) {
+            // It must compitable with MPP 1.x. This configuration is a global variable in MPP 1.x.
+            _isSavePasswordEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:GATEWAY_KEY_SAVEPASSWORDENABLED_V1];
+        } else {
+            _isSavePasswordEnabled = [dict[GATEWAY_KEY_SAVEPASSWORDENABLED] boolValue];
+        }
+        _proxyHost = dict[GATEWAY_KEY_PROXY_HOST];
+        _proxyUsername = dict[GATEWAY_KEY_PROXY_USERNAME];
+        if (dict[GATEWAY_KEY_PROXY_PASSWORD]) {
+            NSString *password = dict[GATEWAY_KEY_PROXY_PASSWORD];
+            _proxyPassword = [password aes256_decrypt:kEncryptKey];
+        }
+        if (dict[GATEWAY_KEY_SAVEPROXYPASSWORDENABLED] == nil) {
+            _isSaveProxyPaswordEnabled = NO;
+        } else {
+            _isSaveProxyPaswordEnabled = [dict[GATEWAY_KEY_SAVEPROXYPASSWORDENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_WEB_SSO_ENABLED] == nil) {
+            _isWebSSOEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:GATEWAY_KEY_WEB_SSO_ENABLED_V1];
+        } else {
+            _isWebSSOEnabled = [dict[GATEWAY_KEY_WEB_SSO_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SYFERLOCKENABLED] == nil) {
+            _isSyferLockEnabled = NO;
+        } else {
+            _isSyferLockEnabled = [dict[GATEWAY_KEY_SYFERLOCKENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SHOW_LOGIN_DIALOG] == nil) {
+            _isShowLoginDialogEnabled = ![[NSUserDefaults standardUserDefaults] boolForKey:GATEWAY_KEY_SHOW_LOGIN_DIALOG_V1];
+        } else {
+            _isShowLoginDialogEnabled = [dict[GATEWAY_KEY_SHOW_LOGIN_DIALOG] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SECURE_TUNNEL_ENABLED] == nil) {
+            _isSecureTunnelEnabled = YES;
+        } else {
+            _isSecureTunnelEnabled = [dict[GATEWAY_KEY_SECURE_TUNNEL_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_WEBAUTH_ENABLED] == nil) {
+            _isWebAuthEnabled = NO;
+        } else {
+            _isWebAuthEnabled = [dict[GATEWAY_KEY_WEBAUTH_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_GESTURE_ENABLED] == nil) {
+            _isGestureEnabled = NO;
+        } else {
+            _isGestureEnabled = [dict[GATEWAY_KEY_GESTURE_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_FACE_TOUCHID_ENABLED] == nil) {
+            _isFaceOrTouchIDEnabled = NO;
+        } else {
+            _isFaceOrTouchIDEnabled = [dict[GATEWAY_KEY_FACE_TOUCHID_ENABLED] boolValue];
+        }
+    }
+    
+    return self;
+}
+
+@end
+
+#pragma mark - Gateway Manager
+
+//For forward compatibility, the file still named Accounts.plist.
+NSString * const GATEWAY_FILE_NAME = @"Accounts.plist";
+
+#define GATEWAY_DEFAULT_PORT    @"443"
+
+@interface GatewayManager()
+{
+    NSMutableArray *_gateways;
+}
+@end
+
+@implementation GatewayManager
+
+@synthesize filePath = _filePath;
+@synthesize lastClientVersion = _lastClientVersion;
+@synthesize clientDownloadURL = _clientDownloadURL;
+
+- (NSString *)filePath {
+    if (!_filePath) {
+        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+        NSString *documentsDirectory = [paths objectAtIndex:0];
+        
+        _filePath = [documentsDirectory stringByAppendingPathComponent:GATEWAY_FILE_NAME];
+    }
+    
+    return _filePath;
+}
+
+- (BOOL)URLInitGateway
+{
+    if(strlen(INIT_CONFIG_URL) <= 0) {
+        return NO;
+    }
+    motionpro_config_t motionpro_config;
+    memset(&motionpro_config, 0, sizeof(motionpro_config_t));
+    array_vpn_get_motionpro_config_byurl(INIT_CONFIG_URL, DD_DEV_TYPE_IPHONE, &motionpro_config);
+    ANInfo(@"URLInitGateway, profile number=%d", motionpro_config.profilenum);
+    if(motionpro_config.profilenum > 0) {
+        [self deleteAllGateways];
+        _gateways = [[NSMutableArray alloc] init];
+    } else {
+        ANError(@"URLInitGateway, init gateway failed.");
+        return NO;
+    }
+    
+    for (int i = 0; i < motionpro_config.profilenum; i ++)
+    {
+        Gateway *newGateway = [[Gateway alloc] init];
+        newGateway.title = [NSString stringWithUTF8String:motionpro_config.profile[i].name];
+        newGateway.url = [NSString stringWithUTF8String:motionpro_config.profile[i].host];
+        newGateway.host = [NSString stringWithUTF8String:motionpro_config.profile[i].host];
+        newGateway.alias = [NSString stringWithUTF8String:motionpro_config.profile[i].alias];
+        newGateway.port = [NSString stringWithFormat:@"%d",motionpro_config.profile[i].port];
+        newGateway.username = [NSString stringWithUTF8String:motionpro_config.profile[i].username];
+        newGateway.isWebSSOEnabled = NO;
+        newGateway.isSyferLockEnabled = NO;
+        newGateway.isSavePasswordEnabled = NO;
+        newGateway.isShowLoginDialogEnabled = YES;
+        newGateway.isSecureTunnelEnabled = YES;
+        newGateway.isWebAuthEnabled = NO;
+        newGateway.certname = @"";
+        
+        [self addGateway:newGateway];
+    }
+    _lastClientVersion = [NSString stringWithUTF8String:motionpro_config.version];
+    _clientDownloadURL = [NSString stringWithUTF8String:motionpro_config.downloadurl];
+    
+    return YES;
+}
+
+- (void)gatewaysInit
+{
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    NSMutableArray *savedGateways = [NSMutableArray arrayWithContentsOfFile: self.filePath];
+    _gateways = [[NSMutableArray alloc] init];
+    
+    if (![fileManager fileExistsAtPath: self.filePath])
+    {
+        [fileManager changeCurrentDirectoryPath:[self.filePath stringByExpandingTildeInPath]];
+        NSData *null = [[NSData alloc] init];
+        [fileManager createFileAtPath:self.filePath contents:null attributes:nil];
+        
+        if(![[NSFileManager defaultManager] fileExistsAtPath:self.filePath])
+        {
+            ANWarn(@"%@ does not exist", self.filePath);
+        }
+        else
+        {
+            if ([self URLInitGateway])  return;
+        }
+    }
+    else
+    {
+        if ([self URLInitGateway])  return;
+    }
+
+    if (savedGateways) {
+        [savedGateways enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+            Gateway *gateway = [[Gateway alloc] initWithDictionary:obj];
+            [_gateways addObject:gateway];
+        }];
+    }
+}
+
+- (id)init
+{
+    self = [super init];
+    if(self) {
+        [self gatewaysInit];
+    }
+    
+    return self;
+}
+
+- (void)synToFile
+{
+    NSMutableArray *allGateways = [[NSMutableArray alloc] initWithCapacity:3];
+    
+    [_gateways enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+        [allGateways addObject:[(Gateway *)obj archive]];
+    }];
+    
+    [allGateways writeToFile:self.filePath atomically:YES];
+}
+
+- (NSInteger)numberOfGateways
+{
+    return _gateways.count;
+}
+
+- (Gateway *)gatewayAtIndex:(NSUInteger)index
+{
+    if (index >= _gateways.count || _gateways.count == 0) {
+        return nil;
+    }
+    
+    return _gateways[index];
+}
+
+- (void)addGateway:(Gateway *)gateway
+{
+    [_gateways addObject:gateway];
+    [self synToFile];
+}
+
+- (void)updateGateway:(Gateway *)gateway atIndex:(NSUInteger)index
+{
+    if (index > _gateways.count) {
+        return;
+    }
+    
+    _gateways[index] = gateway;
+    [self synToFile];
+}
+
+- (void)updateGateway:(Gateway *)newGateway
+{
+    for (NSInteger index = 0; index < _gateways.count; index++) {
+        Gateway *gateway = [_gateways objectAtIndex:index];
+        if ([gateway.url isEqualToString:newGateway.url] && [gateway.port isEqualToString:newGateway.port]) {
+            _gateways[index] = newGateway;
+            [self synToFile];
+        }
+    }
+}
+
+- (void)deleteGatewayAtIndex:(NSUInteger)index
+{
+    if (index > _gateways.count) {
+        return;
+    }
+
+    [_gateways removeObjectAtIndex:index];
+    [self synToFile];
+}
+
+- (void)deleteGateway:(Gateway *)gateway
+{
+    for (NSInteger index = 0; index < _gateways.count; index++) {
+        Gateway *iter = [_gateways objectAtIndex:index];
+        if ([iter.title isEqualToString:gateway.title]) {
+            [_gateways removeObjectAtIndex:index];
+            [self synToFile];
+            return;
+        }
+    }
+}
+
+- (void)didAccessGatewayAtIndex:(NSUInteger)index
+{
+    if (index > _gateways.count) {
+        return;
+    }
+    
+    Gateway *gateway = _gateways[index];
+
+    if (!gateway) {
+        ANDebug(@"Gateway at index: %zi not found", index);
+        return;
+    }
+
+    gateway.lastAccessedDate = [NSDate date];
+    [self synToFile];
+}
+
+- (NSInteger)indexOfUrl:(NSString *)url andport:(NSString *) port
+{
+    NSInteger index = -1;
+    for (Gateway *gateway in _gateways) {
+        index++;
+        
+        if ([url isEqualToString:gateway.url] && [port isEqualToString:gateway.port]) {
+            return index;
+        }
+    }
+    
+    return NSNotFound;
+}
+
+- (Gateway *)gatewayOfUrl:(NSString *)url andport:(NSString *) port
+{
+    NSInteger index = -1;
+    for (Gateway *gateway in _gateways) {
+        index++;
+        
+        if ([url isEqualToString:gateway.url] && [port isEqualToString:gateway.port]) {
+            return gateway;
+        }
+    }
+    
+    return nil;
+}
+
+- (NSInteger)indexOfTitle:(NSString *)title
+{
+    NSInteger index = -1;
+    for (Gateway *gateway in _gateways) {
+        index++;
+        
+        if ([title isEqualToString:gateway.title]) {
+            return index;
+        }
+    }
+    
+    return NSNotFound;
+}
+
+- (Gateway *)gatewayOfTitle:(NSString *)title
+{
+    for (Gateway *gateway in _gateways) {
+        if ([gateway.title isEqualToString:title]) {
+            return gateway;
+        }
+    }
+    
+    return nil;
+}
+
+- (BOOL)isGatewayExist:(NSString *)title
+{
+    return [self gatewayOfTitle:title] != nil ? YES : NO;
+}
+
+- (NSString *)getLastClientVersion
+{
+    return _lastClientVersion;
+}
+
+- (NSString *)getClientDownloadURL
+{
+    return _clientDownloadURL;
+}
+
+- (void)deleteAllGateways
+{
+    if (_gateways) {
+        [_gateways removeAllObjects];
+        _gateways = nil;
+    }
+}
+
+- (void)reloadGateways
+{
+    [self deleteAllGateways];
+    [self gatewaysInit];
+}
+
++ (GatewayManager *)sharedInstance
+{
+    static GatewayManager * instance;
+    @synchronized([GatewayManager class]) {
+        if(instance == nil){
+            instance = [[GatewayManager alloc] init];
+        }
+    }
+    return instance;
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.m.zrt
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.m.zrt	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayManager.m.zrt	(working copy)
@@ -0,0 +1,507 @@
+//
+//  GatewayManager.m
+//  MobileNow
+//
+//  Created by array on 2/10/14.
+//  Copyright (c) 2014 MobileNow. All rights reserved.
+//
+
+#import "GatewayManager.h"
+#import "NSString+AES256.h"
+#import "ANLogger.h"
+#import "ANKeychain.h"
+#import "arrayapi.h"
+
+#define INIT_CONFIG_URL  ""
+static NSString * const kEncryptKey = @"jkajiofpiejqw4i3qu8weji4sa4f890l34";
+
+@interface Gateway()
+
+- (NSDictionary *)archive;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+
+@end
+
+#define GATEWAY_KEY_TITLE        @"title"
+#define GATEWAY_KEY_URL          @"url"
+#define GATEWAY_KEY_HOST         @"host"
+#define GATEWAT_KEY_BEST_HOST    @"besthost"
+#define GATEWAY_KEY_ALIAS        @"alias"
+#define GATEWAY_KEY_USERNAME     @"username"
+#define GATEWAY_KEY_PORT         @"port"
+#define GATEWAY_KEY_CERTNAME     @"certname"
+#define GATEWAY_KEY_LASTACCESS   @"lastAccessedDate"
+#define GATEWAY_KEY_AUTH_TYPE    @"authType"
+#define GATEWAY_KEY_METHOD_NAME  @"methodName"
+#define GATEWAY_KEY_RECONNECT_COUNTS    @"reconnectCounts"
+#define GATEWAY_KEY_RECONNECT_TIME      @"reconnectTime"
+#define GATEWAY_KEY_PROXY_ENABLED       @"proxyEnabled"
+#define GATEWAY_KEY_PROXY_HOST          @"proxyHost"
+#define GATEWAY_KEY_PROXY_USERNAME      @"proxyUsername"
+#define GATEWAY_KEY_PROXY_PASSWORD      @"proxyPassword"
+#define GATEWAY_KEY_WEB_SSO_ENABLED     @"webSSOEnabled"
+#define GATEWAY_KEY_SYFERLOCKENABLED    @"syferLocakEnabled"
+#define GATEWAY_KEY_SAVEPASSWORDENABLED @"savePasswordEnabled"
+#define GATEWAY_KEY_SAVEPROXYPASSWORDENABLED    @"saveProxyPasswordEnabled"
+#define GATEWAY_KEY_SHOW_LOGIN_DIALOG           @"showLoginDialog"
+#define GATEWAY_KEY_SECURE_TUNNEL_ENABLED       @"ipsecEnabled"  // To compatible with v1.0.
+#define GATEWAY_KEY_WEBAUTH_ENABLED             @"webAuthEnabled"
+#define GATEWAY_KEY_GESTURE_ENABLED             @"gestureEnabled"
+#define GATEWAY_KEY_FACE_TOUCHID_ENABLED        @"faceOrTouchIDEnabled"
+
+// MPP v1.0 global setting keys
+#define GATEWAY_KEY_SAVEPASSWORDENABLED_V1    @"save_password"
+#define GATEWAY_KEY_WEB_SSO_ENABLED_V1        @"enable_SSO"
+#define GATEWAY_KEY_SHOW_LOGIN_DIALOG_V1      @"disable_login_dialog"
+
+#define GATEWAY_KEY_CUSTOM_DNS_LIST @"customDnsList"
+
+@implementation Gateway
+
+- (NSDictionary *)archive
+{
+    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:19];
+    
+    if (_title) dict[GATEWAY_KEY_TITLE] = _title;
+    if (_url) dict[GATEWAY_KEY_URL] = _url;
+    if (_host) dict[GATEWAY_KEY_HOST] = _host;
+    if (_bestHost) dict[GATEWAT_KEY_BEST_HOST] = _bestHost;
+    if (_alias) dict[GATEWAY_KEY_ALIAS] = _alias;
+    if (_port) dict[GATEWAY_KEY_PORT] = _port;
+    if (_username) dict[GATEWAY_KEY_USERNAME] = _username;
+    if (_certname) dict[GATEWAY_KEY_CERTNAME] = _certname;
+    if (_lastAccessedDate) dict[GATEWAY_KEY_LASTACCESS] = _lastAccessedDate;
+    dict[GATEWAY_KEY_AUTH_TYPE] = @(_authType);
+    if (_methodName) dict[GATEWAY_KEY_METHOD_NAME] = _methodName;
+    dict[GATEWAY_KEY_RECONNECT_COUNTS] = @(_reconnectCounts);
+    dict[GATEWAY_KEY_RECONNECT_TIME] = @(_reconnectTime);
+    dict[GATEWAY_KEY_PROXY_ENABLED] = @(_isProxyEnabled);
+    dict[GATEWAY_KEY_SAVEPASSWORDENABLED] = @(_isSavePasswordEnabled);
+    if (_proxyHost) dict[GATEWAY_KEY_PROXY_HOST] = _proxyHost;
+    if (_proxyUsername) dict[GATEWAY_KEY_PROXY_USERNAME] = _proxyUsername;
+    if (_proxyPassword) dict[GATEWAY_KEY_PROXY_PASSWORD] = [_proxyPassword aes256_encrypt:kEncryptKey];
+    dict[GATEWAY_KEY_SAVEPROXYPASSWORDENABLED] = @(_isSaveProxyPaswordEnabled);
+    dict[GATEWAY_KEY_WEB_SSO_ENABLED] = @(_isWebSSOEnabled);
+    dict[GATEWAY_KEY_SYFERLOCKENABLED] = @(_isSyferLockEnabled);
+    dict[GATEWAY_KEY_SHOW_LOGIN_DIALOG] = @(_isShowLoginDialogEnabled);
+    dict[GATEWAY_KEY_SECURE_TUNNEL_ENABLED] = @(_isSecureTunnelEnabled);
+    dict[GATEWAY_KEY_WEBAUTH_ENABLED] = @(_isWebAuthEnabled);
+    dict[GATEWAY_KEY_GESTURE_ENABLED] = @(_isGestureEnabled);
+    dict[GATEWAY_KEY_FACE_TOUCHID_ENABLED] = @(_isFaceOrTouchIDEnabled);
+    if (_customDnsList) dict[GATEWAY_KEY_CUSTOM_DNS_LIST] = _customDnsList;
+    
+    return dict;
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)dict
+{
+    self = [super init];
+    if (self) {
+        _title = dict[GATEWAY_KEY_TITLE];
+        _url = dict[GATEWAY_KEY_URL];
+        _host = dict[GATEWAY_KEY_HOST]?dict[GATEWAY_KEY_HOST]:_url;
+        _bestHost = dict[GATEWAT_KEY_BEST_HOST];
+        _alias = dict[GATEWAY_KEY_ALIAS];
+        _port = dict[GATEWAY_KEY_PORT];
+        _username = dict[GATEWAY_KEY_USERNAME];
+        _certname = dict[GATEWAY_KEY_CERTNAME];
+        _lastAccessedDate = dict[GATEWAY_KEY_LASTACCESS];
+        _customDnsList = dict[GATEWAY_KEY_CUSTOM_DNS_LIST];
+        if (dict[GATEWAY_KEY_AUTH_TYPE] == nil) {
+            _authType = kAuthTypeRegular;
+        } else {
+            _authType = [dict[GATEWAY_KEY_AUTH_TYPE] integerValue];
+        }
+        _methodName = dict[GATEWAY_KEY_METHOD_NAME];
+        if (dict[GATEWAY_KEY_RECONNECT_COUNTS] == nil) {
+            _reconnectCounts = 0;
+        } else {
+            _reconnectCounts = [dict[GATEWAY_KEY_RECONNECT_COUNTS] integerValue];
+        }
+        if (dict[GATEWAY_KEY_RECONNECT_TIME] == nil) {
+            _reconnectTime = 300;
+        } else {
+            _reconnectTime = [dict[GATEWAY_KEY_RECONNECT_TIME] integerValue];
+        }
+        if (dict[GATEWAY_KEY_PROXY_ENABLED] == nil) {
+            _isProxyEnabled = NO;
+        } else {
+            _isProxyEnabled = [dict[GATEWAY_KEY_PROXY_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SAVEPASSWORDENABLED] == nil) {
+            // It must compitable with MPP 1.x. This configuration is a global variable in MPP 1.x.
+            _isSavePasswordEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:GATEWAY_KEY_SAVEPASSWORDENABLED_V1];
+        } else {
+            _isSavePasswordEnabled = [dict[GATEWAY_KEY_SAVEPASSWORDENABLED] boolValue];
+        }
+        _proxyHost = dict[GATEWAY_KEY_PROXY_HOST];
+        _proxyUsername = dict[GATEWAY_KEY_PROXY_USERNAME];
+        if (dict[GATEWAY_KEY_PROXY_PASSWORD]) {
+            NSString *password = dict[GATEWAY_KEY_PROXY_PASSWORD];
+            _proxyPassword = [password aes256_decrypt:kEncryptKey];
+        }
+        if (dict[GATEWAY_KEY_SAVEPROXYPASSWORDENABLED] == nil) {
+            _isSaveProxyPaswordEnabled = NO;
+        } else {
+            _isSaveProxyPaswordEnabled = [dict[GATEWAY_KEY_SAVEPROXYPASSWORDENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_WEB_SSO_ENABLED] == nil) {
+            _isWebSSOEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:GATEWAY_KEY_WEB_SSO_ENABLED_V1];
+        } else {
+            _isWebSSOEnabled = [dict[GATEWAY_KEY_WEB_SSO_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SYFERLOCKENABLED] == nil) {
+            _isSyferLockEnabled = NO;
+        } else {
+            _isSyferLockEnabled = [dict[GATEWAY_KEY_SYFERLOCKENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SHOW_LOGIN_DIALOG] == nil) {
+            _isShowLoginDialogEnabled = ![[NSUserDefaults standardUserDefaults] boolForKey:GATEWAY_KEY_SHOW_LOGIN_DIALOG_V1];
+        } else {
+            _isShowLoginDialogEnabled = [dict[GATEWAY_KEY_SHOW_LOGIN_DIALOG] boolValue];
+        }
+        if (dict[GATEWAY_KEY_SECURE_TUNNEL_ENABLED] == nil) {
+            _isSecureTunnelEnabled = YES;
+        } else {
+            _isSecureTunnelEnabled = [dict[GATEWAY_KEY_SECURE_TUNNEL_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_WEBAUTH_ENABLED] == nil) {
+            _isWebAuthEnabled = NO;
+        } else {
+            _isWebAuthEnabled = [dict[GATEWAY_KEY_WEBAUTH_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_GESTURE_ENABLED] == nil) {
+            _isGestureEnabled = NO;
+        } else {
+            _isGestureEnabled = [dict[GATEWAY_KEY_GESTURE_ENABLED] boolValue];
+        }
+        if (dict[GATEWAY_KEY_FACE_TOUCHID_ENABLED] == nil) {
+            _isFaceOrTouchIDEnabled = NO;
+        } else {
+            _isFaceOrTouchIDEnabled = [dict[GATEWAY_KEY_FACE_TOUCHID_ENABLED] boolValue];
+        }
+    }
+    
+    return self;
+}
+
+@end
+
+#pragma mark - Gateway Manager
+
+//For forward compatibility, the file still named Accounts.plist.
+NSString * const GATEWAY_FILE_NAME = @"Accounts.plist";
+
+#define GATEWAY_DEFAULT_PORT    @"443"
+
+@interface GatewayManager()
+{
+    NSMutableArray *_gateways;
+}
+@end
+
+@implementation GatewayManager
+
+@synthesize filePath = _filePath;
+@synthesize lastClientVersion = _lastClientVersion;
+@synthesize clientDownloadURL = _clientDownloadURL;
+
+- (NSString *)filePath {
+    if (!_filePath) {
+        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+        NSString *documentsDirectory = [paths objectAtIndex:0];
+        
+        _filePath = [documentsDirectory stringByAppendingPathComponent:GATEWAY_FILE_NAME];
+    }
+    
+    return _filePath;
+}
+
+- (BOOL)URLInitGateway
+{
+    if(strlen(INIT_CONFIG_URL) <= 0) {
+        return NO;
+    }
+    motionpro_config_t motionpro_config;
+    memset(&motionpro_config, 0, sizeof(motionpro_config_t));
+    array_vpn_get_motionpro_config_byurl(INIT_CONFIG_URL, DD_DEV_TYPE_IPHONE, &motionpro_config);
+    ANInfo(@"URLInitGateway, profile number=%d", motionpro_config.profilenum);
+    if(motionpro_config.profilenum > 0) {
+        [self deleteAllGateways];
+        _gateways = [[NSMutableArray alloc] init];
+    } else {
+        ANError(@"URLInitGateway, init gateway failed.");
+        return NO;
+    }
+    
+    for (int i = 0; i < motionpro_config.profilenum; i ++)
+    {
+        Gateway *newGateway = [[Gateway alloc] init];
+        newGateway.title = [NSString stringWithUTF8String:motionpro_config.profile[i].name];
+        newGateway.url = [NSString stringWithUTF8String:motionpro_config.profile[i].host];
+        newGateway.host = [NSString stringWithUTF8String:motionpro_config.profile[i].host];
+        newGateway.alias = [NSString stringWithUTF8String:motionpro_config.profile[i].alias];
+        newGateway.port = [NSString stringWithFormat:@"%d",motionpro_config.profile[i].port];
+        newGateway.username = [NSString stringWithUTF8String:motionpro_config.profile[i].username];
+        newGateway.isWebSSOEnabled = NO;
+        newGateway.isSyferLockEnabled = NO;
+        newGateway.isSavePasswordEnabled = NO;
+        newGateway.isShowLoginDialogEnabled = YES;
+        newGateway.isSecureTunnelEnabled = YES;
+        newGateway.isWebAuthEnabled = NO;
+        newGateway.certname = @"";
+        
+        [self addGateway:newGateway];
+    }
+    _lastClientVersion = [NSString stringWithUTF8String:motionpro_config.version];
+    _clientDownloadURL = [NSString stringWithUTF8String:motionpro_config.downloadurl];
+    
+    return YES;
+}
+
+- (void)gatewaysInit
+{
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    NSMutableArray *savedGateways = [NSMutableArray arrayWithContentsOfFile: self.filePath];
+    _gateways = [[NSMutableArray alloc] init];
+    
+    if (![fileManager fileExistsAtPath: self.filePath])
+    {
+        [fileManager changeCurrentDirectoryPath:[self.filePath stringByExpandingTildeInPath]];
+        NSData *null = [[NSData alloc] init];
+        [fileManager createFileAtPath:self.filePath contents:null attributes:nil];
+        
+        if(![[NSFileManager defaultManager] fileExistsAtPath:self.filePath])
+        {
+            ANWarn(@"%@ does not exist", self.filePath);
+        }
+        else
+        {
+            ANInfo(@"iqiyi init profile file:%@", self.filePath);
+            [self addInitGateway];
+        }
+    }
+
+    if (savedGateways) {
+        [savedGateways enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+            Gateway *gateway = [[Gateway alloc] initWithDictionary:obj];
+            [_gateways addObject:gateway];
+        }];
+    }
+}
+
+- (id)init
+{
+    self = [super init];
+    if(self) {
+        [self gatewaysInit];
+    }
+    
+    return self;
+}
+
+- (void)synToFile
+{
+    NSMutableArray *allGateways = [[NSMutableArray alloc] initWithCapacity:3];
+    
+    [_gateways enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+        [allGateways addObject:[(Gateway *)obj archive]];
+    }];
+    
+    [allGateways writeToFile:self.filePath atomically:YES];
+}
+
+- (void)addInitGateway
+{
+    Gateway *newGateway = [[Gateway alloc] init];
+    newGateway.title = @"中融专网";
+    newGateway.url = @"oatoarray.zritc.com";
+    newGateway.host = @"oatoarray.zritc.com";
+    newGateway.alias = @"";
+    newGateway.port = @"443";
+    newGateway.username = @"";
+    newGateway.isWebSSOEnabled = YES;
+    newGateway.isSyferLockEnabled = NO;
+    newGateway.isSavePasswordEnabled = YES;
+    newGateway.isShowLoginDialogEnabled = NO;
+    newGateway.isSecureTunnelEnabled = YES;
+    newGateway.isWebAuthEnabled = NO;
+    newGateway.certname = @"";
+
+    [self addGateway:newGateway];
+}
+
+
+- (NSInteger)numberOfGateways
+{
+    return _gateways.count;
+}
+
+- (Gateway *)gatewayAtIndex:(NSUInteger)index
+{
+    if (index >= _gateways.count || _gateways.count == 0) {
+        return nil;
+    }
+    
+    return _gateways[index];
+}
+
+- (void)addGateway:(Gateway *)gateway
+{
+    [_gateways addObject:gateway];
+    [self synToFile];
+}
+
+- (void)updateGateway:(Gateway *)gateway atIndex:(NSUInteger)index
+{
+    if (index > _gateways.count) {
+        return;
+    }
+    
+    _gateways[index] = gateway;
+    [self synToFile];
+}
+
+- (void)updateGateway:(Gateway *)newGateway
+{
+    for (NSInteger index = 0; index < _gateways.count; index++) {
+        Gateway *gateway = [_gateways objectAtIndex:index];
+        if ([gateway.url isEqualToString:newGateway.url] && [gateway.port isEqualToString:newGateway.port]) {
+            _gateways[index] = newGateway;
+            [self synToFile];
+        }
+    }
+}
+
+- (void)deleteGatewayAtIndex:(NSUInteger)index
+{
+    if (index > _gateways.count) {
+        return;
+    }
+
+    [_gateways removeObjectAtIndex:index];
+    [self synToFile];
+}
+
+- (void)deleteGateway:(Gateway *)gateway
+{
+    for (NSInteger index = 0; index < _gateways.count; index++) {
+        Gateway *iter = [_gateways objectAtIndex:index];
+        if ([iter.title isEqualToString:gateway.title]) {
+            [_gateways removeObjectAtIndex:index];
+            [self synToFile];
+            return;
+        }
+    }
+}
+
+- (void)didAccessGatewayAtIndex:(NSUInteger)index
+{
+    if (index > _gateways.count) {
+        return;
+    }
+    
+    Gateway *gateway = _gateways[index];
+
+    if (!gateway) {
+        ANDebug(@"Gateway at index: %zi not found", index);
+        return;
+    }
+
+    gateway.lastAccessedDate = [NSDate date];
+    [self synToFile];
+}
+
+- (NSInteger)indexOfUrl:(NSString *)url andport:(NSString *) port
+{
+    NSInteger index = -1;
+    for (Gateway *gateway in _gateways) {
+        index++;
+        
+        if ([url isEqualToString:gateway.url] && [port isEqualToString:gateway.port]) {
+            return index;
+        }
+    }
+    
+    return NSNotFound;
+}
+
+- (Gateway *)gatewayOfUrl:(NSString *)url andport:(NSString *) port
+{
+    NSInteger index = -1;
+    for (Gateway *gateway in _gateways) {
+        index++;
+        
+        if ([url isEqualToString:gateway.url] && [port isEqualToString:gateway.port]) {
+            return gateway;
+        }
+    }
+    
+    return nil;
+}
+
+- (NSInteger)indexOfTitle:(NSString *)title
+{
+    NSInteger index = -1;
+    for (Gateway *gateway in _gateways) {
+        index++;
+        
+        if ([title isEqualToString:gateway.title]) {
+            return index;
+        }
+    }
+    
+    return NSNotFound;
+}
+
+- (Gateway *)gatewayOfTitle:(NSString *)title
+{
+    for (Gateway *gateway in _gateways) {
+        if ([gateway.title isEqualToString:title]) {
+            return gateway;
+        }
+    }
+    
+    return nil;
+}
+
+- (BOOL)isGatewayExist:(NSString *)title
+{
+    return [self gatewayOfTitle:title] != nil ? YES : NO;
+}
+
+- (NSString *)getLastClientVersion
+{
+    return _lastClientVersion;
+}
+
+- (NSString *)getClientDownloadURL
+{
+    return _clientDownloadURL;
+}
+
+- (void)deleteAllGateways
+{
+    if (_gateways) {
+        [_gateways removeAllObjects];
+        _gateways = nil;
+    }
+}
+
+- (void)reloadGateways
+{
+    [self deleteAllGateways];
+    [self gatewaysInit];
+}
+
++ (GatewayManager *)sharedInstance
+{
+    static GatewayManager * instance;
+    @synchronized([GatewayManager class]) {
+        if(instance == nil){
+            instance = [[GatewayManager alloc] init];
+        }
+    }
+    return instance;
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayModel.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayModel.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayModel.h	(working copy)
@@ -0,0 +1,75 @@
+//
+//  GatewayModel.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/7/26.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "AAAManager.h"
+#import "GatewayManager.h"
+
+typedef NS_ENUM(NSInteger, LoginCallbackType) {
+    LoginCallbackTypeLogin,
+    LoginCallbackTypeRegister,
+    LoginCallbackTypeVDIAuth,
+};
+
+@protocol GatewayModelDelegate <NSObject>
+
+@optional
+- (void)needLoginInfo;
+- (void)needRegister;
+- (void)needConfirm:(NSString *)message;
+- (void)needLogout;
+- (void)needVDIAuth;
+- (void)needDoPreLoginCV;
+- (void)needProxyAuth;
+- (void)loginFinished:(BOOL)success;
+- (void)loginError:(NSString *)message;
+- (void)loginErrorOfTip:(NSString *)message;
+@end
+
+@interface GatewayModel : NSObject
+
+@property (nonatomic, readonly) NSInteger currentGatewayIndex;
+@property (nonatomic, strong, readonly) Gateway *currentGateway;
+@property (nonatomic, weak) id <GatewayModelDelegate> delegate;
+
+#pragma mark - Gateway
+
+- (NSInteger)numberOfGateways;
+- (Gateway *)gatewayAtIndex:(NSInteger)index;
+- (Gateway *)gatewayOfTitle:(NSString *)title;
+- (Gateway *)gatewayOfUrl:(NSString *)Url andPort:(NSString *)port;
+- (Gateway *) currentGatewayUpInside;
+
+- (void)detectCurrentGateway;
+
+- (void)deleteCurrentGateway;
+- (void)deleteGatewayAtIndex:(NSInteger)index;
+- (void)selectGatewayAtIndex:(NSInteger)index;
+- (void)selectGatewayWithUrl:(NSString *)url andport:(NSString *)port;
+- (void)selectGatewayWithTitle:(NSString *)title;
+- (void)didAccessCurrentGateway;
+- (NSDate *)currentGatewayAccessDate;
+
+- (void)suppressCheckServerCertForCurrentGateway;
+- (BOOL)shouldCheckServerCertForCurrentGateway;
+
+#pragma mark - Login
+
+- (void)login;
+- (void)loginWithSession:(NSString *)session andUsername:(NSString *)username;
+- (void)loginWithSession:(NSString *)session andUsername:(NSString *)username andoAuthURL:(NSString *)url andcallbackURL:(NSString *)callback;
+- (void)autoLoginwithAccount:(VPNAccount *)account;
+- (void)continueLogin;
+- (void)loginWithVDIUsername:(NSString *)username password:(NSString *)password;
+
+- (void)cancelLogin;
+
+- (void)logoutCurrentSession:(void (^)())completion;
+- (void)logoutAccount:(VPNAccount *)account complete:(void(^)())completion;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayModel.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayModel.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewayModel.m	(working copy)
@@ -0,0 +1,561 @@
+//
+//  GatewayModel.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/7/26.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "ANLogger.h"
+#import "GatewayModel.h"
+#import "GatewayManager.h"
+#import "CertificateManager.h"
+#import "DetectHostManager.h"
+#import "Singleton.h"
+
+#define CHECK_SERVER_CERT_KEY   @"CheckServerCertKey"
+
+@interface GatewayModel() {
+    void (^logoutAction)(void);
+    GatewayManager *gm;
+}
+
+@property DetectHostManager *detectHostManager;
+
+@property (nonatomic, readwrite) NSInteger currentGatewayIndex;
+@property (nonatomic, strong) NSURLConnection *checkConnection;
+@property (nonatomic, strong) VPNAccount *loginAccount;
+
+@end
+
+@implementation GatewayModel
+
+#pragma mark - Gateway
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        gm = [GatewayManager sharedInstance];
+        if ([gm numberOfGateways] > 0) {
+            _currentGatewayIndex = 0;
+        } else {
+            _currentGatewayIndex = NSNotFound;
+        }
+    }
+    
+    self.detectHostManager = [[DetectHostManager alloc] init];
+    
+    return self;
+}
+
+- (Gateway *)currentGateway {
+    return [gm gatewayAtIndex:_currentGatewayIndex];
+}
+
+- (Gateway *) currentGatewayUpInside{
+    
+    NSInteger integer = [Singleton sharedSingleton].currentPageNumber;
+    return [gm gatewayAtIndex:integer];
+}
+
+- (NSInteger)numberOfGateways {
+    return [gm numberOfGateways];
+}
+
+- (Gateway *)gatewayAtIndex:(NSInteger)index {
+    return [gm gatewayAtIndex:index];
+}
+
+- (Gateway *)gatewayOfTitle:(NSString *)title {
+    return [gm gatewayOfTitle:title];
+}
+
+- (Gateway *)gatewayOfUrl:(NSString *)Url andPort:(NSString *) port{
+    return [gm gatewayOfUrl:Url andport:port];
+}
+
+- (void)deleteCurrentGateway {
+    NSInteger total = gm.numberOfGateways;
+    if (total > 0 && _currentGatewayIndex < total) {
+        [gm deleteGatewayAtIndex:_currentGatewayIndex];
+    }
+}
+
+- (void)deleteGatewayAtIndex:(NSInteger)index {
+    [gm deleteGatewayAtIndex:index];
+    if (index <= _currentGatewayIndex) {
+        _currentGatewayIndex -= 1;
+    }
+    
+    if (_currentGatewayIndex < 0) {
+        _currentGatewayIndex = 0;
+    }
+}
+
+- (HostInfo *)detectBestHostInfoWithUrl:(NSString *)url
+{
+    HostInfo *hostInfo = [[HostInfo alloc] init];
+    if ([url containsString:@";"]) {
+        self.detectHostManager = [[DetectHostManager alloc] init];
+        [self.detectHostManager setDetectHostValue:url withAllConnTime:YES withLoopTimes:20 withLoopInterval:100];
+        [self.detectHostManager startDetect];
+        hostInfo = self.detectHostManager.bestHost;
+    }
+    
+    return hostInfo;
+}
+
+- (void)detectCurrentGateway
+{
+    Gateway *gateway = [gm gatewayAtIndex:_currentGatewayIndex];
+    if ([gateway.url containsString:@";"]) {
+        HostInfo *hostInfo = [self detectBestHostInfoWithUrl:gateway.url];
+        gateway.bestHost = hostInfo.host;
+        gateway.port = hostInfo.port;
+        gateway.alias = hostInfo.alias;
+    } else {
+        gateway.bestHost = gateway.host;
+    }
+    
+    [gm updateGateway:gateway atIndex:_currentGatewayIndex];
+}
+
+- (void)selectGatewayAtIndex:(NSInteger)index {
+    if (index >= [gm numberOfGateways]) {
+        return;
+    }
+    _currentGatewayIndex = index;
+}
+
+- (void)selectGatewayWithUrl:(NSString *)url andport:(NSString *)port {
+    NSInteger index = [gm indexOfUrl:url andport:port];
+    if (index != NSNotFound) {
+        [self selectGatewayAtIndex:index];
+    }
+}
+
+- (void)selectGatewayWithTitle:(NSString *)title {
+    NSInteger index = [gm indexOfTitle:title];
+    if (index != NSNotFound) {
+        [self selectGatewayAtIndex:index];
+    }
+}
+
+- (void)didAccessCurrentGateway {
+    [gm didAccessGatewayAtIndex:_currentGatewayIndex];
+}
+
+- (NSDate *)currentGatewayAccessDate {
+    Gateway *gateway = [gm gatewayAtIndex:_currentGatewayIndex];
+    if (gateway) {
+        return gateway.lastAccessedDate;
+    }
+    
+    return nil;
+}
+
+-(void)suppressCheckServerCertForCurrentGateway {
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    NSDictionary *checkServerCertDictionary = [defaults dictionaryForKey:CHECK_SERVER_CERT_KEY];
+    NSMutableDictionary *mutableCheckServerCertDictionary = [[NSMutableDictionary alloc] initWithDictionary:checkServerCertDictionary];
+    [mutableCheckServerCertDictionary setObject:[NSNumber numberWithBool:YES] forKey:[self currentGateway].url];
+    [defaults setObject:mutableCheckServerCertDictionary forKey:CHECK_SERVER_CERT_KEY];
+    [defaults synchronize];
+}
+
+- (BOOL)shouldCheckServerCertForCurrentGateway {
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    NSDictionary *checkServerCertDictionary = [defaults dictionaryForKey:CHECK_SERVER_CERT_KEY];
+    if (checkServerCertDictionary) {
+        NSNumber *disabledCheckServerCert = [checkServerCertDictionary objectForKey:[self currentGateway].url];
+        if (disabledCheckServerCert && [disabledCheckServerCert boolValue]) {
+            return NO;
+        }
+    }
+    
+    return YES;
+}
+
+#pragma mark - Login
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self name:kVPNMessageNotification object:nil];
+    self.detectHostManager = nil;
+}
+
+- (void)login {
+    [self loginWithSession:nil andUsername:nil];
+}
+
+- (void)loginWithSession:(NSString *)session andUsername:(NSString *)username andoAuthURL:(NSString *)url andcallbackURL:(NSString *)callback {
+    NSURL *urllogin = [NSURL URLWithString:url];
+    NSString *host = urllogin.host;
+    if (!host || host.length == 0) {
+        ANError(@"Fail to parse URL: %@", url);
+        return;
+    }
+    
+    NSNumber *port = urllogin.port;
+    if (!port) {
+        port = @443;
+    }
+    
+    ANInfo(@"loginWithSession:url=%@, username=%@, callback=%@", url, username, callback);
+    VPNAccount *account = [[VPNAccount alloc] init];
+    account.vsHost = host;
+    account.vsPort = [port stringValue];
+    account.userName = username;
+    account.session = session;
+    account.autoLoginCallback = callback;
+    
+    [self loginWithAccount:account];
+}
+
+- (void)loginWithSession:(NSString *)session andUsername:(NSString *)username {
+    Gateway *gw = [self currentGateway];
+    if (!gw) {
+        ANError(@"Current gateway is nil, can't login.");
+        return;
+    }
+    
+    VPNAccount *account = [[VPNAccount alloc] init];
+    if (username && username.length > 0) {
+        account.userName = username;
+    } else {
+        account.userName = gw.username;
+    }
+    if ([gw.bestHost length] > 0) {
+        account.vsHost = gw.bestHost;
+    } else {
+        account.vsHost = gw.host;
+    }
+    
+    account.alias = gw.alias;
+    account.vsURL = gw.url;
+    account.vsPort = gw.port;
+    account.certName = gw.certname;
+    account.session = session;
+    
+    [self loginWithAccount:account];
+}
+
+- (void)loginWithAccount:(VPNAccount *)account {
+    self.loginAccount = account;
+
+    [self verifyHost:account.vsHost port:account.vsPort];
+
+}
+
+- (void)autoLoginwithAccount:(VPNAccount *)account {
+    AAAManager *manager = [AAAManager sharedInstance];
+    
+    if (manager.status != VPN_CONNECTED && manager.status != VPN_CONNECTING) {
+        // VPN not start, login directly.
+        [self loginWithAccount:account];
+        return;
+    }
+    
+    BOOL accountMatch = [account.vsHost isEqualToString:manager.account.vsHost] && [account.vsPort isEqualToString:manager.account.vsPort];
+    
+    if (!accountMatch) {
+        [_delegate needLogout];
+        return;
+    } else if (manager.status == VPN_CONNECTING) {
+        self.loginAccount = account;
+        [self continueLogin];
+    }
+}
+
+- (void)verifyHost:(NSString *)host port:(NSString *)port {
+    if ([host containsString:@"@"]) {
+        [self continueLogin];
+        return;
+    }
+    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@:%@", host, port]];
+    
+    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
+    request.HTTPMethod = @"HEAD";
+    NSURLSession *sharedSession = [NSURLSession sharedSession];
+
+    NSURLSessionDataTask *task = [sharedSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
+        if (data && (error == nil)) {
+            ANInfo(@"verifyHost: this site is accessbile.");
+            [self continueLogin];
+        } else {
+            ANInfo(@"Verify gateway failed, error: %@", error.localizedDescription);
+            NSString *realURL = [[request URL] host];
+            NSString *savedURL = [[self currentGateway] url];
+
+            if ([error.domain isEqualToString:@"NSURLErrorDomain"]) {
+                switch (error.code) {
+                    case NSURLErrorServerCertificateUntrusted:
+                        if ([self shouldCheckServerCertForCurrentGateway]) {
+                            /**
+                             *  If no gateway is configured in MPP, but MPP is launched outside,
+                             *  it will trust this url and remember directly.
+                             */
+                            // TODO: Should compatible with alias site.
+                            if ([realURL isEqualToString:savedURL]) {
+                                [_delegate needConfirm:NSLocalizedString(@"The server's certificate untrusted, would you like to continue?", nil)];
+                                break;
+                            } else {
+                                ANInfo(@"Real URL (%@) is not equal to saved URL (%@).", realURL, savedURL);
+                            }
+                        }
+                        [self continueLogin];
+                        break;
+                    case NSURLErrorSecureConnectionFailed:
+                        // XXX: Ignore this error???
+                        [self continueLogin];
+                        break;
+                    case NSURLErrorHTTPTooManyRedirects:
+                        // enable clientsecurity will lead to this error.
+                        [self continueLogin];
+                        break;
+                    case NSURLErrorCancelled:
+                        //user cancel, do noting;
+                        break;
+                    default:
+                        //Ignore this error
+                        [self continueLogin];
+                        //[_delegate loginError:NSLocalizedString(@"Server unreachable",nil)];
+                        break;
+                }
+            } else {
+                [_delegate loginError:NSLocalizedString(@"Server unreachable",nil)];
+            };
+        }
+    }];
+    
+    [task resume];
+}
+
+- (void)continueLogin {
+    VPNAccount *vpnAccount;
+    if (_loginAccount) {
+        vpnAccount = _loginAccount;
+    } else {
+        Gateway *gw = [self currentGateway];
+        vpnAccount = [[VPNAccount alloc] initWithHost:gw.host
+                                                 port:gw.port
+                                                alias:gw.alias
+                                                  url:gw.url
+                                             username:nil
+                                             password:nil
+                                    speedTunnelEnable:YES  speedTunnelEncrypt:YES];
+        vpnAccount.certName = gw.certname;
+
+    }
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleVPNNotification:) name:kVPNMessageNotification object:nil];
+    
+    AAAManager *manager = [AAAManager sharedInstance];
+    
+    [manager resetAuthInfoBak];
+    if (manager.status == VPN_CONNECTING) {
+        [manager continueVPNThreadWithAccount:vpnAccount];
+    } else {
+        [manager startL3VPN:vpnAccount];
+    }
+}
+
+- (void)loginWithVDIUsername:(NSString *)username password:(NSString *)password {
+    VPNAccount *account = [[VPNAccount alloc] init];
+    account.userName = username;
+    account.passWord = password;
+    
+    [[AAAManager sharedInstance] continueVPNThreadWithVDIAccount:account];
+    
+}
+
+- (void)cancelLogin {
+    [self.checkConnection cancel];
+    self.checkConnection = nil;
+    
+    [[AAAManager sharedInstance] cancelLogin];
+}
+
+- (void)logoutCurrentSession:(void (^)())completion {
+    [self.checkConnection cancel];
+    self.checkConnection = nil;
+    
+    logoutAction = completion;
+    
+    // Stop handle login notifications
+    [self stopHandleVPNNotification];
+    
+    // Handle logout notifications
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleLogoutVPNNotification:) name:kVPNMessageNotification object:nil];
+    
+    AAAManager *manager = [AAAManager sharedInstance];
+    if (manager.status == VPN_CONNECTING) {
+        [manager cancelLogin];
+    } else {
+        [manager stopL3VPN];
+    }
+}
+
+- (void)logoutAccount:(VPNAccount *)account complete:(void (^)())completion {
+    AAAManager *manager = [AAAManager sharedInstance];
+    
+    if (manager.status != VPN_CONNECTED && manager.status != VPN_CONNECTING && manager.status != VPN_IDLE) {
+        return;
+    }
+    
+    BOOL accountMatch = [account.vsHost isEqualToString:manager.account.vsHost] && [account.vsPort isEqualToString:manager.account.vsPort];
+    
+    if (accountMatch) {
+        [self logoutCurrentSession:completion];
+    }
+}
+
+#pragma mark - Notification Handlers
+
+- (void)stopHandleVPNNotification {
+    [[NSNotificationCenter defaultCenter] removeObserver:self name:kVPNMessageNotification object:nil];
+}
+
+- (void)handleLogoutVPNNotification:(NSNotification *)notification {
+    VPNMessage *msg = notification.object;
+    
+    if (msg.code == VPN_CB_DISCONNECTED || msg.code == VPN_CB_CONN_FAILED) {
+        [self stopHandleVPNNotification];
+        
+        if (logoutAction) {
+            logoutAction();
+        }
+    }
+}
+
+- (void)handleVPNNotification:(NSNotification *)notification {
+    VPNMessage *message = notification.object;
+    AAAManager *manager = [AAAManager sharedInstance];
+    NSInteger error = manager.errorCode;
+    
+    switch (message.code) {
+        case VPN_CB_DISCONNECTED:
+            [self stopHandleVPNNotification];
+            [_delegate loginFinished:NO];
+            break;
+        case VPN_CB_CONNECTED:
+            [self stopHandleVPNNotification];
+            [_delegate loginFinished:YES];
+            break;
+        case VPN_CB_CONN_FAILED:
+        {
+            [self stopHandleVPNNotification];
+            if (error == ERR_CALLBACK_FAILED || error == ERR_INTERRUPTED) {
+                ANInfo(@"Login failed, error code is %zi", error);
+                [_delegate loginError:nil];
+                break;
+            }
+            ANInfo(@"Login failed, error code is %zi", error);
+            
+            NSString *errorMessage = [self errorMessageOfCode:VPN_CB_CONN_FAILED error:error];
+            if ([manager.errorInformation length] > 0) {
+                errorMessage = manager.errorInformation;
+            }
+            [_delegate loginError:errorMessage];
+            [_delegate loginFinished:NO];
+            break;
+        }
+        case VPN_CB_DEVID_REG:
+            [_delegate needRegister];
+            break;
+        case VPN_CB_LOGIN:
+        case VPN_CB_SYFERLOCK_AUTH:
+            [_delegate needLoginInfo];
+            break;
+        case VPN_CB_VDI_AUTH:
+            [_delegate needVDIAuth];
+            break;
+        case VPN_CB_CV_GLOBAL:
+            [_delegate needDoPreLoginCV];
+            break;
+        case VPN_CB_CLIENT_SECURITY:
+            [_delegate loginErrorOfTip:message.information];
+            [_delegate loginFinished:NO];
+            break;
+
+            
+        default:
+            break;
+    }
+}
+
+- (NSString *)errorMessageOfCode:(NSInteger)code error:(NSInteger)error {
+    NSString *errorMessage;
+    
+    switch (error) {
+        case ERR_SUCCESS:
+            break;
+        case ERR_CALLBACK_FAILED:
+            break;
+        case ERR_DEVID_APPROVE_PENDING:
+            errorMessage = NSLocalizedString(@"Your device is registering, please request manager approval",nil);
+            break;
+        case ERR_DEVID_APPROVE_DENY:
+            errorMessage = NSLocalizedString(@"Register device deny, not allow register device auto approve",nil);
+            break;
+        case ERR_DEVID_USER_LIMIT:
+            errorMessage = NSLocalizedString(@"User for this device has reached his or her limit",nil);
+            break;
+        case ERR_DEVID_DEV_LIMIT:
+            errorMessage = NSLocalizedString(@"Device has reached its limit",nil);
+            break;
+        case ERR_WRONG_USER_PASS:
+            errorMessage = NSLocalizedString(@"Login failed, please check username and password",nil);
+            break;
+        case ERR_AUTHORIZE_FAILED:
+            errorMessage = NSLocalizedString(@"Authorize failed", nil);
+            break;
+        case ERR_CLIENT_SECURITY:
+            errorMessage = NSLocalizedString(@"Client security is not supported", nil);
+            break;
+        case ERR_CERT_NO:
+            errorMessage = NSLocalizedString(@"Please select a certificate", nil);
+            break;
+        case ERR_CERT_INVALID_SIGNTURE:
+            errorMessage = NSLocalizedString(@"The certificate of client has an invalid signature", nil);
+            break;
+        case ERR_CERT_UNTRUSTED:
+            errorMessage = NSLocalizedString(@"The certificate of client is untrusted", nil);
+            break;
+        case ERR_CERT_EXPIRED:
+            errorMessage = NSLocalizedString(@"The certificate of client is expired", nil);
+            break;
+        case ERR_CERT_INVALID:
+            errorMessage = NSLocalizedString(@"The certificate of client is invalid", nil);
+            break;
+        case ERR_CERT_REVOKED:
+            errorMessage = NSLocalizedString(@"The certificate of client is revoked", nil);
+            break;
+        case ERR_SMS_GET_PHONE:
+            errorMessage = NSLocalizedString(@"The system failed to get your phone number to do OTP authentication", nil);
+            break;
+        case ERR_SMS_SEND:
+            errorMessage = NSLocalizedString(@"The system failed to send message to your phone", nil);
+            break;
+        case ERR_SMS_TOO_MANY_RETRY:
+            errorMessage = NSLocalizedString(@"Your attempt to sign in failed, because you have entered wrong SMS verification code for too many times", nil);
+            break;
+        case ERR_HWID_DENY:
+            errorMessage = NSLocalizedString(@"The device is denied because of wrong hardware ID!", nil);
+            break;
+        case ERR_HWID_PENDING:
+            errorMessage = NSLocalizedString(@"The hardware ID of this device is not approved yet!", nil);
+            break;
+        case ERR_PROXY_AUTH:
+            errorMessage = NSLocalizedString(@"Proxy Auth failed, please try again!", nil);
+            break;
+        case ERR_CREATE_SESSION:
+            errorMessage = NSLocalizedString(@"The MotionPro client fails to create a session.", nil);
+            break;
+        default:
+            errorMessage = NSLocalizedString(@"Connection to server failed",nil);
+            break;
+    }
+    return errorMessage;
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewaySettingTree.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewaySettingTree.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewaySettingTree.h	(working copy)
@@ -0,0 +1,29 @@
+//
+//  GatewaySettingTree.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/4/25.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface GatewaySettingTreeNode : NSObject
+
+@property (copy) NSString *name;
+@property (strong) GatewaySettingTreeNode *parent;
+
++ (GatewaySettingTreeNode *)buildSettingTreeWithGroupNames:(NSArray *)names;
++ (NSInteger)totalSettingItems;
++ (GatewaySettingTreeNode *)rootNode;
++ (void)setRootNode:(GatewaySettingTreeNode *)rootNode;
++ (GatewaySettingTreeNode *)searchNodeWithName:(NSString *)name;
+
+- (BOOL)hasChild;
+- (void)setHadChild;
+- (void)addChild:(GatewaySettingTreeNode *)child;
+- (GatewaySettingTreeNode *)childAtIndex:(NSInteger)index;
+- (NSInteger)childrenCounts;
+- (NSArray *)allChildren;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewaySettingTree.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewaySettingTree.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/GatewaySettingTree.m	(working copy)
@@ -0,0 +1,120 @@
+//
+//  GatewaySettingTree.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/4/25.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "GatewaySettingTree.h"
+
+static GatewaySettingTreeNode *gRootNode = nil;
+
+GatewaySettingTreeNode *searchNode(GatewaySettingTreeNode *node, NSString *name) {
+    if (!node) { return nil; }
+    
+    NSArray *children = [node allChildren];
+    
+    if ([node.name isEqualToString:name]) {
+        return node;
+    } else {
+        if ([node hasChild]) {
+            for (GatewaySettingTreeNode *child in children) {
+                GatewaySettingTreeNode *result = searchNode(child, name);
+                if (result) {
+                    return result;
+                }
+            }
+        }
+    }
+    
+    return nil;
+}
+
+@implementation GatewaySettingTreeNode {
+    NSMutableArray *_children;
+    BOOL _isHasChild;
+    BOOL _isParentRoot;
+}
+
+- (BOOL)hasChild {
+    return _isHasChild;
+}
+
+- (void)setHadChild {
+    _isHasChild = YES;
+    _children = [[NSMutableArray alloc] initWithCapacity:1];
+}
+
+- (void)addChild:(GatewaySettingTreeNode *)child {
+    if (_children) {
+        child.parent = self;
+        [_children addObject:child];
+    }
+}
+
+- (GatewaySettingTreeNode *)childAtIndex:(NSInteger)index {
+    if (_children) {
+        if (index < _children.count) {
+            return [_children objectAtIndex:index];
+        }
+    }
+    
+    return nil;
+}
+
+- (NSInteger)childrenCounts {
+    return _children != nil ? _children.count : 0;
+}
+
+- (NSArray *)allChildren {
+    return _children;
+}
+
++ (GatewaySettingTreeNode *)buildSettingTreeWithGroupNames:(NSArray *)names {
+    GatewaySettingTreeNode *rootNode = [[GatewaySettingTreeNode alloc] init];
+    
+    [GatewaySettingTreeNode setRootNode:rootNode];
+    
+    for (int i = 0; i < names.count; i++) {
+        GatewaySettingTreeNode *node = [[GatewaySettingTreeNode alloc] init];
+        node.name = names[i];
+        [node setHadChild];
+        
+        // Add a child.
+        GatewaySettingTreeNode *childNode = [[GatewaySettingTreeNode alloc] init];
+        childNode.name = [NSString stringWithFormat:@"%@_SettingView", node.name];
+        [node addChild:childNode];
+        
+        // Add into root item.
+        [rootNode addChild:node];
+    }
+    
+    return rootNode;
+}
+
++ (NSInteger)totalSettingItems {
+    if (gRootNode) {
+        return [gRootNode childrenCounts];
+    }
+    
+    return 0;
+}
+
++ (GatewaySettingTreeNode *)rootNode {
+    return gRootNode;
+}
+
++ (void)setRootNode:(GatewaySettingTreeNode *)rootNode {
+    [rootNode setHadChild];
+    rootNode.parent = nil;  // Root has not parent.
+    gRootNode = rootNode;
+}
+
++ (GatewaySettingTreeNode *)searchNodeWithName:(NSString *)name {
+    GatewaySettingTreeNode *node = gRootNode;
+    
+    return searchNode(node, name);
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/InformationToSave.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/InformationToSave.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/InformationToSave.h	(working copy)
@@ -0,0 +1,29 @@
+//
+//  InfoStorage.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/3/17.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "AAAManager.h"
+#if TARGET_OS_IPHONE
+#import "ANBookmarkManager.h"
+#endif
+
+@interface InformationToSave : NSObject
+
+@property (nonatomic, strong) VPNAccount *autoLoginAccount;
+@property (nonatomic, strong) NSArray *savedAccounts;
+@property (nonatomic, strong) VPNAccount *lastLoginAccount;
+
+#if TARGET_OS_IPHONE
+@property (nonatomic, strong) ANBookmarkManager * bookmarkManager;
+#endif
+@property (nonatomic, strong) NSMutableSet * webAppSsoSignedHosts;
+
+- (void)save;
++ (InformationToSave *)sharedInstance;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/InformationToSave.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/InformationToSave.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/InformationToSave.m	(working copy)
@@ -0,0 +1,91 @@
+//
+//  InfoStorage.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/3/17.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "InformationToSave.h"
+
+@implementation InformationToSave
+
+@synthesize autoLoginAccount = _autoLoginAccount;
+@synthesize savedAccounts = _savedAccounts;
+@synthesize lastLoginAccount = _lastLoginAccount;
+
+@synthesize bookmarkManager = _bookmarkManager;
+
+@synthesize webAppSsoSignedHosts = _webAppSsoSignedHosts;
+
+- (id)initWithCoder:(NSCoder *)aDecoder {
+    self = [super init];
+    if (self != nil)
+    {
+        self.autoLoginAccount = [aDecoder decodeObjectForKey:@"AUTOACCOUNT"];
+        self.savedAccounts = [aDecoder decodeObjectForKey:@"SAVEDACCOUNTS"];
+        self.lastLoginAccount = [aDecoder decodeObjectForKey:@"LASTACCOUNT"];
+        
+    }
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder {
+    [aCoder encodeObject:self.autoLoginAccount  forKey:@"AUTOACCOUNT"];
+    [aCoder encodeObject:self.savedAccounts forKey:@"SAVEDACCOUNTS"];
+    [aCoder encodeObject:self.lastLoginAccount forKey:@"LASTACCOUNT"];
+}
+
+- (void)save {
+    NSData *archiveInformation = [NSKeyedArchiver archivedDataWithRootObject:self];
+    [[NSUserDefaults standardUserDefaults] setObject:archiveInformation forKey:@"SAVEDINFORMAINTION"];
+    [[NSUserDefaults standardUserDefaults] synchronize];
+}
+
+
+- (id)bookmarkManager {
+    if (_bookmarkManager == nil) {
+        _bookmarkManager = [[ANBookmarkManager alloc] initRootDirectory];
+    }
+    return _bookmarkManager;
+}
+
+
+- (NSMutableSet *) webAppSsoSignedHosts {
+    if (_webAppSsoSignedHosts == nil) {
+        _webAppSsoSignedHosts = [[NSMutableSet alloc] initWithCapacity:0];
+    }
+    
+    return _webAppSsoSignedHosts;
+}
+
+- (void)dealloc {
+
+    [self removeObserver:self forKeyPath:@"bookmarkManager"];
+
+}
+
++ (InformationToSave *)sharedInstance {
+    static InformationToSave * instance;
+    @synchronized([InformationToSave class]) {
+        if(instance == nil){
+            NSData * data = [[NSUserDefaults standardUserDefaults] objectForKey:@"SAVEDINFORMAINTION"];
+            instance =  [NSKeyedUnarchiver unarchiveObjectWithData:data];
+            if (instance == nil) {
+                instance = [[InformationToSave alloc] init];
+                
+
+                [instance addObserver:instance forKeyPath:@"bookmarkManager" options:NSKeyValueObservingOptionNew  context:nil];
+
+            }
+        }
+    }
+    
+    return instance;
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
+    [self save];
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/PasswordManager.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/PasswordManager.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/PasswordManager.h	(working copy)
@@ -0,0 +1,17 @@
+//
+//  PasswordManager.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/4/20.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface PasswordManager : NSObject
+
++ (NSArray *)passwordsOfHost:(NSString *)host username:(NSString *)username port:(NSString *)port;
++ (void)savePasswords:(NSArray *)passwords forHost:(NSString *)host username:(NSString *)username port:(NSString *)port;
++ (void)removePasswordsOfHost:(NSString *)host username:(NSString *)username port:(NSString *)port;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/PasswordManager.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/PasswordManager.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/PasswordManager.m	(working copy)
@@ -0,0 +1,80 @@
+//
+//  PasswordManager.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/4/20.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "ANKeychain.h"
+#import "PasswordManager.h"
+
+@implementation PasswordManager
+
+static NSString *makeKey(NSString *host, NSString *username, NSString *port, NSString *extend) {
+    NSString *key;
+    if (extend) {
+        key = [NSString stringWithFormat:@"%@/%@/%@/%@", username, host, port, extend];
+    } else {
+        key = [NSString stringWithFormat:@"%@/%@/%@",username ,host, port];
+    }
+    return key;
+}
+
+#define PASSWD2_EXTEND_KEY @"password2"
+#define PASSWD3_EXTEND_KEY @"password3"
+
++ (NSArray *)passwordsOfHost:(NSString *)host username:(NSString *)username port:(NSString *)port
+{
+    NSString *passwd1 = [ANKeychain passwordForAccountKey:makeKey(host, username, port, nil)];
+    if (passwd1 == nil) {
+        return @[@"", @"", @""];
+    }
+    
+    NSString *passwd2 = [ANKeychain passwordForAccountKey:makeKey(host, username, port,  PASSWD2_EXTEND_KEY)];
+    if (passwd2 == nil) {
+        return @[passwd1, @"", @""];
+    }
+    
+    NSString *passwd3 = [ANKeychain passwordForAccountKey:makeKey(host, username, port,  PASSWD3_EXTEND_KEY)];
+    if (passwd3 == nil) {
+        return @[passwd1, passwd2, @""];
+    }
+    
+    return @[passwd1, passwd2, passwd3];
+    
+}
+
++ (void)savePasswords:(NSArray *)passwords forHost:(NSString *)host username:(NSString *)username port:(NSString *)port
+{
+    NSArray *allKeys = @[makeKey(host, username, port,  nil),
+                         makeKey(host, username, port,  PASSWD2_EXTEND_KEY),
+                         makeKey(host, username, port,  PASSWD3_EXTEND_KEY),];
+    
+    NSInteger i = 0;
+    NSInteger count = passwords.count;
+    
+    for (i = 0; i < count; i++) {
+        if (i == 3) {
+            //Only support 3 passwords
+            break;
+        }
+        
+        NSString *passwd = passwords[i];
+        [ANKeychain savePassword:passwd forAccoutKey:allKeys[i]];
+    }
+    
+}
+
++ (void)removePasswordsOfHost:(NSString *)host username:(NSString *)username port:(NSString *)port
+{
+    NSArray *allKeys = @[makeKey(host, username, port,  nil),
+                         makeKey(host, username, port,  PASSWD2_EXTEND_KEY),
+                         makeKey(host, username, port,  PASSWD3_EXTEND_KEY),];
+    
+    for (NSString *key in allKeys) {
+        [ANKeychain deletePasswordForAccountKey:key];
+    }
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h	(working copy)
@@ -0,0 +1,37 @@
+//
+//  AppManager.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/27.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "WebApp.h"
+#import "NativeApp.h"
+#import "FolderItem.h"
+
+typedef void(^CompleteHandler)(BOOL isNeedUpdate);
+
+#define APPSTORE_SEARCH_STRING  @"https://search.itunes.apple.com/WebObjects/MZSearch.woa/wa/search?media=software&term=%@"
+
+@interface AppManager : NSObject
+
+@property (nonatomic, strong) FolderApp *webApps;
+@property (nonatomic, strong) FolderApp *nativeApps;
+@property (nonatomic, strong) FolderItem *desktopApps;
+
+@property (nonatomic, strong) DesktopSetting *desktopSettings;
+
+@property (nonatomic, readonly) BOOL isEmpty;
+
+- (BOOL)isEmpty;
+- (void)parseResources;
+- (void)parseBookMarkResources;
+
+- (void)fetchAppsFromServer:(NSString *)host port:(NSString *)port completion:(CompleteHandler)completion;
+
++ (instancetype)sharedInstance;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.InfosecEnterprise
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.InfosecEnterprise	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.InfosecEnterprise	(working copy)
@@ -0,0 +1,38 @@
+//
+//  AppManager.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/27.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "WebApp.h"
+#import "NativeApp.h"
+#import "FolderItem.h"
+
+typedef void(^CompleteHandler)(BOOL isNeedUpdate);
+
+#define APPSTORE_SEARCH_STRING  @"https://search.itunes.apple.com/WebObjects/MZSearch.woa/wa/search?media=software&term=%@"
+#define ITMS_SERVICE_PREFIX     @"itms-services://?action=download-manifest&url=%@"
+
+@interface AppManager : NSObject
+
+@property (nonatomic, strong) FolderApp *webApps;
+@property (nonatomic, strong) FolderApp *nativeApps;
+@property (nonatomic, strong) FolderItem *desktopApps;
+
+@property (nonatomic, strong) DesktopSetting *desktopSettings;
+
+@property (nonatomic, readonly) BOOL isEmpty;
+
+- (BOOL)isEmpty;
+- (void)parseResources;
+- (void)parseBookMarkResources;
+
+- (void)fetchAppsFromServer:(NSString *)host port:(NSString *)port completion:(CompleteHandler)completion;
+
++ (instancetype)sharedInstance;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.InfosecStore
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.InfosecStore	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.InfosecStore	(working copy)
@@ -0,0 +1,37 @@
+//
+//  AppManager.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/27.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "WebApp.h"
+#import "NativeApp.h"
+#import "FolderItem.h"
+
+typedef void(^CompleteHandler)(BOOL isNeedUpdate);
+
+#define APPSTORE_SEARCH_STRING  @"https://search.itunes.apple.com/WebObjects/MZSearch.woa/wa/search?media=software&term=%@"
+
+@interface AppManager : NSObject
+
+@property (nonatomic, strong) FolderApp *webApps;
+@property (nonatomic, strong) FolderApp *nativeApps;
+@property (nonatomic, strong) FolderItem *desktopApps;
+
+@property (nonatomic, strong) DesktopSetting *desktopSettings;
+
+@property (nonatomic, readonly) BOOL isEmpty;
+
+- (BOOL)isEmpty;
+- (void)parseResources;
+- (void)parseBookMarkResources;
+
+- (void)fetchAppsFromServer:(NSString *)host port:(NSString *)port completion:(CompleteHandler)completion;
+
++ (instancetype)sharedInstance;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.MotionPro
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.MotionPro	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.MotionPro	(working copy)
@@ -0,0 +1,37 @@
+//
+//  AppManager.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/27.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "WebApp.h"
+#import "NativeApp.h"
+#import "FolderItem.h"
+
+typedef void(^CompleteHandler)(BOOL isNeedUpdate);
+
+#define APPSTORE_SEARCH_STRING  @"https://search.itunes.apple.com/WebObjects/MZSearch.woa/wa/search?media=software&term=%@"
+
+@interface AppManager : NSObject
+
+@property (nonatomic, strong) FolderApp *webApps;
+@property (nonatomic, strong) FolderApp *nativeApps;
+@property (nonatomic, strong) FolderItem *desktopApps;
+
+@property (nonatomic, strong) DesktopSetting *desktopSettings;
+
+@property (nonatomic, readonly) BOOL isEmpty;
+
+- (BOOL)isEmpty;
+- (void)parseResources;
+- (void)parseBookMarkResources;
+
+- (void)fetchAppsFromServer:(NSString *)host port:(NSString *)port completion:(CompleteHandler)completion;
+
++ (instancetype)sharedInstance;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.MotionProEnterprise
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.MotionProEnterprise	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.h.MotionProEnterprise	(working copy)
@@ -0,0 +1,38 @@
+//
+//  AppManager.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/27.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "WebApp.h"
+#import "NativeApp.h"
+#import "FolderItem.h"
+
+typedef void(^CompleteHandler)(BOOL isNeedUpdate);
+
+#define APPSTORE_SEARCH_STRING  @"https://search.itunes.apple.com/WebObjects/MZSearch.woa/wa/search?media=software&term=%@"
+#define ITMS_SERVICE_PREFIX     @"itms-services://?action=download-manifest&url=%@"
+
+@interface AppManager : NSObject
+
+@property (nonatomic, strong) FolderApp *webApps;
+@property (nonatomic, strong) FolderApp *nativeApps;
+@property (nonatomic, strong) FolderItem *desktopApps;
+
+@property (nonatomic, strong) DesktopSetting *desktopSettings;
+
+@property (nonatomic, readonly) BOOL isEmpty;
+
+- (BOOL)isEmpty;
+- (void)parseResources;
+- (void)parseBookMarkResources;
+
+- (void)fetchAppsFromServer:(NSString *)host port:(NSString *)port completion:(CompleteHandler)completion;
+
++ (instancetype)sharedInstance;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/AppManager.m	(working copy)
@@ -0,0 +1,532 @@
+//
+//  AppManager.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/27.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+#import "ANLogger.h"
+#import "XMLParser.h"
+#import "Base64.h"
+#import "AAAManager.h"
+#import "GCustomItem.h"
+#import "PubAppItem.h"
+#import "ANHttpClient.h"
+#import "AppManager.h"
+#import "ArrayVPNManager.h"
+
+#define MOTIONPRO_APPS_V2   @"/prx/000/http/localhost:65200/motionpro/postlogin/apps"
+
+@implementation AppManager
+
++ (instancetype)sharedInstance {
+    static AppManager *instance = nil;
+    static dispatch_once_t token;
+    
+    dispatch_once(&token, ^{
+        instance = [[AppManager alloc] init];
+        
+        [[NSNotificationCenter defaultCenter] addObserver:instance
+                                                 selector:@selector(prepareWhenConnect:)
+                                                     name:kVPNMessageNotification
+                                                   object:nil];
+        [[NSNotificationCenter defaultCenter] addObserver:instance
+                                                 selector:@selector(getCustomIconOnVPNTunnelSetup:)
+                                                     name:kArrayVPNStatusNotification
+                                                   object:nil];
+    });
+    
+    return instance;
+}
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (void)getCustomIconOnVPNTunnelSetup:(NSNotification *)notification {
+    ArrayVPNStatus status = [ArrayVPNManager sharedInstance].vpnStatus;
+    if(status == ArrayVPNConnected){
+        ANDebug(@"vpn tunnel connected,get custom icon");
+        for(ResourceApp *app in self.nativeApps.children){
+            [app getAPPsCustomIconFromURL];
+        }
+    }
+}
+
+- (void)prepareWhenConnect:(NSNotification *)notfiy {
+    VPNMessage *msg = (VPNMessage *)notfiy.object;
+    if (msg.code == VPN_CB_CONNECTED) {
+        for (ResourceApp *app in self.nativeApps.children) {
+            [app getMobileAPPIconFromURL];
+        }
+    }
+}
+
+- (BOOL)isEmpty {
+    NSInteger webAppCount = self.webApps.children.count;
+    NSInteger nativeAppCount = self.nativeApps.children.count;
+    NSInteger desktopCount = self.desktopApps.resourceItems.count;
+    
+    return webAppCount == 0 && nativeAppCount == 0 && desktopCount == 0;
+}
+
+- (void)parseBookMarkResources {
+    //Desktop type is 2, weblink type is 0
+    bookmark_list_info_t *info = [AAAManager sharedInstance].bookmark_info;
+    for(int i=0; i<info->bookmark_num; i++) {
+        ANInfo(@"parseBookMarkResources:type=%d, desc=%s", info->bookmarkinfo[i].type, info->bookmarkinfo[i].description);
+        if (info->bookmarkinfo[i].type == 0) {
+            NSString *name = [[NSString alloc] initWithCString:info->bookmarkinfo[i].description encoding:NSUTF8StringEncoding];
+            NSString *urlString = [[NSString alloc] initWithCString:info->bookmarkinfo[i].url encoding:NSUTF8StringEncoding];
+            NSString *fullUrlString = nil;
+            
+            if (![urlString containsString:@"http://" ] && ![urlString containsString:@"https://"]) {
+                ANWarn(@"parseBookMarkResources: Web app is invalid, url is: \"%@\"", urlString);
+                
+                fullUrlString = [NSString stringWithFormat:@"http://%@", urlString];
+            }
+            
+            WebApp *app = [[WebApp alloc] init];
+            app.name = name;
+            app.ID = urlString;
+            app.url = [NSURL URLWithString:fullUrlString == nil ? urlString : fullUrlString];
+            
+            [self.webApps addApp:app forPath:nil];
+        }
+        if (info->bookmarkinfo[i].type == 2) {
+            HostItem *hostItem = [[HostItem alloc] init];
+            hostItem.ID = [[NSString alloc] initWithCString:info->bookmarkinfo[i].url encoding:NSUTF8StringEncoding];
+            hostItem.desc = [[NSString alloc] initWithCString:info->bookmarkinfo[i].description encoding:NSUTF8StringEncoding];
+            hostItem.server = [[NSString alloc] initWithCString:info->bookmarkinfo[i].url encoding:NSUTF8StringEncoding];
+            hostItem.ssoUsername = [[NSString alloc] initWithCString:info->bookmarkinfo[i].username encoding:NSUTF8StringEncoding];
+            hostItem.name = [[NSString alloc] initWithCString:info->bookmarkinfo[i].description encoding:NSUTF8StringEncoding];
+            
+            [hostItem completeInit];
+            [self.desktopApps addResourceItem:hostItem forPath:nil];
+        }
+    }
+}
+
+- (void)parseResources {
+    NSString *resource = [AAAManager sharedInstance].resources;
+    
+    NSString *rootName = [XMLParser getRootNodeNameWithXMLString:resource];
+    if ([rootName isEqualToString:TAG_ARP]) {
+        self.desktopSettings = [[DesktopSetting alloc] init];
+        self.desktopApps = [[FolderItem alloc] init];
+        
+        [self configureDesktopSettingsWithXMLString:resource];
+        [self configureDesktopsWithXMLString:resource];
+        
+        return;
+    }
+    
+    self.webApps = [[WebApp alloc] init];
+    self.nativeApps = [[NativeApp alloc] init];
+    
+    [self configureWebAppWithXMLString:resource];
+    [self configureNativeAppWithXMLString:resource];
+}
+
+- (void)configureDesktopSettingsWithXMLString:(NSString *)string {
+    NSArray *allKeys = @[TAG_ARP_SETTINGS_DOMAIN, TAG_ARP_INSTANCE, TAG_ARP_SETTINGS_POWERMNG, TAG_ARP_SETTINGS_CUSTOMDEST, TAG_ARP_SETTINGS_BITMAPCACHE,
+                         TAG_ARP_SETTINGS_DESKTOPWALL, TAG_ARP_SETTINGS_FULLWINDOWDRAG, TAG_ARP_SETTINGS_MENUANIM, TAG_ARP_SETTINGS_THEMES,
+                         TAG_ARP_SETTINGS_SSO, TAG_ARP_SETTINGS_VENDOR_NEC];
+    
+    for (NSString *key in allKeys) {
+        [self.desktopSettings.settings setObject:@"" forKey:key];
+    }
+    
+    NSString *domainString = [XMLParser parseXMLString:string
+                                                  tags:@[TAG_ARP, TAG_ARP_SETTINGS, TAG_ARP_SETTINGS_DOMAIN]];
+    if (!domainString) {
+        ANDebug(@"Desktop setting of \"%@\" has not been found.", TAG_ARP_SETTINGS_DOMAIN);
+    } else {
+        [self.desktopSettings.settings setObject:domainString forKey:TAG_ARP_SETTINGS_DOMAIN];
+    }
+    
+    NSString *instance = [XMLParser parseXMLString:string
+                                              tags:@[TAG_ARP, TAG_ARP_INSTANCE]];
+    if (!instance) {
+        ANDebug(@"Desktop setting of \"%@\" has not been found.", TAG_ARP_INSTANCE);
+    } else {
+        [self.desktopSettings.settings setObject:instance forKey:[TAG_ARP_INSTANCE lowercaseString]];
+    }
+    
+    for (NSInteger index = 2; index < allKeys.count; index++) {
+        NSString *key = [allKeys objectAtIndex:index];
+        NSString *result = [XMLParser parseXMLString:string
+                                                tags:@[TAG_ARP, TAG_ARP_SETTINGS, key]];
+        if (!result) {
+            ANDebug(@"Desktop setting of \"%@\" has not been found.", key);
+        } else {
+            [self.desktopSettings.settings setObject:result forKey:key];
+        }
+    }
+    
+    for (NSString *key in @[TAG_ARP_SETTINGS_DESKTOPWALL, TAG_ARP_SETTINGS_FULLWINDOWDRAG, TAG_ARP_SETTINGS_MENUANIM, TAG_ARP_SETTINGS_THEMES]) {
+        // Reverse these values, because RD client's values are "disable xxx".
+        if ([self.desktopSettings.settings[key] isEqualToString:@"0"]) {
+            self.desktopSettings.settings[key] = @"1";
+        } else {
+            self.desktopSettings.settings[key] = @"0";
+        }
+    }
+}
+
+- (void)configureDesktopsWithXMLString:(NSString *)string {
+    [self parseDesktopHostsWithXMLString:string];
+    [self parsePubAppsWithXMLString:string];
+}
+
+- (void)parseDesktopHostsWithXMLString:(NSString *)string {
+    AppManager *manager = [AppManager sharedInstance];
+    NSDictionary *desktopSettings = manager.desktopSettings.settings;
+    if ([desktopSettings[TAG_ARP_SETTINGS_CUSTOMDEST] isEqualToString:@"1"]) {
+        GCustomItem *customItem = [[GCustomItem alloc] init];
+        customItem.ID = @"";
+        customItem.name = NSLocalizedString(@"Other", nil);
+        customItem.desc = customItem.name;
+        
+        [self.desktopApps addResourceItem:customItem forPath:nil];
+    }
+    
+    NSArray *hostNodes = [XMLParser getNodesWithXMLString:string tags:@[TAG_ARP, TAG_ARP_HOSTS]];
+    if (!hostNodes || hostNodes.count == 0) {
+        return;
+    }
+    
+    NSString *rdpPort = [[hostNodes[0] attributeForName:TAG_ARP_PORT] stringValue];
+    
+    NSArray *hosts = [XMLParser getNodesWithXMLString:string tags:@[TAG_ARP, TAG_ARP_HOSTS, TAG_HOST]];
+    for (GDataXMLElement *host in hosts) {
+        NSDictionary *dict = [XMLParser parseXMLNode:host
+                                          attributes:@[ATR_DESC, ATR_FOLDER, TAG_ARP_SESSINFO, ATR_WEBAPP_ID, TAG_ARP_PROVIDER, TAG_ARP_PROVIDERID]];
+        NSString *description = dict[ATR_DESC];
+        NSString *folder = dict[ATR_FOLDER];
+        NSString *sessionInfo = dict[TAG_ARP_SESSINFO];
+        
+        description = [self decodeHostDesc:description];
+        NSArray *userAndPassword = [self decodeUsernameAndPassword:sessionInfo];
+        NSString *username = nil;
+        NSString *password = nil;
+        
+        if (userAndPassword && userAndPassword.count == 2) {
+            username = userAndPassword[0];
+            password = userAndPassword[1];
+        }
+        
+        HostItem *hostItem = [[HostItem alloc] init];
+        hostItem.ID = dict[ATR_WEBAPP_ID];
+        hostItem.server = host.stringValue;
+        hostItem.name = description;
+        hostItem.desc = description;
+        hostItem.ssoUsername = username;
+        hostItem.ssoPassword = password;
+        hostItem.port = rdpPort;
+        hostItem.provider = dict[TAG_ARP_PROVIDER];
+        hostItem.providerID = dict[TAG_ARP_PROVIDERID];
+        
+        [hostItem completeInit];
+        
+        [self.desktopApps addResourceItem:hostItem forPath:folder];
+    }
+}
+
+- (void)parsePubAppsWithXMLString:(NSString *)string {
+    // <App Name="aaa" Desc="&#x6211;&#x7684;&#x8BB0;&#x4E8B;&#x672C;" Loc="c:\windows\system32\notepad.
+    // exe" Dir="" Folder="other" Height="-1" Width="-1" IconUpdated="2014-01-26 13:44:22" Publisher="TS">2</App>
+    
+    NSArray *apps = [XMLParser getNodesWithXMLString:string tags:@[TAG_ARP, TAG_ARP_APPS, TAG_ARP_APP]];
+    
+    for (GDataXMLElement *app in apps) {
+        NSDictionary *dict = [XMLParser parseXMLNode:app attributes:@[ARP_APP_NAME, ATR_DESC, ARP_APP_LOC, ARP_APP_DIR, ATR_FOLDER]];
+        if (dict) {
+            PubAppItem *item = [[PubAppItem alloc] init];
+            
+            item.ID = app.stringValue;
+            item.name = dict[ARP_APP_NAME];
+            item.desc = dict[ATR_DESC];
+            item.location = dict[ARP_APP_LOC];
+            item.directory = dict[ARP_APP_DIR];
+            
+            if (!item.desc || item.desc.length == 0) {
+                item.desc = item.name;
+            }
+            
+            [item completeInit];
+            
+            [self.desktopApps addResourceItem:item forPath:dict[ATR_FOLDER]];
+        }
+    }
+}
+
+- (void)configureWebAppWithXMLString:(NSString *)string {
+    NSArray *results = [XMLParser parseXMLString:string
+                                            tags:@[TAG_HOST, TAG_WEBAPPS, TAG_WEBAPP]
+                                      attributes:@[ATR_DESC, ATR_WEBAPP_ID, ATR_FOLDER]];
+    
+    for (NSDictionary *dict in results) {
+        NSString *name = dict[ATR_DESC];
+        NSString *urlString = dict[ATR_WEBAPP_ID];
+        NSString *folder = dict[ATR_FOLDER];
+        NSString *fullUrlString = nil;
+        
+        if (![urlString containsString:@"http://" ] && ![urlString containsString:@"https://"]) {
+            ANWarn(@"Web app is invalid, url is: \"%@\"", urlString);
+            
+            fullUrlString = [NSString stringWithFormat:@"http://%@", urlString];
+        }
+        
+        WebApp *app = [[WebApp alloc] init];
+        
+        app.name = name;
+        app.ID = urlString;
+        app.url = [NSURL URLWithString:fullUrlString == nil ? urlString : fullUrlString];
+        
+        [self.webApps addApp:app forPath:folder];
+    }
+}
+
+- (void)configureNativeAppWithXMLString:(NSString *)string {
+
+    NSString *folder = nil;
+    NSArray *attributes = @[ATR_NATIVEAPP_OS, ATR_NATIVEAPP_NAME, ATR_DESC, ATR_NATIVEAPP_PARA, ATR_NATIVEAPP_TYPE, ATR_FOLDER, ATR_WEBAPP_ID,
+                            ATR_NATIVEAPP_CUSTOM_ICON_URL];
+    NSArray *nodes = [XMLParser getNodesWithXMLString:string tags:@[TAG_HOST, TAG_NATIVEAPPS, TAG_NATIVEAPP]];
+    
+    for (GDataXMLElement *node in nodes) {
+        NativeApp *nativeApp = [[NativeApp alloc] init];
+        
+        NSDictionary *dict = [XMLParser parseXMLNode:node attributes:attributes];
+        if (dict) {
+            NSString *os = dict[ATR_NATIVEAPP_OS];
+            if ([[os lowercaseString] isEqualToString:@"android"]) {
+                continue;
+            }
+            
+            NSString *name = dict[ATR_NATIVEAPP_NAME];
+            NSString *desc = dict[ATR_DESC];
+            NSString *para = dict[ATR_NATIVEAPP_PARA];
+            NSString *typeString = dict[ATR_NATIVEAPP_TYPE];
+            NSString *nativeID = dict[ATR_WEBAPP_ID];
+            NSString *customIconURL = dict[ATR_NATIVEAPP_CUSTOM_ICON_URL];
+            folder = dict[ATR_FOLDER];
+            
+            BOOL isBuiltIn = [typeString isEqualToString:NATIVEAPP_TYPE_BUILDIN];
+            
+            nativeApp.type = isBuiltIn ? APP_TYPE_NATIVE_SDK : APP_TYPE_NATIVEAPP;
+            nativeApp.name = name;
+            nativeApp.desc = desc;
+            nativeApp.scheme = para;
+            nativeApp.ID = nativeID;
+            nativeApp.customIconURL = customIconURL;
+        }
+        
+        NSArray *subNodesMobileApp = [XMLParser getSubNodesWithXMLNode:node tag:TAG_MOBILEAPP];
+        if (subNodesMobileApp && subNodesMobileApp.count > 0) {
+            GDataXMLElement *mobileAppNode = subNodesMobileApp[0];
+            NSArray *subNodesAppPackage = [XMLParser getSubNodesWithXMLNode:mobileAppNode tag:TAG_PACKAGE];
+            if (!subNodesAppPackage || subNodesAppPackage.count <= 0) {
+                ANInfo(@"The mobile app has no install package information.");
+            } else {
+                // Parse subnode of "MobileApp".
+                NSArray *mobileAppAttributes = @[ATR_NATIVEAPP_NAME, ATR_MOBILE_LOCALTIONTYPE, ATR_MOBILE_CATEGORY,
+                                                 ATR_MOBILE_ICONURL, ATR_MOBILE_SCHEMES, ATR_MOBILE_APPID];
+                NSDictionary *mobileAppDict = [XMLParser parseXMLNode:mobileAppNode attributes:mobileAppAttributes];
+                NSString *mobileAppName = mobileAppDict[ATR_NATIVEAPP_NAME];
+                NSString *ltype = mobileAppDict[ATR_MOBILE_LOCALTIONTYPE];
+                NSString *category = mobileAppDict[ATR_MOBILE_CATEGORY];
+                NSString *iconUrl = mobileAppDict[ATR_MOBILE_ICONURL];
+                NSString *schemeString = mobileAppDict[ATR_MOBILE_SCHEMES];
+                NSString *appID = mobileAppDict[ATR_MOBILE_APPID];
+                
+                // Parse subnode of "Package".
+                GDataXMLElement *appPackageNode = subNodesAppPackage[0];
+                NSArray *appPackageAttributes = @[ATR_PKG_DEVICETYPE, ATR_PKG_VERSIONNAME, ATR_PKG_FILESIZE, ATR_PKG_FILEURL, ATR_PKG_CREATETIME];
+                NSDictionary *appPackageDict = [XMLParser parseXMLNode:appPackageNode attributes:appPackageAttributes];
+                NSString *deviceType = appPackageDict[ATR_PKG_DEVICETYPE];
+                NSString *version = appPackageDict[ATR_PKG_VERSIONNAME];
+                NSString *fileSize = appPackageDict[ATR_PKG_FILESIZE];
+                NSString *fileUrl = appPackageDict[ATR_PKG_FILEURL];
+                NSString *createdTime = appPackageDict[ATR_PKG_CREATETIME];
+                
+                // 0 is for all devices, 1 is for iPhone and 2 is for iPad.
+                if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+                    if ([deviceType isEqualToString:@"1"]) {
+                        continue;
+                    }
+                } else if ([deviceType isEqualToString:@"2"]){
+                    continue;
+                }
+                
+                NSArray *schemes  = [schemeString componentsSeparatedByString:@";"];
+                bool found = NO;
+                for (NSString *scheme in schemes) {
+                    if ([nativeApp.scheme hasPrefix:scheme]) {
+                        found = YES;
+                    }
+                }
+                if (!found && schemes.count != 0) {
+                    NSString *tmpScheme = [schemes objectAtIndex:0];
+                    if (tmpScheme.length != 0) {
+                        nativeApp.scheme = tmpScheme;
+                    }
+                }
+                nativeApp.name = mobileAppName;
+                nativeApp.appId = appID;
+                nativeApp.locationType = ltype.intValue;
+                nativeApp.category = category;
+                nativeApp.iconUrl = iconUrl;
+                nativeApp.version = version;
+                nativeApp.installUrl = fileUrl;
+                nativeApp.createTime = createdTime;
+                nativeApp.filesize = fileSize.intValue;
+            }
+        }
+        
+        [self.nativeApps addApp:nativeApp forPath:folder];
+    }
+
+}
+
+#pragma mark - Network Related
+- (void)fetchAppsFromServer:(NSString *)host port:(NSString *)port completion:(CompleteHandler)completion {
+    if (!host || host.length <= 0) {
+        ANError(@"Invalid host for fetching apps.");
+        return;
+    }
+    
+    NSString *fullPath = nil;
+    if (port && port.length > 0) {
+        fullPath = [NSString stringWithFormat:@"https://%@:%@%@", host, port, MOTIONPRO_APPS_V2];
+    } else {
+        fullPath = [NSString stringWithFormat:@"https://%@%@", host, MOTIONPRO_APPS_V2];
+    }
+    
+    NSString *ANSession = [AAAManager sharedInstance].sessionID;
+    if (!ANSession || ANSession.length <= 0) {
+        ANError(@"Session is invalid, can't fetch apps from server.");
+        return;
+    }
+    
+    __weak typeof(self) weakSelf = self;
+    ANHttpClient *client = [[ANHttpClient alloc] init];
+    [client setANSessionWithValue:ANSession];
+    [client getWithURL:fullPath
+                params:nil
+                success:^(NSURLSessionDataTask * _Nullable task, id  _Nullable response) {
+                    NSData *responseData = (NSData *)response;
+                    NSString *content = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
+                    if (!content || content.length <= 0) {
+                        ANError(@"Resource xml is invalid, can't be parsed.");
+                        return;
+                    }
+                    
+                    __strong typeof(weakSelf) strongSelf = weakSelf;
+                    [strongSelf configureWebAppWithXMLString:content];
+                    [strongSelf configureDesktopsWithXMLString:content];
+                    
+                    completion(YES);
+                }
+                failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nullable error) {
+                    ANError(@"Fetch apps failed with error: %@", error);
+                    
+                    completion(NO);
+                }];
+}
+
+// Helpers
+/*
+ * Decode "abc&#31508;def&#35760;&#26412;ghi" to UTF-8 string.
+ * find '$&*;'pattern, replace it by Chinese/Japanese word
+ */
+- (NSString *)decodeHostDesc:(NSString *)desc {
+    NSRange range = NSMakeRange(0, [desc length]);
+    NSRange subrange = [desc rangeOfString:@"&" options:NSBackwardsSearch range:range];
+    
+    // if no ampersands, we've got a quick way out
+    if (subrange.length == 0) return desc;
+    NSMutableString *finalString = [NSMutableString stringWithString:desc];
+    do {
+        NSRange semiColonRange = NSMakeRange(subrange.location, NSMaxRange(range) - subrange.location);
+        semiColonRange = [desc rangeOfString:@";" options:0 range:semiColonRange];
+        range = NSMakeRange(0, subrange.location);
+        // if we don't find a semicolon in the range, we don't have a sequence
+        if (semiColonRange.location == NSNotFound) {
+            continue;
+        }
+        NSRange escapeRange = NSMakeRange(subrange.location, semiColonRange.location - subrange.location + 1);
+        NSString *escapeString = [desc substringWithRange:escapeRange];
+        NSUInteger length = [escapeString length];
+        // a squence must be longer than 3 (&lt;) and less than 11 (&thetasym;)
+        if (length > 3 && length < 11) {
+            if ([escapeString characterAtIndex:1] == '#') {
+                unichar char2 = [escapeString characterAtIndex:2];
+                if (char2 == 'x' || char2 == 'X') {
+                    // Hex escape squences &#xa3;
+                    NSString *hexSequence = [escapeString substringWithRange:NSMakeRange(3, length - 4)];
+                    NSScanner *scanner = [NSScanner scannerWithString:hexSequence];
+                    unsigned value;
+                    if ([scanner scanHexInt:&value] &&
+                        value < USHRT_MAX &&
+                        value > 0
+                        && [scanner scanLocation] == length - 4) {
+                        unichar uchar = value;
+                        NSString *charString = [NSString stringWithCharacters:&uchar length:1];
+                        [finalString replaceCharactersInRange:escapeRange withString:charString];
+                    }
+                    
+                } else {
+                    // Decimal Sequences &#123;
+                    NSString *numberSequence = [escapeString substringWithRange:NSMakeRange(2, length - 3)];
+                    NSScanner *scanner = [NSScanner scannerWithString:numberSequence];
+                    int value;
+                    if ([scanner scanInt:&value] &&
+                        value < USHRT_MAX &&
+                        value > 0
+                        && [scanner scanLocation] == length - 3) {
+                        unichar uchar = value;
+                        NSString *charString = [NSString stringWithCharacters:&uchar length:1];
+                        [finalString replaceCharactersInRange:escapeRange withString:charString];
+                    }
+                }
+            }
+        }
+    } while ((subrange = [desc rangeOfString:@"&" options:NSBackwardsSearch range:range]).length != 0);
+    return finalString;
+}
+
+- (NSString *)unmaskString:(NSString *)inputString {
+    const char *input = [inputString cStringUsingEncoding:NSUTF8StringEncoding];
+    NSUInteger length = inputString.length;
+    
+    char *output = malloc(length+1);
+    memset(output, 0, length+1);
+    
+    for (int i = 0; i<length; i++)
+    {
+        output[i] = input[i] ^ ENC_DEC_KEY[i%(sizeof(ENC_DEC_KEY)-1)];
+    }
+    
+    return [NSString stringWithCString:output encoding:NSUTF8StringEncoding];
+}
+
+- (NSArray *)decodeUsernameAndPassword:(NSString *)sessInfo {
+    NSArray *listItems = [sessInfo componentsSeparatedByString:@"@"];
+    
+    if(listItems.count != 2) {
+        // Not a valid format.
+        return nil;
+    }
+    
+    NSString *username = [(NSString *)listItems[0] base64DecodedString];
+    NSString *password = [(NSString *)listItems[1] base64DecodedString];
+    
+    return @[[self unmaskString:username], [self unmaskString:password]];
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/NativeApp.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/NativeApp.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/NativeApp.h	(working copy)
@@ -0,0 +1,26 @@
+//
+//  NativeApp.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/23.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "ResourceApp.h"
+#import "ConfigurationManager.h"
+
+@interface NativeApp : FolderApp <ResourceAppProtocol>
+
+@property (nonatomic, copy) NSString *scheme;
+@property (nonatomic, copy) NSString *appId;
+@property (nonatomic, copy) NSString *version;
+@property (nonatomic, copy) NSString *createTime;
+@property (nonatomic, copy) NSString *descUrl;
+@property (nonatomic, copy) NSString *detailDesc;
+@property (nonatomic, copy) NSString *category;
+@property (nonatomic, copy) NSString *installUrl;
+@property (nonatomic, copy) NSString *createdTime;
+@property (nonatomic) NSInteger filesize;   //bytes
+@property (nonatomic) NSInteger locationType;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/NativeApp.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/NativeApp.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/NativeApp.m	(working copy)
@@ -0,0 +1,15 @@
+//
+//  NativeApp.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/23.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "ANLogger.h"
+#import "NativeApp.h"
+#import "XMLParser.h"
+
+@implementation NativeApp
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/ResourceApp.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/ResourceApp.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/ResourceApp.h	(working copy)
@@ -0,0 +1,132 @@
+//
+//  ResourceApp.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/5/9.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+#import <TargetConditionals.h>
+
+
+#import <UIKit/UIKit.h>
+#import <UIKit/UIDevice.h>
+
+
+#import <Foundation/Foundation.h>
+
+#define TAG_HOST        @"Host"
+#define TAG_WEBAPPS     @"WebApps"
+#define TAG_WEBAPP      @"WebApp"
+#define TAG_WebAcls     @"WebAcls"
+#define TAG_NATIVEAPPS  @"NativeApps"
+#define TAG_NATIVEAPP   @"NativeApp"
+#define TAG_MOBILEAPP   @"MobileApp"
+#define TAG_PACKAGE     @"Package"
+#define TAG_APPDESC     @"AppDesc"
+#define TAG_PORTAL      @"Portal"
+#define TAG_TABPAGE     @"TabPage"
+
+#define TAG_ExtMDM      @"ExternalMDM"
+
+// For MotionPro Desktop
+#define TAG_ARP             @"ARP"
+#define TAG_ARP_SETTINGS    @"Settings"
+#define TAG_ARP_HOSTS       @"Hosts"
+#define TAG_ARP_APPS        @"Apps"
+#define TAG_ARP_APP         @"App"
+#define TAG_ARP_SESSINFO    @"SessInfo"
+#define TAG_ARP_PORT        @"RDPPort"
+#define TAG_ARP_INSTANCE    @"Instance"
+#define TAG_ARP_PROVIDERID  @"ProviderID"
+#define TAG_ARP_PROVIDER    @"Provider"
+
+// For MotionPro Desktop Settings
+#define TAG_ARP_SETTINGS_DOMAIN         @"domain"
+#define TAG_ARP_SETTINGS_POWERMNG       @"powermng"
+#define TAG_ARP_SETTINGS_CUSTOMDEST     @"customdest"
+
+#define TAG_ARP_SETTINGS_BITMAPCACHE    @"bitmapcache"
+#define TAG_ARP_SETTINGS_DESKTOPWALL    @"desktopwall"
+#define TAG_ARP_SETTINGS_FULLWINDOWDRAG @"fullwindowdrag"
+#define TAG_ARP_SETTINGS_MENUANIM       @"menuanim"
+#define TAG_ARP_SETTINGS_THEMES         @"themes"
+#define TAG_ARP_SETTINGS_SSO            @"sso"
+#define TAG_ARP_SETTINGS_VENDOR_NEC     @"jp-rdp"
+
+// For Pub Apps
+#define ARP_APP_NAME                    @"Name"
+#define ARP_APP_LOC                     @"Loc"
+#define ARP_APP_DIR                     @"Dir"
+
+#define ATR_DESC                        @"Desc"
+#define ATR_FOLDER                      @"Folder"
+#define ATR_WEBAPP_ID                   @"ID"
+#define ATR_NATIVEAPP_NAME              @"Name"
+#define ATR_NATIVEAPP_OS                @"OS"
+#define ATR_NATIVEAPP_TYPE              @"Type"
+#define ATR_NATIVEAPP_PARA              @"Para"
+#define ATR_NATIVEAPP_CUSTOM_ICON_URL   @"Icon"
+
+#define HOST_CUSTOM_ICON_URL            @"http://2.255.255.249"
+
+typedef enum {
+    APP_TYPE_WEBAPP,            //contain a url which should be open with secbrowser
+    APP_TYPE_FOLDER,
+    APP_TYPE_NATIVEAPP,
+    APP_TYPE_NATIVE_SDK,
+} APP_TYPE;
+
+enum {
+    LOCATION_TYPE_INTERVAL = 1,
+    LOCATION_TYPE_EXTERNAL,
+};
+
+@class ResourceApp;
+
+@protocol ResourceAppProtocol <NSObject>
+
+@optional
+- (void)prepare;    // Called when the app create.
+- (void)open;
+- (void)install;    // For native app.
+
+- (void)addApp:(ResourceApp *)app;
+- (void)addApp:(ResourceApp *)app forPath:(NSString *)path;
+- (void)removeApp:(ResourceApp *)app;
+
+@end
+
+@interface ResourceApp : NSObject
+
+@property (nonatomic, copy) NSString *ID;
+@property (nonatomic, copy) NSString *name;  // Sibling leaf has the uniqure name.
+@property (nonatomic, assign) APP_TYPE type;
+@property (nonatomic, weak) ResourceApp *parent;
+@property (nonatomic, copy) NSString *desc;
+@property (nonatomic, copy) NSString *customIconURL;  // Can be nil.
+@property (nonatomic, copy) NSString *iconUrl;
+@property (nonatomic, strong) UIImage *icon;
+@property (nonatomic, strong) UIImage *customIcon;
+@property (nonatomic, strong) UIImage *appIcon;
+
+
+- (id)initWithName:(NSString *)name;
+- (id)initWithName:(NSString *)name type:(APP_TYPE)type;
+
+- (bool)isNativeApp;
+- (BOOL)isEqualToApp:(ResourceApp *)app;
+
+- (void)getAPPsCustomIconFromURL;
+- (void)getMobileAPPIconFromURL;
+
+@end
+
+@interface FolderApp : ResourceApp
+
+@property (nonatomic, strong) NSMutableArray *children;
+
+- (id)initWithParent:(FolderApp *)parent children:(NSMutableArray *)children;
+- (void)addApp:(ResourceApp *)app;
+- (void)addApp:(ResourceApp *)app forPath:(NSString *)path;  // UNIX like file path
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/ResourceApp.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/ResourceApp.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/ResourceApp.m	(working copy)
@@ -0,0 +1,172 @@
+//
+//  ResourceApp.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/5/9.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "ANLogger.h"
+#import "ANHttpClient.h"
+#import "ResourceApp.h"
+
+#pragma mark - Resource App
+@implementation ResourceApp
+
+- (id)initWithName:(NSString *)name {
+    self = [super init];
+    if (self) {
+        self.name = name;
+    }
+    
+    return self;
+}
+
+- (id)initWithName:(NSString *)name type:(APP_TYPE)type {
+    self = [super init];
+    if (self) {
+        self.name = name;
+        self.type = type;
+    }
+    
+    return self;
+}
+
+- (bool)isNativeApp {
+    return (self.type == APP_TYPE_NATIVEAPP || self.type == APP_TYPE_NATIVE_SDK);
+}
+
+- (NSString *)description {
+    NSString *ret = [NSString stringWithFormat:@"type:%d, name:%@", self.type, self.name];
+    
+    return ret;
+}
+
+- (BOOL)isEqualToApp:(ResourceApp *)app {
+    if ([self.ID isEqualToString:app.ID]) {
+        return YES;
+    }
+    
+    return NO;
+}
+
+- (void)getAPPsCustomIconFromURL {
+    if (!self.customIconURL || self.customIconURL.length <= 0) {
+        return;
+    }
+    
+    __weak typeof(self) weakSelf = self;
+    ANHttpClient *client = [[ANHttpClient alloc] init];
+    NSString *iconURL = [HOST_CUSTOM_ICON_URL stringByAppendingString:self.customIconURL];
+    
+    [client getImageWithURL:self.customIconURL params:nil success:^(NSURLSessionDataTask *task, id response) {
+        if (response) {
+
+            UIImage *icon = (UIImage *)response;
+
+            if(icon){
+                weakSelf.customIcon = icon;
+            } else {
+                ANDebug(@"folder [%@], can not alloc image icon, url %@", weakSelf.name, iconURL);
+            }
+        }
+    } failure:^(NSURLSessionDataTask *task, NSError *error) {
+        ANDebug(@"folder [%@] get custom icon failed with error: %@.", weakSelf.name, error.localizedDescription);
+    }];
+}
+
+- (void)getMobileAPPIconFromURL {
+    if (!self.iconUrl || self.iconUrl.length <= 0) {
+        return;
+    }
+
+    //public resource, no need to login to vsite
+    __weak typeof(self) weakSelf = self;
+    ANHttpClient *client = [[ANHttpClient alloc] init];
+    
+    [client getImageWithURL:self.iconUrl params:nil success:^(NSURLSessionDataTask *task, id response) {
+        if (response) {
+
+            UIImage *icon = (UIImage *)response;
+
+            if (icon) {
+                self.appIcon = icon;
+            } else {
+                ANDebug(@"app [%@] get icon failed,url %@", weakSelf.name, weakSelf.iconUrl);
+            }
+        }
+    } failure:^(NSURLSessionDataTask *task, NSError *error) {
+        ANError(@"folder [%@] get app icon failed with error: %@.", weakSelf.name, error.localizedDescription);
+    }];
+}
+
+@end
+
+#pragma mark - Folder App
+@implementation FolderApp
+
+@synthesize children = _children;
+
+- (NSMutableArray *)children {
+    if (_children == nil) {
+        _children = [[NSMutableArray alloc] initWithCapacity:1];
+    }
+    
+    return _children;
+}
+
+- (id)initWithParent:(FolderApp *)parent children:(NSMutableArray *)children {
+    self = [super init];
+    if (self) {
+        self.children = children;
+        self.parent = parent;
+        self.type = APP_TYPE_FOLDER;
+    }
+    
+    return self;
+}
+
+- (void)addApp:(ResourceApp *)app {
+    for (ResourceApp *r in self.children) {
+        if ([r isEqualToApp:app]) {
+            return;
+        }
+    }
+    
+    app.parent = self;
+    [self.children addObject:app];
+}
+
+- (void)addApp:(ResourceApp *)app forPath:(NSString *)path {
+    FolderApp *currentFolder = self;
+    NSArray *paths = [path pathComponents];
+    
+    for (int i = 0; i < paths.count; i++) {
+        NSString *p = [paths objectAtIndex:i];
+        if ([p isEqualToString:@"/"]) {
+            continue;
+        }
+        
+        currentFolder = [currentFolder folderForName:p create:YES];
+    }
+    
+    [currentFolder addApp:app];
+}
+
+- (FolderApp *)folderForName:(NSString *)name create:(bool)create {
+    for (ResourceApp *app in self.children) {
+        if ([app.name isEqualToString:name] && app.type == APP_TYPE_FOLDER) {
+            return (FolderApp *)app;
+        }
+    }
+    
+    if (create) {
+        FolderApp *app = [[FolderApp alloc] initWithName:name type:APP_TYPE_FOLDER];
+        [self addApp:app];
+        return app;
+    } else {
+        return nil;
+    }
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/WebApp.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/WebApp.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/WebApp.h	(working copy)
@@ -0,0 +1,16 @@
+//
+//  WebApp.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/23.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "ResourceApp.h"
+#import "ConfigurationManager.h"
+
+@interface WebApp : FolderApp <ResourceAppProtocol>
+
+@property (nonatomic, strong) NSURL *url;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/WebApp.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/WebApp.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/Shared/Models/Resources/WebApp.m	(working copy)
@@ -0,0 +1,27 @@
+//
+//  WebApp.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/6/23.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+
+#import <UIKit/UIKit.h>
+
+#import "ANLogger.h"
+#import "WebApp.h"
+#import "XMLParser.h"
+
+@implementation WebApp
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        self.type = APP_TYPE_WEBAPP;
+    }
+    
+    return self;
+}
+
+@end
