/*
 * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jvm_md.h"

#include "proxy_util.h"

#include "sun_net_spi_DefaultProxySelector.h"


/**
 * These functions are used by the sun.net.spi.DefaultProxySelector class
 * to access some platform specific settings.
 * This is the Solaris/Linux Gnome 2.x code using the GConf-2 library.
 * Everything is loaded dynamically so no hard link with any library exists.
 * The GConf-2 settings used are:
 * - /system/http_proxy/use_http_proxy          boolean
 * - /system/http_proxy/use_authentcation       boolean
 * - /system/http_proxy/use_same_proxy          boolean
 * - /system/http_proxy/host                    string
 * - /system/http_proxy/authentication_user     string
 * - /system/http_proxy/authentication_password string
 * - /system/http_proxy/port                    int
 * - /system/proxy/socks_host                   string
 * - /system/proxy/mode                         string
 * - /system/proxy/ftp_host                     string
 * - /system/proxy/secure_host                  string
 * - /system/proxy/socks_port                   int
 * - /system/proxy/ftp_port                     int
 * - /system/proxy/secure_port                  int
 * - /system/proxy/no_proxy_for                 list
 *
 * The following keys are not used in the new gnome 3
 * - /system/http_proxy/use_http_proxy
 * - /system/http_proxy/use_same_proxy
 */
typedef void* gconf_client_get_default_func();
typedef char* gconf_client_get_string_func(void *, char *, void**);
typedef int   gconf_client_get_int_func(void*, char *, void**);
typedef int   gconf_client_get_bool_func(void*, char *, void**);
typedef int   gconf_init_func(int, char**, void**);
typedef void  g_type_init_func ();
gconf_client_get_default_func* my_get_default_func = NULL;
gconf_client_get_string_func* my_get_string_func = NULL;
gconf_client_get_int_func* my_get_int_func = NULL;
gconf_client_get_bool_func* my_get_bool_func = NULL;
g_type_init_func* my_g_type_init_func = NULL;


/*
 * GProxyResolver provides synchronous and asynchronous network
 * proxy resolution. It is based on GSettings, which is the standard
 * of Gnome 3, to get system settings.
 *
 * In the current implementation, GProxyResolver has a higher priority
 * than the old GConf. And we only resolve the proxy synchronously. In
 * the future, we can also do the asynchronous network proxy resolution
 * if necessary.
 *
 */
typedef struct _GProxyResolver GProxyResolver;
typedef struct _GSocketConnectable GSocketConnectable;
typedef struct GError GError;
typedef GProxyResolver* g_proxy_resolver_get_default_func(void);
typedef char** g_proxy_resolver_lookup_func(GProxyResolver* resolver, char* uri, void *null, GError **error_p);
typedef GSocketConnectable* g_network_address_parse_uri_func(char* proxy, unsigned short default_port, GError **error_p);
typedef const char* g_network_address_get_hostname_func(GSocketConnectable* conn);
typedef unsigned short g_network_address_get_port_func(GSocketConnectable* conn);
typedef void g_strfreev_func(char** proxies);
typedef void g_clear_error_func(GError **error_p);

static g_proxy_resolver_get_default_func* g_proxy_resolver_get_default = NULL;
static g_proxy_resolver_lookup_func* g_proxy_resolver_lookup = NULL;
static g_network_address_parse_uri_func* g_network_address_parse_uri = NULL;
static g_network_address_get_hostname_func* g_network_address_get_hostname = NULL;
static g_network_address_get_port_func* g_network_address_get_port = NULL;
static g_strfreev_func* g_strfreev = NULL;
static g_clear_error_func* g_clear_error = NULL;

static void* gconf_client = NULL;
static int use_gproxyResolver = 0;
static int use_gconf = 0;


