├── .gitignore
├── MaterialSkin
├── Animations
│ ├── AnimationDirection.cs
│ ├── AnimationManager.cs
│ └── Animations.cs
├── ColorScheme.cs
├── Controls
│ ├── MaterialCheckbox.cs
│ ├── MaterialContextMenuStrip.cs
│ ├── MaterialDivider.cs
│ ├── MaterialFlatButton.cs
│ ├── MaterialForm.cs
│ ├── MaterialLabel.cs
│ ├── MaterialListView.cs
│ ├── MaterialMenuStrip.cs
│ ├── MaterialProgressBar.cs
│ ├── MaterialRadioButton.cs
│ ├── MaterialRaisedButton.cs
│ ├── MaterialSingleLineTextField.cs
│ ├── MaterialTabControl.cs
│ └── MaterialTabSelector.cs
├── DrawHelper.cs
├── IMaterialControl.cs
├── MaterialSkin.csproj
├── MaterialSkinManager.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
└── Resources
│ ├── Roboto-Medium.ttf
│ └── Roboto-Regular.ttf
├── README.md
├── shadowsocks-csharp.sln
└── shadowsocks-csharp
├── Config
└── Constants.cs
├── Controller
├── FileManager.cs
├── I18N.cs
├── Logging.cs
├── Service
│ ├── AvailabilityStatistics.cs
│ ├── GfwListUpdater.cs
│ ├── Listener.cs
│ ├── PACServer.cs
│ ├── PortForwarder.cs
│ ├── PrivoxyRunner.cs
│ ├── Sip003Plugin.cs
│ ├── TCPRelay.cs
│ ├── UDPRelay.cs
│ └── UpdateChecker.cs
├── ShadowsocksController.cs
├── Strategy
│ ├── BalancingStrategy.cs
│ ├── HighAvailabilityStrategy.cs
│ ├── IStrategy.cs
│ ├── StatisticsStrategy.cs
│ └── StrategyManager.cs
└── System
│ ├── AutoStartup.cs
│ ├── Hotkeys
│ ├── HotkeyCallbacks.cs
│ └── Hotkeys.cs
│ └── SystemProxy.cs
├── Data
├── abp.js.gz
├── libsscrypto.dll.gz
├── mgwz.dll.gz
├── privoxy.exe.gz
├── privoxy_conf.txt
├── proxy.pac.txt.gz
├── sysproxy.exe.gz
├── sysproxy64.exe.gz
└── user-rule.txt
├── Encryption
├── AEAD
│ ├── AEADEncryptor.cs
│ ├── AEADMbedTLSEncryptor.cs
│ └── AEADSodiumEncryptor.cs
├── CircularBuffer
│ └── ByteCircularBuffer.cs
├── DES.cs
├── EncryptorBase.cs
├── EncryptorFactory.cs
├── Exception
│ └── CryptoException.cs
├── IEncryptor.cs
├── MbedTLS.cs
├── RNG.cs
├── Sodium.cs
└── Stream
│ ├── StreamEncryptor.cs
│ ├── StreamMbedTLSEncryptor.cs
│ └── StreamSodiumEncryptor.cs
├── Exceptions
└── AlleyException.cs
├── Extensions
├── JsonExtensions.cs
└── StringExtensions.cs
├── FodyWeavers.xml
├── Model
├── Configuration.cs
├── HotKeyConfig.cs
├── LogViewerConfig.cs
├── ProxyConfig.cs
├── Server.cs
├── ServerNode.cs
├── SiteConfig.cs
├── StatisticsRecord.cs
├── StatisticsStrategyConfiguration.cs
├── SysproxyConfig.cs
└── User.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── DataSources
│ └── Shadowsocks.Model.StatisticsStrategyConfiguration.datasource
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── Proxy
├── DirectConnect.cs
├── HttpProxy.cs
├── IProxy.cs
└── Socks5Proxy.cs
├── Resources
├── flag
│ ├── flag-canada.png
│ ├── flag-china.png
│ ├── flag-finland.png
│ ├── flag-france.png
│ ├── flag-germany.png
│ ├── flag-hongkong.png
│ ├── flag-ireland.png
│ ├── flag-italy.png
│ ├── flag-japan.png
│ ├── flag-korea.png
│ ├── flag-norway.png
│ ├── flag-russia.png
│ ├── flag-spain.png
│ ├── flag-taiwan.png
│ ├── flag-uk.png
│ ├── flag-usa.png
│ └── flag_holland.png
├── ico-check.png
├── ico-in24.png
├── ico-out24.png
├── ico-vip.png
├── ico_connecting.gif
├── ico_connection_stop.png
├── ico_loading.gif
├── logo-white.png
├── logo.png
├── logo32.png
├── logo40.png
└── logo48.png
├── Settings.cs
├── StringEx.cs
├── Util
├── DateHelper.cs
├── ProcessManagement
│ ├── Job.cs
│ └── ThreadUtil.cs
├── Request.cs
├── Sockets
│ ├── LineReader.cs
│ ├── SocketUtil.cs
│ └── WrappedSocket.cs
├── SystemProxy
│ ├── INTERNET_OPTION.cs
│ ├── INTERNET_PER_CONN_OPTION.cs
│ ├── INTERNET_PER_CONN_OPTION_LIST.cs
│ ├── NativeMethods.cs
│ ├── ProxyException.cs
│ ├── RAS.cs
│ ├── Sysproxy.cs
│ └── WinINet.cs
├── Util.cs
├── ValidateHelper.cs
└── ViewUtils.cs
├── View
├── Log.Designer.cs
├── Log.cs
├── Log.resx
├── Login.Designer.cs
├── Login.cs
├── Login.resx
├── Main.Designer.cs
├── Main.cs
├── Main.resx
├── MenuViewController.cs
├── Notice.Designer.cs
├── Notice.cs
├── Notice.resx
├── Setting.Designer.cs
├── Setting.cs
├── Setting.resx
└── ViewManager.cs
├── app.config
├── app.manifest
├── logo.ico
├── logo.png
├── packages.config
├── shadowsocks-csharp.csproj
└── shadowsocks-csharp.csproj.user
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | npm-debug.log
3 | __tests__
4 | bin/Debug/
5 | bin/Release/
6 | packages
7 | build/
8 | *.exe
9 | .vs
10 | Debug/
11 | Release/
--------------------------------------------------------------------------------
/MaterialSkin/Animations/AnimationDirection.cs:
--------------------------------------------------------------------------------
1 | namespace MaterialSkin.Animations
2 | {
3 | enum AnimationDirection
4 | {
5 | In, //In. Stops if finished.
6 | Out, //Out. Stops if finished.
7 | InOutIn, //Same as In, but changes to InOutOut if finished.
8 | InOutOut, //Same as Out.
9 | InOutRepeatingIn, // Same as In, but changes to InOutRepeatingOut if finished.
10 | InOutRepeatingOut // Same as Out, but changes to InOutRepeatingIn if finished.
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/MaterialSkin/Animations/Animations.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace MaterialSkin.Animations
4 | {
5 | enum AnimationType
6 | {
7 | Linear,
8 | EaseInOut,
9 | EaseOut,
10 | CustomQuadratic
11 | }
12 |
13 | static class AnimationLinear
14 | {
15 | public static double CalculateProgress(double progress)
16 | {
17 | return progress;
18 | }
19 | }
20 |
21 | static class AnimationEaseInOut
22 | {
23 | public static double PI = Math.PI;
24 | public static double PI_HALF = Math.PI / 2;
25 |
26 | public static double CalculateProgress(double progress)
27 | {
28 | return EaseInOut(progress);
29 | }
30 |
31 | private static double EaseInOut(double s)
32 | {
33 | return s - Math.Sin(s * 2 * PI) / (2 * PI);
34 | }
35 | }
36 |
37 | public static class AnimationEaseOut
38 | {
39 | public static double CalculateProgress(double progress)
40 | {
41 | return -1 * progress * (progress - 2);
42 | }
43 | }
44 |
45 | public static class AnimationCustomQuadratic
46 | {
47 | public static double CalculateProgress(double progress)
48 | {
49 | var kickoff = 0.6;
50 | return 1 - Math.Cos((Math.Max(progress, kickoff) - kickoff) * Math.PI / (2 - (2 * kickoff)));
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/MaterialSkin/Controls/MaterialDivider.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows.Forms;
3 |
4 | namespace MaterialSkin.Controls
5 | {
6 | public sealed class MaterialDivider : Control, IMaterialControl
7 | {
8 | [Browsable(false)]
9 | public int Depth { get; set; }
10 | [Browsable(false)]
11 | public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
12 | [Browsable(false)]
13 | public MouseState MouseState { get; set; }
14 |
15 | public MaterialDivider()
16 | {
17 | SetStyle(ControlStyles.SupportsTransparentBackColor, true);
18 | Height = 1;
19 | BackColor = SkinManager.GetDividersColor();
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/MaterialSkin/Controls/MaterialLabel.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows.Forms;
3 |
4 | namespace MaterialSkin.Controls
5 | {
6 | public class MaterialLabel : Label, IMaterialControl
7 | {
8 | [Browsable(false)]
9 | public int Depth { get; set; }
10 | [Browsable(false)]
11 | public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
12 | [Browsable(false)]
13 | public MouseState MouseState { get; set; }
14 | protected override void OnCreateControl()
15 | {
16 | base.OnCreateControl();
17 |
18 | ForeColor = SkinManager.GetPrimaryTextColor();
19 | Font = SkinManager.ROBOTO_REGULAR_11;
20 |
21 | BackColorChanged += (sender, args) => ForeColor = SkinManager.GetPrimaryTextColor();
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/MaterialSkin/Controls/MaterialMenuStrip.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Drawing.Drawing2D;
5 | using System.Drawing.Text;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace MaterialSkin.Controls
12 | {
13 | public class MaterialMenuStrip : MenuStrip, IMaterialControl
14 | {
15 | public int Depth { get; set; }
16 | public MaterialSkinManager SkinManager { get { return MaterialSkinManager.Instance; } }
17 | public MouseState MouseState { get; set; }
18 |
19 | public MaterialMenuStrip()
20 | {
21 | Renderer = new MaterialMenuStripRender();
22 |
23 | if (DesignMode)
24 | {
25 | Dock = DockStyle.None;
26 | Anchor |= AnchorStyles.Right;
27 | AutoSize = false;
28 | Location = new Point(0, 28);
29 | }
30 | }
31 |
32 | protected override void OnCreateControl()
33 | {
34 | base.OnCreateControl();
35 | Font = SkinManager.ROBOTO_MEDIUM_10;
36 | BackColor = SkinManager.PrimaryColor;
37 | }
38 | }
39 |
40 | internal class MaterialMenuStripRender : ToolStripProfessionalRenderer, IMaterialControl
41 | {
42 | //Properties for managing the material design properties
43 | public int Depth { get; set; }
44 | public MaterialSkinManager SkinManager { get { return MaterialSkinManager.Instance; } }
45 | public MouseState MouseState { get; set; }
46 |
47 | protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
48 | {
49 | var g = e.Graphics;
50 | g.TextRenderingHint = TextRenderingHint.AntiAlias;
51 |
52 | if (e.Item.IsOnDropDown)
53 | {
54 | var itemRect = GetItemRect(e.Item);
55 | var textRect = new Rectangle(24, itemRect.Y, itemRect.Width - (24 + 16), itemRect.Height);
56 | g.DrawString(e.Text, SkinManager.ROBOTO_MEDIUM_10, e.Item.Enabled ? SkinManager.GetMainTextBrush() : SkinManager.GetDisabledOrHintBrush(), textRect, new StringFormat() { LineAlignment = StringAlignment.Center });
57 | }
58 | else
59 | {
60 | g.DrawString(e.Text, SkinManager.ROBOTO_MEDIUM_10, Brushes.White, e.TextRectangle, new StringFormat() { LineAlignment = StringAlignment.Center });
61 | }
62 | }
63 |
64 | protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
65 | {
66 | var g = e.Graphics;
67 | g.Clear(SkinManager.PrimaryColor);
68 |
69 | //Draw background
70 | var itemRect = GetItemRect(e.Item);
71 | if (e.Item.IsOnDropDown)
72 | {
73 | g.FillRectangle(e.Item.Selected && e.Item.Enabled ? SkinManager.GetCmsSelectedItemBrush() : new SolidBrush(SkinManager.GetApplicationBackgroundColor()), itemRect);
74 | }
75 | else
76 | {
77 | g.FillRectangle(e.Item.Selected ? SkinManager.GetFlatButtonPressedBackgroundBrush() : SkinManager.PrimaryColorBrush, itemRect);
78 | }
79 |
80 | //Ripple animation
81 | var toolStrip = e.ToolStrip as MaterialContextMenuStrip;
82 | if (toolStrip != null)
83 | {
84 | var animationManager = toolStrip.animationManager;
85 | var animationSource = toolStrip.animationSource;
86 | if (toolStrip.animationManager.IsAnimating() && e.Item.Bounds.Contains(animationSource))
87 | {
88 | for (int i = 0; i < animationManager.GetAnimationCount(); i++)
89 | {
90 | var animationValue = animationManager.GetProgress(i);
91 | var rippleBrush = new SolidBrush(Color.FromArgb((int)(51 - (animationValue * 50)), Color.Black));
92 | var rippleSize = (int)(animationValue * itemRect.Width * 2.5);
93 | g.FillEllipse(rippleBrush, new Rectangle(animationSource.X - rippleSize / 2, itemRect.Y - itemRect.Height, rippleSize, itemRect.Height * 3));
94 | }
95 | }
96 | }
97 | }
98 |
99 | protected override void OnRenderImageMargin(ToolStripRenderEventArgs e)
100 | {
101 | //base.OnRenderImageMargin(e);
102 | }
103 |
104 | protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
105 | {
106 | var g = e.Graphics;
107 |
108 | g.FillRectangle(new SolidBrush(SkinManager.GetApplicationBackgroundColor()), e.Item.Bounds);
109 | g.DrawLine(new Pen(SkinManager.GetDividersColor()), new Point(e.Item.Bounds.Left, e.Item.Bounds.Height / 2), new Point(e.Item.Bounds.Right, e.Item.Bounds.Height / 2));
110 | }
111 |
112 | protected override void OnRenderToolStripBorder(ToolStripRenderEventArgs e)
113 | {
114 | //var g = e.Graphics;
115 |
116 | //g.DrawRectangle(new Pen(SkinManager.GetDividersColor()), new Rectangle(e.AffectedBounds.X, e.AffectedBounds.Y, e.AffectedBounds.Width - 1, e.AffectedBounds.Height - 1));
117 | }
118 |
119 | protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
120 | {
121 | var g = e.Graphics;
122 | const int ARROW_SIZE = 4;
123 |
124 | var arrowMiddle = new Point(e.ArrowRectangle.X + e.ArrowRectangle.Width / 2, e.ArrowRectangle.Y + e.ArrowRectangle.Height / 2);
125 | var arrowBrush = e.Item.Enabled ? SkinManager.GetMainTextBrush() : SkinManager.GetDisabledOrHintBrush();
126 | using (var arrowPath = new GraphicsPath())
127 | {
128 | arrowPath.AddLines(new[] { new Point(arrowMiddle.X - ARROW_SIZE, arrowMiddle.Y - ARROW_SIZE), new Point(arrowMiddle.X, arrowMiddle.Y), new Point(arrowMiddle.X - ARROW_SIZE, arrowMiddle.Y + ARROW_SIZE) });
129 | arrowPath.CloseFigure();
130 |
131 | g.FillPath(arrowBrush, arrowPath);
132 | }
133 | }
134 |
135 | private Rectangle GetItemRect(ToolStripItem item)
136 | {
137 | return new Rectangle(0, item.ContentRectangle.Y, item.ContentRectangle.Width + 4, item.ContentRectangle.Height);
138 | }
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/MaterialSkin/Controls/MaterialProgressBar.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows.Forms;
3 |
4 | namespace MaterialSkin.Controls
5 | {
6 | ///
7 | /// Material design-like progress bar
8 | ///
9 | public class MaterialProgressBar : ProgressBar, IMaterialControl
10 | {
11 | ///
12 | /// Initializes a new instance of the class.
13 | ///
14 | public MaterialProgressBar()
15 | {
16 | SetStyle(ControlStyles.UserPaint, true);
17 | SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
18 | }
19 |
20 | ///
21 | /// Gets or sets the depth.
22 | ///
23 | ///
24 | /// The depth.
25 | ///
26 | [Browsable(false)]
27 | public int Depth { get; set; }
28 |
29 | ///
30 | /// Gets the skin manager.
31 | ///
32 | ///
33 | /// The skin manager.
34 | ///
35 | [Browsable(false)]
36 | public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
37 |
38 | ///
39 | /// Gets or sets the state of the mouse.
40 | ///
41 | ///
42 | /// The state of the mouse.
43 | ///
44 | [Browsable(false)]
45 | public MouseState MouseState { get; set; }
46 |
47 | ///
48 | /// Performs the work of setting the specified bounds of this control.
49 | ///
50 | /// The new property value of the control.
51 | /// The new property value of the control.
52 | /// The new property value of the control.
53 | /// The new property value of the control.
54 | /// A bitwise combination of the values.
55 | protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
56 | {
57 | base.SetBoundsCore(x, y, width, 5, specified);
58 | }
59 |
60 | ///
61 | /// Raises the event.
62 | ///
63 | /// A that contains the event data.
64 | protected override void OnPaint(PaintEventArgs e)
65 | {
66 | var doneProgress = (int)(e.ClipRectangle.Width * ((double)Value / Maximum));
67 | e.Graphics.FillRectangle(SkinManager.ColorScheme.PrimaryBrush, 0, 0, doneProgress, e.ClipRectangle.Height);
68 | e.Graphics.FillRectangle(SkinManager.GetDisabledOrHintBrush(), doneProgress, 0, e.ClipRectangle.Width, e.ClipRectangle.Height);
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/MaterialSkin/Controls/MaterialRaisedButton.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Drawing;
3 | using System.Drawing.Drawing2D;
4 | using System.Drawing.Text;
5 | using System.Windows.Forms;
6 | using MaterialSkin.Animations;
7 | using System;
8 |
9 | namespace MaterialSkin.Controls
10 | {
11 | public class MaterialRaisedButton : Button, IMaterialControl
12 | {
13 | [Browsable(false)]
14 | public int Depth { get; set; }
15 | [Browsable(false)]
16 | public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
17 | [Browsable(false)]
18 | public MouseState MouseState { get; set; }
19 | public bool Primary { get; set; }
20 |
21 | private readonly AnimationManager _animationManager;
22 |
23 | private SizeF _textSize;
24 |
25 | private Image _icon;
26 | public Image Icon
27 | {
28 | get { return _icon; }
29 | set
30 | {
31 | _icon = value;
32 | if (AutoSize)
33 | Size = GetPreferredSize();
34 | Invalidate();
35 | }
36 | }
37 |
38 | public MaterialRaisedButton()
39 | {
40 | Primary = true;
41 |
42 | _animationManager = new AnimationManager(false)
43 | {
44 | Increment = 0.03,
45 | AnimationType = AnimationType.EaseOut
46 | };
47 | _animationManager.OnAnimationProgress += sender => Invalidate();
48 |
49 | AutoSizeMode = AutoSizeMode.GrowAndShrink;
50 | AutoSize = true;
51 | }
52 |
53 | public override string Text
54 | {
55 | get { return base.Text; }
56 | set
57 | {
58 | base.Text = value;
59 | _textSize = CreateGraphics().MeasureString(value.ToUpper(), SkinManager.ROBOTO_MEDIUM_10);
60 | if (AutoSize)
61 | Size = GetPreferredSize();
62 | Invalidate();
63 | }
64 | }
65 |
66 | protected override void OnMouseUp(MouseEventArgs mevent)
67 | {
68 | base.OnMouseUp(mevent);
69 |
70 | _animationManager.StartNewAnimation(AnimationDirection.In, mevent.Location);
71 | }
72 |
73 | protected override void OnPaint(PaintEventArgs pevent)
74 | {
75 | var g = pevent.Graphics;
76 | g.SmoothingMode = SmoothingMode.AntiAlias;
77 | g.TextRenderingHint = TextRenderingHint.AntiAlias;
78 |
79 | g.Clear(Parent.BackColor);
80 |
81 | using (var backgroundPath = DrawHelper.CreateRoundRect(ClientRectangle.X,
82 | ClientRectangle.Y,
83 | ClientRectangle.Width - 1,
84 | ClientRectangle.Height - 1,
85 | 1f))
86 | {
87 | g.FillPath(Primary ? SkinManager.ColorScheme.PrimaryBrush : SkinManager.GetRaisedButtonBackgroundBrush(), backgroundPath);
88 | }
89 |
90 | if (_animationManager.IsAnimating())
91 | {
92 | for (int i = 0; i < _animationManager.GetAnimationCount(); i++)
93 | {
94 | var animationValue = _animationManager.GetProgress(i);
95 | var animationSource = _animationManager.GetSource(i);
96 | var rippleBrush = new SolidBrush(Color.FromArgb((int)(51 - (animationValue * 50)), Color.White));
97 | var rippleSize = (int)(animationValue * Width * 2);
98 | g.FillEllipse(rippleBrush, new Rectangle(animationSource.X - rippleSize / 2, animationSource.Y - rippleSize / 2, rippleSize, rippleSize));
99 | }
100 | }
101 |
102 | //Icon
103 | var iconRect = new Rectangle(8, 6, 24, 24);
104 |
105 | if (string.IsNullOrEmpty(Text))
106 | // Center Icon
107 | iconRect.X += 2;
108 |
109 | if (Icon != null)
110 | g.DrawImage(Icon, iconRect);
111 |
112 | //Text
113 | var textRect = ClientRectangle;
114 |
115 | if (Icon != null)
116 | {
117 | //
118 | // Resize and move Text container
119 | //
120 |
121 | // First 8: left padding
122 | // 24: icon width
123 | // Second 4: space between Icon and Text
124 | // Third 8: right padding
125 | textRect.Width -= 8 + 24 + 4 + 8;
126 |
127 | // First 8: left padding
128 | // 24: icon width
129 | // Second 4: space between Icon and Text
130 | textRect.X += 8 + 24 + 4;
131 | }
132 |
133 | g.DrawString(
134 | Text.ToUpper(),
135 | SkinManager.ROBOTO_MEDIUM_10,
136 | SkinManager.GetRaisedButtonTextBrush(Primary),
137 | textRect,
138 | new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
139 | }
140 |
141 | private Size GetPreferredSize()
142 | {
143 | return GetPreferredSize(new Size(0, 0));
144 | }
145 |
146 | public override Size GetPreferredSize(Size proposedSize)
147 | {
148 | // Provides extra space for proper padding for content
149 | var extra = 16;
150 |
151 | if (Icon != null)
152 | // 24 is for icon size
153 | // 4 is for the space between icon & text
154 | extra += 24 + 4;
155 |
156 | return new Size((int)Math.Ceiling(_textSize.Width) + extra, 36);
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/MaterialSkin/Controls/MaterialTabControl.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Windows.Forms;
4 |
5 | namespace MaterialSkin.Controls
6 | {
7 | public class MaterialTabControl : TabControl, IMaterialControl
8 | {
9 | [Browsable(false)]
10 | public int Depth { get; set; }
11 | [Browsable(false)]
12 | public MaterialSkinManager SkinManager => MaterialSkinManager.Instance;
13 | [Browsable(false)]
14 | public MouseState MouseState { get; set; }
15 |
16 | protected override void WndProc(ref Message m)
17 | {
18 | if (m.Msg == 0x1328 && !DesignMode) m.Result = (IntPtr)1;
19 | else base.WndProc(ref m);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/MaterialSkin/DrawHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Drawing.Drawing2D;
3 |
4 | namespace MaterialSkin
5 | {
6 | static class DrawHelper
7 | {
8 | public static GraphicsPath CreateRoundRect(float x, float y, float width, float height, float radius)
9 | {
10 | var gp = new GraphicsPath();
11 | gp.AddLine(x + radius, y, x + width - (radius * 2), y);
12 | gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90);
13 | gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2));
14 | gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
15 | gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height);
16 | gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
17 | gp.AddLine(x, y + height - (radius * 2), x, y + radius);
18 | gp.AddArc(x, y, radius * 2, radius * 2, 180, 90);
19 | gp.CloseFigure();
20 | return gp;
21 | }
22 |
23 | public static GraphicsPath CreateRoundRect(Rectangle rect, float radius)
24 | {
25 | return CreateRoundRect(rect.X, rect.Y, rect.Width, rect.Height, radius);
26 | }
27 |
28 | public static Color BlendColor(Color backgroundColor, Color frontColor, double blend)
29 | {
30 | var ratio = blend / 255d;
31 | var invRatio = 1d - ratio;
32 | var r = (int)((backgroundColor.R * invRatio) + (frontColor.R * ratio));
33 | var g = (int)((backgroundColor.G * invRatio) + (frontColor.G * ratio));
34 | var b = (int)((backgroundColor.B * invRatio) + (frontColor.B * ratio));
35 | return Color.FromArgb(r, g, b);
36 | }
37 |
38 | public static Color BlendColor(Color backgroundColor, Color frontColor)
39 | {
40 | return BlendColor(backgroundColor, frontColor, frontColor.A);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/MaterialSkin/IMaterialControl.cs:
--------------------------------------------------------------------------------
1 | namespace MaterialSkin
2 | {
3 | public interface IMaterialControl
4 | {
5 | int Depth { get; set; }
6 | MaterialSkinManager SkinManager { get; }
7 | MouseState MouseState { get; set; }
8 |
9 | }
10 |
11 | public enum MouseState
12 | {
13 | HOVER,
14 | DOWN,
15 | OUT
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MaterialSkin/MaterialSkin.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8EB7611B-68CD-4B8B-987A-11717E2B250C}
8 | Library
9 | Properties
10 | MaterialSkin
11 | MaterialSkin
12 | v4.6.1
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 | true
35 | bin\x86\Debug\
36 | DEBUG;TRACE
37 | full
38 | x86
39 | prompt
40 | MinimumRecommendedRules.ruleset
41 |
42 |
43 | bin\x86\Release\
44 | TRACE
45 | true
46 | pdbonly
47 | x86
48 | prompt
49 | MinimumRecommendedRules.ruleset
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | Component
64 |
65 |
66 | Component
67 |
68 |
69 | Component
70 |
71 |
72 | Component
73 |
74 |
75 | Form
76 |
77 |
78 | Component
79 |
80 |
81 | Component
82 |
83 |
84 | Component
85 |
86 |
87 | Component
88 |
89 |
90 | Component
91 |
92 |
93 | Component
94 |
95 |
96 | Component
97 |
98 |
99 |
100 |
101 | Component
102 |
103 |
104 |
105 |
106 | True
107 | True
108 | Resources.resx
109 |
110 |
111 |
112 |
113 | ResXFileCodeGenerator
114 | Resources.Designer.cs
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
131 |
--------------------------------------------------------------------------------
/MaterialSkin/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("MaterialSkin")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("MaterialSkin")]
12 | [assembly: AssemblyCopyright("Copyright © 2014")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("52781de3-a323-49ee-9a4f-c67280f8d328")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/MaterialSkin/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace MaterialSkin.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MaterialSkin.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Byte[].
65 | ///
66 | internal static byte[] Roboto_Medium {
67 | get {
68 | object obj = ResourceManager.GetObject("Roboto_Medium", resourceCulture);
69 | return ((byte[])(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Byte[].
75 | ///
76 | internal static byte[] Roboto_Regular {
77 | get {
78 | object obj = ResourceManager.GetObject("Roboto_Regular", resourceCulture);
79 | return ((byte[])(obj));
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/MaterialSkin/Resources/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/MaterialSkin/Resources/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/MaterialSkin/Resources/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/MaterialSkin/Resources/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### 绿点加速器windows客户端
2 |
3 | #### 相关说明
4 |
5 | 出于安全方面考虑,仓库代码去除了接口定义部分。自学成材,代码仅供参考。
6 |
7 | #### 应用截图
8 |
9 | ![此处输入图片的描述][1]
10 |
11 | #### 下载地址
12 |
13 | http://www.greenuuu.com/pub/update/windows/greendot-windows.zip
14 |
15 | #### 软件介绍
16 | 详情:http://www.greenuuu.com
17 |
18 | [1]: http://www.greenuuu.com/pub/home/img/guide/win2.png
--------------------------------------------------------------------------------
/shadowsocks-csharp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26730.16
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{84529DA0-A4B4-4258-A1C6-26E093170C5C}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaterialSkin", "MaterialSkin\MaterialSkin.csproj", "{8EB7611B-68CD-4B8B-987A-11717E2B250C}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|x86 = Debug|x86
14 | Release|Any CPU = Release|Any CPU
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {84529DA0-A4B4-4258-A1C6-26E093170C5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {84529DA0-A4B4-4258-A1C6-26E093170C5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {84529DA0-A4B4-4258-A1C6-26E093170C5C}.Debug|x86.ActiveCfg = Debug|x86
21 | {84529DA0-A4B4-4258-A1C6-26E093170C5C}.Debug|x86.Build.0 = Debug|x86
22 | {84529DA0-A4B4-4258-A1C6-26E093170C5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {84529DA0-A4B4-4258-A1C6-26E093170C5C}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {84529DA0-A4B4-4258-A1C6-26E093170C5C}.Release|x86.ActiveCfg = Release|x86
25 | {84529DA0-A4B4-4258-A1C6-26E093170C5C}.Release|x86.Build.0 = Release|x86
26 | {8EB7611B-68CD-4B8B-987A-11717E2B250C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {8EB7611B-68CD-4B8B-987A-11717E2B250C}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {8EB7611B-68CD-4B8B-987A-11717E2B250C}.Debug|x86.ActiveCfg = Debug|x86
29 | {8EB7611B-68CD-4B8B-987A-11717E2B250C}.Debug|x86.Build.0 = Debug|x86
30 | {8EB7611B-68CD-4B8B-987A-11717E2B250C}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {8EB7611B-68CD-4B8B-987A-11717E2B250C}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {8EB7611B-68CD-4B8B-987A-11717E2B250C}.Release|x86.ActiveCfg = Release|x86
33 | {8EB7611B-68CD-4B8B-987A-11717E2B250C}.Release|x86.Build.0 = Release|x86
34 | EndGlobalSection
35 | GlobalSection(SolutionProperties) = preSolution
36 | HideSolutionNode = FALSE
37 | EndGlobalSection
38 | GlobalSection(ExtensibilityGlobals) = postSolution
39 | SolutionGuid = {C0AC34BD-C17F-4E5A-9D96-A9BB6F036613}
40 | EndGlobalSection
41 | EndGlobal
42 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Config/Constants.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ShadowSocks.Config
8 | {
9 | class Constants
10 | {
11 | public static string DES_KEY = "";
12 |
13 | //网站根目录
14 | public static string DEFAULT_SEVER_ROOT = "";
15 |
16 | //用户注册链接
17 | public static string USER_REGISTER_URI = "";
18 |
19 | //用户找回密码链接
20 | public static string USER_FINDPWD_URI = "";
21 |
22 | //用户个人中心链接
23 | public static string USER_CENTER_URI = "";
24 |
25 | //用户充值链接
26 | public static string RECHARGE_URI = "";
27 |
28 | //用户登录接口
29 | public static string USER_LOGIN_API = "";
30 |
31 | //用户注销接口
32 | public static string USER_LOGOUT_API = "";
33 |
34 | //用户信息接口
35 | public static string USER_INFO_API = "";
36 |
37 | //服务列表接口
38 | public static string SERVER_LIST_API = "";
39 |
40 | //服务器连接接口
41 | public static string SERVER_CONNECT_API = "";
42 |
43 | //服务器断开连接接口
44 | public static string SERVER_DISCONNECT_API = "";
45 |
46 | //更新检测接口
47 | public static string UPDATE_CHECK_API = "";
48 |
49 | //应用配置接口
50 | public static string APP_CONFIG_API = "";
51 |
52 | //PAC更新链接
53 | public static string PAC_UPDATE_URI = "";
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/FileManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.IO.Compression;
4 | using System.Text;
5 |
6 | namespace ShadowSocks.Controller
7 | {
8 | public static class FileManager
9 | {
10 | public static bool ByteArrayToFile(string fileName, byte[] content)
11 | {
12 | try
13 | {
14 | using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
15 | fs.Write(content, 0, content.Length);
16 | return true;
17 | }
18 | catch (Exception ex)
19 | {
20 | Logging.Error(ex);
21 | }
22 | return false;
23 | }
24 |
25 | public static void UncompressFile(string fileName, byte[] content)
26 | {
27 | // Because the uncompressed size of the file is unknown,
28 | // we are using an arbitrary buffer size.
29 | byte[] buffer = new byte[4096];
30 | int n;
31 |
32 | using(var fs = File.Create(fileName))
33 | using (var input = new GZipStream(new MemoryStream(content),
34 | CompressionMode.Decompress, false))
35 | {
36 | while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
37 | {
38 | fs.Write(buffer, 0, n);
39 | }
40 | }
41 | }
42 |
43 | public static string NonExclusiveReadAllText(string path)
44 | {
45 | return NonExclusiveReadAllText(path, Encoding.Default);
46 | }
47 |
48 | public static string NonExclusiveReadAllText(string path, Encoding encoding)
49 | {
50 | try
51 | {
52 | using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
53 | using (var sr = new StreamReader(fs, encoding))
54 | {
55 | return sr.ReadToEnd();
56 | }
57 | }
58 | catch (Exception ex)
59 | {
60 | Logging.Error(ex);
61 | throw ex;
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/I18N.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.IO;
5 |
6 | namespace ShadowSocks.Controller
7 | {
8 | using ShadowSocks.Properties;
9 |
10 | public static class I18N
11 | {
12 | private static Dictionary _strings = new Dictionary();
13 |
14 | private static void Init(string res)
15 | {
16 | using (var sr = new StringReader(res))
17 | {
18 | foreach (var line in sr.NonWhiteSpaceLines())
19 | {
20 | if (line[0] == '#')
21 | continue;
22 |
23 | var pos = line.IndexOf('=');
24 | if (pos < 1)
25 | continue;
26 | _strings[line.Substring(0, pos)] = line.Substring(pos + 1);
27 | }
28 | }
29 | }
30 |
31 | static I18N()
32 | {
33 | string name = CultureInfo.CurrentCulture.EnglishName;
34 | if (name.StartsWith("Chinese", StringComparison.OrdinalIgnoreCase))
35 | {
36 | // choose Traditional Chinese only if we get explicit indication
37 | Init(name.Contains("Traditional")
38 | ? Resources.zh_TW
39 | : Resources.zh_CN);
40 | }
41 | else if (name.StartsWith("Japan", StringComparison.OrdinalIgnoreCase))
42 | {
43 | Init(Resources.ja);
44 | }
45 | }
46 |
47 | public static string GetString(string key)
48 | {
49 | return _strings.ContainsKey(key)
50 | ? _strings[key]
51 | : key;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Logging.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.IO;
4 | using System.Net.Sockets;
5 | using System.Net;
6 | using System.Diagnostics;
7 | using System.Text;
8 | using ShadowSocks.Util;
9 |
10 | namespace ShadowSocks.Controller
11 | {
12 | public class Logging
13 | {
14 | public static string LogFilePath;
15 |
16 | private static FileStream _fs;
17 | private static StreamWriterWithTimestamp _sw;
18 |
19 | public static bool OpenLogFile()
20 | {
21 | try
22 | {
23 | LogFilePath = Utils.GetTempPath("greendot.log");
24 |
25 | _fs = new FileStream(LogFilePath, FileMode.Append);
26 | _sw = new StreamWriterWithTimestamp(_fs);
27 | _sw.AutoFlush = true;
28 | Console.SetOut(_sw);
29 | Console.SetError(_sw);
30 |
31 | return true;
32 | }
33 | catch (IOException e)
34 | {
35 | Console.WriteLine(e.ToString());
36 | return false;
37 | }
38 | }
39 |
40 | private static void WriteToLogFile(object o)
41 | {
42 | try {
43 | Console.WriteLine(o);
44 | } catch(ObjectDisposedException) {
45 | }
46 | }
47 |
48 | public static void Error(object o)
49 | {
50 | WriteToLogFile("[E] " + o);
51 | }
52 |
53 | public static void Info(object o)
54 | {
55 | WriteToLogFile(o);
56 | }
57 |
58 | public static void Clear() {
59 | _sw.Close();
60 | _sw.Dispose();
61 | _fs.Close();
62 | _fs.Dispose();
63 | File.Delete(LogFilePath);
64 | OpenLogFile();
65 | }
66 |
67 | [Conditional("DEBUG")]
68 | public static void Debug(object o)
69 | {
70 | WriteToLogFile("[D] " + o);
71 | }
72 |
73 | [Conditional("DEBUG")]
74 | public static void Dump(string tag, byte[] arr, int length)
75 | {
76 | var sb = new StringBuilder($"{Environment.NewLine}{tag}: ");
77 | for (int i = 0; i < length - 1; i++) {
78 | sb.Append($"0x{arr[i]:X2}, ");
79 | }
80 | sb.Append($"0x{arr[length - 1]:X2}");
81 | sb.Append(Environment.NewLine);
82 | Debug(sb.ToString());
83 | }
84 |
85 | [Conditional("DEBUG")]
86 | public static void Debug(EndPoint local, EndPoint remote, int len, string header = null, string tailer = null)
87 | {
88 | if (header == null && tailer == null)
89 | Debug($"{local} => {remote} (size={len})");
90 | else if (header == null && tailer != null)
91 | Debug($"{local} => {remote} (size={len}), {tailer}");
92 | else if (header != null && tailer == null)
93 | Debug($"{header}: {local} => {remote} (size={len})");
94 | else
95 | Debug($"{header}: {local} => {remote} (size={len}), {tailer}");
96 | }
97 |
98 | [Conditional("DEBUG")]
99 | public static void Debug(Socket sock, int len, string header = null, string tailer = null)
100 | {
101 | Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer);
102 | }
103 |
104 | public static void LogUsefulException(Exception e)
105 | {
106 | // just log useful exceptions, not all of them
107 | if (e is SocketException)
108 | {
109 | SocketException se = (SocketException)e;
110 | if (se.SocketErrorCode == SocketError.ConnectionAborted)
111 | {
112 | // closed by browser when sending
113 | // normally happens when download is canceled or a tab is closed before page is loaded
114 | }
115 | else if (se.SocketErrorCode == SocketError.ConnectionReset)
116 | {
117 | // received rst
118 | }
119 | else if (se.SocketErrorCode == SocketError.NotConnected)
120 | {
121 | // The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected.
122 | }
123 | else if (se.SocketErrorCode == SocketError.HostUnreachable)
124 | {
125 | // There is no network route to the specified host.
126 | }
127 | else if (se.SocketErrorCode == SocketError.TimedOut)
128 | {
129 | // The connection attempt timed out, or the connected host has failed to respond.
130 | }
131 | else
132 | {
133 | Info(e);
134 | }
135 | }
136 | else if (e is ObjectDisposedException)
137 | {
138 | }
139 | else if (e is Win32Exception)
140 | {
141 | var ex = (Win32Exception) e;
142 |
143 | // Win32Exception (0x80004005): A 32 bit processes cannot access modules of a 64 bit process.
144 | if ((uint) ex.ErrorCode != 0x80004005)
145 | {
146 | Info(e);
147 | }
148 | }
149 | else
150 | {
151 | Info(e);
152 | }
153 | }
154 | }
155 |
156 | // Simply extended System.IO.StreamWriter for adding timestamp workaround
157 | public class StreamWriterWithTimestamp : StreamWriter
158 | {
159 | public StreamWriterWithTimestamp(Stream stream) : base(stream)
160 | {
161 | }
162 |
163 | private string GetTimestamp()
164 | {
165 | return "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] ";
166 | }
167 |
168 | public override void WriteLine(string value)
169 | {
170 | base.WriteLine(GetTimestamp() + value);
171 | }
172 |
173 | public override void Write(string value)
174 | {
175 | base.Write(GetTimestamp() + value);
176 | }
177 | }
178 |
179 | }
180 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Net;
5 | using System.Text;
6 |
7 | using Newtonsoft.Json;
8 |
9 | using ShadowSocks.Model;
10 | using ShadowSocks.Properties;
11 | using ShadowSocks.Util;
12 | using ShadowSocks.Config;
13 |
14 | namespace ShadowSocks.Controller
15 | {
16 | public class GFWListUpdater
17 | {
18 | public event EventHandler UpdateCompleted;
19 |
20 | public event ErrorEventHandler Error;
21 |
22 | public class ResultEventArgs : EventArgs
23 | {
24 | public bool Success;
25 |
26 | public ResultEventArgs(bool success)
27 | {
28 | this.Success = success;
29 | }
30 | }
31 |
32 | private static readonly IEnumerable IgnoredLineBegins = new[] { '!', '[' };
33 | private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
34 | {
35 | try
36 | {
37 | File.WriteAllText(Utils.GetTempPath("gfwlist.txt"), e.Result, Encoding.UTF8);
38 | List lines = ParseResult(e.Result);
39 | if (File.Exists(PACServer.USER_RULE_FILE))
40 | {
41 | string local = FileManager.NonExclusiveReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8);
42 | using (var sr = new StringReader(local))
43 | {
44 | foreach (var rule in sr.NonWhiteSpaceLines())
45 | {
46 | if (rule.BeginWithAny(IgnoredLineBegins))
47 | continue;
48 | lines.Add(rule);
49 | }
50 | }
51 | }
52 | string abpContent;
53 | if (File.Exists(PACServer.USER_ABP_FILE))
54 | {
55 | abpContent = FileManager.NonExclusiveReadAllText(PACServer.USER_ABP_FILE, Encoding.UTF8);
56 | }
57 | else
58 | {
59 | abpContent = Utils.UnGzip(Resources.abp_js);
60 | }
61 | abpContent = abpContent.Replace("__RULES__", JsonConvert.SerializeObject(lines, Formatting.Indented));
62 | if (File.Exists(PACServer.PAC_FILE))
63 | {
64 | string original = FileManager.NonExclusiveReadAllText(PACServer.PAC_FILE, Encoding.UTF8);
65 | if (original == abpContent)
66 | {
67 | UpdateCompleted(this, new ResultEventArgs(false));
68 | return;
69 | }
70 | }
71 | File.WriteAllText(PACServer.PAC_FILE, abpContent, Encoding.UTF8);
72 | if (UpdateCompleted != null)
73 | {
74 | UpdateCompleted(this, new ResultEventArgs(true));
75 | }
76 | }
77 | catch (Exception ex)
78 | {
79 | if (Error != null)
80 | {
81 | Error(this, new ErrorEventArgs(ex));
82 | }
83 | }
84 | }
85 |
86 | public void UpdatePACFromGFWList(Configuration config)
87 | {
88 | string pacUpdateUri = Constants.PAC_UPDATE_URI;
89 | WebClient http = new WebClient();
90 | http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort);
91 | http.DownloadStringCompleted += http_DownloadStringCompleted;
92 | http.DownloadStringAsync(new Uri(pacUpdateUri));
93 | }
94 |
95 | public static List ParseResult(string response)
96 | {
97 | byte[] bytes = Convert.FromBase64String(response);
98 | string content = Encoding.ASCII.GetString(bytes);
99 | List valid_lines = new List();
100 | using (var sr = new StringReader(content))
101 | {
102 | foreach (var line in sr.NonWhiteSpaceLines())
103 | {
104 | if (line.BeginWithAny(IgnoredLineBegins))
105 | continue;
106 | valid_lines.Add(line);
107 | }
108 | }
109 | return valid_lines;
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Service/PrivoxyRunner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Net.Sockets;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using ShadowSocks.Model;
10 | using ShadowSocks.Properties;
11 | using ShadowSocks.Util;
12 | using ShadowSocks.Util.ProcessManagement;
13 |
14 | namespace ShadowSocks.Controller
15 | {
16 | class PrivoxyRunner
17 | {
18 | private static int _uid;
19 | private static string _uniqueConfigFile;
20 | private static Job _privoxyJob;
21 | private Process _process;
22 | private int _runningPort;
23 |
24 | static PrivoxyRunner()
25 | {
26 | try
27 | {
28 | _uid = Application.StartupPath.GetHashCode(); // Currently we use ss's StartupPath to identify different Privoxy instance.
29 | _uniqueConfigFile = $"privoxy_{_uid}.conf";
30 | _privoxyJob = new Job();
31 |
32 | FileManager.UncompressFile(Utils.GetTempPath("greendot_privoxy.exe"), Resources.privoxy_exe);
33 | FileManager.UncompressFile(Utils.GetTempPath("mgwz.dll"), Resources.mgwz_dll);
34 | }
35 | catch (IOException e)
36 | {
37 | Logging.LogUsefulException(e);
38 | }
39 | }
40 |
41 | public int RunningPort => _runningPort;
42 |
43 | public void Start(Configuration configuration)
44 | {
45 | if (_process == null)
46 | {
47 | Process[] existingPrivoxy = Process.GetProcessesByName("greendot_privoxy");
48 | foreach (Process p in existingPrivoxy.Where(IsChildProcess))
49 | {
50 | KillProcess(p);
51 | }
52 | string privoxyConfig = Resources.privoxy_conf;
53 | _runningPort = GetFreePort();
54 | privoxyConfig = privoxyConfig.Replace("__SOCKS_PORT__", configuration.localPort.ToString());
55 | privoxyConfig = privoxyConfig.Replace("__PRIVOXY_BIND_PORT__", _runningPort.ToString());
56 | privoxyConfig = privoxyConfig.Replace("__PRIVOXY_BIND_IP__", configuration.shareOverLan ? "0.0.0.0" : "127.0.0.1");
57 | FileManager.ByteArrayToFile(Utils.GetTempPath(_uniqueConfigFile), Encoding.UTF8.GetBytes(privoxyConfig));
58 |
59 | _process = new Process
60 | {
61 | // Configure the process using the StartInfo properties.
62 | StartInfo =
63 | {
64 | FileName = "greendot_privoxy.exe",
65 | Arguments = _uniqueConfigFile,
66 | WorkingDirectory = Utils.GetTempPath(),
67 | WindowStyle = ProcessWindowStyle.Hidden,
68 | UseShellExecute = true,
69 | CreateNoWindow = true
70 | }
71 | };
72 | _process.Start();
73 |
74 | /*
75 | * Add this process to job obj associated with this ss process, so that
76 | * when ss exit unexpectedly, this process will be forced killed by system.
77 | */
78 | _privoxyJob.AddProcess(_process.Handle);
79 | }
80 | }
81 |
82 | public void Stop()
83 | {
84 | if (_process != null)
85 | {
86 | KillProcess(_process);
87 | _process.Dispose();
88 | _process = null;
89 | }
90 | }
91 |
92 | private static void KillProcess(Process p)
93 | {
94 | try
95 | {
96 | p.CloseMainWindow();
97 | p.WaitForExit(100);
98 | if (!p.HasExited)
99 | {
100 | p.Kill();
101 | p.WaitForExit();
102 | }
103 | }
104 | catch (Exception e)
105 | {
106 | Logging.LogUsefulException(e);
107 | }
108 | }
109 |
110 | /*
111 | * We won't like to kill other ss instances' ss_privoxy.exe.
112 | * This function will check whether the given process is created
113 | * by this process by checking the module path or command line.
114 | *
115 | * Since it's required to put ss in different dirs to run muti instances,
116 | * different instance will create their unique "privoxy_UID.conf" where
117 | * UID is hash of ss's location.
118 | */
119 |
120 | private static bool IsChildProcess(Process process)
121 | {
122 | try
123 | {
124 | /*
125 | * Under PortableMode, we could identify it by the path of ss_privoxy.exe.
126 | */
127 | var path = process.MainModule.FileName;
128 |
129 | return Utils.GetTempPath("greendot_privoxy.exe").Equals(path);
130 |
131 | }
132 | catch (Exception ex)
133 | {
134 | /*
135 | * Sometimes Process.GetProcessesByName will return some processes that
136 | * are already dead, and that will cause exceptions here.
137 | * We could simply ignore those exceptions.
138 | */
139 | Logging.LogUsefulException(ex);
140 | return false;
141 | }
142 | }
143 |
144 | private int GetFreePort()
145 | {
146 | int defaultPort = 8123;
147 | try
148 | {
149 | // TCP stack please do me a favor
150 | TcpListener l = new TcpListener(IPAddress.Loopback, 0);
151 | l.Start();
152 | var port = ((IPEndPoint)l.LocalEndpoint).Port;
153 | l.Stop();
154 | return port;
155 | }
156 | catch (Exception e)
157 | {
158 | // in case access denied
159 | Logging.LogUsefulException(e);
160 | return defaultPort;
161 | }
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Service/Sip003Plugin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Net;
5 | using System.Net.Sockets;
6 | using System.Reflection;
7 | using ShadowSocks.Model;
8 | using ShadowSocks.Util.ProcessManagement;
9 |
10 | namespace ShadowSocks.Controller.Service
11 | {
12 | public sealed class Sip003Plugin : IDisposable
13 | {
14 | public IPEndPoint LocalEndPoint { get; private set; }
15 | public int ProcessId => _started ? _pluginProcess.Id : 0;
16 |
17 | private readonly object _startProcessLock = new object();
18 | private readonly Job _pluginJob;
19 | private readonly Process _pluginProcess;
20 | private bool _started;
21 | private bool _disposed;
22 |
23 | public static Sip003Plugin CreateIfConfigured(Server server)
24 | {
25 | if (server == null)
26 | {
27 | throw new ArgumentNullException(nameof(server));
28 | }
29 |
30 | if (string.IsNullOrWhiteSpace(server.plugin))
31 | {
32 | return null;
33 | }
34 |
35 | return new Sip003Plugin(server.plugin, server.plugin_opts, server.server, server.server_port);
36 | }
37 |
38 | private Sip003Plugin(string plugin, string pluginOpts, string serverAddress, int serverPort)
39 | {
40 | if (plugin == null) throw new ArgumentNullException(nameof(plugin));
41 | if (string.IsNullOrWhiteSpace(serverAddress))
42 | {
43 | throw new ArgumentException("Value cannot be null or whitespace.", nameof(serverAddress));
44 | }
45 | if ((ushort)serverPort != serverPort)
46 | {
47 | throw new ArgumentOutOfRangeException("serverPort");
48 | }
49 |
50 | var appPath = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase).LocalPath);
51 |
52 | _pluginProcess = new Process
53 | {
54 | StartInfo = new ProcessStartInfo
55 | {
56 | FileName = plugin,
57 | UseShellExecute = false,
58 | CreateNoWindow = true,
59 | ErrorDialog = false,
60 | WindowStyle = ProcessWindowStyle.Hidden,
61 | WorkingDirectory = appPath ?? Environment.CurrentDirectory,
62 | Environment =
63 | {
64 | ["SS_REMOTE_HOST"] = serverAddress,
65 | ["SS_REMOTE_PORT"] = serverPort.ToString(),
66 | ["SS_PLUGIN_OPTIONS"] = pluginOpts
67 | }
68 | }
69 | };
70 |
71 | _pluginJob = new Job();
72 | }
73 |
74 | public bool StartIfNeeded()
75 | {
76 | if (_disposed)
77 | {
78 | throw new ObjectDisposedException(GetType().FullName);
79 | }
80 |
81 | lock (_startProcessLock)
82 | {
83 | if (_started && !_pluginProcess.HasExited)
84 | {
85 | return false;
86 | }
87 |
88 | var localPort = GetNextFreeTcpPort();
89 | LocalEndPoint = new IPEndPoint(IPAddress.Loopback, localPort);
90 |
91 | _pluginProcess.StartInfo.Environment["SS_LOCAL_HOST"] = LocalEndPoint.Address.ToString();
92 | _pluginProcess.StartInfo.Environment["SS_LOCAL_PORT"] = LocalEndPoint.Port.ToString();
93 | _pluginProcess.Start();
94 | _pluginJob.AddProcess(_pluginProcess.Handle);
95 | _started = true;
96 | }
97 |
98 | return true;
99 | }
100 |
101 | static int GetNextFreeTcpPort()
102 | {
103 | var l = new TcpListener(IPAddress.Loopback, 0);
104 | l.Start();
105 | int port = ((IPEndPoint)l.LocalEndpoint).Port;
106 | l.Stop();
107 | return port;
108 | }
109 |
110 | public void Dispose()
111 | {
112 | if (_disposed)
113 | {
114 | return;
115 | }
116 |
117 | try
118 | {
119 | if (!_pluginProcess.HasExited)
120 | {
121 | _pluginProcess.Kill();
122 | _pluginProcess.WaitForExit();
123 | }
124 | }
125 | catch (Exception) { }
126 | finally
127 | {
128 | try
129 | {
130 | _pluginProcess.Dispose();
131 | _pluginJob.Dispose();
132 | }
133 | catch (Exception) { }
134 |
135 | _disposed = true;
136 | }
137 | }
138 | }
139 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Service/UpdateChecker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net;
4 | using System.Text.RegularExpressions;
5 | using Newtonsoft.Json.Linq;
6 | using ShadowSocks.Model;
7 | using ShadowSocks.Util;
8 | using ShadowSocks.Config;
9 | using ShadowSocks.Extensions;
10 |
11 | namespace ShadowSocks.Controller
12 | {
13 | public class UpdateChecker
14 | {
15 | private const string UserAgent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36";
16 |
17 | private Configuration config;
18 | public bool NewVersionFound;
19 | public string LatestVersionNumber;
20 | public string LatestVersionSuffix;
21 | public string LatestVersionName;
22 | public string LatestVersionURL;
23 | public string LatestVersionLocalName;
24 | public event EventHandler CheckUpdateCompleted;
25 |
26 | public static string Version;
27 |
28 | private class CheckUpdateTimer : System.Timers.Timer
29 | {
30 | public Configuration config;
31 |
32 | public CheckUpdateTimer(int p) : base(p)
33 | {
34 | }
35 | }
36 |
37 | public void CheckUpdate(Configuration config, int delay)
38 | {
39 | CheckUpdateTimer timer = new CheckUpdateTimer(delay);
40 | timer.AutoReset = false;
41 | timer.Elapsed += Timer_Elapsed;
42 | timer.config = config;
43 | timer.Enabled = true;
44 | }
45 |
46 | private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
47 | {
48 | CheckUpdateTimer timer = (CheckUpdateTimer)sender;
49 | Configuration config = timer.config;
50 | timer.Elapsed -= Timer_Elapsed;
51 | timer.Enabled = false;
52 | timer.Dispose();
53 | CheckUpdate(config);
54 | }
55 |
56 | public void CheckUpdate(Configuration config)
57 | {
58 | this.config = config;
59 | try
60 | {
61 | Version = Util.Utils.getCurrentVersion();
62 | string checkUri = Constants.DEFAULT_SEVER_ROOT + Constants.UPDATE_CHECK_API + "?device=windows" + "&version=" + Version;
63 |
64 | Logging.Debug("Checking updates...");
65 | WebClient http = CreateWebClient();
66 | http.DownloadStringCompleted += http_DownloadStringCompleted;
67 | http.DownloadStringAsync(new Uri(checkUri));
68 | }
69 | catch (Exception ex)
70 | {
71 | Logging.LogUsefulException(ex);
72 | }
73 | }
74 |
75 | private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
76 | {
77 | try
78 | {
79 | string response = e.Result;
80 | JObject result = JObject.Parse(response);
81 | if (result.ok() && result.content() != null)
82 | {
83 | var content = result.content();
84 | var version = content.version;
85 | var downloadLink = content.downloadlink;
86 | var name = content.name;
87 | if (version != null && downloadLink != null && name != null)
88 | {
89 | NewVersionFound = true;
90 | LatestVersionNumber = (string)version;
91 | LatestVersionURL = (string)downloadLink;
92 | LatestVersionName = (string)name;
93 | startDownload();
94 | }
95 | }
96 | else
97 | {
98 | Logging.Debug("No update is available");
99 | if (CheckUpdateCompleted != null)
100 | {
101 | CheckUpdateCompleted(this, new EventArgs());
102 | }
103 | }
104 | }
105 | catch (Exception ex)
106 | {
107 | Logging.LogUsefulException(ex);
108 | }
109 | }
110 |
111 | private void startDownload()
112 | {
113 | try
114 | {
115 | LatestVersionLocalName = Utils.GetTempPath(LatestVersionName);
116 | WebClient http = CreateWebClient();
117 | http.DownloadFileCompleted += Http_DownloadFileCompleted;
118 | http.DownloadFileAsync(new Uri(LatestVersionURL), LatestVersionLocalName);
119 | }
120 | catch (Exception ex)
121 | {
122 | Logging.LogUsefulException(ex);
123 | }
124 | }
125 |
126 | private void Http_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
127 | {
128 | try
129 | {
130 | if (e.Error != null)
131 | {
132 | Logging.LogUsefulException(e.Error);
133 | return;
134 | }
135 | Logging.Debug($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}");
136 | if (CheckUpdateCompleted != null)
137 | {
138 | CheckUpdateCompleted(this, new EventArgs());
139 | }
140 | }
141 | catch (Exception ex)
142 | {
143 | Logging.LogUsefulException(ex);
144 | }
145 | }
146 |
147 | private WebClient CreateWebClient()
148 | {
149 | WebClient http = new WebClient();
150 | http.Headers.Add("User-Agent", UserAgent);
151 | //http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort);
152 | return http;
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Strategy/BalancingStrategy.cs:
--------------------------------------------------------------------------------
1 | using ShadowSocks.Controller;
2 | using ShadowSocks.Model;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Net;
6 | using System.Text;
7 |
8 | namespace ShadowSocks.Controller.Strategy
9 | {
10 | class BalancingStrategy : IStrategy
11 | {
12 | ShadowSocksController _controller;
13 | Random _random;
14 |
15 | public BalancingStrategy(ShadowSocksController controller)
16 | {
17 | _controller = controller;
18 | _random = new Random();
19 | }
20 |
21 | public string Name
22 | {
23 | get { return I18N.GetString("Load Balance"); }
24 | }
25 |
26 | public string ID
27 | {
28 | get { return "com.greendot.strategy.balancing"; }
29 | }
30 |
31 | public void ReloadServers()
32 | {
33 | // do nothing
34 | }
35 |
36 | public Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint, EndPoint destEndPoint)
37 | {
38 | var configs = _controller.GetCurrentConfiguration().configs;
39 | int index;
40 | if (type == IStrategyCallerType.TCP)
41 | {
42 | index = _random.Next();
43 | }
44 | else
45 | {
46 | index = localIPEndPoint.GetHashCode();
47 | }
48 | return configs[index % configs.Count];
49 | }
50 |
51 | public void UpdateLatency(Model.Server server, TimeSpan latency)
52 | {
53 | // do nothing
54 | }
55 |
56 | public void UpdateLastRead(Model.Server server)
57 | {
58 | // do nothing
59 | }
60 |
61 | public void UpdateLastWrite(Model.Server server)
62 | {
63 | // do nothing
64 | }
65 |
66 | public void SetFailure(Model.Server server)
67 | {
68 | // do nothing
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Strategy/IStrategy.cs:
--------------------------------------------------------------------------------
1 | using ShadowSocks.Model;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Net;
5 | using System.Text;
6 |
7 | namespace ShadowSocks.Controller.Strategy
8 | {
9 | public enum IStrategyCallerType
10 | {
11 | TCP,
12 | UDP
13 | }
14 |
15 | /*
16 | * IStrategy
17 | *
18 | * Subclasses must be thread-safe
19 | */
20 | public interface IStrategy
21 | {
22 | string Name { get; }
23 |
24 | string ID { get; }
25 |
26 | /*
27 | * Called when servers need to be reloaded, i.e. new configuration saved
28 | */
29 | void ReloadServers();
30 |
31 | /*
32 | * Get a new server to use in TCPRelay or UDPRelay
33 | */
34 | Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint, EndPoint destEndPoint);
35 |
36 | /*
37 | * TCPRelay will call this when latency of a server detected
38 | */
39 | void UpdateLatency(Server server, TimeSpan latency);
40 |
41 | /*
42 | * TCPRelay will call this when reading from a server
43 | */
44 | void UpdateLastRead(Server server);
45 |
46 | /*
47 | * TCPRelay will call this when writing to a server
48 | */
49 | void UpdateLastWrite(Server server);
50 |
51 | /*
52 | * TCPRelay will call this when fatal failure detected
53 | */
54 | void SetFailure(Server server);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/Strategy/StrategyManager.cs:
--------------------------------------------------------------------------------
1 | using ShadowSocks.Controller;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace ShadowSocks.Controller.Strategy
7 | {
8 | class StrategyManager
9 | {
10 | List _strategies;
11 | public StrategyManager(ShadowSocksController controller)
12 | {
13 | _strategies = new List();
14 | _strategies.Add(new BalancingStrategy(controller));
15 | _strategies.Add(new HighAvailabilityStrategy(controller));
16 | _strategies.Add(new StatisticsStrategy(controller));
17 | // TODO: load DLL plugins
18 | }
19 | public IList GetStrategies()
20 | {
21 | return _strategies;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/System/AutoStartup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Windows.Forms;
4 | using Microsoft.Win32;
5 | using ShadowSocks.Util;
6 |
7 | namespace ShadowSocks.Controller
8 | {
9 | static class AutoStartup
10 | {
11 | // Don't use Application.ExecutablePath
12 | // see https://stackoverflow.com/questions/12945805/odd-c-sharp-path-issue
13 | private static readonly string ExecutablePath = Assembly.GetEntryAssembly().Location;
14 |
15 | private static string Key = "greendot_" + Application.StartupPath.GetHashCode();
16 |
17 | public static bool Set(bool enabled)
18 | {
19 | RegistryKey runKey = null;
20 | try
21 | {
22 | runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
23 | if ( runKey == null ) {
24 | Logging.Error( @"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run" );
25 | return false;
26 | }
27 | if (enabled)
28 | {
29 | runKey.SetValue(Key, ExecutablePath);
30 | }
31 | else
32 | {
33 | runKey.DeleteValue(Key);
34 | }
35 | return true;
36 | }
37 | catch (Exception e)
38 | {
39 | Logging.LogUsefulException(e);
40 | return false;
41 | }
42 | finally
43 | {
44 | if (runKey != null)
45 | {
46 | try {
47 | runKey.Close();
48 | runKey.Dispose();
49 | } catch (Exception e)
50 | { Logging.LogUsefulException(e); }
51 | }
52 | }
53 | }
54 |
55 | public static bool Check()
56 | {
57 | RegistryKey runKey = null;
58 | try
59 | {
60 | runKey = Utils.OpenRegKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
61 | if (runKey == null) {
62 | Logging.Error(@"Cannot find HKCU\Software\Microsoft\Windows\CurrentVersion\Run");
63 | return false;
64 | }
65 | string[] runList = runKey.GetValueNames();
66 | foreach (string item in runList)
67 | {
68 | if (item.Equals(Key, StringComparison.OrdinalIgnoreCase))
69 | return true;
70 | else if (item.Equals("GreenDot", StringComparison.OrdinalIgnoreCase)) // Compatibility with older versions
71 | {
72 | string value = Convert.ToString(runKey.GetValue(item));
73 | if (ExecutablePath.Equals(value, StringComparison.OrdinalIgnoreCase))
74 | {
75 | runKey.DeleteValue(item);
76 | runKey.SetValue(Key, ExecutablePath);
77 | return true;
78 | }
79 | }
80 | }
81 | return false;
82 | }
83 | catch (Exception e)
84 | {
85 | Logging.LogUsefulException(e);
86 | return false;
87 | }
88 | finally
89 | {
90 | if (runKey != null)
91 | {
92 | try {
93 | runKey.Close();
94 | runKey.Dispose();
95 | } catch (Exception e)
96 | { Logging.LogUsefulException(e); }
97 | }
98 | }
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/System/Hotkeys/HotkeyCallbacks.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 |
4 | namespace ShadowSocks.Controller.Hotkeys
5 | {
6 | public class HotkeyCallbacks
7 | {
8 |
9 | public static void InitInstance(ShadowSocksController controller)
10 | {
11 | if (Instance != null)
12 | {
13 | return;
14 | }
15 |
16 | Instance = new HotkeyCallbacks(controller);
17 | }
18 |
19 | ///
20 | /// Create hotkey callback handler delegate based on callback name
21 | ///
22 | ///
23 | ///
24 | public static Delegate GetCallback(string methodname)
25 | {
26 | if (methodname.IsNullOrEmpty()) throw new ArgumentException(nameof(methodname));
27 | MethodInfo dynMethod = typeof(HotkeyCallbacks).GetMethod(methodname,
28 | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);
29 | return dynMethod == null ? null : Delegate.CreateDelegate(typeof(HotKeys.HotKeyCallBackHandler), Instance, dynMethod);
30 | }
31 |
32 | #region Singleton
33 |
34 | private static HotkeyCallbacks Instance { get; set; }
35 |
36 | private readonly ShadowSocksController _controller;
37 |
38 | private HotkeyCallbacks(ShadowSocksController controller)
39 | {
40 | _controller = controller;
41 | }
42 |
43 | #endregion
44 |
45 | #region Callbacks
46 |
47 | private void SwitchSystemProxyCallback()
48 | {
49 | bool enabled = _controller.GetConfigurationCopy().enabled;
50 | _controller.ToggleEnable(!enabled);
51 | }
52 |
53 | private void SwitchProxyModeCallback()
54 | {
55 | var config = _controller.GetConfigurationCopy();
56 | if (config.enabled == false) return;
57 | var currStatus = config.global;
58 | _controller.ToggleGlobal(!currStatus);
59 | }
60 |
61 | private void SwitchAllowLanCallback()
62 | {
63 | var status = _controller.GetConfigurationCopy().shareOverLan;
64 | _controller.ToggleShareOverLAN(!status);
65 | }
66 |
67 | private void ShowLogsCallback()
68 | {
69 | //Program.MenuController.ShowLogForm_HotKey();
70 | }
71 |
72 | private void ServerMoveUpCallback()
73 | {
74 | int currIndex;
75 | int serverCount;
76 | GetCurrServerInfo(out currIndex, out serverCount);
77 | if (currIndex - 1 < 0)
78 | {
79 | // revert to last server
80 | currIndex = serverCount - 1;
81 | }
82 | else
83 | {
84 | currIndex -= 1;
85 | }
86 | _controller.SelectServerIndex(currIndex);
87 | }
88 |
89 | private void ServerMoveDownCallback()
90 | {
91 | int currIndex;
92 | int serverCount;
93 | GetCurrServerInfo(out currIndex, out serverCount);
94 | if (currIndex + 1 == serverCount)
95 | {
96 | // revert to first server
97 | currIndex = 0;
98 | }
99 | else
100 | {
101 | currIndex += 1;
102 | }
103 | _controller.SelectServerIndex(currIndex);
104 | }
105 |
106 | private void GetCurrServerInfo(out int currIndex, out int serverCount)
107 | {
108 | var currConfig = _controller.GetCurrentConfiguration();
109 | currIndex = currConfig.index;
110 | serverCount = currConfig.configs.Count;
111 | }
112 |
113 | #endregion
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/System/Hotkeys/Hotkeys.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Windows.Input;
6 | using GlobalHotKey;
7 |
8 | namespace ShadowSocks.Controller.Hotkeys
9 | {
10 | public static class HotKeys
11 | {
12 | private static HotKeyManager _hotKeyManager;
13 |
14 | public delegate void HotKeyCallBackHandler();
15 | // map key and corresponding handler function
16 | private static Dictionary _keymap = new Dictionary();
17 |
18 | public static void Init(ShadowSocksController controller)
19 | {
20 | _hotKeyManager = new HotKeyManager();
21 | _hotKeyManager.KeyPressed += HotKeyManagerPressed;
22 |
23 | HotkeyCallbacks.InitInstance(controller);
24 | }
25 |
26 | public static void Destroy()
27 | {
28 | _hotKeyManager.KeyPressed -= HotKeyManagerPressed;
29 | _hotKeyManager.Dispose();
30 | }
31 |
32 | private static void HotKeyManagerPressed(object sender, KeyPressedEventArgs e)
33 | {
34 | var hotkey = e.HotKey;
35 | HotKeyCallBackHandler callback;
36 | if (_keymap.TryGetValue(hotkey, out callback))
37 | callback();
38 | }
39 |
40 | public static bool IsHotkeyExists( HotKey hotKey )
41 | {
42 | if (hotKey == null) throw new ArgumentNullException(nameof(hotKey));
43 | return _keymap.Any( v => v.Key.Equals( hotKey ) );
44 | }
45 |
46 | public static bool IsCallbackExists( HotKeyCallBackHandler cb, out HotKey hotkey)
47 | {
48 | if (cb == null) throw new ArgumentNullException(nameof(cb));
49 | try
50 | {
51 | var key = _keymap.First(x => x.Value == cb).Key;
52 | hotkey = key;
53 | return true;
54 | }
55 | catch (InvalidOperationException)
56 | {
57 | // not found
58 | hotkey = null;
59 | return false;
60 | }
61 | }
62 | public static string HotKey2Str( HotKey key )
63 | {
64 | if (key == null) throw new ArgumentNullException(nameof(key));
65 | return HotKey2Str( key.Key, key.Modifiers );
66 | }
67 |
68 | public static string HotKey2Str( Key key, ModifierKeys modifier )
69 | {
70 | if (!Enum.IsDefined(typeof(Key), key))
71 | throw new InvalidEnumArgumentException(nameof(key), (int) key, typeof(Key));
72 | try
73 | {
74 | ModifierKeysConverter mkc = new ModifierKeysConverter();
75 | var keyStr = Enum.GetName(typeof(Key), key);
76 | var modifierStr = mkc.ConvertToInvariantString(modifier);
77 |
78 | return $"{modifierStr}+{keyStr}";
79 | }
80 | catch (NotSupportedException)
81 | {
82 | // converter exception
83 | return null;
84 | }
85 | }
86 |
87 | public static HotKey Str2HotKey(string s)
88 | {
89 | try
90 | {
91 | if (s.IsNullOrEmpty()) return null;
92 | int offset = s.LastIndexOf("+", StringComparison.OrdinalIgnoreCase);
93 | if (offset <= 0) return null;
94 | string modifierStr = s.Substring(0, offset).Trim();
95 | string keyStr = s.Substring(offset + 1).Trim();
96 |
97 | KeyConverter kc = new KeyConverter();
98 | ModifierKeysConverter mkc = new ModifierKeysConverter();
99 | Key key = (Key) kc.ConvertFrom(keyStr.ToUpper());
100 | ModifierKeys modifier = (ModifierKeys) mkc.ConvertFrom(modifierStr.ToUpper());
101 |
102 | return new HotKey(key, modifier);
103 | }
104 | catch (NotSupportedException)
105 | {
106 | // converter exception
107 | return null;
108 | }
109 | catch (NullReferenceException)
110 | {
111 | return null;
112 | }
113 | }
114 |
115 | public static bool Regist( HotKey key, HotKeyCallBackHandler callBack )
116 | {
117 | if (key == null)
118 | throw new ArgumentNullException(nameof(key));
119 | if (callBack == null)
120 | throw new ArgumentNullException(nameof(callBack));
121 | try
122 | {
123 | _hotKeyManager.Register(key);
124 | _keymap[key] = callBack;
125 | return true;
126 | }
127 | catch (ArgumentException)
128 | {
129 | // already called this method with the specific hotkey
130 | // return success silently
131 | return true;
132 | }
133 | catch (Win32Exception)
134 | {
135 | // this hotkey already registered by other programs
136 | // notify user to change key
137 | return false;
138 | }
139 | }
140 |
141 | public static bool Regist(Key key, ModifierKeys modifiers, HotKeyCallBackHandler callBack)
142 | {
143 | if (!Enum.IsDefined(typeof(Key), key))
144 | throw new InvalidEnumArgumentException(nameof(key), (int) key, typeof(Key));
145 | try
146 | {
147 | var hotkey = _hotKeyManager.Register(key, modifiers);
148 | _keymap[hotkey] = callBack;
149 | return true;
150 | }
151 | catch (ArgumentException)
152 | {
153 | // already called this method with the specific hotkey
154 | // return success silently
155 | return true;
156 | }
157 | catch (Win32Exception)
158 | {
159 | // already registered by other programs
160 | // notify user to change key
161 | return false;
162 | }
163 | }
164 |
165 | public static void UnRegist(HotKey key)
166 | {
167 | if (key == null)
168 | throw new ArgumentNullException(nameof(key));
169 | _hotKeyManager.Unregister(key);
170 | if(_keymap.ContainsKey(key))
171 | _keymap.Remove(key);
172 | }
173 | }
174 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Controller/System/SystemProxy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using ShadowSocks.Model;
3 | using ShadowSocks.Util.SystemProxy;
4 |
5 | namespace ShadowSocks.Controller
6 | {
7 | public static class SystemProxy
8 | {
9 | private static string GetTimestamp(DateTime value)
10 | {
11 | return value.ToString("yyyyMMddHHmmssfff");
12 | }
13 |
14 | public static void Disable()
15 | {
16 | WinINet.SetIEProxy(false, false, "", "");
17 | }
18 |
19 | public static void Update(Configuration config, bool forceDisable, PACServer pacSrv)
20 | {
21 | bool global = config.global;
22 | bool enabled = config.enabled;
23 |
24 | if (forceDisable)
25 | {
26 | enabled = false;
27 | }
28 |
29 | try
30 | {
31 | if (enabled)
32 | {
33 | if (global)
34 | {
35 | Sysproxy.SetIEProxy(true, true, "127.0.0.1:" + config.localPort.ToString(), null);
36 | }
37 | else
38 | {
39 | string pacUrl;
40 | if (config.useOnlinePac && !config.pacUrl.IsNullOrEmpty())
41 | {
42 | pacUrl = config.pacUrl;
43 | }
44 | else
45 | {
46 | pacUrl = pacSrv.PacUrl;
47 | }
48 | Sysproxy.SetIEProxy(true, false, null, pacUrl);
49 | }
50 | }
51 | else
52 | {
53 | Sysproxy.SetIEProxy(false, false, null, null);
54 | }
55 | }
56 | catch (ProxyException ex)
57 | {
58 | Logging.LogUsefulException(ex);
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/abp.js.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Data/abp.js.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/libsscrypto.dll.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Data/libsscrypto.dll.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/mgwz.dll.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Data/mgwz.dll.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/privoxy.exe.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Data/privoxy.exe.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/privoxy_conf.txt:
--------------------------------------------------------------------------------
1 | listen-address __PRIVOXY_BIND_IP__:__PRIVOXY_BIND_PORT__
2 | toggle 0
3 | logfile greendot_privoxy.log
4 | show-on-task-bar 0
5 | activity-animation 0
6 | forward-socks5 / 127.0.0.1:__SOCKS_PORT__ .
7 | hide-console
8 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/proxy.pac.txt.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Data/proxy.pac.txt.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/sysproxy.exe.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Data/sysproxy.exe.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/sysproxy64.exe.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Data/sysproxy64.exe.gz
--------------------------------------------------------------------------------
/shadowsocks-csharp/Data/user-rule.txt:
--------------------------------------------------------------------------------
1 | ! Put user rules line by line in this file.
2 | ! See https://adblockplus.org/en/filter-cheatsheet
3 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/AEAD/AEADSodiumEncryptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using ShadowSocks.Controller;
5 | using ShadowSocks.Encryption.Exception;
6 |
7 | namespace ShadowSocks.Encryption.AEAD
8 | {
9 | public class AEADSodiumEncryptor
10 | : AEADEncryptor, IDisposable
11 | {
12 | private const int CIPHER_CHACHA20IETFPOLY1305 = 1;
13 | private const int CIPHER_AES256GCM = 2;
14 |
15 | private byte[] _sodiumEncSubkey;
16 | private byte[] _sodiumDecSubkey;
17 |
18 | public AEADSodiumEncryptor(string method, string password)
19 | : base(method, password)
20 | {
21 | _sodiumEncSubkey = new byte[keyLen];
22 | _sodiumDecSubkey = new byte[keyLen];
23 | }
24 |
25 | private static Dictionary _ciphers = new Dictionary
26 | {
27 | {"chacha20-ietf-poly1305", new EncryptorInfo(32, 32, 12, 16, CIPHER_CHACHA20IETFPOLY1305)},
28 | {"aes-256-gcm", new EncryptorInfo(32, 32, 12, 16, CIPHER_AES256GCM)},
29 | };
30 |
31 | public static List SupportedCiphers()
32 | {
33 | return new List(_ciphers.Keys);
34 | }
35 |
36 | protected override Dictionary getCiphers()
37 | {
38 | return _ciphers;
39 | }
40 |
41 | public override void InitCipher(byte[] salt, bool isEncrypt, bool isUdp)
42 | {
43 | base.InitCipher(salt, isEncrypt, isUdp);
44 | DeriveSessionKey(isEncrypt ? _encryptSalt : _decryptSalt, _Masterkey,
45 | isEncrypt ? _sodiumEncSubkey : _sodiumDecSubkey);
46 | }
47 |
48 |
49 | public override int cipherEncrypt(byte[] plaintext, uint plen, byte[] ciphertext, ref uint clen)
50 | {
51 | Debug.Assert(_sodiumEncSubkey != null);
52 | // buf: all plaintext
53 | // outbuf: ciphertext + tag
54 | int ret;
55 | ulong encClen = 0;
56 | Logging.Dump("_encNonce before enc", _encNonce, nonceLen);
57 | Logging.Dump("_sodiumEncSubkey", _sodiumEncSubkey, keyLen);
58 | Logging.Dump("before cipherEncrypt: plain", plaintext, (int) plen);
59 | switch (_cipher)
60 | {
61 | case CIPHER_CHACHA20IETFPOLY1305:
62 | ret = Sodium.crypto_aead_chacha20poly1305_ietf_encrypt(ciphertext, ref encClen,
63 | plaintext, (ulong) plen,
64 | null, 0,
65 | null, _encNonce,
66 | _sodiumEncSubkey);
67 | break;
68 | case CIPHER_AES256GCM:
69 | ret = Sodium.crypto_aead_aes256gcm_encrypt(ciphertext, ref encClen,
70 | plaintext, (ulong)plen,
71 | null, 0,
72 | null, _encNonce,
73 | _sodiumEncSubkey);
74 | break;
75 | default:
76 | throw new System.Exception("not implemented");
77 | }
78 | if (ret != 0) throw new CryptoErrorException();
79 | Logging.Dump("after cipherEncrypt: cipher", ciphertext, (int) encClen);
80 | clen = (uint) encClen;
81 | return ret;
82 | }
83 |
84 | public override int cipherDecrypt(byte[] ciphertext, uint clen, byte[] plaintext, ref uint plen)
85 | {
86 | Debug.Assert(_sodiumDecSubkey != null);
87 | // buf: ciphertext + tag
88 | // outbuf: plaintext
89 | int ret;
90 | ulong decPlen = 0;
91 | Logging.Dump("_decNonce before dec", _decNonce, nonceLen);
92 | Logging.Dump("_sodiumDecSubkey", _sodiumDecSubkey, keyLen);
93 | Logging.Dump("before cipherDecrypt: cipher", ciphertext, (int) clen);
94 | switch (_cipher)
95 | {
96 | case CIPHER_CHACHA20IETFPOLY1305:
97 | ret = Sodium.crypto_aead_chacha20poly1305_ietf_decrypt(plaintext, ref decPlen,
98 | null,
99 | ciphertext, (ulong) clen,
100 | null, 0,
101 | _decNonce, _sodiumDecSubkey);
102 | break;
103 | case CIPHER_AES256GCM:
104 | ret = Sodium.crypto_aead_aes256gcm_decrypt(plaintext, ref decPlen,
105 | null,
106 | ciphertext, (ulong)clen,
107 | null, 0,
108 | _decNonce, _sodiumDecSubkey);
109 | break;
110 | default:
111 | throw new System.Exception("not implemented");
112 | }
113 |
114 | if (ret != 0) throw new CryptoErrorException();
115 | Logging.Dump("after cipherDecrypt: plain", plaintext, (int) decPlen);
116 | plen = (uint) decPlen;
117 | return ret;
118 | }
119 |
120 | public override void Dispose()
121 | {
122 | }
123 | }
124 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/DES.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web;
3 | using System.Security.Cryptography;
4 | using System.IO;
5 | using System.Text;
6 | using ShadowSocks.Config;
7 |
8 | namespace ShadowSocks.Encryption {
9 |
10 | public class DES
11 | {
12 | private static byte[] DESIV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
13 |
14 | public static string DESEnCode(string pToEncrypt)
15 | {
16 | DESCryptoServiceProvider des = new DESCryptoServiceProvider();
17 | byte[] inputByteArray = Encoding.GetEncoding("UTF-8").GetBytes(pToEncrypt);
18 |
19 | des.Key = ASCIIEncoding.ASCII.GetBytes(Constants.DES_KEY);
20 | des.IV = ASCIIEncoding.ASCII.GetBytes(Constants.DES_KEY);
21 | MemoryStream ms = new MemoryStream();
22 | CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
23 |
24 | cs.Write(inputByteArray, 0, inputByteArray.Length);
25 | cs.FlushFinalBlock();
26 |
27 | StringBuilder ret = new StringBuilder();
28 | foreach (byte b in ms.ToArray())
29 | {
30 | ret.AppendFormat("{0:X2}", b);
31 | }
32 | ret.ToString();
33 | return ret.ToString();
34 | }
35 |
36 | public static string DESDeCode(string pToDecrypt)
37 | {
38 | DESCryptoServiceProvider des = new DESCryptoServiceProvider();
39 | byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
40 | for (int x = 0; x < pToDecrypt.Length / 2; x++)
41 | {
42 | int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
43 | inputByteArray[x] = (byte)i;
44 | }
45 |
46 | des.Key = ASCIIEncoding.ASCII.GetBytes(Constants.DES_KEY);
47 | des.IV = ASCIIEncoding.ASCII.GetBytes(Constants.DES_KEY);
48 | MemoryStream ms = new MemoryStream();
49 | CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
50 | cs.Write(inputByteArray, 0, inputByteArray.Length);
51 | cs.FlushFinalBlock();
52 |
53 | StringBuilder ret = new StringBuilder();
54 |
55 | return Encoding.Default.GetString(ms.ToArray());
56 | }
57 | }
58 |
59 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/EncryptorBase.cs:
--------------------------------------------------------------------------------
1 | namespace ShadowSocks.Encryption
2 | {
3 | public class EncryptorInfo
4 | {
5 | public int KeySize;
6 | public int IvSize;
7 | public int SaltSize;
8 | public int TagSize;
9 | public int NonceSize;
10 | public int Type;
11 | public string InnerLibName;
12 |
13 | // For those who make use of internal crypto method name
14 | // e.g. mbed TLS
15 |
16 | #region Stream ciphers
17 |
18 | public EncryptorInfo(string innerLibName, int keySize, int ivSize, int type)
19 | {
20 | this.KeySize = keySize;
21 | this.IvSize = ivSize;
22 | this.Type = type;
23 | this.InnerLibName = innerLibName;
24 | }
25 |
26 | public EncryptorInfo(int keySize, int ivSize, int type)
27 | {
28 | this.KeySize = keySize;
29 | this.IvSize = ivSize;
30 | this.Type = type;
31 | this.InnerLibName = string.Empty;
32 | }
33 |
34 | #endregion
35 |
36 | #region AEAD ciphers
37 |
38 | public EncryptorInfo(string innerLibName, int keySize, int saltSize, int nonceSize, int tagSize, int type)
39 | {
40 | this.KeySize = keySize;
41 | this.SaltSize = saltSize;
42 | this.NonceSize = nonceSize;
43 | this.TagSize = tagSize;
44 | this.Type = type;
45 | this.InnerLibName = innerLibName;
46 | }
47 |
48 | public EncryptorInfo(int keySize, int saltSize, int nonceSize, int tagSize, int type)
49 | {
50 | this.KeySize = keySize;
51 | this.SaltSize = saltSize;
52 | this.NonceSize = nonceSize;
53 | this.TagSize = tagSize;
54 | this.Type = type;
55 | this.InnerLibName = string.Empty;
56 | }
57 |
58 | #endregion
59 | }
60 |
61 | public abstract class EncryptorBase
62 | : IEncryptor
63 | {
64 | public const int MAX_INPUT_SIZE = 32768;
65 |
66 | public const int MAX_DOMAIN_LEN = 255;
67 | public const int ADDR_PORT_LEN = 2;
68 | public const int ADDR_ATYP_LEN = 1;
69 |
70 | public const int ATYP_IPv4 = 0x01;
71 | public const int ATYP_DOMAIN = 0x03;
72 | public const int ATYP_IPv6 = 0x04;
73 |
74 | public const int MD5_LEN = 16;
75 |
76 | protected EncryptorBase(string method, string password)
77 | {
78 | Method = method;
79 | Password = password;
80 | }
81 |
82 | protected string Method;
83 | protected string Password;
84 |
85 | public abstract void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
86 |
87 | public abstract void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
88 |
89 | public abstract void EncryptUDP(byte[] buf, int length, byte[] outbuf, out int outlength);
90 |
91 | public abstract void DecryptUDP(byte[] buf, int length, byte[] outbuf, out int outlength);
92 |
93 | public abstract void Dispose();
94 |
95 | public int AddrBufLength { get; set; } = - 1;
96 | }
97 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/EncryptorFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using ShadowSocks.Encryption.AEAD;
5 | using ShadowSocks.Encryption.Stream;
6 |
7 | namespace ShadowSocks.Encryption
8 | {
9 | public static class EncryptorFactory
10 | {
11 | private static Dictionary _registeredEncryptors = new Dictionary();
12 |
13 | private static readonly Type[] ConstructorTypes = {typeof(string), typeof(string)};
14 |
15 | static EncryptorFactory()
16 | {
17 | var AEADMbedTLSEncryptorSupportedCiphers = AEADMbedTLSEncryptor.SupportedCiphers();
18 | var AEADSodiumEncryptorSupportedCiphers = AEADSodiumEncryptor.SupportedCiphers();
19 | if (Sodium.AES256GCMAvailable)
20 | {
21 | // prefer to aes-256-gcm in libsodium
22 | AEADMbedTLSEncryptorSupportedCiphers.Remove("aes-256-gcm");
23 | }
24 | else
25 | {
26 | AEADSodiumEncryptorSupportedCiphers.Remove("aes-256-gcm");
27 | }
28 |
29 | foreach (string method in StreamMbedTLSEncryptor.SupportedCiphers())
30 | {
31 | _registeredEncryptors.Add(method, typeof(StreamMbedTLSEncryptor));
32 | }
33 | foreach (string method in StreamSodiumEncryptor.SupportedCiphers())
34 | {
35 | _registeredEncryptors.Add(method, typeof(StreamSodiumEncryptor));
36 | }
37 | foreach (string method in AEADMbedTLSEncryptorSupportedCiphers)
38 | {
39 | _registeredEncryptors.Add(method, typeof(AEADMbedTLSEncryptor));
40 | }
41 | foreach (string method in AEADSodiumEncryptorSupportedCiphers)
42 | {
43 | _registeredEncryptors.Add(method, typeof(AEADSodiumEncryptor));
44 | }
45 | }
46 |
47 | public static IEncryptor GetEncryptor(string method, string password)
48 | {
49 | if (method.IsNullOrEmpty())
50 | {
51 | method = "aes-256-cfb";
52 | }
53 | method = method.ToLowerInvariant();
54 | Type t = _registeredEncryptors[method];
55 | ConstructorInfo c = t.GetConstructor(ConstructorTypes);
56 | if (c == null) throw new System.Exception("Invalid ctor");
57 | IEncryptor result = (IEncryptor) c.Invoke(new object[] {method, password});
58 | return result;
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/Exception/CryptoException.cs:
--------------------------------------------------------------------------------
1 | namespace ShadowSocks.Encryption.Exception
2 | {
3 | public class CryptoErrorException : System.Exception
4 | {
5 | public CryptoErrorException()
6 | {
7 | }
8 |
9 | public CryptoErrorException(string msg) : base(msg)
10 | {
11 | }
12 |
13 | public CryptoErrorException(string message, System.Exception innerException) : base(message, innerException)
14 | {
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/IEncryptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ShadowSocks.Encryption
4 | {
5 | public interface IEncryptor : IDisposable
6 | {
7 | /* length == -1 means not used */
8 | int AddrBufLength { set; get; }
9 | void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
10 | void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
11 | void EncryptUDP(byte[] buf, int length, byte[] outbuf, out int outlength);
12 | void DecryptUDP(byte[] buf, int length, byte[] outbuf, out int outlength);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/MbedTLS.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Runtime.InteropServices;
4 | using ShadowSocks.Controller;
5 | using ShadowSocks.Properties;
6 | using ShadowSocks.Util;
7 |
8 | namespace ShadowSocks.Encryption
9 | {
10 | public static class MbedTLS
11 | {
12 | private const string DLLNAME = "libsscrypto.dll";
13 |
14 | public const int MBEDTLS_ENCRYPT = 1;
15 | public const int MBEDTLS_DECRYPT = 0;
16 |
17 | static MbedTLS()
18 | {
19 | string dllPath = Utils.GetTempPath(DLLNAME);
20 | try
21 | {
22 | FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
23 | }
24 | catch (IOException)
25 | {
26 | }
27 | catch (System.Exception e)
28 | {
29 | Logging.LogUsefulException(e);
30 | }
31 | LoadLibrary(dllPath);
32 | }
33 |
34 | public static byte[] MD5(byte[] input)
35 | {
36 | byte[] output = new byte[16];
37 | md5(input, (uint) input.Length, output);
38 | return output;
39 | }
40 |
41 | [DllImport("Kernel32.dll")]
42 | private static extern IntPtr LoadLibrary(string path);
43 |
44 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
45 | public static extern void md5(byte[] input, uint ilen, byte[] output);
46 |
47 | ///
48 | /// Get cipher ctx size for unmanaged memory allocation
49 | ///
50 | ///
51 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
52 | public static extern int cipher_get_size_ex();
53 |
54 | #region Cipher layer wrappers
55 |
56 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
57 | public static extern IntPtr cipher_info_from_string(string cipher_name);
58 |
59 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
60 | public static extern void cipher_init(IntPtr ctx);
61 |
62 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
63 | public static extern int cipher_setup(IntPtr ctx, IntPtr cipher_info);
64 |
65 | // XXX: Check operation before using it
66 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
67 | public static extern int cipher_setkey(IntPtr ctx, byte[] key, int key_bitlen, int operation);
68 |
69 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
70 | public static extern int cipher_set_iv(IntPtr ctx, byte[] iv, int iv_len);
71 |
72 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
73 | public static extern int cipher_reset(IntPtr ctx);
74 |
75 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
76 | public static extern int cipher_update(IntPtr ctx, byte[] input, int ilen, byte[] output, ref int olen);
77 |
78 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
79 | public static extern void cipher_free(IntPtr ctx);
80 |
81 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
82 | public static extern int cipher_auth_encrypt(IntPtr ctx,
83 | byte[] iv, uint iv_len,
84 | IntPtr ad, uint ad_len,
85 | byte[] input, uint ilen,
86 | byte[] output, ref uint olen,
87 | byte[] tag, uint tag_len);
88 |
89 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
90 | public static extern int cipher_auth_decrypt(IntPtr ctx,
91 | byte[] iv, uint iv_len,
92 | IntPtr ad, uint ad_len,
93 | byte[] input, uint ilen,
94 | byte[] output, ref uint olen,
95 | byte[] tag, uint tag_len);
96 |
97 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
98 | public static extern int hkdf(byte[] salt,
99 | int salt_len, byte[] ikm, int ikm_len,
100 | byte[] info, int info_len, byte[] okm,
101 | int okm_len);
102 |
103 | #endregion
104 | }
105 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/RNG.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security.Cryptography;
3 |
4 | namespace ShadowSocks.Encryption
5 | {
6 | public static class RNG
7 | {
8 | private static RNGCryptoServiceProvider _rng = null;
9 |
10 | public static void Init()
11 | {
12 | if (_rng == null)
13 | _rng = new RNGCryptoServiceProvider();
14 | }
15 |
16 | public static void Close()
17 | {
18 | if (_rng == null) return;
19 | _rng.Dispose();
20 | _rng = null;
21 | }
22 |
23 | public static void Reload()
24 | {
25 | Close();
26 | Init();
27 | }
28 |
29 | public static void GetBytes(byte[] buf)
30 | {
31 | GetBytes(buf, buf.Length);
32 | }
33 |
34 | public static void GetBytes(byte[] buf, int len)
35 | {
36 | if (_rng == null) Reload();
37 | try
38 | {
39 | _rng.GetBytes(buf, 0, len);
40 | }
41 | catch (System.Exception)
42 | {
43 | // the backup way
44 | byte[] tmp = new byte[len];
45 | _rng.GetBytes(tmp);
46 | Buffer.BlockCopy(tmp, 0, buf, 0, len);
47 | }
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/Sodium.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Runtime.InteropServices;
4 | using ShadowSocks.Controller;
5 | using ShadowSocks.Properties;
6 | using ShadowSocks.Util;
7 |
8 | namespace ShadowSocks.Encryption
9 | {
10 | public static class Sodium
11 | {
12 | private const string DLLNAME = "libsscrypto.dll";
13 |
14 | private static bool _initialized = false;
15 | private static readonly object _initLock = new object();
16 |
17 | public static bool AES256GCMAvailable { get; private set; } = false;
18 |
19 | static Sodium()
20 | {
21 | string dllPath = Utils.GetTempPath(DLLNAME);
22 | try
23 | {
24 | FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
25 | }
26 | catch (IOException)
27 | {
28 | }
29 | catch (System.Exception e)
30 | {
31 | Logging.LogUsefulException(e);
32 | }
33 | LoadLibrary(dllPath);
34 |
35 | lock (_initLock)
36 | {
37 | if (!_initialized)
38 | {
39 | if (sodium_init() == -1)
40 | {
41 | throw new System.Exception("Failed to initialize sodium");
42 | }
43 | else /* 1 means already initialized; 0 means success */
44 | {
45 | _initialized = true;
46 | }
47 |
48 | AES256GCMAvailable = crypto_aead_aes256gcm_is_available() == 1;
49 | Logging.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}");
50 | }
51 | }
52 | }
53 |
54 | [DllImport("Kernel32.dll")]
55 | private static extern IntPtr LoadLibrary(string path);
56 |
57 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
58 | private static extern int sodium_init();
59 |
60 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
61 | private static extern int crypto_aead_aes256gcm_is_available();
62 |
63 | #region AEAD
64 |
65 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
66 | public static extern int sodium_increment(byte[] n, int nlen);
67 |
68 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
69 | public static extern int crypto_aead_chacha20poly1305_ietf_encrypt(byte[] c, ref ulong clen_p, byte[] m,
70 | ulong mlen, byte[] ad, ulong adlen, byte[] nsec, byte[] npub, byte[] k);
71 |
72 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
73 | public static extern int crypto_aead_chacha20poly1305_ietf_decrypt(byte[] m, ref ulong mlen_p,
74 | byte[] nsec, byte[] c, ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k);
75 |
76 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
77 | public static extern int crypto_aead_aes256gcm_encrypt(byte[] c, ref ulong clen_p, byte[] m, ulong mlen,
78 | byte[] ad, ulong adlen, byte[] nsec, byte[] npub, byte[] k);
79 |
80 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
81 | public static extern int crypto_aead_aes256gcm_decrypt(byte[] m, ref ulong mlen_p, byte[] nsec, byte[] c,
82 | ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k);
83 |
84 | #endregion
85 |
86 | #region Stream
87 |
88 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
89 | public static extern int crypto_stream_salsa20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic,
90 | byte[] k);
91 |
92 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
93 | public static extern int crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic,
94 | byte[] k);
95 |
96 | [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
97 | public static extern int crypto_stream_chacha20_ietf_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, uint ic,
98 | byte[] k);
99 |
100 | #endregion
101 | }
102 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/Stream/StreamMbedTLSEncryptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.InteropServices;
4 | using ShadowSocks.Encryption.Exception;
5 |
6 | namespace ShadowSocks.Encryption.Stream
7 | {
8 | public class StreamMbedTLSEncryptor
9 | : StreamEncryptor, IDisposable
10 | {
11 | const int CIPHER_RC4 = 1;
12 | const int CIPHER_AES = 2;
13 | const int CIPHER_BLOWFISH = 3;
14 | const int CIPHER_CAMELLIA = 4;
15 |
16 | private IntPtr _encryptCtx = IntPtr.Zero;
17 | private IntPtr _decryptCtx = IntPtr.Zero;
18 |
19 | public StreamMbedTLSEncryptor(string method, string password)
20 | : base(method, password)
21 | {
22 | }
23 |
24 | private static Dictionary _ciphers = new Dictionary {
25 | { "aes-128-cfb", new EncryptorInfo("AES-128-CFB128", 16, 16, CIPHER_AES) },
26 | { "aes-192-cfb", new EncryptorInfo("AES-192-CFB128", 24, 16, CIPHER_AES) },
27 | { "aes-256-cfb", new EncryptorInfo("AES-256-CFB128", 32, 16, CIPHER_AES) },
28 | { "aes-128-ctr", new EncryptorInfo("AES-128-CTR", 16, 16, CIPHER_AES) },
29 | { "aes-192-ctr", new EncryptorInfo("AES-192-CTR", 24, 16, CIPHER_AES) },
30 | { "aes-256-ctr", new EncryptorInfo("AES-256-CTR", 32, 16, CIPHER_AES) },
31 | { "bf-cfb", new EncryptorInfo("BLOWFISH-CFB64", 16, 8, CIPHER_BLOWFISH) },
32 | { "camellia-128-cfb", new EncryptorInfo("CAMELLIA-128-CFB128", 16, 16, CIPHER_CAMELLIA) },
33 | { "camellia-192-cfb", new EncryptorInfo("CAMELLIA-192-CFB128", 24, 16, CIPHER_CAMELLIA) },
34 | { "camellia-256-cfb", new EncryptorInfo("CAMELLIA-256-CFB128", 32, 16, CIPHER_CAMELLIA) },
35 | { "rc4-md5", new EncryptorInfo("ARC4-128", 16, 16, CIPHER_RC4) }
36 | };
37 |
38 | public static List SupportedCiphers()
39 | {
40 | return new List(_ciphers.Keys);
41 | }
42 |
43 | protected override Dictionary getCiphers()
44 | {
45 | return _ciphers;
46 | }
47 |
48 | protected override void initCipher(byte[] iv, bool isEncrypt)
49 | {
50 | base.initCipher(iv, isEncrypt);
51 | IntPtr ctx = Marshal.AllocHGlobal(MbedTLS.cipher_get_size_ex());
52 | if (isEncrypt)
53 | {
54 | _encryptCtx = ctx;
55 | }
56 | else
57 | {
58 | _decryptCtx = ctx;
59 | }
60 | byte[] realkey;
61 | if (_method == "rc4-md5")
62 | {
63 | byte[] temp = new byte[keyLen + ivLen];
64 | realkey = new byte[keyLen];
65 | Array.Copy(_key, 0, temp, 0, keyLen);
66 | Array.Copy(iv, 0, temp, keyLen, ivLen);
67 | realkey = MbedTLS.MD5(temp);
68 | }
69 | else
70 | {
71 | realkey = _key;
72 | }
73 | MbedTLS.cipher_init(ctx);
74 | if (MbedTLS.cipher_setup( ctx, MbedTLS.cipher_info_from_string( _innerLibName ) ) != 0 )
75 | throw new System.Exception("Cannot initialize mbed TLS cipher context");
76 | /*
77 | * MbedTLS takes key length by bit
78 | * cipher_setkey() will set the correct key schedule
79 | * and operation
80 | *
81 | * MBEDTLS_AES_{EN,DE}CRYPT
82 | * == MBEDTLS_BLOWFISH_{EN,DE}CRYPT
83 | * == MBEDTLS_CAMELLIA_{EN,DE}CRYPT
84 | * == MBEDTLS_{EN,DE}CRYPT
85 | *
86 | */
87 | if (MbedTLS.cipher_setkey(ctx, realkey, keyLen * 8,
88 | isEncrypt ? MbedTLS.MBEDTLS_ENCRYPT : MbedTLS.MBEDTLS_DECRYPT) != 0 )
89 | throw new System.Exception("Cannot set mbed TLS cipher key");
90 | if (MbedTLS.cipher_set_iv(ctx, iv, ivLen) != 0)
91 | throw new System.Exception("Cannot set mbed TLS cipher IV");
92 | if (MbedTLS.cipher_reset(ctx) != 0)
93 | throw new System.Exception("Cannot finalize mbed TLS cipher context");
94 | }
95 |
96 | protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf)
97 | {
98 | // C# could be multi-threaded
99 | if (_disposed)
100 | {
101 | throw new ObjectDisposedException(this.ToString());
102 | }
103 | if (MbedTLS.cipher_update(isEncrypt ? _encryptCtx : _decryptCtx,
104 | buf, length, outbuf, ref length) != 0 )
105 | throw new CryptoErrorException();
106 | }
107 |
108 | #region IDisposable
109 |
110 | private bool _disposed;
111 |
112 | // instance based lock
113 | private readonly object _lock = new object();
114 |
115 | public override void Dispose()
116 | {
117 | Dispose(true);
118 | GC.SuppressFinalize(this);
119 | }
120 |
121 | ~StreamMbedTLSEncryptor()
122 | {
123 | Dispose(false);
124 | }
125 |
126 | protected virtual void Dispose(bool disposing)
127 | {
128 | lock (_lock)
129 | {
130 | if (_disposed) return;
131 | _disposed = true;
132 | }
133 |
134 | if (disposing)
135 | {
136 | // free managed objects
137 | }
138 |
139 | // free unmanaged objects
140 | if (_encryptCtx != IntPtr.Zero)
141 | {
142 | MbedTLS.cipher_free(_encryptCtx);
143 | Marshal.FreeHGlobal(_encryptCtx);
144 | _encryptCtx = IntPtr.Zero;
145 | }
146 | if (_decryptCtx != IntPtr.Zero)
147 | {
148 | MbedTLS.cipher_free(_decryptCtx);
149 | Marshal.FreeHGlobal(_decryptCtx);
150 | _decryptCtx = IntPtr.Zero;
151 | }
152 | }
153 |
154 | #endregion
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Encryption/Stream/StreamSodiumEncryptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using ShadowSocks.Encryption.Exception;
4 |
5 | namespace ShadowSocks.Encryption.Stream
6 | {
7 | public class StreamSodiumEncryptor
8 | : StreamEncryptor, IDisposable
9 | {
10 | const int CIPHER_SALSA20 = 1;
11 | const int CIPHER_CHACHA20 = 2;
12 | const int CIPHER_CHACHA20_IETF = 3;
13 |
14 | const int SODIUM_BLOCK_SIZE = 64;
15 |
16 | protected int _encryptBytesRemaining;
17 | protected int _decryptBytesRemaining;
18 | protected ulong _encryptIC;
19 | protected ulong _decryptIC;
20 | protected byte[] _encryptBuf;
21 | protected byte[] _decryptBuf;
22 |
23 | public StreamSodiumEncryptor(string method, string password)
24 | : base(method, password)
25 | {
26 | _encryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
27 | _decryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
28 | }
29 |
30 | private static Dictionary _ciphers = new Dictionary {
31 | { "salsa20", new EncryptorInfo(32, 8, CIPHER_SALSA20) },
32 | { "chacha20", new EncryptorInfo(32, 8, CIPHER_CHACHA20) },
33 | { "chacha20-ietf", new EncryptorInfo(32, 12, CIPHER_CHACHA20_IETF) }
34 | };
35 |
36 | protected override Dictionary getCiphers()
37 | {
38 | return _ciphers;
39 | }
40 |
41 | public static List SupportedCiphers()
42 | {
43 | return new List(_ciphers.Keys);
44 | }
45 |
46 | protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf)
47 | {
48 | // TODO write a unidirection cipher so we don't have to if if if
49 | int bytesRemaining;
50 | ulong ic;
51 | byte[] sodiumBuf;
52 | byte[] iv;
53 | int ret = -1;
54 |
55 | if (isEncrypt)
56 | {
57 | bytesRemaining = _encryptBytesRemaining;
58 | ic = _encryptIC;
59 | sodiumBuf = _encryptBuf;
60 | iv = _encryptIV;
61 | }
62 | else
63 | {
64 | bytesRemaining = _decryptBytesRemaining;
65 | ic = _decryptIC;
66 | sodiumBuf = _decryptBuf;
67 | iv = _decryptIV;
68 | }
69 | int padding = bytesRemaining;
70 | Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length);
71 |
72 | switch (_cipher)
73 | {
74 | case CIPHER_SALSA20:
75 | ret = Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
76 | break;
77 | case CIPHER_CHACHA20:
78 | ret = Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
79 | break;
80 | case CIPHER_CHACHA20_IETF:
81 | ret = Sodium.crypto_stream_chacha20_ietf_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, (uint)ic, _key);
82 | break;
83 | }
84 | if (ret != 0) throw new CryptoErrorException();
85 |
86 | Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length);
87 | padding += length;
88 | ic += (ulong)padding / SODIUM_BLOCK_SIZE;
89 | bytesRemaining = padding % SODIUM_BLOCK_SIZE;
90 |
91 | if (isEncrypt)
92 | {
93 | _encryptBytesRemaining = bytesRemaining;
94 | _encryptIC = ic;
95 | }
96 | else
97 | {
98 | _decryptBytesRemaining = bytesRemaining;
99 | _decryptIC = ic;
100 | }
101 | }
102 |
103 | public override void Dispose()
104 | {
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Exceptions/AlleyException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ShadowSocks.Exceptions
8 | {
9 | class GreenDotException: Exception
10 | {
11 | public GreenDotException(string message)
12 | {
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Extensions/JsonExtensions.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json.Linq;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace ShadowSocks.Extensions
10 | {
11 | public static class JsonExtensions
12 | {
13 | public static bool ok(this JToken token)
14 | {
15 | if (token == null) {
16 | return false;
17 | }
18 |
19 | var status = token["code"];
20 | return status!=null && status.Type == JTokenType.Integer && status.ToString().Equals("200");
21 | }
22 |
23 | public static bool expired(this JToken token) {
24 | if (token == null)
25 | {
26 | return false;
27 | }
28 |
29 | var status = token["code"];
30 | return status != null && status.Type == JTokenType.Integer && status.ToString().Equals("403");
31 | }
32 |
33 | public static dynamic content(this JToken token) {
34 | return token["content"];
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Extensions/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ShadowSocks.Extensions
8 | {
9 | public static class StringExtensions
10 | {
11 | public static string ToBase64(this string value)
12 | {
13 | var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(value);
14 | return System.Convert.ToBase64String(plainTextBytes);
15 | }
16 | public static string FromBase64(this string value)
17 | {
18 | var base64EncodedBytes = System.Convert.FromBase64String(value);
19 | return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
20 | }
21 | public static string ToUrlEncodeBase64(this string value)
22 | {
23 | return Uri.EscapeDataString(value.ToBase64());
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/HotKeyConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ShadowSocks.Model
4 | {
5 | /*
6 | * Format:
7 | * +
8 | *
9 | */
10 |
11 | [Serializable]
12 | public class HotkeyConfig
13 | {
14 | public string SwitchSystemProxy;
15 | public string SwitchSystemProxyMode;
16 | public string SwitchAllowLan;
17 | public string ShowLogs;
18 | public string ServerMoveUp;
19 | public string ServerMoveDown;
20 |
21 | public HotkeyConfig()
22 | {
23 | SwitchSystemProxy = "";
24 | SwitchSystemProxyMode = "";
25 | SwitchAllowLan = "";
26 | ShowLogs = "";
27 | ServerMoveUp = "";
28 | ServerMoveDown = "";
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/LogViewerConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 | using Newtonsoft.Json;
5 |
6 | namespace ShadowSocks.Model
7 | {
8 | [Serializable]
9 | public class LogViewerConfig
10 | {
11 | public bool topMost;
12 | public bool wrapText;
13 | public bool toolbarShown;
14 |
15 | public Font Font { get; set; } = new Font("Consolas", 8F);
16 |
17 | public Color BackgroundColor { get; set; } = Color.Black;
18 |
19 | public Color TextColor { get; set; } = Color.White;
20 |
21 | public LogViewerConfig()
22 | {
23 | topMost = false;
24 | wrapText = false;
25 | toolbarShown = false;
26 | }
27 |
28 |
29 | #region Size
30 |
31 | public void SaveSize()
32 | {
33 | Properties.Settings.Default.Save();
34 | }
35 |
36 | [JsonIgnore]
37 | public int Width
38 | {
39 | get { return Properties.Settings.Default.LogViewerWidth; }
40 | set { Properties.Settings.Default.LogViewerWidth = value; }
41 | }
42 |
43 | [JsonIgnore]
44 | public int Height
45 | {
46 | get { return Properties.Settings.Default.LogViewerHeight; }
47 | set { Properties.Settings.Default.LogViewerHeight = value; }
48 | }
49 | [JsonIgnore]
50 | public int Top
51 | {
52 | get { return Properties.Settings.Default.LogViewerTop; }
53 | set { Properties.Settings.Default.LogViewerTop = value; }
54 | }
55 | [JsonIgnore]
56 | public int Left
57 | {
58 | get { return Properties.Settings.Default.LogViewerLeft; }
59 | set { Properties.Settings.Default.LogViewerLeft = value; }
60 | }
61 | [JsonIgnore]
62 | public bool Maximized
63 | {
64 | get { return Properties.Settings.Default.LogViewerMaximized; }
65 | set { Properties.Settings.Default.LogViewerMaximized = value; }
66 | }
67 |
68 | [JsonIgnore]
69 | // Use GetBestTop() and GetBestLeft() to ensure the log viwer form can be always display IN screen.
70 | public int BestLeft
71 | {
72 | get
73 | {
74 | int width = Width;
75 | width = (width >= 400) ? width : 400; // set up the minimum size
76 | return Screen.PrimaryScreen.WorkingArea.Width - width;
77 | }
78 | }
79 |
80 | [JsonIgnore]
81 | public int BestTop
82 | {
83 | get
84 | {
85 | int height = Height;
86 | height = (height >= 200) ? height : 200; // set up the minimum size
87 | return Screen.PrimaryScreen.WorkingArea.Height - height;
88 | }
89 | }
90 |
91 | #endregion
92 |
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/ProxyConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ShadowSocks.Model
4 | {
5 | [Serializable]
6 | public class ProxyConfig
7 | {
8 | public const int PROXY_SOCKS5 = 0;
9 | public const int PROXY_HTTP = 1;
10 |
11 | public const int MaxProxyTimeoutSec = 10;
12 | private const int DefaultProxyTimeoutSec = 3;
13 |
14 | public bool useProxy;
15 | public int proxyType;
16 | public string proxyServer;
17 | public int proxyPort;
18 | public int proxyTimeout;
19 |
20 | public ProxyConfig()
21 | {
22 | useProxy = false;
23 | proxyType = PROXY_SOCKS5;
24 | proxyServer = "";
25 | proxyPort = 0;
26 | proxyTimeout = DefaultProxyTimeoutSec;
27 | }
28 |
29 | public void CheckConfig()
30 | {
31 | if (proxyType < PROXY_SOCKS5 || proxyType > PROXY_HTTP)
32 | {
33 | proxyType = PROXY_SOCKS5;
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/ServerNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ShadowSocks.Model
8 | {
9 | public class ServerNode
10 | {
11 | private int id;
12 | private string name;
13 | private string icon;
14 | private string remark;
15 | private int linkcount;
16 | private bool selected;
17 | private string host;
18 | private string port;
19 | private string method;
20 | private string password;
21 |
22 | public int Linkcount { get => linkcount; set => linkcount = value; }
23 | public string Remark { get => remark; set => remark = value; }
24 | public string Icon { get => icon; set => icon = value; }
25 | public string Name { get => name; set => name = value; }
26 | public bool Selected { get => selected; set => selected = value; }
27 | public string Host { get => host; set => host = value; }
28 | public string Port { get => port; set => port = value; }
29 | public string Method { get => method; set => method = value; }
30 | public string Password { get => password; set => password = value; }
31 | public int Id { get => id; set => id = value; }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/SiteConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ShadowSocks.Model
8 | {
9 | public class SiteConfig
10 | {
11 | private Properties.Settings settings = Properties.Settings.Default;
12 |
13 | public int usergiftday
14 | {
15 | get
16 | {
17 | return settings.usergiftday;
18 | }
19 | set
20 | {
21 | settings.usergiftday = value;
22 | settings.Save();
23 | }
24 | }
25 |
26 | public string sitename
27 | {
28 | get
29 | {
30 | return settings.sitename;
31 | }
32 | set
33 | {
34 | settings.sitename = value;
35 | settings.Save();
36 | }
37 | }
38 |
39 | public string siteword
40 | {
41 | get
42 | {
43 | return settings.siteword;
44 | }
45 | set
46 | {
47 | settings.siteword = value;
48 | settings.Save();
49 | }
50 | }
51 |
52 | public string company
53 | {
54 | get
55 | {
56 | return settings.company;
57 | }
58 | set
59 | {
60 | settings.company = value;
61 | settings.Save();
62 | }
63 | }
64 |
65 | public string version
66 | {
67 | get
68 | {
69 | return settings.version;
70 | }
71 | set
72 | {
73 | settings.version = value;
74 | settings.Save();
75 | }
76 | }
77 |
78 | public void setConfig(dynamic configInfo)
79 | {
80 | if (configInfo["usergiftday"]!=null)
81 | {
82 | this.usergiftday = Convert.ToInt32(configInfo["usergiftday"]);
83 | }
84 |
85 | this.sitename = (string)configInfo["sitename"];
86 | this.siteword = (string)configInfo["siteword"];
87 | this.company = (string)configInfo["company"];
88 | }
89 |
90 | private static SiteConfig _config = null;
91 |
92 | public static SiteConfig instance()
93 | {
94 | if (_config == null)
95 | {
96 | _config = new SiteConfig();
97 | }
98 | return _config;
99 | }
100 |
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/StatisticsRecord.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace ShadowSocks.Model
7 | {
8 | // Simple processed records for a short period of time
9 | public class StatisticsRecord
10 | {
11 | public DateTime Timestamp { get; set; } = DateTime.Now;
12 | public string ServerIdentifier { get; set; }
13 |
14 | // in ping-only records, these fields would be null
15 | public int? AverageLatency;
16 | public int? MinLatency;
17 | public int? MaxLatency;
18 |
19 | private bool EmptyLatencyData => (AverageLatency == null) && (MinLatency == null) && (MaxLatency == null);
20 |
21 | public int? AverageInboundSpeed;
22 | public int? MinInboundSpeed;
23 | public int? MaxInboundSpeed;
24 |
25 | private bool EmptyInboundSpeedData
26 | => (AverageInboundSpeed == null) && (MinInboundSpeed == null) && (MaxInboundSpeed == null);
27 |
28 | public int? AverageOutboundSpeed;
29 | public int? MinOutboundSpeed;
30 | public int? MaxOutboundSpeed;
31 |
32 | private bool EmptyOutboundSpeedData
33 | => (AverageOutboundSpeed == null) && (MinOutboundSpeed == null) && (MaxOutboundSpeed == null);
34 |
35 | // if user disabled ping test, response would be null
36 | public int? AverageResponse;
37 | public int? MinResponse;
38 | public int? MaxResponse;
39 | public float? PackageLoss;
40 |
41 | private bool EmptyResponseData
42 | => (AverageResponse == null) && (MinResponse == null) && (MaxResponse == null) && (PackageLoss == null);
43 |
44 | public bool IsEmptyData() {
45 | return EmptyInboundSpeedData && EmptyOutboundSpeedData && EmptyResponseData && EmptyLatencyData;
46 | }
47 |
48 | public StatisticsRecord()
49 | {
50 | }
51 |
52 | public StatisticsRecord(string identifier, ICollection inboundSpeedRecords, ICollection outboundSpeedRecords, ICollection latencyRecords)
53 | {
54 | ServerIdentifier = identifier;
55 | var inbound = inboundSpeedRecords?.Where(s => s > 0).ToList();
56 | if (inbound != null && inbound.Any())
57 | {
58 | AverageInboundSpeed = (int) inbound.Average();
59 | MinInboundSpeed = inbound.Min();
60 | MaxInboundSpeed = inbound.Max();
61 | }
62 | var outbound = outboundSpeedRecords?.Where(s => s > 0).ToList();
63 | if (outbound!= null && outbound.Any())
64 | {
65 | AverageOutboundSpeed = (int) outbound.Average();
66 | MinOutboundSpeed = outbound.Min();
67 | MaxOutboundSpeed = outbound.Max();
68 | }
69 | var latency = latencyRecords?.Where(s => s > 0).ToList();
70 | if (latency!= null && latency.Any())
71 | {
72 | AverageLatency = (int) latency.Average();
73 | MinLatency = latency.Min();
74 | MaxLatency = latency.Max();
75 | }
76 | }
77 |
78 | public StatisticsRecord(string identifier, ICollection responseRecords)
79 | {
80 | ServerIdentifier = identifier;
81 | SetResponse(responseRecords);
82 | }
83 |
84 | public void SetResponse(ICollection responseRecords)
85 | {
86 | if (responseRecords == null) return;
87 | var records = responseRecords.Where(response => response != null).Select(response => response.Value).ToList();
88 | if (!records.Any()) return;
89 | AverageResponse = (int?) records.Average();
90 | MinResponse = records.Min();
91 | MaxResponse = records.Max();
92 | PackageLoss = responseRecords.Count(response => response != null)/(float) responseRecords.Count;
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Reflection;
6 |
7 | using Newtonsoft.Json;
8 |
9 | using ShadowSocks.Controller;
10 |
11 | namespace ShadowSocks.Model
12 | {
13 | [Serializable]
14 | public class StatisticsStrategyConfiguration
15 | {
16 | public static readonly string ID = "com.shadowsocks.strategy.statistics";
17 | public bool StatisticsEnabled { get; set; } = false;
18 | public bool ByHourOfDay { get; set; } = true;
19 | public bool Ping { get; set; }
20 | public int ChoiceKeptMinutes { get; set; } = 10;
21 | public int DataCollectionMinutes { get; set; } = 10;
22 | public int RepeatTimesNum { get; set; } = 4;
23 |
24 | private const string ConfigFile = "statistics-config.json";
25 |
26 | public static StatisticsStrategyConfiguration Load()
27 | {
28 | try
29 | {
30 | var content = File.ReadAllText(ConfigFile);
31 | var configuration = JsonConvert.DeserializeObject(content);
32 | return configuration;
33 | }
34 | catch (FileNotFoundException)
35 | {
36 | var configuration = new StatisticsStrategyConfiguration();
37 | Save(configuration);
38 | return configuration;
39 | }
40 | catch (Exception e)
41 | {
42 | Logging.LogUsefulException(e);
43 | return new StatisticsStrategyConfiguration();
44 | }
45 | }
46 |
47 | public static void Save(StatisticsStrategyConfiguration configuration)
48 | {
49 | try
50 | {
51 | var content = JsonConvert.SerializeObject(configuration, Formatting.Indented);
52 | File.WriteAllText(ConfigFile, content);
53 | }
54 | catch (Exception e)
55 | {
56 | Logging.LogUsefulException(e);
57 | }
58 | }
59 |
60 | public Dictionary Calculations;
61 |
62 | public StatisticsStrategyConfiguration()
63 | {
64 | var properties = typeof(StatisticsRecord).GetFields(BindingFlags.Instance | BindingFlags.Public);
65 | Calculations = properties.ToDictionary(p => p.Name, _ => (float)0);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Model/SysproxyConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace ShadowSocks.Model
4 | {
5 | /*
6 | * Data come from WinINET
7 | */
8 |
9 | [Serializable]
10 | public class SysproxyConfig
11 | {
12 | public bool UserSettingsRecorded;
13 | public string Flags;
14 | public string ProxyServer;
15 | public string BypassList;
16 | public string PacUrl;
17 |
18 | public SysproxyConfig()
19 | {
20 | UserSettingsRecorded = false;
21 | Flags = "1";
22 | ProxyServer = "";
23 | BypassList = "";
24 | PacUrl = "";
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Threading;
5 | using System.Windows.Forms;
6 | using Microsoft.Win32;
7 |
8 | using ShadowSocks.Controller;
9 | using ShadowSocks.Controller.Hotkeys;
10 | using ShadowSocks.Util;
11 | using ShadowSocks.View;
12 |
13 | namespace ShadowSocks
14 | {
15 | static class Program
16 | {
17 | ///
18 | /// 应用程序的主入口点。
19 | ///
20 | [STAThread]
21 | static void Main()
22 | {
23 | if (!Utils.IsWinVistaOrHigher())
24 | {
25 | MessageBox.Show(
26 | "不支持的操作系统版本,最低需求为Windows Vista。",
27 | "系统提示",
28 | MessageBoxButtons.OK,
29 | MessageBoxIcon.Error
30 | );
31 | return;
32 | }
33 |
34 | if (!Utils.IsSupportedRuntimeVersion())
35 | {
36 | MessageBox.Show(
37 | "当前 .NET Framework 版本过低,请升级至4.6.2或更新版本。",
38 | "系统提示",
39 | MessageBoxButtons.OK,
40 | MessageBoxIcon.Error
41 | );
42 |
43 | Process.Start("http://dotnetsocial.cloudapp.net/GetDotnet?tfm=.NETFramework,Version=v4.6.2");
44 | return;
45 | }
46 |
47 | Utils.ReleaseMemory(true);
48 |
49 | using (Mutex mutex = new Mutex(false, $"Global\\GreenDot_{Application.StartupPath.GetHashCode()}"))
50 | {
51 | Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
52 | Application.ThreadException += Application_ThreadException;
53 | AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
54 | Application.ApplicationExit += Application_ApplicationExit;
55 | SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
56 | Application.EnableVisualStyles();
57 | Application.SetCompatibleTextRenderingDefault(false);
58 |
59 | if (!mutex.WaitOne(0, false))
60 | {
61 | Process[] oldProcesses = Process.GetProcessesByName("GreenDot Windows");
62 | if (oldProcesses.Length > 0)
63 | {
64 | Process oldProcess = oldProcesses[0];
65 | }
66 | MessageBox.Show(
67 | "加速服务正在运行中,请在任务栏查找相关图标。",
68 | "系统提示",
69 | MessageBoxButtons.OK,
70 | MessageBoxIcon.Information
71 | );
72 | return;
73 | }
74 |
75 | Directory.SetCurrentDirectory(Application.StartupPath);
76 |
77 | Logging.OpenLogFile();
78 |
79 | HotKeys.Init(ViewManager.instance.MainController);
80 |
81 | Login loginForm = new Login();
82 | Application.Run(loginForm);
83 | }
84 | }
85 |
86 | private static int exited = 0;
87 |
88 | private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
89 | {
90 | if (Interlocked.Increment(ref exited) == 1)
91 | {
92 | Environment.Exit(0);
93 | }
94 | }
95 |
96 | private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
97 | {
98 | if (Interlocked.Increment(ref exited) == 1)
99 | {
100 | Environment.Exit(0);
101 | }
102 | }
103 |
104 | private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
105 | {
106 | ShadowSocksController mainController = ViewManager.instance.MainController;
107 |
108 | switch (e.Mode)
109 | {
110 | case PowerModes.Resume:
111 | Logging.Info("os wake up");
112 | if (mainController != null)
113 | {
114 | System.Timers.Timer timer = new System.Timers.Timer(10 * 1000);
115 | timer.Elapsed += Timer_Elapsed;
116 | timer.AutoReset = false;
117 | timer.Enabled = true;
118 | timer.Start();
119 | }
120 | break;
121 | case PowerModes.Suspend:
122 | if (mainController != null)
123 | {
124 | mainController.Stop();
125 | Logging.Info("main controller stopped");
126 | }
127 | Logging.Info("os suspend");
128 | break;
129 | }
130 | }
131 |
132 | private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
133 | {
134 | try
135 | {
136 | if (ViewManager.instance.MainController != null)
137 | {
138 | ViewManager.instance.MainController.Start();
139 | Logging.Info("main controller started");
140 | }
141 | }
142 | catch (Exception ex)
143 | {
144 | Logging.LogUsefulException(ex);
145 | }
146 | finally
147 | {
148 | try
149 | {
150 | System.Timers.Timer timer = (System.Timers.Timer)sender;
151 | timer.Enabled = false;
152 | timer.Stop();
153 | timer.Dispose();
154 | }
155 | catch (Exception ex)
156 | {
157 | Logging.LogUsefulException(ex);
158 | }
159 | }
160 | }
161 |
162 | private static void Application_ApplicationExit(object sender, EventArgs e)
163 | {
164 | Application.ApplicationExit -= Application_ApplicationExit;
165 | SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
166 | Application.ThreadException -= Application_ThreadException;
167 | HotKeys.Destroy();
168 |
169 | ViewManager viewManager = ViewManager.instance;
170 |
171 | if (viewManager.MainController != null)
172 | {
173 | viewManager.closeMainController();
174 | }
175 | SystemProxy.Disable();
176 | }
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // 有关程序集的一般信息由以下
5 | // 控制。更改这些特性值可修改
6 | // 与程序集关联的信息。
7 | [assembly: AssemblyTitle("GreenDot Windows")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("GreenDot")]
11 | [assembly: AssemblyProduct("GreenDot Windows")]
12 | [assembly: AssemblyCopyright("Copyright © 2017")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // 将 ComVisible 设置为 false 会使此程序集中的类型
17 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
18 | //请将此类型的 ComVisible 特性设置为 true。
19 | [assembly: ComVisible(false)]
20 |
21 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
22 | [assembly: Guid("84529da0-a4b4-4258-a1c6-26e093170c5c")]
23 |
24 | // 程序集的版本信息由下列四个值组成:
25 | //
26 | // 主版本
27 | // 次版本
28 | // 生成号
29 | // 修订号
30 | //
31 | // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
32 | // 方法是按如下所示使用“*”: :
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.2")]
35 | [assembly: AssemblyFileVersion("1.0.2")]
36 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Properties/DataSources/Shadowsocks.Model.StatisticsStrategyConfiguration.datasource:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | ShadowSocks.Model.StatisticsStrategyConfiguration, ShadowSocks, Version=2.5.2.0, Culture=neutral, PublicKeyToken=null
10 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 0
22 |
23 |
24 |
25 |
26 |
27 | 0
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | 0
40 |
41 |
42 | 0
43 |
44 |
45 | 0
46 |
47 |
48 | 0
49 |
50 |
51 | False
52 |
53 |
54 | 0
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Proxy/DirectConnect.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Net.Sockets;
4 | using System.Threading;
5 | using ShadowSocks.Util.Sockets;
6 |
7 | namespace ShadowSocks.Proxy
8 | {
9 | public class DirectConnect : IProxy
10 | {
11 | private class FakeAsyncResult : IAsyncResult
12 | {
13 | public FakeAsyncResult(object state)
14 | {
15 | AsyncState = state;
16 | }
17 |
18 | public bool IsCompleted { get; } = true;
19 | public WaitHandle AsyncWaitHandle { get; } = null;
20 | public object AsyncState { get; }
21 | public bool CompletedSynchronously { get; } = true;
22 | }
23 |
24 | private class FakeEndPoint : EndPoint
25 | {
26 | public override AddressFamily AddressFamily { get; } = AddressFamily.Unspecified;
27 |
28 | public override string ToString()
29 | {
30 | return "null proxy";
31 | }
32 | }
33 |
34 | private WrappedSocket _remote = new WrappedSocket();
35 |
36 | public EndPoint LocalEndPoint => _remote.LocalEndPoint;
37 |
38 | public EndPoint ProxyEndPoint { get; } = new FakeEndPoint();
39 | public EndPoint DestEndPoint { get; private set; }
40 |
41 | public void BeginConnectProxy(EndPoint remoteEP, AsyncCallback callback, object state)
42 | {
43 | // do nothing
44 |
45 | var r = new FakeAsyncResult(state);
46 | callback?.Invoke(r);
47 | }
48 |
49 | public void EndConnectProxy(IAsyncResult asyncResult)
50 | {
51 | // do nothing
52 | }
53 |
54 | public void BeginConnectDest(EndPoint destEndPoint, AsyncCallback callback, object state)
55 | {
56 | DestEndPoint = destEndPoint;
57 |
58 | _remote.BeginConnect(destEndPoint, callback, state);
59 | }
60 |
61 | public void EndConnectDest(IAsyncResult asyncResult)
62 | {
63 | _remote.EndConnect(asyncResult);
64 | _remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
65 | }
66 |
67 | public void BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback,
68 | object state)
69 | {
70 | _remote.BeginSend(buffer, offset, size, socketFlags, callback, state);
71 | }
72 |
73 | public int EndSend(IAsyncResult asyncResult)
74 | {
75 | return _remote.EndSend(asyncResult);
76 | }
77 |
78 | public void BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback,
79 | object state)
80 | {
81 | _remote.BeginReceive(buffer, offset, size, socketFlags, callback, state);
82 | }
83 |
84 | public int EndReceive(IAsyncResult asyncResult)
85 | {
86 | return _remote.EndReceive(asyncResult);
87 | }
88 |
89 | public void Shutdown(SocketShutdown how)
90 | {
91 | _remote.Shutdown(how);
92 | }
93 |
94 | public void Close()
95 | {
96 | _remote.Dispose();
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Proxy/IProxy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Net.Sockets;
4 |
5 | namespace ShadowSocks.Proxy
6 | {
7 |
8 | public interface IProxy
9 | {
10 | EndPoint LocalEndPoint { get; }
11 |
12 | EndPoint ProxyEndPoint { get; }
13 |
14 | EndPoint DestEndPoint { get; }
15 |
16 | void BeginConnectProxy(EndPoint remoteEP, AsyncCallback callback, object state);
17 |
18 | void EndConnectProxy(IAsyncResult asyncResult);
19 |
20 | void BeginConnectDest(EndPoint destEndPoint, AsyncCallback callback, object state);
21 |
22 | void EndConnectDest(IAsyncResult asyncResult);
23 |
24 | void BeginSend(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback,
25 | object state);
26 |
27 | int EndSend(IAsyncResult asyncResult);
28 |
29 | void BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback,
30 | object state);
31 |
32 | int EndReceive(IAsyncResult asyncResult);
33 |
34 | void Shutdown(SocketShutdown how);
35 |
36 | void Close();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-canada.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-canada.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-china.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-china.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-finland.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-finland.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-france.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-france.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-germany.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-germany.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-hongkong.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-hongkong.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-ireland.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-ireland.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-italy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-italy.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-japan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-japan.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-korea.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-korea.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-norway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-norway.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-russia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-russia.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-spain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-spain.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-taiwan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-taiwan.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-uk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-uk.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag-usa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag-usa.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/flag/flag_holland.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/flag/flag_holland.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ico-check.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/ico-check.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ico-in24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/ico-in24.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ico-out24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/ico-out24.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ico-vip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/ico-vip.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ico_connecting.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/ico_connecting.gif
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ico_connection_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/ico_connection_stop.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/ico_loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/ico_loading.gif
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/logo-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/logo-white.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/logo.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/logo32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/logo32.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/logo40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/logo40.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Resources/logo48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/Resources/logo48.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/Settings.cs:
--------------------------------------------------------------------------------
1 | namespace ShadowSocks.Properties {
2 |
3 |
4 | // 通过此类可以处理设置类的特定事件:
5 | // 在更改某个设置的值之前将引发 SettingChanging 事件。
6 | // 在更改某个设置的值之后将引发 PropertyChanged 事件。
7 | // 在加载设置值之后将引发 SettingsLoaded 事件。
8 | // 在保存设置值之前将引发 SettingsSaving 事件。
9 | internal sealed partial class Settings {
10 |
11 | public Settings() {
12 | // // 若要为保存和更改设置添加事件处理程序,请取消注释下列行:
13 | //
14 | // this.SettingChanging += this.SettingChangingEventHandler;
15 | //
16 | // this.SettingsSaving += this.SettingsSavingEventHandler;
17 | //
18 | }
19 |
20 | private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
21 | // 在此处添加用于处理 SettingChangingEvent 事件的代码。
22 | }
23 |
24 | private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
25 | // 在此处添加用于处理 SettingsSaving 事件的代码。
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/DateHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace ShadowSocks.Util
8 | {
9 | public static class DateHelper
10 | {
11 | public static TimeSpan subtractCurrentDate(String dateStr) {
12 | String currentDateStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
13 | DateTime currentDate = DateTime.Parse(currentDateStr);
14 | DateTime subtractDate = DateTime.Parse(dateStr);
15 | TimeSpan span = subtractDate.Subtract(currentDate);
16 | return span;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/ProcessManagement/Job.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Runtime.InteropServices;
4 | using ShadowSocks.Controller;
5 |
6 | namespace ShadowSocks.Util.ProcessManagement
7 | {
8 | public class Job : IDisposable
9 | {
10 | private IntPtr handle = IntPtr.Zero;
11 |
12 | public Job()
13 | {
14 | handle = CreateJobObject(IntPtr.Zero, null);
15 | var extendedInfoPtr = IntPtr.Zero;
16 | var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
17 | {
18 | LimitFlags = 0x2000
19 | };
20 |
21 | var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
22 | {
23 | BasicLimitInformation = info
24 | };
25 |
26 | try
27 | {
28 | int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
29 | extendedInfoPtr = Marshal.AllocHGlobal(length);
30 | Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
31 |
32 | if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr,
33 | (uint) length))
34 | throw new Exception(string.Format("Unable to set information. Error: {0}",
35 | Marshal.GetLastWin32Error()));
36 | }
37 | finally
38 | {
39 | if (extendedInfoPtr != IntPtr.Zero)
40 | {
41 | Marshal.FreeHGlobal(extendedInfoPtr);
42 | extendedInfoPtr = IntPtr.Zero;
43 | }
44 | }
45 | }
46 |
47 | public bool AddProcess(IntPtr processHandle)
48 | {
49 | var succ = AssignProcessToJobObject(handle, processHandle);
50 |
51 | if (!succ)
52 | {
53 | Logging.Error("Failed to call AssignProcessToJobObject! GetLastError=" + Marshal.GetLastWin32Error());
54 | }
55 |
56 | return succ;
57 | }
58 |
59 | public bool AddProcess(int processId)
60 | {
61 | return AddProcess(Process.GetProcessById(processId).Handle);
62 | }
63 |
64 | #region IDisposable
65 |
66 | private bool disposed;
67 |
68 | public void Dispose()
69 | {
70 | Dispose(true);
71 | GC.SuppressFinalize(this);
72 | }
73 |
74 | protected virtual void Dispose(bool disposing)
75 | {
76 | if (disposed) return;
77 | disposed = true;
78 |
79 | if (disposing)
80 | {
81 | // no managed objects to free
82 | }
83 |
84 | if (handle != IntPtr.Zero)
85 | {
86 | CloseHandle(handle);
87 | handle = IntPtr.Zero;
88 | }
89 | }
90 |
91 | ~Job()
92 | {
93 | Dispose(false);
94 | }
95 |
96 | #endregion
97 |
98 | #region Interop
99 |
100 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
101 | private static extern IntPtr CreateJobObject(IntPtr a, string lpName);
102 |
103 | [DllImport("kernel32.dll", SetLastError = true)]
104 | private static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength);
105 |
106 | [DllImport("kernel32.dll", SetLastError = true)]
107 | private static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
108 |
109 | [DllImport("kernel32.dll", SetLastError = true)]
110 | [return: MarshalAs(UnmanagedType.Bool)]
111 | private static extern bool CloseHandle(IntPtr hObject);
112 |
113 | #endregion
114 | }
115 |
116 | #region Helper classes
117 |
118 | [StructLayout(LayoutKind.Sequential)]
119 | struct IO_COUNTERS
120 | {
121 | public UInt64 ReadOperationCount;
122 | public UInt64 WriteOperationCount;
123 | public UInt64 OtherOperationCount;
124 | public UInt64 ReadTransferCount;
125 | public UInt64 WriteTransferCount;
126 | public UInt64 OtherTransferCount;
127 | }
128 |
129 |
130 | [StructLayout(LayoutKind.Sequential)]
131 | struct JOBOBJECT_BASIC_LIMIT_INFORMATION
132 | {
133 | public Int64 PerProcessUserTimeLimit;
134 | public Int64 PerJobUserTimeLimit;
135 | public UInt32 LimitFlags;
136 | public UIntPtr MinimumWorkingSetSize;
137 | public UIntPtr MaximumWorkingSetSize;
138 | public UInt32 ActiveProcessLimit;
139 | public UIntPtr Affinity;
140 | public UInt32 PriorityClass;
141 | public UInt32 SchedulingClass;
142 | }
143 |
144 | [StructLayout(LayoutKind.Sequential)]
145 | public struct SECURITY_ATTRIBUTES
146 | {
147 | public UInt32 nLength;
148 | public IntPtr lpSecurityDescriptor;
149 | public Int32 bInheritHandle;
150 | }
151 |
152 | [StructLayout(LayoutKind.Sequential)]
153 | struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
154 | {
155 | public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
156 | public IO_COUNTERS IoInfo;
157 | public UIntPtr ProcessMemoryLimit;
158 | public UIntPtr JobMemoryLimit;
159 | public UIntPtr PeakProcessMemoryUsed;
160 | public UIntPtr PeakJobMemoryUsed;
161 | }
162 |
163 | public enum JobObjectInfoType
164 | {
165 | AssociateCompletionPortInformation = 7,
166 | BasicLimitInformation = 2,
167 | BasicUIRestrictions = 4,
168 | EndOfJobTimeInformation = 6,
169 | ExtendedLimitInformation = 9,
170 | SecurityLimitInformation = 5,
171 | GroupInformation = 11
172 | }
173 |
174 | #endregion
175 | }
176 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/ProcessManagement/ThreadUtil.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Management;
3 | using System.Text;
4 |
5 | namespace ShadowSocks.Util.ProcessManagement
6 | {
7 | static class ThreadUtil
8 | {
9 | public static string GetCommandLine(this Process process)
10 | {
11 | var commandLine = new StringBuilder(process.MainModule.FileName);
12 |
13 | commandLine.Append(" ");
14 | using (var searcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + process.Id))
15 | {
16 | foreach (var @object in searcher.Get())
17 | {
18 | commandLine.Append(@object["CommandLine"]);
19 | commandLine.Append(" ");
20 | }
21 | }
22 |
23 | return commandLine.ToString();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/Sockets/SocketUtil.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Net.Sockets;
4 |
5 | namespace ShadowSocks.Util.Sockets
6 | {
7 | public static class SocketUtil
8 | {
9 | private class DnsEndPoint2 : DnsEndPoint
10 | {
11 | public DnsEndPoint2(string host, int port) : base(host, port)
12 | {
13 | }
14 |
15 | public DnsEndPoint2(string host, int port, AddressFamily addressFamily) : base(host, port, addressFamily)
16 | {
17 | }
18 |
19 | public override string ToString()
20 | {
21 | return this.Host + ":" + this.Port;
22 | }
23 | }
24 |
25 | public static EndPoint GetEndPoint(string host, int port)
26 | {
27 | IPAddress ipAddress;
28 | bool parsed = IPAddress.TryParse(host, out ipAddress);
29 | if (parsed)
30 | {
31 | return new IPEndPoint(ipAddress, port);
32 | }
33 |
34 | // maybe is a domain name
35 | return new DnsEndPoint2(host, port);
36 | }
37 |
38 |
39 | public static void FullClose(this System.Net.Sockets.Socket s)
40 | {
41 | try
42 | {
43 | s.Shutdown(SocketShutdown.Both);
44 | }
45 | catch (Exception)
46 | {
47 | }
48 | try
49 | {
50 | s.Disconnect(false);
51 | }
52 | catch (Exception)
53 | {
54 | }
55 | try
56 | {
57 | s.Close();
58 | }
59 | catch (Exception)
60 | {
61 | }
62 | try
63 | {
64 | s.Dispose();
65 | }
66 | catch (Exception)
67 | {
68 | }
69 | }
70 |
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/SystemProxy/INTERNET_OPTION.cs:
--------------------------------------------------------------------------------
1 | /****************************** Module Header ******************************\
2 | Module Name: INTERNET_OPTION.cs
3 | Project: CSWebBrowserWithProxy
4 | Copyright (c) Microsoft Corporation.
5 |
6 | This enum contains 4 WinINet constants used in method InternetQueryOption and
7 | InternetSetOption functions.
8 | Visit http://msdn.microsoft.com/en-us/library/aa385328(VS.85).aspx to get the
9 | whole constants list.
10 |
11 | This source is subject to the Microsoft Public License.
12 | See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
13 | All other rights reserved.
14 |
15 | THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
16 | EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
18 | \***************************************************************************/
19 |
20 | namespace ShadowSocks.Util.SystemProxy
21 | {
22 | public enum INTERNET_OPTION
23 | {
24 | // Sets or retrieves an INTERNET_PER_CONN_OPTION_LIST structure that specifies
25 | // a list of options for a particular connection.
26 | INTERNET_OPTION_PER_CONNECTION_OPTION = 75,
27 |
28 | // Notify the system that the registry settings have been changed so that
29 | // it verifies the settings on the next call to InternetConnect.
30 | INTERNET_OPTION_SETTINGS_CHANGED = 39,
31 |
32 | // Causes the proxy data to be reread from the registry for a handle.
33 | INTERNET_OPTION_REFRESH = 37,
34 |
35 | // Alerts the current WinInet instance that proxy settings have changed
36 | // and that they must update with the new settings.
37 | // To alert all available WinInet instances, set the Buffer parameter of
38 | // InternetSetOption to NULL and BufferLength to 0 when passing this option.
39 | INTERNET_OPTION_PROXY_SETTINGS_CHANGED = 95
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION.cs:
--------------------------------------------------------------------------------
1 | /****************************** Module Header ******************************\
2 | Module Name: INTERNET_PER_CONN_OPTION.cs
3 | Project: CSWebBrowserWithProxy
4 | Copyright (c) Microsoft Corporation.
5 |
6 | This file defines the struct INTERNET_PER_CONN_OPTION and constants used by it.
7 | The struct INTERNET_PER_CONN_OPTION contains the value of an option that to be
8 | set to internet settings.
9 | Visit http://msdn.microsoft.com/en-us/library/aa385145(VS.85).aspx to get the
10 | detailed description.
11 |
12 | This source is subject to the Microsoft Public License.
13 | See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
14 | All other rights reserved.
15 |
16 | THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
17 | EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
19 | \***************************************************************************/
20 |
21 | using System;
22 | using System.Runtime.InteropServices;
23 |
24 | namespace ShadowSocks.Util.SystemProxy
25 | {
26 | ///
27 | /// Constants used in INTERNET_PER_CONN_OPTION_OptionUnion struct.
28 | ///
29 | public enum INTERNET_PER_CONN_OptionEnum
30 | {
31 | INTERNET_PER_CONN_FLAGS = 1,
32 | INTERNET_PER_CONN_PROXY_SERVER = 2,
33 | INTERNET_PER_CONN_PROXY_BYPASS = 3,
34 | INTERNET_PER_CONN_AUTOCONFIG_URL = 4,
35 | INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5,
36 | INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL = 6,
37 | INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS = 7,
38 | INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME = 8,
39 | INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL = 9,
40 | INTERNET_PER_CONN_FLAGS_UI = 10
41 | }
42 |
43 | ///
44 | /// Constants used in INTERNET_PER_CONN_OPTON struct.
45 | ///
46 | [Flags]
47 | public enum INTERNET_OPTION_PER_CONN_FLAGS
48 | {
49 | PROXY_TYPE_DIRECT = 0x00000001, // direct to net
50 | PROXY_TYPE_PROXY = 0x00000002, // via named proxy
51 | PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL
52 | PROXY_TYPE_AUTO_DETECT = 0x00000008 // use autoproxy detection
53 | }
54 |
55 | ///
56 | /// Constants used in INTERNET_PER_CONN_OPTON struct.
57 | /// Windows 7 and later:
58 | /// Clients that support Internet Explorer 8 should query the connection type using INTERNET_PER_CONN_FLAGS_UI.
59 | /// If this query fails, then the system is running a previous version of Internet Explorer and the client should
60 | /// query again with INTERNET_PER_CONN_FLAGS.
61 | /// Restore the connection type using INTERNET_PER_CONN_FLAGS regardless of the version of Internet Explorer.
62 | /// XXX: If fails, notify user to upgrade Internet Explorer
63 | ///
64 | [Flags]
65 | public enum INTERNET_OPTION_PER_CONN_FLAGS_UI
66 | {
67 | PROXY_TYPE_DIRECT = 0x00000001, // direct to net
68 | PROXY_TYPE_PROXY = 0x00000002, // via named proxy
69 | PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL
70 | PROXY_TYPE_AUTO_DETECT = 0x00000008 // use autoproxy detection
71 | }
72 |
73 | ///
74 | /// Used in INTERNET_PER_CONN_OPTION.
75 | /// When create a instance of OptionUnion, only one filed will be used.
76 | /// The StructLayout and FieldOffset attributes could help to decrease the struct size.
77 | ///
78 | [StructLayout(LayoutKind.Explicit)]
79 | public struct INTERNET_PER_CONN_OPTION_OptionUnion : IDisposable
80 | {
81 | // A value in INTERNET_OPTION_PER_CONN_FLAGS.
82 | [FieldOffset(0)]
83 | public int dwValue;
84 | [FieldOffset(0)]
85 | public System.IntPtr pszValue;
86 | [FieldOffset(0)]
87 | public System.Runtime.InteropServices.ComTypes.FILETIME ftValue;
88 |
89 | public void Dispose()
90 | {
91 | Dispose(true);
92 | GC.SuppressFinalize(this);
93 | }
94 |
95 | private void Dispose(bool disposing)
96 | {
97 | if (disposing)
98 | {
99 | if (pszValue != IntPtr.Zero)
100 | {
101 | Marshal.FreeHGlobal(pszValue);
102 | pszValue = IntPtr.Zero;
103 | }
104 | }
105 | }
106 | }
107 |
108 | [StructLayout(LayoutKind.Sequential)]
109 | public struct INTERNET_PER_CONN_OPTION
110 | {
111 | // A value in INTERNET_PER_CONN_OptionEnum.
112 | public int dwOption;
113 | public INTERNET_PER_CONN_OPTION_OptionUnion Value;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/SystemProxy/INTERNET_PER_CONN_OPTION_LIST.cs:
--------------------------------------------------------------------------------
1 | /****************************** Module Header ******************************\
2 | Module Name: INTERNET_PER_CONN_OPTION_LIST.cs
3 | Project: CSWebBrowserWithProxy
4 | Copyright (c) Microsoft Corporation.
5 |
6 | The struct INTERNET_PER_CONN_OPTION contains a list of options that to be
7 | set to internet connection.
8 | Visit http://msdn.microsoft.com/en-us/library/aa385146(VS.85).aspx to get the
9 | detailed description.
10 |
11 | This source is subject to the Microsoft Public License.
12 | See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
13 | All other rights reserved.
14 |
15 | THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
16 | EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
18 | \***************************************************************************/
19 |
20 | using System;
21 | using System.Runtime.InteropServices;
22 |
23 | namespace ShadowSocks.Util.SystemProxy
24 | {
25 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
26 | public struct INTERNET_PER_CONN_OPTION_LIST : IDisposable
27 | {
28 | public int Size;
29 |
30 | // The connection to be set. NULL means LAN.
31 | public System.IntPtr Connection;
32 |
33 | public int OptionCount;
34 | public int OptionError;
35 |
36 | // List of INTERNET_PER_CONN_OPTIONs.
37 | public System.IntPtr pOptions;
38 |
39 | public void Dispose()
40 | {
41 | Dispose( true );
42 | GC.SuppressFinalize( this );
43 | }
44 |
45 | private void Dispose( bool disposing )
46 | {
47 | if ( disposing )
48 | {
49 | if ( Connection != IntPtr.Zero )
50 | {
51 | Marshal.FreeHGlobal( Connection );
52 | Connection = IntPtr.Zero;
53 | }
54 |
55 | if ( pOptions != IntPtr.Zero )
56 | {
57 | Marshal.FreeHGlobal( pOptions );
58 | pOptions = IntPtr.Zero;
59 | }
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/SystemProxy/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | /****************************** Module Header ******************************\
2 | Module Name: NativeMethods.cs
3 | Project: CSWebBrowserWithProxy
4 | Copyright (c) Microsoft Corporation.
5 |
6 | This class is a simple .NET wrapper of wininet.dll. It contains 4 extern
7 | methods in wininet.dll. They are InternetOpen, InternetCloseHandle,
8 | InternetSetOption and InternetQueryOption.
9 |
10 | This source is subject to the Microsoft Public License.
11 | See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
12 | All other rights reserved.
13 |
14 | THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
15 | EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
16 | WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
17 | \***************************************************************************/
18 |
19 | using System;
20 | using System.Runtime.InteropServices;
21 |
22 | namespace ShadowSocks.Util.SystemProxy
23 | {
24 | internal static class NativeMethods
25 | {
26 | ///
27 | /// Sets an Internet option.
28 | ///
29 | [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
30 | internal static extern bool InternetSetOption(
31 | IntPtr hInternet,
32 | INTERNET_OPTION dwOption,
33 | IntPtr lpBuffer,
34 | int lpdwBufferLength);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/SystemProxy/ProxyException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.Serialization;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace ShadowSocks.Util.SystemProxy
9 | {
10 | class ProxyException : Exception
11 | {
12 | public ProxyException()
13 | {
14 | }
15 |
16 | public ProxyException(string message) : base(message)
17 | {
18 | }
19 |
20 | public ProxyException(string message, Exception innerException) : base(message, innerException)
21 | {
22 | }
23 |
24 | protected ProxyException(SerializationInfo info, StreamingContext context) : base(info, context)
25 | {
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/SystemProxy/RAS.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace ShadowSocks.Util.SystemProxy
4 | {
5 | internal static class RemoteAccessService
6 | {
7 | private enum RasFieldSizeConstants
8 | {
9 | #region original header
10 |
11 | //#if (WINVER >= 0x400)
12 | //#define RAS_MaxEntryName 256
13 | //#define RAS_MaxDeviceName 128
14 | //#define RAS_MaxCallbackNumber RAS_MaxPhoneNumber
15 | //#else
16 | //#define RAS_MaxEntryName 20
17 | //#define RAS_MaxDeviceName 32
18 | //#define RAS_MaxCallbackNumber 48
19 | //#endif
20 |
21 | #endregion
22 |
23 | RAS_MaxEntryName = 256,
24 | RAS_MaxPath = 260
25 | }
26 |
27 | private const int ERROR_SUCCESS = 0;
28 | private const int RASBASE = 600;
29 | private const int ERROR_BUFFER_TOO_SMALL = RASBASE + 3;
30 |
31 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
32 | private struct RasEntryName
33 | {
34 | #region original header
35 |
36 | //#define RASENTRYNAMEW struct tagRASENTRYNAMEW
37 | //RASENTRYNAMEW
38 | //{
39 | // DWORD dwSize;
40 | // WCHAR szEntryName[RAS_MaxEntryName + 1];
41 | //
42 | //#if (WINVER >= 0x500)
43 | // //
44 | // // If this flag is REN_AllUsers then its a
45 | // // system phonebook.
46 | // //
47 | // DWORD dwFlags;
48 | // WCHAR szPhonebookPath[MAX_PATH + 1];
49 | //#endif
50 | //};
51 | //
52 | //#define RASENTRYNAMEA struct tagRASENTRYNAMEA
53 | //RASENTRYNAMEA
54 | //{
55 | // DWORD dwSize;
56 | // CHAR szEntryName[RAS_MaxEntryName + 1];
57 | //
58 | //#if (WINVER >= 0x500)
59 | // DWORD dwFlags;
60 | // CHAR szPhonebookPath[MAX_PATH + 1];
61 | //#endif
62 | //};
63 |
64 | #endregion
65 |
66 | public int dwSize;
67 |
68 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst=(int)RasFieldSizeConstants.RAS_MaxEntryName + 1)]
69 | public string szEntryName;
70 |
71 | public int dwFlags;
72 |
73 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst=(int)RasFieldSizeConstants.RAS_MaxPath + 1)]
74 | public string szPhonebookPath;
75 | }
76 |
77 | [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]
78 | private static extern uint RasEnumEntries(
79 | // reserved, must be NULL
80 | string reserved,
81 | // pointer to full path and file name of phone-book file
82 | string lpszPhonebook,
83 | // buffer to receive phone-book entries
84 | [In, Out] RasEntryName[] lprasentryname,
85 | // size in bytes of buffer
86 | ref int lpcb,
87 | // number of entries written to buffer
88 | out int lpcEntries
89 | );
90 |
91 | ///
92 | /// Get all entries from RAS
93 | ///
94 | ///
95 | ///
96 | /// 0: success with entries
97 | /// 1: success but no entries found
98 | /// 2: failed
99 | ///
100 | public static uint GetAllConns(ref string[] allConns)
101 | {
102 | int lpNames = 0;
103 | int entryNameSize = 0;
104 | int lpSize = 0;
105 | uint retval = ERROR_SUCCESS;
106 | RasEntryName[] names = null;
107 |
108 | entryNameSize = Marshal.SizeOf(typeof(RasEntryName));
109 |
110 | // Windows Vista or later: To determine the required buffer size, call RasEnumEntries
111 | // with lprasentryname set to NULL. The variable pointed to by lpcb should be set to zero.
112 | // The function will return the required buffer size in lpcb and an error code of ERROR_BUFFER_TOO_SMALL.
113 | retval = RasEnumEntries(null, null, null, ref lpSize, out lpNames);
114 |
115 | if (retval == ERROR_BUFFER_TOO_SMALL)
116 | {
117 | names = new RasEntryName[lpNames];
118 | for (int i = 0; i < names.Length; i++)
119 | {
120 | names[i].dwSize = entryNameSize;
121 | }
122 |
123 | retval = RasEnumEntries(null, null, names, ref lpSize, out lpNames);
124 | }
125 |
126 | if (retval == ERROR_SUCCESS)
127 | {
128 | if (lpNames == 0)
129 | {
130 | // no entries found.
131 | return 1;
132 | }
133 |
134 | allConns = new string[names.Length];
135 |
136 | for (int i = 0; i < names.Length; i++)
137 | {
138 | allConns[i] = names[i].szEntryName;
139 | }
140 | return 0;
141 | }
142 | else
143 | {
144 | return 2;
145 | }
146 | }
147 | }
148 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/ValidateHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace ShadowSocks.Util
5 | {
6 | public static class ValidateHelper
7 | {
8 | public static bool PhoneValidator(String phone) {
9 | Regex r = new Regex(@"^(13[0-9]|147|15[0-9]|17[0-9]|18[0-9])\d{8}$");
10 | Match m = r.Match(phone);
11 | if (m.Success){
12 | return true;
13 | }
14 | return false;
15 | }
16 |
17 | public static bool PasswordValidator(String password) {
18 | Regex r = new Regex(@"^[A-Za-z0-9_]{6,30}$");
19 | Match m = r.Match(password);
20 | if (m.Success)
21 | {
22 | return true;
23 | }
24 | return false;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/Util/ViewUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Windows.Forms;
6 |
7 | namespace ShadowSocks.Util
8 | {
9 | public static class ViewUtils
10 | {
11 | public static IEnumerable GetChildControls(this Control control) where TControl : Control
12 | {
13 | if (control.Controls.Count == 0)
14 | {
15 | return Enumerable.Empty();
16 | }
17 |
18 | var children = control.Controls.OfType().ToList();
19 | return children.SelectMany(GetChildControls).Concat(children);
20 | }
21 |
22 | // Workaround NotifyIcon's 63 chars limit
23 | // https://stackoverflow.com/questions/579665/how-can-i-show-a-systray-tooltip-longer-than-63-chars
24 | public static void SetNotifyIconText(NotifyIcon ni, string text)
25 | {
26 | if (text.Length >= 128)
27 | throw new ArgumentOutOfRangeException("Text limited to 127 characters");
28 | Type t = typeof(NotifyIcon);
29 | BindingFlags hidden = BindingFlags.NonPublic | BindingFlags.Instance;
30 | t.GetField("text", hidden).SetValue(ni, text);
31 | if ((bool)t.GetField("added", hidden).GetValue(ni))
32 | t.GetMethod("UpdateIcon", hidden).Invoke(ni, new object[] { true });
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/View/Notice.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace ShadowSocks.View
2 | {
3 | partial class Notice
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Notice));
32 | this.lblWindowTitle = new System.Windows.Forms.Label();
33 | this.SuspendLayout();
34 | //
35 | // lblWindowTitle
36 | //
37 | this.lblWindowTitle.AutoSize = true;
38 | this.lblWindowTitle.BackColor = System.Drawing.Color.Transparent;
39 | this.lblWindowTitle.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
40 | this.lblWindowTitle.ForeColor = System.Drawing.Color.White;
41 | this.lblWindowTitle.Location = new System.Drawing.Point(11, 10);
42 | this.lblWindowTitle.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
43 | this.lblWindowTitle.Name = "lblWindowTitle";
44 | this.lblWindowTitle.Size = new System.Drawing.Size(92, 27);
45 | this.lblWindowTitle.TabIndex = 1;
46 | this.lblWindowTitle.Text = "系统通知";
47 | //
48 | // Notice
49 | //
50 | this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 24F);
51 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
52 | this.ClientSize = new System.Drawing.Size(400, 400);
53 | this.Controls.Add(this.lblWindowTitle);
54 | this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
55 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
56 | this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
57 | this.Name = "Notice";
58 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
59 | this.ResumeLayout(false);
60 | this.PerformLayout();
61 |
62 | }
63 |
64 | #endregion
65 |
66 | private System.Windows.Forms.Label lblWindowTitle;
67 | }
68 | }
--------------------------------------------------------------------------------
/shadowsocks-csharp/View/Notice.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | using MaterialSkin;
12 | using MaterialSkin.Controls;
13 |
14 | namespace ShadowSocks.View
15 | {
16 | public partial class Notice : MaterialForm
17 | {
18 | private readonly MaterialSkinManager materialSkinManager;
19 |
20 | public Notice()
21 | {
22 | InitializeComponent();
23 |
24 | materialSkinManager = MaterialSkinManager.Instance;
25 | materialSkinManager.AddFormToManage(this);
26 | materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT;
27 | materialSkinManager.ColorScheme = new ColorScheme(Primary.LightBlue500, Primary.LightBlue500, Primary.Amber900, Accent.Amber700, TextShade.WHITE);
28 |
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/View/ViewManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using ShadowSocks.Controller;
7 | using System.Windows.Forms;
8 |
9 | namespace ShadowSocks.View
10 | {
11 | public class ViewManager
12 | {
13 |
14 | private static ViewManager viewManager;
15 |
16 | private Main mainForm;
17 | private Log logForm;
18 | private Setting settingForm;
19 | private Login loginForm;
20 | private Notice noticeForm;
21 |
22 | private MenuViewController menuController;
23 | private ShadowSocksController mainController;
24 |
25 | public ViewManager()
26 | {
27 | }
28 |
29 | public static ViewManager instance
30 | {
31 | get
32 | {
33 | if (viewManager == null)
34 | {
35 | viewManager = new ViewManager();
36 | }
37 | return viewManager;
38 | }
39 | }
40 |
41 | public ShadowSocksController MainController {
42 | get
43 | {
44 | if (mainController == null)
45 | {
46 | mainController = ShadowSocksController.instance();
47 | }
48 | return mainController;
49 | }
50 | }
51 |
52 | public MenuViewController MenuController {
53 | get
54 | {
55 | if (menuController == null)
56 | {
57 | menuController = new MenuViewController();
58 | }
59 | return menuController;
60 | }
61 | }
62 |
63 | public Main MainForm {
64 | get {
65 | if (this.mainForm == null || this.mainForm.IsDisposed)
66 | {
67 | this.mainForm = new Main();
68 | }
69 | return mainForm;
70 | }
71 | }
72 |
73 | public Login LoginForm {
74 | get
75 | {
76 | if (this.loginForm == null || this.loginForm.IsDisposed)
77 | {
78 | this.loginForm = new Login();
79 | }
80 | return loginForm;
81 | }
82 | }
83 |
84 | public Setting SettingForm
85 | {
86 | get
87 | {
88 | if (this.settingForm == null || this.settingForm.IsDisposed)
89 | {
90 | this.settingForm = new Setting();
91 | }
92 | return settingForm;
93 | }
94 | }
95 |
96 | public Log LogForm
97 | {
98 | get
99 | {
100 | if (this.logForm == null || this.logForm.IsDisposed)
101 | {
102 | this.logForm = new Log();
103 | }
104 | return logForm;
105 | }
106 | }
107 |
108 | public Notice NoticeForm
109 | {
110 | get
111 | {
112 | if (this.noticeForm == null || this.noticeForm.IsDisposed)
113 | {
114 | this.noticeForm = new Notice();
115 | }
116 | return noticeForm;
117 | }
118 | }
119 |
120 |
121 | public void showMainForm() {
122 | this.MainForm.Show();
123 | this.MainForm.Activate();
124 | this.MainForm.WindowState = FormWindowState.Normal;
125 | this.MainForm.BringToFront();
126 | }
127 |
128 | public void closeMainForm() {
129 | if (mainForm!=null)
130 | {
131 | mainForm.Hide();
132 | }
133 | }
134 |
135 | public void showLoginForm()
136 | {
137 | this.LoginForm.Show();
138 | this.LoginForm.Activate();
139 | this.LoginForm.WindowState = FormWindowState.Normal;
140 | this.LoginForm.BringToFront();
141 | }
142 |
143 | public void closeLoginForm() {
144 | if (loginForm!=null)
145 | {
146 | loginForm.Hide();
147 | }
148 | }
149 |
150 | public void showLogForm()
151 | {
152 | this.LogForm.Show();
153 | this.LogForm.Activate();
154 | this.LogForm.WindowState = FormWindowState.Normal;
155 | this.LogForm.BringToFront();
156 | }
157 |
158 | public void closeLogForm()
159 | {
160 | if (logForm!=null)
161 | {
162 | logForm.Hide();
163 | }
164 | }
165 |
166 | public void showSettingForm()
167 | {
168 | this.SettingForm.Show();
169 | this.SettingForm.Activate();
170 | this.SettingForm.WindowState = FormWindowState.Normal;
171 | this.SettingForm.BringToFront();
172 | }
173 |
174 | public void showNoticeForm() {
175 | this.NoticeForm.Show();
176 | this.NoticeForm.Activate();
177 | this.NoticeForm.WindowState = FormWindowState.Normal;
178 | this.NoticeForm.BringToFront();
179 | }
180 |
181 | public void closeSettingForm()
182 | {
183 | if (settingForm!=null)
184 | {
185 | settingForm.Hide();
186 | }
187 | }
188 |
189 | public void closeNoticeForm() {
190 | if (noticeForm != null)
191 | {
192 | noticeForm.Hide();
193 | }
194 | }
195 |
196 | public void closeMainController() {
197 | if (mainController!=null)
198 | {
199 | mainController.Stop();
200 | mainController = null;
201 | }
202 | }
203 |
204 | public void controlNotifyTray(bool visiable) {
205 | if (menuController!=null)
206 | {
207 | menuController.controlNotifyTray(visiable);
208 | }
209 | if (visiable == false)
210 | {
211 | menuController = null;
212 | }
213 | }
214 |
215 | public void showBalloonTip(string title, string content, ToolTipIcon icon, int timeout) {
216 | if (menuController!=null)
217 | {
218 | menuController.showBalloonTip(title, content, icon, timeout);
219 | }
220 | }
221 |
222 | }
223 | }
224 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | 0
42 |
43 |
44 |
45 |
46 |
47 | 0
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 0
60 |
61 |
62 | 0
63 |
64 |
65 | 0
66 |
67 |
68 | 0
69 |
70 |
71 | False
72 |
73 |
74 | 0
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/logo.ico
--------------------------------------------------------------------------------
/shadowsocks-csharp/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/greenuuu/greendot-windows/7b86d402bd0d33a78e5ffa91da9ba93256951e51/shadowsocks-csharp/logo.png
--------------------------------------------------------------------------------
/shadowsocks-csharp/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/shadowsocks-csharp/shadowsocks-csharp.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ProjectFiles
5 | publish\
6 |
7 |
8 |
9 |
10 |
11 | zh-CN
12 | false
13 |
14 |
--------------------------------------------------------------------------------