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
Line 
1using System;
2using System.Collections.Generic;
3using System.Net;
4using System.Net.Sockets;
5using System.Threading;
6
7namespace AllocsFixes.NetConnections.Servers.Telnet
8{
9 public class Telnet : IServer
10 {
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
34 private TcpListener listener = null;
35 private bool authEnabled = false;
36 private List<TelnetConnection> connections = new List<TelnetConnection> ();
37 private Dictionary<int, LoginAttempts> loginAttemptsPerIP = new Dictionary<int, LoginAttempts> ();
38
39 public Telnet ()
40 {
41 try {
42 if (!GamePrefs.GetBool (EnumGamePrefs.TelnetEnabled)) {
43 return;
44 }
45
46 int port = GamePrefs.GetInt (EnumGamePrefs.TelnetPort);
47
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);
53
54 listener.Start ();
55 listener.BeginAcceptTcpClient (new AsyncCallback (AcceptClient), null);
56
57 NetTelnetServer.RegisterServer (this);
58
59 Log.Out ("Started Telnet on " + port);
60 } catch (Exception e) {
61 Log.Out ("Error in Telnet.ctor: " + e);
62 }
63 }
64
65 public bool RegisterFailedLogin (int addressHash)
66 {
67 lock (loginAttemptsPerIP) {
68 LoginAttempts la = loginAttemptsPerIP [addressHash];
69 return la.LogAttempt ();
70 }
71 }
72
73 private void AcceptClient (IAsyncResult asyncResult)
74 {
75 if (listener.Server.IsBound) {
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 }
103 listener.BeginAcceptTcpClient (new AsyncCallback (AcceptClient), null);
104 }
105 }
106
107 public void Disconnect ()
108 {
109 try {
110 if (listener != null) {
111 listener.Stop ();
112 listener = null;
113 }
114 foreach (TelnetConnection c in connections) {
115 c.Close ();
116 }
117 } catch (Exception e) {
118 Log.Out ("Error in Telnet.Disconnect: " + e);
119 }
120 }
121
122 private void RemoveClosedConnections ()
123 {
124 try {
125 List<TelnetConnection> toRemove = new List<TelnetConnection> ();
126 foreach (TelnetConnection c in connections) {
127 if (c.IsClosed ())
128 toRemove.Add (c);
129 }
130 foreach (TelnetConnection c in toRemove) {
131 connections.Remove (c);
132 }
133 } catch (Exception e) {
134 Log.Out ("Error in Telnet.RemoveClosedConnections: " + e);
135 }
136 }
137
138 public void WriteToClient (string line)
139 {
140 if (line == null) {
141 return;
142 }
143 RemoveClosedConnections ();
144 foreach (TelnetConnection c in connections) {
145 if (c.IsAuthenticated ())
146 c.WriteLine (line);
147 }
148 }
149
150 public void WriteToClient_Single (string line, IConnection client)
151 {
152 if (line == null) {
153 return;
154 }
155 RemoveClosedConnections ();
156 foreach (TelnetConnection con in connections) {
157 if (con == client) {
158 if (con.IsAuthenticated ())
159 con.WriteLine (line);
160 }
161 }
162 }
163
164 }
165}
166
Note: See TracBrowser for help on using the repository browser.