1 /* 2 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <windows.h> 27 #include "jni.h" 28 #include "jni_util.h" 29 #include "jvm.h" 30 #include "jlong.h" 31 #include "sun_net_spi_DefaultProxySelector.h" 32 33 /** 34 * These functions are used by the sun.net.spi.DefaultProxySelector class 35 * to access some platform specific settings. 36 * This is the Windows code using the registry settings. 37 */ 38 39 static jclass proxy_class; 40 static jclass isaddr_class; 41 static jclass ptype_class; 42 static jmethodID isaddr_createUnresolvedID; 43 static jmethodID proxy_ctrID; 44 static jfieldID pr_no_proxyID; 45 static jfieldID ptype_httpID; 46 static jfieldID ptype_socksID; 47 48 #define CHECK_NULL(X) { if ((X) == NULL) fprintf (stderr,"JNI errror at line %d\n", __LINE__); } 49 50 51 /* 52 * Class: sun_net_spi_DefaultProxySelector 53 * Method: init 54 * Signature: ()Z 55 */ 56 JNIEXPORT jboolean JNICALL 57 Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) { 58 HKEY hKey; 59 LONG ret; 60 jclass cls; 61 62 /** 63 * Get all the method & field IDs for later use. 64 */ 65 CHECK_NULL(cls = (*env)->FindClass(env,"java/net/Proxy")); 66 proxy_class = (*env)->NewGlobalRef(env, cls); 67 CHECK_NULL(cls = (*env)->FindClass(env,"java/net/Proxy$Type")); 68 ptype_class = (*env)->NewGlobalRef(env, cls); 69 CHECK_NULL(cls = (*env)->FindClass(env, "java/net/InetSocketAddress")); 70 isaddr_class = (*env)->NewGlobalRef(env, cls); 71 proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>", "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V"); 72 pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY", "Ljava/net/Proxy;"); 73 ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP", "Ljava/net/Proxy$Type;"); 74 ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS", "Ljava/net/Proxy$Type;"); 75 isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class, "createUnresolved", "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;"); 76 77 /** 78 * Let's see if we can find the proper Registry entry. 79 */ 80 ret = RegOpenKeyEx(HKEY_CURRENT_USER, 81 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 82 0, KEY_READ, (PHKEY)&hKey); 83 if (ret == ERROR_SUCCESS) { 84 RegCloseKey(hKey); 85 /** 86 * It worked, we can probably rely on it then. 87 */ 88 return JNI_TRUE; 89 } 90 91 return JNI_FALSE; 92 } 93 94 #define MAX_STR_LEN 1024 95 96 /* 97 * Class: sun_net_spi_DefaultProxySelector 98 * Method: getSystemProxy 99 * Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy; 100 */ 101 JNIEXPORT jobject JNICALL 102 Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env, 103 jobject this, 104 jstring proto, 105 jstring host) 106 { 107 jobject isa = NULL; 108 jobject proxy = NULL; 109 jobject type_proxy = NULL; 110 jobject no_proxy = NULL; 111 jboolean isCopy; 112 HKEY hKey; 113 LONG ret; 114 const char* cproto; 115 const char* urlhost; 116 char pproto[MAX_STR_LEN]; 117 char regserver[MAX_STR_LEN]; 118 char override[MAX_STR_LEN]; 119 char *s, *s2; 120 int pport = 0; 121 int defport = 0; 122 char *phost; 123 124 /** 125 * Let's opem the Registry entry. We'll check a few values in it: 126 * 127 * - ProxyEnable: 0 means no proxy, 1 means use the proxy 128 * - ProxyServer: a string that can take 2 forms: 129 * "server[:port]" 130 * or 131 * "protocol1=server[:port][;protocol2=server[:port]]..." 132 * - ProxyOverride: a string containing a list of prefixes for hostnames. 133 * e.g.: hoth;localhost;<local> 134 */ 135 ret = RegOpenKeyEx(HKEY_CURRENT_USER, 136 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 137 0, KEY_READ, (PHKEY)&hKey); 138 if (ret == ERROR_SUCCESS) { 139 DWORD dwLen; 140 DWORD dwProxyEnabled; 141 ULONG ulType; 142 dwLen = sizeof(dwProxyEnabled); 143 144 /** 145 * Let's see if the proxy settings are to be used. 146 */ 147 ret = RegQueryValueEx(hKey, "ProxyEnable", NULL, &ulType, 148 (LPBYTE)&dwProxyEnabled, &dwLen); 149 if ((ret == ERROR_SUCCESS) && (dwProxyEnabled > 0)) { 150 /* 151 * Yes, ProxyEnable == 1 152 */ 153 dwLen = sizeof(override); 154 override[0] = 0; 155 ret = RegQueryValueEx(hKey, "ProxyOverride", NULL, &ulType, 156 (LPBYTE)&override, &dwLen); 157 dwLen = sizeof(regserver); 158 regserver[0] = 0; 159 ret = RegQueryValueEx(hKey, "ProxyServer", NULL, &ulType, 160 (LPBYTE)®server, &dwLen); 161 RegCloseKey(hKey); 162 if (ret == ERROR_SUCCESS) { 163 if (strlen(override) > 0) { 164 /** 165 * we did get ProxyServer and may have an override. 166 * So let's check the override list first, by walking down the list 167 * The semicolons (;) separated entries have to be matched with the 168 * the beginning of the hostname. 169 */ 170 s = strtok(override, "; "); 171 urlhost = (*env)->GetStringUTFChars(env, host, &isCopy); 172 while (s != NULL) { 173 if (strncmp(s, urlhost, strlen(s)) == 0) { 174 /** 175 * the URL host name matches with one of the prefixes, 176 * therefore we have to use a direct connection. 177 */ 178 if (isCopy == JNI_TRUE) 179 (*env)->ReleaseStringUTFChars(env, host, urlhost); 180 goto noproxy; 181 } 182 s = strtok(NULL, "; "); 183 } 184 if (isCopy == JNI_TRUE) 185 (*env)->ReleaseStringUTFChars(env, host, urlhost); 186 } 187 188 cproto = (*env)->GetStringUTFChars(env, proto, &isCopy); 189 if (cproto == NULL) 190 goto noproxy; 191 192 /* 193 * Set default port value & proxy type from protocol. 194 */ 195 if ((strcmp(cproto, "http") == 0) || 196 (strcmp(cproto, "ftp") == 0) || 197 (strcmp(cproto, "gopher") == 0)) 198 defport = 80; 199 if (strcmp(cproto, "https") == 0) 200 defport = 443; 201 if (strcmp(cproto, "socks") == 0) { 202 defport = 1080; 203 type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID); 204 } else { 205 type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID); 206 } 207 208 sprintf(pproto,"%s=", cproto); 209 if (isCopy == JNI_TRUE) 210 (*env)->ReleaseStringUTFChars(env, proto, cproto); 211 /** 212 * Let's check the protocol specific form first. 213 */ 214 if ((s = strstr(regserver, pproto)) != NULL) { 215 s += strlen(pproto); 216 } else { 217 /** 218 * If we couldn't find *this* protocol but the string is in the 219 * protocol specific format, then don't use proxy 220 */ 221 if (strchr(regserver, '=') != NULL) 222 goto noproxy; 223 s = regserver; 224 } 225 s2 = strchr(s, ';'); 226 if (s2 != NULL) 227 *s2 = 0; 228 229 /** 230 * Is there a port specified? 231 */ 232 s2 = strchr(s, ':'); 233 if (s2 != NULL) { 234 *s2 = 0; 235 s2++; 236 sscanf(s2, "%d", &pport); 237 } 238 phost = s; 239 240 if (phost != NULL) { 241 /** 242 * Let's create the appropriate Proxy object then. 243 */ 244 jstring jhost; 245 if (pport == 0) 246 pport = defport; 247 jhost = (*env)->NewStringUTF(env, phost); 248 isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport); 249 proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa); 250 return proxy; 251 } 252 } 253 } else { 254 /* ProxyEnable == 0 or Query failed */ 255 /* close the handle to the registry key */ 256 RegCloseKey(hKey); 257 } 258 } 259 260 noproxy: 261 no_proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID); 262 return no_proxy; 263 } --- EOF ---