ProxyDetect.hx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Copyright (C)2005-2012 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. package neko.net;
  23. typedef ProxySettings = {
  24. var host : String;
  25. var port : Int;
  26. var auth : {
  27. var user : String;
  28. var pass : String;
  29. };
  30. }
  31. class ProxyDetect {
  32. static function parseSettings( settings : String ) {
  33. var r = ~/^([^:]+):([^@]*)@([^:]+):([0-9]+)$/;
  34. if( r.match(settings) )
  35. return {
  36. auth : {
  37. user : r.matched(1),
  38. pass : r.matched(2),
  39. },
  40. host : r.matched(3),
  41. port : Std.parseInt(r.matched(4)),
  42. };
  43. var r = ~/^([^:]+):([0-9]+)$/;
  44. if( !r.match(settings) ) {
  45. var r2 = ~/http=([^:]+):([0-9]+)/;
  46. if( !r2.match(settings) )
  47. throw "Invalid settings '"+settings+"'";
  48. r = r2;
  49. }
  50. return {
  51. host : r.matched(1),
  52. port : Std.parseInt(r.matched(2)),
  53. auth : null,
  54. };
  55. }
  56. static function detectFF( basedir : String ) {
  57. var files = try sys.FileSystem.readDirectory(basedir) catch( e : Dynamic ) return null;
  58. var profile = null;
  59. for( f in files )
  60. if( f.substr(-8) == ".default" ) {
  61. profile = f;
  62. break;
  63. }
  64. if( profile == null )
  65. return null;
  66. var prefs = sys.io.File.getContent(basedir+"/"+profile+"/prefs.js");
  67. // enabled ?
  68. var r = ~/user_pref\("network\.proxy\.type", 1\);/;
  69. if( !r.match(prefs) )
  70. return null;
  71. // prefs
  72. var r = ~/user_pref\("network\.proxy\.http", "([^"]+)"\);/;
  73. if( !r.match(prefs) )
  74. return null;
  75. var host = r.matched(1);
  76. var r = ~/user_pref\("network\.proxy\.http_port", ([0-9]+)\);/;
  77. if( !r.match(prefs) )
  78. return null;
  79. var port = r.matched(1);
  80. return parseSettings(host+":"+port);
  81. }
  82. static function detectIE() {
  83. var dir = Sys.getEnv("TMP");
  84. if( dir == null )
  85. dir = ".";
  86. var temp = dir + "/proxy.txt";
  87. if( Sys.command('regedit /E "'+temp+'" "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"') != 0 ) {
  88. // might fail without appropriate rights
  89. return null;
  90. }
  91. // it's possible that if registry access was disabled the proxy file is not created
  92. var content = try sys.io.File.getContent(temp) catch( e : Dynamic ) return null;
  93. sys.FileSystem.deleteFile(temp);
  94. // turn 16-bit string into 8-bit one
  95. var b = new StringBuf();
  96. var p = 0;
  97. while( p < content.length ) {
  98. b.addChar(content.charCodeAt(p));
  99. p += 2;
  100. }
  101. content = b.toString();
  102. // enabled ?
  103. var renabled = ~/"ProxyEnable"=dword:0000000(0|1)/;
  104. if( !renabled.match(content) )
  105. return null;
  106. if( renabled.matched(1) == "0" )
  107. return null;
  108. // value ?
  109. var rproxy = ~/"ProxyServer"="([^"]+)"/;
  110. if( !rproxy.match(content) )
  111. return null;
  112. return parseSettings(rproxy.matched(1));
  113. }
  114. static function parseOSXConfiguration(xml : Xml) : Dynamic {
  115. switch( xml.nodeName ) {
  116. case "dict":
  117. var o = {};
  118. var it = xml.elements();
  119. for( x in it ) {
  120. if( x.nodeName != "key" ) throw "Missing key";
  121. var v = x.firstChild().nodeValue;
  122. var r = parseOSXConfiguration(it.next());
  123. Reflect.setField(o,v,r);
  124. }
  125. return o;
  126. case "string":
  127. return xml.firstChild().nodeValue;
  128. case "integer":
  129. return Std.parseInt(xml.firstChild().nodeValue);
  130. case "array":
  131. var a = new Array();
  132. for( x in xml.elements() )
  133. a.push(parseOSXConfiguration(x));
  134. return a;
  135. case "true":
  136. return true;
  137. case "false":
  138. return false;
  139. case "data":
  140. return xml.firstChild().nodeValue;
  141. default:
  142. throw "Invalid value type '"+xml.nodeName+"'";
  143. }
  144. }
  145. static function detectOSX() {
  146. var prefs = sys.io.File.getContent("/Library/Preferences/SystemConfiguration/preferences.plist");
  147. var xml = Xml.parse(prefs).firstElement().firstElement(); // plist/dict
  148. var data : Dynamic = parseOSXConfiguration(xml);
  149. for( nsname in Reflect.fields(data.NetworkServices) ) {
  150. var ns : Dynamic = Reflect.field(data.NetworkServices,nsname);
  151. if( ns.Proxies != null && ns.Proxies.HTTPEnable == 1 )
  152. return { host : ns.Proxies.HTTPProxy, port : ns.Proxies.HTTPPort, auth : null };
  153. }
  154. return null;
  155. }
  156. static function detectAll() : ProxySettings {
  157. switch( Sys.systemName() ) {
  158. case "Windows":
  159. try {
  160. var ffdir = Sys.getEnv("APPDATA")+"/Mozilla/Firefox/Profiles";
  161. var p = detectFF(ffdir);
  162. if( p == null )
  163. throw "No Firefox proxy";
  164. return p;
  165. } catch( e : Dynamic ) {
  166. return detectIE();
  167. }
  168. case "Mac":
  169. var p = detectOSX();
  170. if( p != null )
  171. return p;
  172. var ffdir = Sys.getEnv("HOME")+"/Library/Application Support/Firefox/Profiles";
  173. return detectFF(ffdir);
  174. case "Linux":
  175. var ffdir = Sys.getEnv("HOME")+"/.mozilla/firefox";
  176. return detectFF(ffdir);
  177. default:
  178. throw "This system is not supported";
  179. }
  180. }
  181. static var save : { r : ProxySettings } = null;
  182. public static function detect() {
  183. if( save == null )
  184. save = { r : try detectAll() catch( e : Dynamic ) null };
  185. return save.r;
  186. }
  187. static function main() {
  188. trace(detect());
  189. }
  190. }