source: binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/Telnet.cs@ 188

Last change on this file since 188 was 187, checked in by alloc, 11 years ago

fixes

File size: 4.1 KB
RevLine 
[73]1using System;
2using System.Collections.Generic;
3using System.Net;
4using System.Net.Sockets;
5using System.Threading;
6
[132]7namespace AllocsFixes.NetConnections.Servers.Telnet
[73]8{
[132]9 public class Telnet : IServer
[130]10 {
[187]11 private const int MAX_LOGIN_ATTEMPTS = 10;
12 private const int BLOCK_TIME_SECONDS = 10;
13
14 private class LoginAttempts
15 {
16 private int count = 0;
17 private DateTime lastAttempt = new DateTime (0);
18
19 public bool LogAttempt ()
20 {
21 lastAttempt = DateTime.Now;
22 count++;
23 return count < MAX_LOGIN_ATTEMPTS;
24 }
25
26 public bool IsBanned ()
27 {
28 if ((DateTime.Now - lastAttempt).TotalSeconds > BLOCK_TIME_SECONDS)
29 count = 0;
30 return count >= MAX_LOGIN_ATTEMPTS;
31 }
32 }
33
[182]34 private TcpListener listener = null;
35 private bool authEnabled = false;
36 private List<TelnetConnection> connections = new List<TelnetConnection> ();
[187]37 private Dictionary<int, LoginAttempts> loginAttemptsPerIP = new Dictionary<int, LoginAttempts> ();
[74]38
[182]39 public Telnet ()
[130]40 {
41 try {
[182]42 if (!GamePrefs.GetBool (EnumGamePrefs.TelnetEnabled)) {
43 return;
44 }
45
46 int port = GamePrefs.GetInt (EnumGamePrefs.TelnetPort);
47
[130]48 authEnabled = GamePrefs.GetString (EnumGamePrefs.TelnetPassword).Length != 0;
49 if (authEnabled)
50 listener = new TcpListener (IPAddress.Any, port);
51 else
52 listener = new TcpListener (IPAddress.Loopback, port);
[182]53
[183]54 listener.Start ();
55 listener.BeginAcceptTcpClient (new AsyncCallback (AcceptClient), null);
56
[182]57 NetTelnetServer.RegisterServer (this);
58
59 Log.Out ("Started Telnet on " + port);
[130]60 } catch (Exception e) {
[132]61 Log.Out ("Error in Telnet.ctor: " + e);
[130]62 }
[103]63 }
[73]64
[187]65 public bool RegisterFailedLogin (int addressHash)
[184]66 {
[187]67 lock (loginAttemptsPerIP) {
68 LoginAttempts la = loginAttemptsPerIP [addressHash];
69 return la.LogAttempt ();
70 }
[184]71 }
72
[183]73 private void AcceptClient (IAsyncResult asyncResult)
[130]74 {
[183]75 if (listener.Server.IsBound) {
[187]76 TcpClient client = listener.EndAcceptTcpClient (asyncResult);
77
78 EndPoint endpoint = client.Client.RemoteEndPoint;
79 int addressHash = -1;
80 if (endpoint is IPEndPoint) {
81 addressHash = ((IPEndPoint)endpoint).Address.GetHashCode ();
82 //Log.Out ("Hash: " + endpointAddressHash);
83 } else {
84 Log.Out ("EndPoint is not an IPEndPoint but: " + endpoint.GetType ().ToString ());
85 }
86
87 lock (loginAttemptsPerIP) {
88 LoginAttempts la = null;
89 if (loginAttemptsPerIP.ContainsKey(addressHash))
90 la = loginAttemptsPerIP [addressHash];
91 if (la == null) {
92 la = new LoginAttempts ();
93 loginAttemptsPerIP [addressHash] = la;
94 }
95 if (!la.IsBanned ()) {
96 TelnetConnection con = new TelnetConnection (this, client, authEnabled);
97 connections.Add (con);
98 } else {
99 client.Close ();
100 Log.Out ("Telnet connection not accepted for too many login attempts: " + endpoint);
101 }
102 }
[183]103 listener.BeginAcceptTcpClient (new AsyncCallback (AcceptClient), null);
[73]104 }
105 }
106
[132]107 public void Disconnect ()
[130]108 {
109 try {
110 if (listener != null) {
111 listener.Stop ();
[182]112 listener = null;
[130]113 }
[132]114 foreach (TelnetConnection c in connections) {
[130]115 c.Close ();
116 }
117 } catch (Exception e) {
[132]118 Log.Out ("Error in Telnet.Disconnect: " + e);
[103]119 }
[73]120 }
121
[132]122 private void RemoveClosedConnections ()
[130]123 {
124 try {
[182]125 List<TelnetConnection> toRemove = new List<TelnetConnection> ();
[132]126 foreach (TelnetConnection c in connections) {
[182]127 if (c.IsClosed ())
128 toRemove.Add (c);
[103]129 }
[182]130 foreach (TelnetConnection c in toRemove) {
131 connections.Remove (c);
132 }
[130]133 } catch (Exception e) {
[132]134 Log.Out ("Error in Telnet.RemoveClosedConnections: " + e);
[74]135 }
136 }
137
[132]138 public void WriteToClient (string line)
[130]139 {
140 if (line == null) {
141 return;
142 }
143 RemoveClosedConnections ();
[132]144 foreach (TelnetConnection c in connections) {
[130]145 if (c.IsAuthenticated ())
146 c.WriteLine (line);
147 }
[73]148 }
[107]149
[132]150 public void WriteToClient_Single (string line, IConnection client)
[130]151 {
152 if (line == null) {
153 return;
154 }
155 RemoveClosedConnections ();
[132]156 foreach (TelnetConnection con in connections) {
157 if (con == client) {
158 if (con.IsAuthenticated ())
159 con.WriteLine (line);
160 }
[130]161 }
[107]162 }
[132]163
[107]164 }
[73]165}
[132]166
Note: See TracBrowser for help on using the repository browser.