OSDN Git Service

FavoriteTweet/UnfavoriteTweetを使用したFav追加・削除に対応
[opentween/open-tween.git] / OpenTween / InternetSecurityManager.cs
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.
9 //
10 // This file is part of OpenTween.
11 //
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)
15 // any later version.
16 //
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
20 // for more details.
21 //
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.
26
27 #nullable enable
28 #pragma warning disable SA1310
29
30 using System;
31 using System.Collections.Generic;
32 using System.Linq;
33 using System.Runtime.InteropServices;
34 using System.Runtime.InteropServices.ComTypes;
35 using System.Text;
36 using System.Text.RegularExpressions;
37 using System.Threading;
38 using System.Windows.Forms;
39
40 namespace OpenTween
41 {
42     public class InternetSecurityManager : WebBrowserAPI.IServiceProvider, WebBrowserAPI.IInternetSecurityManager
43     {
44         #region "HRESULT"
45         private enum HRESULT
46         {
47             S_OK = 0x0,
48             S_FALSE = 0x1,
49             E_NOTIMPL = unchecked((int)0x80004001),
50             E_NOINTERFACE = unchecked((int)0x80004002),
51         }
52         #endregion
53
54         [Flags]
55         public enum POLICY
56         {
57             ALLOW_ACTIVEX = 0x1,
58             ALLOW_SCRIPT = 0x2,
59         }
60
61         private readonly object ocx = new();
62         private readonly WebBrowserAPI.IServiceProvider ocxServiceProvider;
63         private readonly IntPtr profferServicePtr = new();
64         private readonly WebBrowserAPI.IProfferService profferService = null!;
65
66         public POLICY SecurityPolicy { get; set; } = 0;
67
68         public InternetSecurityManager(WebBrowser webBrowser)
69         {
70             // ActiveXコントロール取得
71             webBrowser.Url = new Uri("about:blank"); // ActiveXを初期化する
72
73             do
74             {
75                 Thread.Sleep(100);
76                 Application.DoEvents();
77             }
78             while (webBrowser.ReadyState != WebBrowserReadyState.Complete);
79
80             this.ocx = webBrowser.ActiveXInstance;
81
82             // IServiceProvider.QueryService() を使って IProfferService を取得
83             this.ocxServiceProvider = (WebBrowserAPI.IServiceProvider)this.ocx;
84
85             try
86             {
87                 this.ocxServiceProvider.QueryService(
88                     ref WebBrowserAPI.SID_SProfferService,
89                     ref WebBrowserAPI.IID_IProfferService,
90                     out this.profferServicePtr);
91             }
92             catch (SEHException ex)
93             {
94                 MyCommon.TraceOut(ex, "ocxServiceProvider.QueryService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine);
95                 return;
96             }
97             catch (ExternalException ex)
98             {
99                 MyCommon.TraceOut(ex, "ocxServiceProvider.QueryService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine);
100                 return;
101             }
102
103             this.profferService = (WebBrowserAPI.IProfferService)Marshal.GetObjectForIUnknown(this.profferServicePtr);
104
105             // IProfferService.ProfferService() を使って
106             // 自分を IInternetSecurityManager として提供
107             try
108             {
109                 this.profferService.ProfferService(
110                     ref WebBrowserAPI.IID_IInternetSecurityManager, this, out var cookie);
111             }
112             catch (SEHException ex)
113             {
114                 MyCommon.TraceOut(ex, "IProfferSerive.ProfferService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine);
115                 return;
116             }
117             catch (ExternalException ex)
118             {
119                 MyCommon.TraceOut(ex, "IProfferSerive.ProfferService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine);
120                 return;
121             }
122         }
123
124         int WebBrowserAPI.IServiceProvider.QueryService(
125             ref Guid guidService,
126             ref Guid riid,
127             out IntPtr ppvObject)
128         {
129             ppvObject = IntPtr.Zero;
130             if (guidService.CompareTo(
131                 WebBrowserAPI.IID_IInternetSecurityManager) == 0)
132             {
133                 // 自分から IID_IInternetSecurityManager を
134                 // QueryInterface して返す
135                 var punk = Marshal.GetIUnknownForObject(this);
136                 return Marshal.QueryInterface(punk, ref riid, out ppvObject);
137             }
138             return (int)HRESULT.E_NOINTERFACE;
139         }
140
141         int WebBrowserAPI.IInternetSecurityManager.GetSecurityId(string pwszUrl, byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved)
142             => WebBrowserAPI.INET_E_DEFAULT_ACTION;
143
144         int WebBrowserAPI.IInternetSecurityManager.GetSecuritySite(out WebBrowserAPI.IInternetSecurityMgrSite? pSite)
145         {
146             pSite = null;
147             return WebBrowserAPI.INET_E_DEFAULT_ACTION;
148         }
149
150         int WebBrowserAPI.IInternetSecurityManager.GetZoneMappings(int dwZone, ref IEnumString? ppenumstring, int dwFlags)
151         {
152             ppenumstring = null;
153             return WebBrowserAPI.INET_E_DEFAULT_ACTION;
154         }
155
156         int WebBrowserAPI.IInternetSecurityManager.MapUrlToZone(string pwszUrl, out int pdwZone, int dwFlags)
157         {
158             pdwZone = 0;
159             if (pwszUrl == "about:blank") return WebBrowserAPI.INET_E_DEFAULT_ACTION;
160             try
161             {
162                 var urlStr = MyCommon.IDNEncode(pwszUrl);
163                 if (urlStr == null) return WebBrowserAPI.URLPOLICY_DISALLOW;
164                 var url = new Uri(urlStr);
165                 if (url.Scheme == "data")
166                 {
167                     return WebBrowserAPI.URLPOLICY_DISALLOW;
168                 }
169             }
170             catch (Exception)
171             {
172                 return WebBrowserAPI.URLPOLICY_DISALLOW;
173             }
174             return WebBrowserAPI.INET_E_DEFAULT_ACTION;
175         }
176
177         private const byte URLPOLICY_ALLOW = 0;
178
179         int WebBrowserAPI.IInternetSecurityManager.ProcessUrlAction(string pwszUrl, int dwAction, out byte pPolicy, int cbPolicy, byte pContext, int cbContext, int dwFlags, int dwReserved)
180         {
181             pPolicy = URLPOLICY_ALLOW;
182             // スクリプト実行状態かを検査しポリシー設定
183             if (WebBrowserAPI.URLACTION_SCRIPT_MIN <= dwAction &
184                 dwAction <= WebBrowserAPI.URLACTION_SCRIPT_MAX)
185             {
186                 // スクリプト実行状態
187                 if ((this.SecurityPolicy & POLICY.ALLOW_SCRIPT) == POLICY.ALLOW_SCRIPT)
188                 {
189                     pPolicy = WebBrowserAPI.URLPOLICY_ALLOW;
190                 }
191                 else
192                 {
193                     pPolicy = WebBrowserAPI.URLPOLICY_DISALLOW;
194                 }
195                 if (Regex.IsMatch(pwszUrl, @"^https?://((api\.)?twitter\.com/|([a-zA-Z0-9]+\.)?twimg\.com/)")) pPolicy = WebBrowserAPI.URLPOLICY_ALLOW;
196                 return (int)HRESULT.S_OK;
197             }
198             // ActiveX実行状態かを検査しポリシー設定
199             if (WebBrowserAPI.URLACTION_ACTIVEX_MIN <= dwAction &
200                 dwAction <= WebBrowserAPI.URLACTION_ACTIVEX_MAX)
201             {
202                 // ActiveX実行状態
203                 if ((this.SecurityPolicy & POLICY.ALLOW_ACTIVEX) == POLICY.ALLOW_ACTIVEX)
204                 {
205                     pPolicy = WebBrowserAPI.URLPOLICY_ALLOW;
206                 }
207                 else
208                 {
209                     pPolicy = WebBrowserAPI.URLPOLICY_DISALLOW;
210                 }
211                 return (int)HRESULT.S_OK;
212             }
213             // 他のものについてはデフォルト処理
214             return WebBrowserAPI.INET_E_DEFAULT_ACTION;
215         }
216
217         int WebBrowserAPI.IInternetSecurityManager.QueryCustomPolicy(string pwszUrl, ref Guid guidKey, byte ppPolicy, int pcbPolicy, byte pContext, int cbContext, int dwReserved)
218             => WebBrowserAPI.INET_E_DEFAULT_ACTION;
219
220         int WebBrowserAPI.IInternetSecurityManager.SetSecuritySite(WebBrowserAPI.IInternetSecurityMgrSite pSite)
221             => WebBrowserAPI.INET_E_DEFAULT_ACTION;
222
223         int WebBrowserAPI.IInternetSecurityManager.SetZoneMapping(int dwZone, string lpszPattern, int dwFlags)
224             => WebBrowserAPI.INET_E_DEFAULT_ACTION;
225     }
226
227     #region "WebBrowserAPI"
228     internal static class WebBrowserAPI
229     {
230         public static int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011);
231
232         public enum URLZONE
233         {
234             URLZONE_LOCAL_MACHINE = 0,
235             URLZONE_INTRANET = URLZONE_LOCAL_MACHINE + 1,
236             URLZONE_TRUSTED = URLZONE_INTRANET + 1,
237             URLZONE_INTERNET = URLZONE_TRUSTED + 1,
238             URLZONE_UNTRUSTED = URLZONE_INTERNET + 1,
239         }
240
241         public static int URLACTION_MIN = 0x1000;
242
243         public static int URLACTION_DOWNLOAD_MIN = 0x1000;
244         public static int URLACTION_DOWNLOAD_SIGNED_ACTIVEX = 0x1001;
245         public static int URLACTION_DOWNLOAD_UNSIGNED_ACTIVEX = 0x1004;
246         public static int URLACTION_DOWNLOAD_CURR_MAX = 0x1004;
247         public static int URLACTION_DOWNLOAD_MAX = 0x11FF;
248
249         public static int URLACTION_ACTIVEX_MIN = 0x1200;
250         public static int URLACTION_ACTIVEX_RUN = 0x1200;
251         public static int URLPOLICY_ACTIVEX_CHECK_LIST = 0x10000;
252         public static int URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY = 0x1201;
253         public static int URLACTION_ACTIVEX_OVERRIDE_DATA_SAFETY = 0x1202;
254         public static int URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY = 0x1203;
255         public static int URLACTION_SCRIPT_OVERRIDE_SAFETY = 0x1401;
256         public static int URLACTION_ACTIVEX_CONFIRM_NOOBJECTSAFETY = 0x1204;
257         public static int URLACTION_ACTIVEX_TREATASUNTRUSTED = 0x1205;
258         public static int URLACTION_ACTIVEX_NO_WEBOC_SCRIPT = 0x1206;
259         public static int URLACTION_ACTIVEX_CURR_MAX = 0x1206;
260         public static int URLACTION_ACTIVEX_MAX = 0x13FF;
261
262         public static int URLACTION_SCRIPT_MIN = 0x1400;
263         public static int URLACTION_SCRIPT_RUN = 0x1400;
264         public static int URLACTION_SCRIPT_JAVA_USE = 0x1402;
265         public static int URLACTION_SCRIPT_SAFE_ACTIVEX = 0x1405;
266         public static int URLACTION_CROSS_DOMAIN_DATA = 0x1406;
267         public static int URLACTION_SCRIPT_PASTE = 0x1407;
268         public static int URLACTION_SCRIPT_CURR_MAX = 0x1407;
269         public static int URLACTION_SCRIPT_MAX = 0x15FF;
270
271         public static int URLACTION_HTML_MIN = 0x1600;
272         public static int URLACTION_HTML_SUBMIT_FORMS = 0x1601; // aggregate next two
273         public static int URLACTION_HTML_SUBMIT_FORMS_FROM = 0x1602;
274         public static int URLACTION_HTML_SUBMIT_FORMS_TO = 0x1603;
275         public static int URLACTION_HTML_FONT_DOWNLOAD = 0x1604;
276         public static int URLACTION_HTML_JAVA_RUN = 0x1605; // derive from Java custom policy
277         public static int URLACTION_HTML_USERDATA_SAVE = 0x1606;
278         public static int URLACTION_HTML_SUBFRAME_NAVIGATE = 0x1607;
279         public static int URLACTION_HTML_META_REFRESH = 0x1608;
280         public static int URLACTION_HTML_MIXED_CONTENT = 0x1609;
281         public static int URLACTION_HTML_MAX = 0x17FF;
282
283         public static int URLACTION_SHELL_MIN = 0x1800;
284         public static int URLACTION_SHELL_INSTALL_DTITEMS = 0x1800;
285         public static int URLACTION_SHELL_MOVE_OR_COPY = 0x1802;
286         public static int URLACTION_SHELL_FILE_DOWNLOAD = 0x1803;
287         public static int URLACTION_SHELL_VERB = 0x1804;
288         public static int URLACTION_SHELL_WEBVIEW_VERB = 0x1805;
289         public static int URLACTION_SHELL_SHELLEXECUTE = 0x1806;
290         public static int URLACTION_SHELL_CURR_MAX = 0x1806;
291         public static int URLACTION_SHELL_MAX = 0x19FF;
292
293         public static int URLACTION_NETWORK_MIN = 0x1A00;
294
295         public static int URLACTION_CREDENTIALS_USE = 0x1A00;
296         public static int URLPOLICY_CREDENTIALS_SILENT_LOGON_OK = 0x0;
297         public static int URLPOLICY_CREDENTIALS_MUST_PROMPT_USER = 0x10000;
298         public static int URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT = 0x20000;
299         public static int URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY = 0x30000;
300
301         public static int URLACTION_AUTHENTICATE_CLIENT = 0x1A01;
302         public static int URLPOLICY_AUTHENTICATE_CLEARTEXT_OK = 0x0;
303         public static int URLPOLICY_AUTHENTICATE_CHALLENGE_RESPONSE = 0x10000;
304         public static int URLPOLICY_AUTHENTICATE_MUTUAL_ONLY = 0x30000;
305
306         public static int URLACTION_COOKIES = 0x1A02;
307         public static int URLACTION_COOKIES_SESSION = 0x1A03;
308
309         public static int URLACTION_CLIENT_CERT_PROMPT = 0x1A04;
310
311         public static int URLACTION_COOKIES_THIRD_PARTY = 0x1A05;
312         public static int URLACTION_COOKIES_SESSION_THIRD_PARTY = 0x1A06;
313
314         public static int URLACTION_COOKIES_ENABLED = 0x1A10;
315
316         public static int URLACTION_NETWORK_CURR_MAX = 0x1A10;
317         public static int URLACTION_NETWORK_MAX = 0x1BFF;
318
319         public static int URLACTION_JAVA_MIN = 0x1C00;
320         public static int URLACTION_JAVA_PERMISSIONS = 0x1C00;
321         public static int URLPOLICY_JAVA_PROHIBIT = 0x0;
322         public static int URLPOLICY_JAVA_HIGH = 0x10000;
323         public static int URLPOLICY_JAVA_MEDIUM = 0x20000;
324         public static int URLPOLICY_JAVA_LOW = 0x30000;
325         public static int URLPOLICY_JAVA_CUSTOM = 0x800000;
326         public static int URLACTION_JAVA_CURR_MAX = 0x1C00;
327         public static int URLACTION_JAVA_MAX = 0x1CFF;
328
329         // The following Infodelivery actions should have no default policies
330         // in the registry.  They assume that no default policy means fall
331         // back to the global restriction.  If an admin sets a policy per
332         // zone, then it overrides the global restriction.
333
334         public static int URLACTION_INFODELIVERY_MIN = 0x1D00;
335         public static int URLACTION_INFODELIVERY_NO_ADDING_CHANNELS = 0x1D00;
336         public static int URLACTION_INFODELIVERY_NO_EDITING_CHANNELS = 0x1D01;
337         public static int URLACTION_INFODELIVERY_NO_REMOVING_CHANNELS = 0x1D02;
338         public static int URLACTION_INFODELIVERY_NO_ADDING_SUBSCRIPTIONS = 0x1D03;
339         public static int URLACTION_INFODELIVERY_NO_EDITING_SUBSCRIPTIONS = 0x1D04;
340         public static int URLACTION_INFODELIVERY_NO_REMOVING_SUBSCRIPTIONS = 0x1D05;
341         public static int URLACTION_INFODELIVERY_NO_CHANNEL_LOGGING = 0x1D06;
342         public static int URLACTION_INFODELIVERY_CURR_MAX = 0x1D06;
343         public static int URLACTION_INFODELIVERY_MAX = 0x1DFF;
344         public static int URLACTION_CHANNEL_SOFTDIST_MIN = 0x1E00;
345         public static int URLACTION_CHANNEL_SOFTDIST_PERMISSIONS = 0x1E05;
346         public static int URLPOLICY_CHANNEL_SOFTDIST_PROHIBIT = 0x10000;
347         public static int URLPOLICY_CHANNEL_SOFTDIST_PRECACHE = 0x20000;
348         public static int URLPOLICY_CHANNEL_SOFTDIST_AUTOINSTALL = 0x30000;
349         public static int URLACTION_CHANNEL_SOFTDIST_MAX = 0x1EFF;
350
351         // For each action specified above the system maintains
352         // a set of policies for the action.
353         // The only policies supported currently are permissions (i.e. is something allowed)
354         // and logging status.
355         // IMPORTANT: If you are defining your own policies don't overload the meaning of the
356         // loword of the policy. You can use the hiword to store any policy bits which are only
357         // meaningful to your action.
358         // For an example of how to do this look at the URLPOLICY_JAVA above
359
360         // Permissions
361         public static byte URLPOLICY_ALLOW = 0x0;
362         public static byte URLPOLICY_QUERY = 0x1;
363         public static byte URLPOLICY_DISALLOW = 0x3;
364
365         // Notifications are not done when user already queried.
366         public static int URLPOLICY_NOTIFY_ON_ALLOW = 0x10;
367         public static int URLPOLICY_NOTIFY_ON_DISALLOW = 0x20;
368
369         // Logging is done regardless of whether user was queried.
370         public static int URLPOLICY_LOG_ON_ALLOW = 0x40;
371         public static int URLPOLICY_LOG_ON_DISALLOW = 0x80;
372
373         public static int URLPOLICY_MASK_PERMISSIONS = 0xF;
374
375         public static int URLPOLICY_DONTCHECKDLGBOX = 0x100;
376
377         // ----------------------------------------------------------------------
378         // ここ以下は COM Interface の宣言です。
379         public static Guid IID_IProfferService = new("cb728b20-f786-11ce-92ad-00aa00a74cd0");
380         public static Guid SID_SProfferService = new("cb728b20-f786-11ce-92ad-00aa00a74cd0");
381         public static Guid IID_IInternetSecurityManager = new("79eac9ee-baf9-11ce-8c82-00aa004ba90b");
382
383         [ComImport]
384         [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
385         [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
386         public interface IServiceProvider
387         {
388             [PreserveSig]
389             int QueryService([In] ref Guid guidService, [In] ref Guid riid, out IntPtr ppvObject);
390         }
391
392         [ComImport]
393         [Guid("cb728b20-f786-11ce-92ad-00aa00a74cd0")]
394         [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
395         public interface IProfferService
396         {
397             [PreserveSig]
398             int ProfferService([In] ref Guid guidService, [In] IServiceProvider psp, out int cookie);
399
400             [PreserveSig]
401             int RevokeService([In] int cookie);
402         }
403
404         [ComImport]
405         [Guid("79eac9ed-baf9-11ce-8c82-00aa004ba90b")]
406         [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
407         public interface IInternetSecurityMgrSite
408         {
409             [PreserveSig]
410             int GetWindow(out IntPtr hwnd);
411
412             [PreserveSig]
413             int EnableModeless([In, MarshalAs(UnmanagedType.Bool)] bool fEnable);
414         }
415
416         [ComImport]
417         [Guid("79eac9ee-baf9-11ce-8c82-00aa004ba90b")]
418         [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
419         public interface IInternetSecurityManager
420         {
421             [PreserveSig]
422             int SetSecuritySite([In] IInternetSecurityMgrSite pSite);
423
424             [PreserveSig]
425             int GetSecuritySite(out IInternetSecurityMgrSite? pSite);
426
427             [PreserveSig]
428             int MapUrlToZone([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, out int pdwZone, int dwFlags);
429
430             [PreserveSig]
431             int GetSecurityId([MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, [MarshalAs(UnmanagedType.LPArray)] byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved);
432
433             [PreserveSig]
434             int ProcessUrlAction([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, int dwAction, out byte pPolicy, int cbPolicy, byte pContext, int cbContext, int dwFlags, int dwReserved);
435
436             [PreserveSig]
437             int QueryCustomPolicy([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, ref Guid guidKey, byte ppPolicy, int pcbPolicy, byte pContext, int cbContext, int dwReserved);
438
439             [PreserveSig]
440             int SetZoneMapping(int dwZone, [In, MarshalAs(UnmanagedType.LPWStr)] string lpszPattern, int dwFlags);
441
442             [PreserveSig]
443             int GetZoneMappings(int dwZone, ref IEnumString? ppenumstring, int dwFlags);
444         }
445     }
446     #endregion
447 }