1 // OpenTween - Client of Twitter
2 // Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
3 // (c) 2008-2011 Moz (@syo68k)
4 // (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
5 // (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
6 // (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
7 // (c) 2011 Egtra (@egtra) <http://dev.activebasic.com/egtra/>
8 // All rights reserved.
10 // This file is part of OpenTween.
12 // This program is free software; you can redistribute it and/or modify it
13 // under the terms of the GNU General Public License as published by the Free
14 // Software Foundation; either version 3 of the License, or (at your option)
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
24 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
25 // Boston, MA 02110-1301, USA.
28 #pragma warning disable SA1310
31 using System.Collections.Generic;
33 using System.Runtime.InteropServices;
34 using System.Runtime.InteropServices.ComTypes;
36 using System.Text.RegularExpressions;
37 using System.Threading;
38 using System.Windows.Forms;
42 #region "WebBrowserAPI"
43 internal static class WebBrowserAPI
45 public static int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011);
49 URLZONE_LOCAL_MACHINE = 0,
50 URLZONE_INTRANET = URLZONE_LOCAL_MACHINE + 1,
51 URLZONE_TRUSTED = URLZONE_INTRANET + 1,
52 URLZONE_INTERNET = URLZONE_TRUSTED + 1,
53 URLZONE_UNTRUSTED = URLZONE_INTERNET + 1,
56 public static int URLACTION_MIN = 0x1000;
58 public static int URLACTION_DOWNLOAD_MIN = 0x1000;
59 public static int URLACTION_DOWNLOAD_SIGNED_ACTIVEX = 0x1001;
60 public static int URLACTION_DOWNLOAD_UNSIGNED_ACTIVEX = 0x1004;
61 public static int URLACTION_DOWNLOAD_CURR_MAX = 0x1004;
62 public static int URLACTION_DOWNLOAD_MAX = 0x11FF;
64 public static int URLACTION_ACTIVEX_MIN = 0x1200;
65 public static int URLACTION_ACTIVEX_RUN = 0x1200;
66 public static int URLPOLICY_ACTIVEX_CHECK_LIST = 0x10000;
67 public static int URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY = 0x1201;
68 public static int URLACTION_ACTIVEX_OVERRIDE_DATA_SAFETY = 0x1202;
69 public static int URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY = 0x1203;
70 public static int URLACTION_SCRIPT_OVERRIDE_SAFETY = 0x1401;
71 public static int URLACTION_ACTIVEX_CONFIRM_NOOBJECTSAFETY = 0x1204;
72 public static int URLACTION_ACTIVEX_TREATASUNTRUSTED = 0x1205;
73 public static int URLACTION_ACTIVEX_NO_WEBOC_SCRIPT = 0x1206;
74 public static int URLACTION_ACTIVEX_CURR_MAX = 0x1206;
75 public static int URLACTION_ACTIVEX_MAX = 0x13FF;
77 public static int URLACTION_SCRIPT_MIN = 0x1400;
78 public static int URLACTION_SCRIPT_RUN = 0x1400;
79 public static int URLACTION_SCRIPT_JAVA_USE = 0x1402;
80 public static int URLACTION_SCRIPT_SAFE_ACTIVEX = 0x1405;
81 public static int URLACTION_CROSS_DOMAIN_DATA = 0x1406;
82 public static int URLACTION_SCRIPT_PASTE = 0x1407;
83 public static int URLACTION_SCRIPT_CURR_MAX = 0x1407;
84 public static int URLACTION_SCRIPT_MAX = 0x15FF;
86 public static int URLACTION_HTML_MIN = 0x1600;
87 public static int URLACTION_HTML_SUBMIT_FORMS = 0x1601; // aggregate next two
88 public static int URLACTION_HTML_SUBMIT_FORMS_FROM = 0x1602;
89 public static int URLACTION_HTML_SUBMIT_FORMS_TO = 0x1603;
90 public static int URLACTION_HTML_FONT_DOWNLOAD = 0x1604;
91 public static int URLACTION_HTML_JAVA_RUN = 0x1605; // derive from Java custom policy
92 public static int URLACTION_HTML_USERDATA_SAVE = 0x1606;
93 public static int URLACTION_HTML_SUBFRAME_NAVIGATE = 0x1607;
94 public static int URLACTION_HTML_META_REFRESH = 0x1608;
95 public static int URLACTION_HTML_MIXED_CONTENT = 0x1609;
96 public static int URLACTION_HTML_MAX = 0x17FF;
98 public static int URLACTION_SHELL_MIN = 0x1800;
99 public static int URLACTION_SHELL_INSTALL_DTITEMS = 0x1800;
100 public static int URLACTION_SHELL_MOVE_OR_COPY = 0x1802;
101 public static int URLACTION_SHELL_FILE_DOWNLOAD = 0x1803;
102 public static int URLACTION_SHELL_VERB = 0x1804;
103 public static int URLACTION_SHELL_WEBVIEW_VERB = 0x1805;
104 public static int URLACTION_SHELL_SHELLEXECUTE = 0x1806;
105 public static int URLACTION_SHELL_CURR_MAX = 0x1806;
106 public static int URLACTION_SHELL_MAX = 0x19FF;
108 public static int URLACTION_NETWORK_MIN = 0x1A00;
110 public static int URLACTION_CREDENTIALS_USE = 0x1A00;
111 public static int URLPOLICY_CREDENTIALS_SILENT_LOGON_OK = 0x0;
112 public static int URLPOLICY_CREDENTIALS_MUST_PROMPT_USER = 0x10000;
113 public static int URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT = 0x20000;
114 public static int URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY = 0x30000;
116 public static int URLACTION_AUTHENTICATE_CLIENT = 0x1A01;
117 public static int URLPOLICY_AUTHENTICATE_CLEARTEXT_OK = 0x0;
118 public static int URLPOLICY_AUTHENTICATE_CHALLENGE_RESPONSE = 0x10000;
119 public static int URLPOLICY_AUTHENTICATE_MUTUAL_ONLY = 0x30000;
122 public static int URLACTION_COOKIES = 0x1A02;
123 public static int URLACTION_COOKIES_SESSION = 0x1A03;
125 public static int URLACTION_CLIENT_CERT_PROMPT = 0x1A04;
127 public static int URLACTION_COOKIES_THIRD_PARTY = 0x1A05;
128 public static int URLACTION_COOKIES_SESSION_THIRD_PARTY = 0x1A06;
130 public static int URLACTION_COOKIES_ENABLED = 0x1A10;
132 public static int URLACTION_NETWORK_CURR_MAX = 0x1A10;
133 public static int URLACTION_NETWORK_MAX = 0x1BFF;
136 public static int URLACTION_JAVA_MIN = 0x1C00;
137 public static int URLACTION_JAVA_PERMISSIONS = 0x1C00;
138 public static int URLPOLICY_JAVA_PROHIBIT = 0x0;
139 public static int URLPOLICY_JAVA_HIGH = 0x10000;
140 public static int URLPOLICY_JAVA_MEDIUM = 0x20000;
141 public static int URLPOLICY_JAVA_LOW = 0x30000;
142 public static int URLPOLICY_JAVA_CUSTOM = 0x800000;
143 public static int URLACTION_JAVA_CURR_MAX = 0x1C00;
144 public static int URLACTION_JAVA_MAX = 0x1CFF;
147 // The following Infodelivery actions should have no default policies
148 // in the registry. They assume that no default policy means fall
149 // back to the global restriction. If an admin sets a policy per
150 // zone, then it overrides the global restriction.
152 public static int URLACTION_INFODELIVERY_MIN = 0x1D00;
153 public static int URLACTION_INFODELIVERY_NO_ADDING_CHANNELS = 0x1D00;
154 public static int URLACTION_INFODELIVERY_NO_EDITING_CHANNELS = 0x1D01;
155 public static int URLACTION_INFODELIVERY_NO_REMOVING_CHANNELS = 0x1D02;
156 public static int URLACTION_INFODELIVERY_NO_ADDING_SUBSCRIPTIONS = 0x1D03;
157 public static int URLACTION_INFODELIVERY_NO_EDITING_SUBSCRIPTIONS = 0x1D04;
158 public static int URLACTION_INFODELIVERY_NO_REMOVING_SUBSCRIPTIONS = 0x1D05;
159 public static int URLACTION_INFODELIVERY_NO_CHANNEL_LOGGING = 0x1D06;
160 public static int URLACTION_INFODELIVERY_CURR_MAX = 0x1D06;
161 public static int URLACTION_INFODELIVERY_MAX = 0x1DFF;
162 public static int URLACTION_CHANNEL_SOFTDIST_MIN = 0x1E00;
163 public static int URLACTION_CHANNEL_SOFTDIST_PERMISSIONS = 0x1E05;
164 public static int URLPOLICY_CHANNEL_SOFTDIST_PROHIBIT = 0x10000;
165 public static int URLPOLICY_CHANNEL_SOFTDIST_PRECACHE = 0x20000;
166 public static int URLPOLICY_CHANNEL_SOFTDIST_AUTOINSTALL = 0x30000;
167 public static int URLACTION_CHANNEL_SOFTDIST_MAX = 0x1EFF;
169 // For each action specified above the system maintains
170 // a set of policies for the action.
171 // The only policies supported currently are permissions (i.e. is something allowed)
172 // and logging status.
173 // IMPORTANT: If you are defining your own policies don't overload the meaning of the
174 // loword of the policy. You can use the hiword to store any policy bits which are only
175 // meaningful to your action.
176 // For an example of how to do this look at the URLPOLICY_JAVA above
179 public static byte URLPOLICY_ALLOW = 0x0;
180 public static byte URLPOLICY_QUERY = 0x1;
181 public static byte URLPOLICY_DISALLOW = 0x3;
183 // Notifications are not done when user already queried.
184 public static int URLPOLICY_NOTIFY_ON_ALLOW = 0x10;
185 public static int URLPOLICY_NOTIFY_ON_DISALLOW = 0x20;
187 // Logging is done regardless of whether user was queried.
188 public static int URLPOLICY_LOG_ON_ALLOW = 0x40;
189 public static int URLPOLICY_LOG_ON_DISALLOW = 0x80;
191 public static int URLPOLICY_MASK_PERMISSIONS = 0xF;
194 public static int URLPOLICY_DONTCHECKDLGBOX = 0x100;
197 // ----------------------------------------------------------------------
198 // ここ以下は COM Interface の宣言です。
199 public static Guid IID_IProfferService = new Guid("cb728b20-f786-11ce-92ad-00aa00a74cd0");
200 public static Guid SID_SProfferService = new Guid("cb728b20-f786-11ce-92ad-00aa00a74cd0");
201 public static Guid IID_IInternetSecurityManager = new Guid("79eac9ee-baf9-11ce-8c82-00aa004ba90b");
204 [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
205 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
206 public interface IServiceProvider
209 int QueryService([In] ref Guid guidService, [In] ref Guid riid, out IntPtr ppvObject);
213 [Guid("cb728b20-f786-11ce-92ad-00aa00a74cd0")]
214 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
215 public interface IProfferService
218 int ProfferService([In] ref Guid guidService, [In] IServiceProvider psp, out int cookie);
221 int RevokeService([In] int cookie);
225 [Guid("79eac9ed-baf9-11ce-8c82-00aa004ba90b")]
226 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
227 public interface IInternetSecurityMgrSite
230 int GetWindow(out IntPtr hwnd);
233 int EnableModeless([In, MarshalAs(UnmanagedType.Bool)] bool fEnable);
237 [Guid("79eac9ee-baf9-11ce-8c82-00aa004ba90b")]
238 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
239 public interface IInternetSecurityManager
242 int SetSecuritySite([In] IInternetSecurityMgrSite pSite);
245 int GetSecuritySite(out IInternetSecurityMgrSite? pSite);
248 int MapUrlToZone([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, out int pdwZone, int dwFlags);
251 int GetSecurityId([MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, [MarshalAs(UnmanagedType.LPArray)] byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved);
254 int ProcessUrlAction([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, int dwAction, out byte pPolicy, int cbPolicy, byte pContext, int cbContext, int dwFlags, int dwReserved);
257 int QueryCustomPolicy([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, ref Guid guidKey, byte ppPolicy, int pcbPolicy, byte pContext, int cbContext, int dwReserved);
260 int SetZoneMapping(int dwZone, [In, MarshalAs(UnmanagedType.LPWStr)] string lpszPattern, int dwFlags);
263 int GetZoneMappings(int dwZone, ref IEnumString? ppenumstring, int dwFlags);
268 public class InternetSecurityManager : WebBrowserAPI.IServiceProvider, WebBrowserAPI.IInternetSecurityManager
275 E_NOTIMPL = unchecked((int)0x80004001),
276 E_NOINTERFACE = unchecked((int)0x80004002),
287 private readonly object ocx = new object();
288 private readonly WebBrowserAPI.IServiceProvider ocxServiceProvider;
289 private readonly IntPtr profferServicePtr = new IntPtr();
290 private readonly WebBrowserAPI.IProfferService profferService = null!;
292 public POLICY SecurityPolicy { get; set; } = 0;
294 public InternetSecurityManager(WebBrowser webBrowser)
297 webBrowser.Url = new Uri("about:blank"); // ActiveXを初期化する
302 Application.DoEvents();
304 while (webBrowser.ReadyState != WebBrowserReadyState.Complete);
306 this.ocx = webBrowser.ActiveXInstance;
308 // IServiceProvider.QueryService() を使って IProfferService を取得
309 this.ocxServiceProvider = (WebBrowserAPI.IServiceProvider)this.ocx;
313 this.ocxServiceProvider.QueryService(
314 ref WebBrowserAPI.SID_SProfferService,
315 ref WebBrowserAPI.IID_IProfferService,
316 out this.profferServicePtr);
318 catch (SEHException ex)
320 MyCommon.TraceOut(ex, "ocxServiceProvider.QueryService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine);
323 catch (ExternalException ex)
325 MyCommon.TraceOut(ex, "ocxServiceProvider.QueryService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine);
330 this.profferService = (WebBrowserAPI.IProfferService)Marshal.GetObjectForIUnknown(this.profferServicePtr);
332 // IProfferService.ProfferService() を使って
333 // 自分を IInternetSecurityManager として提供
336 this.profferService.ProfferService(
337 ref WebBrowserAPI.IID_IInternetSecurityManager, this, out var cookie);
339 catch (SEHException ex)
341 MyCommon.TraceOut(ex, "IProfferSerive.ProfferService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine);
344 catch (ExternalException ex)
346 MyCommon.TraceOut(ex, "IProfferSerive.ProfferService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine);
351 int WebBrowserAPI.IServiceProvider.QueryService(
352 ref Guid guidService,
354 out IntPtr ppvObject)
357 ppvObject = IntPtr.Zero;
358 if (guidService.CompareTo(
359 WebBrowserAPI.IID_IInternetSecurityManager) == 0)
361 // 自分から IID_IInternetSecurityManager を
362 // QueryInterface して返す
363 var punk = Marshal.GetIUnknownForObject(this);
364 return Marshal.QueryInterface(punk, ref riid, out ppvObject);
366 return (int)HRESULT.E_NOINTERFACE;
369 int WebBrowserAPI.IInternetSecurityManager.GetSecurityId(string pwszUrl, byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved)
370 => WebBrowserAPI.INET_E_DEFAULT_ACTION;
372 int WebBrowserAPI.IInternetSecurityManager.GetSecuritySite(out WebBrowserAPI.IInternetSecurityMgrSite? pSite)
375 return WebBrowserAPI.INET_E_DEFAULT_ACTION;
378 int WebBrowserAPI.IInternetSecurityManager.GetZoneMappings(int dwZone, ref IEnumString? ppenumstring, int dwFlags)
381 return WebBrowserAPI.INET_E_DEFAULT_ACTION;
384 int WebBrowserAPI.IInternetSecurityManager.MapUrlToZone(string pwszUrl, out int pdwZone, int dwFlags)
387 if (pwszUrl == "about:blank") return WebBrowserAPI.INET_E_DEFAULT_ACTION;
390 var urlStr = MyCommon.IDNEncode(pwszUrl);
391 if (urlStr == null) return WebBrowserAPI.URLPOLICY_DISALLOW;
392 var url = new Uri(urlStr);
393 if (url.Scheme == "data")
395 return WebBrowserAPI.URLPOLICY_DISALLOW;
400 return WebBrowserAPI.URLPOLICY_DISALLOW;
402 return WebBrowserAPI.INET_E_DEFAULT_ACTION;
405 private const byte URLPOLICY_ALLOW = 0;
407 int WebBrowserAPI.IInternetSecurityManager.ProcessUrlAction(string pwszUrl, int dwAction, out byte pPolicy, int cbPolicy, byte pContext, int cbContext, int dwFlags, int dwReserved)
409 pPolicy = URLPOLICY_ALLOW;
410 // スクリプト実行状態かを検査しポリシー設定
411 if (WebBrowserAPI.URLACTION_SCRIPT_MIN <= dwAction &
412 dwAction <= WebBrowserAPI.URLACTION_SCRIPT_MAX)
415 if ((this.SecurityPolicy & POLICY.ALLOW_SCRIPT) == POLICY.ALLOW_SCRIPT)
417 pPolicy = WebBrowserAPI.URLPOLICY_ALLOW;
421 pPolicy = WebBrowserAPI.URLPOLICY_DISALLOW;
423 if (Regex.IsMatch(pwszUrl, @"^https?://((api\.)?twitter\.com/|([a-zA-Z0-9]+\.)?twimg\.com/)")) pPolicy = WebBrowserAPI.URLPOLICY_ALLOW;
424 return (int)HRESULT.S_OK;
426 // ActiveX実行状態かを検査しポリシー設定
427 if (WebBrowserAPI.URLACTION_ACTIVEX_MIN <= dwAction &
428 dwAction <= WebBrowserAPI.URLACTION_ACTIVEX_MAX)
431 if ((this.SecurityPolicy & POLICY.ALLOW_ACTIVEX) == POLICY.ALLOW_ACTIVEX)
433 pPolicy = WebBrowserAPI.URLPOLICY_ALLOW;
437 pPolicy = WebBrowserAPI.URLPOLICY_DISALLOW;
439 return (int)HRESULT.S_OK;
442 return WebBrowserAPI.INET_E_DEFAULT_ACTION;
445 int WebBrowserAPI.IInternetSecurityManager.QueryCustomPolicy(string pwszUrl, ref Guid guidKey, byte ppPolicy, int pcbPolicy, byte pContext, int cbContext, int dwReserved)
446 => WebBrowserAPI.INET_E_DEFAULT_ACTION;
448 int WebBrowserAPI.IInternetSecurityManager.SetSecuritySite(WebBrowserAPI.IInternetSecurityMgrSite pSite)
449 => WebBrowserAPI.INET_E_DEFAULT_ACTION;
451 int WebBrowserAPI.IInternetSecurityManager.SetZoneMapping(int dwZone, string lpszPattern, int dwFlags)
452 => WebBrowserAPI.INET_E_DEFAULT_ACTION;