static int initGConf() {
    /**
     * Let's try to load GConf-2 library
     */
    if (dlopen(JNI_LIB_NAME("gconf-2"), RTLD_GLOBAL | RTLD_LAZY) != NULL ||
        dlopen(VERSIONED_JNI_LIB_NAME("gconf-2", "4"),
               RTLD_GLOBAL | RTLD_LAZY) != NULL)
    {
        /*
         * Now let's get pointer to the functions we need.
         */
        my_g_type_init_func =
                (g_type_init_func*)dlsym(RTLD_DEFAULT, "g_type_init");
        my_get_default_func =
                (gconf_client_get_default_func*)dlsym(RTLD_DEFAULT,
                        "gconf_client_get_default");

        if (my_g_type_init_func != NULL && my_get_default_func != NULL) {
            /**
             * Try to connect to GConf.
             */
            (*my_g_type_init_func)();
            gconf_client = (*my_get_default_func)();
            if (gconf_client != NULL) {
                my_get_string_func =
                        (gconf_client_get_string_func*)dlsym(RTLD_DEFAULT,
                                "gconf_client_get_string");
                my_get_int_func =
                        (gconf_client_get_int_func*)dlsym(RTLD_DEFAULT,
                                "gconf_client_get_int");
                my_get_bool_func =
                        (gconf_client_get_bool_func*)dlsym(RTLD_DEFAULT,
                                "gconf_client_get_bool");
                if (my_get_int_func != NULL && my_get_string_func != NULL &&
                        my_get_bool_func != NULL)
                {
                    /**
                     * We did get all we need. Let's enable the System Proxy Settings.
                     */
                    return 1;
                }
            }
        }
    }
    return 0;
}

static jobjectArray getProxyByGConf(JNIEnv *env, const char* cproto,
                                    const char* chost)
{
    char *phost = NULL;
    char *mode = NULL;
    int pport = 0;
    int use_proxy = 0;
    int use_same_proxy = 0;
    jobjectArray proxy_array = NULL;
    jfieldID ptype_ID = ptype_httpID;

    /* We only check manual proxy configurations */
    mode =  (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
    if (mode && !strcasecmp(mode, "manual")) {
        /*
         * Even though /system/http_proxy/use_same_proxy is no longer used,
         * its value is set to false in gnome 3. So it is not harmful to check
         * it first in case jdk is used with an old gnome.
         */
        use_same_proxy = (*my_get_bool_func)(gconf_client, "/system/http_proxy/use_same_proxy", NULL);
        if (use_same_proxy) {
            phost = (*my_get_string_func)(gconf_client, "/system/http_proxy/host", NULL);
            pport = (*my_get_int_func)(gconf_client, "/system/http_proxy/port", NULL);
            use_proxy = (phost != NULL && pport != 0);
        }

        if (!use_proxy) {
            /**
             * HTTP:
             * /system/http_proxy/use_http_proxy (boolean) - it's no longer used
             * /system/http_proxy/host (string)
             * /system/http_proxy/port (integer)
             */
            if (strcasecmp(cproto, "http") == 0) {
                phost = (*my_get_string_func)(gconf_client, "/system/http_proxy/host", NULL);
                pport = (*my_get_int_func)(gconf_client, "/system/http_proxy/port", NULL);
                use_proxy = (phost != NULL && pport != 0);
            }

            /**
             * HTTPS:
             * /system/proxy/mode (string) [ "manual" means use proxy settings ]
             * /system/proxy/secure_host (string)
             * /system/proxy/secure_port (integer)
             */
            if (strcasecmp(cproto, "https") == 0) {
                phost = (*my_get_string_func)(gconf_client, "/system/proxy/secure_host", NULL);
                pport = (*my_get_int_func)(gconf_client, "/system/proxy/secure_port", NULL);
                use_proxy = (phost != NULL && pport != 0);
            }

            /**
             * FTP:
             * /system/proxy/mode (string) [ "manual" means use proxy settings ]
             * /system/proxy/ftp_host (string)
             * /system/proxy/ftp_port (integer)
             */
            if (strcasecmp(cproto, "ftp") == 0) {
                phost = (*my_get_string_func)(gconf_client, "/system/proxy/ftp_host", NULL);
                pport = (*my_get_int_func)(gconf_client, "/system/proxy/ftp_port", NULL);
                use_proxy = (phost != NULL && pport != 0);
            }

            /**
             * SOCKS:
             * /system/proxy/mode (string) [ "manual" means use proxy settings ]
             * /system/proxy/socks_host (string)
             * /system/proxy/socks_port (integer)
             */
            if (strcasecmp(cproto, "socks") == 0) {
                phost = (*my_get_string_func)(gconf_client, "/system/proxy/socks_host", NULL);
                pport = (*my_get_int_func)(gconf_client, "/system/proxy/socks_port", NULL);
                use_proxy = (phost != NULL && pport != 0);
                if (use_proxy)
                    ptype_ID = ptype_socksID;
            }
        }
    }

    if (use_proxy) {
        char *noproxyfor;
        char *s;

        /**
         * Check for the exclude list (aka "No Proxy For" list).
         * It's a list of comma separated suffixes (e.g. domain name).
         */
        noproxyfor = (*my_get_string_func)(gconf_client, "/system/proxy/no_proxy_for", NULL);
        if (noproxyfor != NULL) {
            char *tmpbuf[512];
            s = strtok_r(noproxyfor, ", ", tmpbuf);

            while (s != NULL && strlen(s) <= strlen(chost)) {
                if (strcasecmp(chost+(strlen(chost) - strlen(s)), s) == 0) {
                    /**
                     * the URL host name matches with one of the sufixes,
                     * therefore we have to use a direct connection.
                     */
                    use_proxy = 0;
                    break;
                }
                s = strtok_r(NULL, ", ", tmpbuf);
            }
        }
        if (use_proxy) {
            jobject proxy = NULL;
            /* create a proxy array with one element. */
            proxy_array = (*env)->NewObjectArray(env, 1, proxy_class, NULL);
            if (proxy_array == NULL || (*env)->ExceptionCheck(env)) {
                return NULL;
            }
            proxy = createProxy(env, ptype_ID, phost, pport);
            if (proxy == NULL || (*env)->ExceptionCheck(env)) {
                return NULL;
            }
            (*env)->SetObjectArrayElement(env, proxy_array, 0, proxy);
            if ((*env)->ExceptionCheck(env)) {
                return NULL;
            }
        }
    }

    return proxy_array;
}

static int initGProxyResolver() {
    void *gio_handle;

    gio_handle = dlopen("libgio-2.0.so", RTLD_LAZY);
    if (!gio_handle) {
        gio_handle = dlopen("libgio-2.0.so.0", RTLD_LAZY);
        if (!gio_handle) {
            return 0;
        }
    }

    my_g_type_init_func = (g_type_init_func*)dlsym(gio_handle, "g_type_init");

    g_proxy_resolver_get_default =
            (g_proxy_resolver_get_default_func*)dlsym(gio_handle,
                    "g_proxy_resolver_get_default");

    g_proxy_resolver_lookup =
            (g_proxy_resolver_lookup_func*)dlsym(gio_handle,
                    "g_proxy_resolver_lookup");

    g_network_address_parse_uri =
            (g_network_address_parse_uri_func*)dlsym(gio_handle,
                    "g_network_address_parse_uri");

    g_network_address_get_hostname =
            (g_network_address_get_hostname_func*)dlsym(gio_handle,
                    "g_network_address_get_hostname");

    g_network_address_get_port =
            (g_network_address_get_port_func*)dlsym(gio_handle,
                    "g_network_address_get_port");

    g_strfreev = (g_strfreev_func*)dlsym(gio_handle, "g_strfreev");

    g_clear_error = (g_clear_error_func*)dlsym(gio_handle, "g_clear_error");

    if (!my_g_type_init_func ||
        !g_proxy_resolver_get_default ||
        !g_proxy_resolver_lookup ||
        !g_network_address_parse_uri ||
        !g_network_address_get_hostname ||
        !g_network_address_get_port ||
        !g_strfreev ||
        !g_clear_error)
    {
        dlclose(gio_handle);
        return 0;
    }

    (*my_g_type_init_func)();
    return 1;
}

static jobjectArray getProxyByGProxyResolver(JNIEnv *env, const char *cproto,
                                             const char *chost)
{
    GProxyResolver* resolver = NULL;
    char** proxies = NULL;
    GError *error = NULL;

    size_t protoLen = 0;
    size_t hostLen = 0;
    char* uri = NULL;

    jobjectArray proxy_array = NULL;

    resolver = (*g_proxy_resolver_get_default)();
    if (resolver == NULL) {
        return NULL;
    }

    /* Construct the uri, cproto + "://" + chost */
    protoLen = strlen(cproto);
    hostLen = strlen(chost);
    uri = malloc(protoLen + hostLen + 4);
    if (!uri) {
        /* Out of memory */
        return NULL;
    }
    memcpy(uri, cproto, protoLen);
    memcpy(uri + protoLen, "://", 3);
    memcpy(uri + protoLen + 3, chost, hostLen + 1);

    /*
     * Looks into the system proxy configuration to determine what proxy,
     * if any, to use to connect to uri. The returned proxy URIs are of
     * the form <protocol>://[user[:password]@]host:port or direct://,
     * where <protocol> could be http, rtsp, socks or other proxying protocol.
     * direct:// is used when no proxy is needed.
     */
    proxies = (*g_proxy_resolver_lookup)(resolver, uri, NULL, &error);
    free(uri);

    if (proxies) {
        if (!error) {
            int i;
            int nr_proxies = 0;
            char** p = proxies;
            /* count the elements in the null terminated string vector. */
            while (*p) {
                nr_proxies++;
                p++;
            }
            /* create a proxy array that has to be filled. */
            proxy_array = (*env)->NewObjectArray(env, nr_proxies, proxy_class, NULL);
            if (proxy_array != NULL && !(*env)->ExceptionCheck(env)) {
                for (i = 0; proxies[i]; i++) {
                    if (strncmp(proxies[i], "direct://", 9)) {
                        GSocketConnectable* conn =
                                (*g_network_address_parse_uri)(proxies[i], 0,
                                                               &error);
                        if (conn && !error) {
                            const char *phost = NULL;
                            unsigned short pport = 0;
                            phost = (*g_network_address_get_hostname)(conn);
                            pport = (*g_network_address_get_port)(conn);
                            if (phost && pport > 0) {
                                jobject proxy = NULL;
                                jfieldID ptype_ID = ptype_httpID;
                                if (!strncmp(proxies[i], "socks", 5))
                                    ptype_ID = ptype_socksID;

                                proxy = createProxy(env, ptype_ID, phost, pport);
                                if (proxy == NULL || (*env)->ExceptionCheck(env)) {
                                    proxy_array = NULL;
                                    break;
                                }
                                (*env)->SetObjectArrayElement(env, proxy_array, i, proxy);
                                if ((*env)->ExceptionCheck(env)) {
                                    proxy_array = NULL;
                                    break;
                                }
                            } else {
                                proxy_array = NULL;
                                break;
                            }
                        } else {
                            proxy_array = NULL;
                            break;
                        }
                    } else {
                        /* direct connection - no proxy */
                        jobject proxy = (*env)->GetStaticObjectField(env, proxy_class,
                                                                     pr_no_proxyID);
                        if (proxy == NULL || (*env)->ExceptionCheck(env)) {
                            proxy_array = NULL;
                            break;
                        }
                        (*env)->SetObjectArrayElement(env, proxy_array, i, proxy);
                        if ((*env)->ExceptionCheck(env)) {
                            proxy_array = NULL;
                            break;
                        }
                    }
                }
            }
        }
        (*g_strfreev)(proxies);
         // as per API doc, g_clear_error doesn't complain if error is NULL, so it's safe to
         // call without null checks
        (*g_clear_error)(&error);
    }

    return proxy_array;
}

/*
 * Class:     sun_net_spi_DefaultProxySelector
 * Method:    init
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL
Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
    use_gproxyResolver = initGProxyResolver();
    if (!use_gproxyResolver)
        use_gconf = initGConf();

    if (use_gproxyResolver || use_gconf) {
        if (initJavaClass(env))
            return JNI_TRUE;
    }
    return JNI_FALSE;
}

/*
 * Class:     sun_net_spi_DefaultProxySelector
 * Method:    getSystemProxies
 * Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
 */
JNIEXPORT jobjectArray JNICALL
Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
                                                       jobject this,
                                                       jstring proto,
                                                       jstring host)
{
    const char* cproto;
    const char* chost;

    jboolean isProtoCopy;
    jboolean isHostCopy;

    jobjectArray proxyArray = NULL;

    cproto = (*env)->GetStringUTFChars(env, proto, &isProtoCopy);

    if (cproto != NULL && (use_gproxyResolver || use_gconf)) {
        chost = (*env)->GetStringUTFChars(env, host, &isHostCopy);
        if (chost != NULL) {
            if (use_gproxyResolver)
                proxyArray = getProxyByGProxyResolver(env, cproto, chost);
            else if (use_gconf)
                proxyArray = getProxyByGConf(env, cproto, chost);
            if (isHostCopy == JNI_TRUE)
                (*env)->ReleaseStringUTFChars(env, host, chost);
        }
        if (isProtoCopy == JNI_TRUE)
            (*env)->ReleaseStringUTFChars(env, proto, cproto);
    }
    return proxyArray;
}

