Advertisement
Guest User

Untitled

a guest
Jan 6th, 2019
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.79 KB | None | 0 0
  1. using System;
  2. using System.Linq;
  3. using System.Security.Cryptography;
  4. using System.Text;
  5. using Dapper.FastCrud;
  6. using DotNetty.Buffers;
  7. using DotNetty.Transport.Channels;
  8. using NeoNetsphere.Database.Auth;
  9. using Serilog;
  10. using Serilog.Core;
  11.  
  12. namespace NeoNetsphere.LoginAPI
  13. {
  14. public class LoginServerHandler : ChannelHandlerAdapter
  15. {
  16. private const short Magic = 0x5713;
  17. private static readonly ILogger Logger = Log.ForContext(Constants.SourceContextPropertyName, "LoginServer");
  18.  
  19. public override void ChannelActive(IChannelHandlerContext context)
  20. {
  21. base.ChannelActive(context);
  22. var firstMessage = new CCMessage();
  23. firstMessage.Write(CCMessage.MessageType.Notify);
  24. firstMessage.Write("<region>EU-S4MAX</region>");
  25. SendA(context, firstMessage);
  26. }
  27.  
  28. public override void ChannelRead(IChannelHandlerContext context, object messageData)
  29. {
  30. var buffer = messageData as IByteBuffer;
  31. var data = new byte[0];
  32. if (buffer != null)
  33. data = buffer.ToArray();
  34.  
  35. var msg = new CCMessage(data, data.Length);
  36. short magic = 0;
  37. var message = new ByteArray();
  38.  
  39. if (msg.Read(ref magic)
  40. && magic == Magic
  41. && msg.Read(ref message))
  42. {
  43. var receivedMessage = new CCMessage(message);
  44. CCMessage.MessageType coreId = 0;
  45. if (!receivedMessage.Read(ref coreId))
  46. return;
  47.  
  48. switch (coreId)
  49. {
  50. case CCMessage.MessageType.Rmi:
  51. short rmiId = 0;
  52. if (receivedMessage.Read(ref rmiId))
  53. switch (rmiId)
  54. {
  55. case 15:
  56. {
  57. var username = "";
  58. var password = "";
  59. var register = false;
  60.  
  61. if (receivedMessage.Read(ref username)
  62. && receivedMessage.Read(ref password)
  63. && receivedMessage.Read(ref register))
  64. {
  65. using (var db = AuthDatabase.Open())
  66. {
  67. Logger.Information("Authentication login from {endpoint}",
  68. context.Channel.RemoteAddress.ToString());
  69.  
  70. if (username.Length > 5 && password.Length > 5 && Namecheck.IsNameValid(username))
  71. {
  72. var result = db.Find<AccountDto>(statement => statement
  73. .Where($"{nameof(AccountDto.Username):C} = @{nameof(username)}")
  74. .Include<BanDto>(join => @join.LeftOuterJoin())
  75. .WithParameters(new { Username = username }));
  76.  
  77. var account = result.FirstOrDefault();
  78.  
  79. if (account == null &&
  80. (Config.Instance.NoobMode || Config.Instance.AutoRegister))
  81. {
  82. account = new AccountDto { Username = username };
  83.  
  84. var newSalt = new byte[24];
  85. using (var csprng = new RNGCryptoServiceProvider())
  86. {
  87. csprng.GetBytes(newSalt);
  88. }
  89.  
  90. var hash = new Rfc2898DeriveBytes(password, newSalt, 24000).GetBytes(24);
  91.  
  92. account.Password = Convert.ToBase64String(hash);
  93. account.Salt = Convert.ToBase64String(newSalt);
  94. db.InsertAsync(account);
  95. }
  96.  
  97. var salt = Convert.FromBase64String(account?.Salt ?? "");
  98.  
  99. var passwordGuess = new Rfc2898DeriveBytes(password, salt, 24000).GetBytes(24);
  100. var actualPassword = Convert.FromBase64String(account?.Password ?? "");
  101.  
  102. var difference =
  103. (uint)passwordGuess.Length ^ (uint)actualPassword.Length;
  104.  
  105. for (var i = 0;
  106. i < passwordGuess.Length && i < actualPassword.Length;
  107. i++)
  108. difference |= (uint)(passwordGuess[i] ^ actualPassword[i]);
  109.  
  110. if ((difference != 0 ||
  111. string.IsNullOrWhiteSpace(account?.Password ?? "")) &&
  112. !Config.Instance.NoobMode)
  113. {
  114. Logger.Error(
  115. "Wrong authentication credentials for {username} / {endpoint}",
  116. username, context.Channel.RemoteAddress.ToString());
  117. var ack = new CCMessage();
  118. ack.Write(false);
  119. ack.Write("Login failed");
  120. RmiSend(context, 16, ack);
  121. }
  122. else
  123. {
  124. if (account != null)
  125. {
  126. account.LoginToken = AuthHash
  127. .GetHash256(
  128. $"{context.Channel.RemoteAddress}-{account.Username}-{account.Password}")
  129. .ToLower();
  130. account.LastLogin = $"{DateTimeOffset.UtcNow:yyyyMMddHHmmss}";
  131. account.AuthToken = "";
  132. account.newToken = "";
  133. db.UpdateAsync(account);
  134.  
  135. var ack = new CCMessage();
  136. ack.Write(true);
  137. ack.Write(account.LoginToken);
  138. RmiSend(context, 16, ack);
  139. }
  140. Logger.Information("Authentication success for {username}",
  141. username);
  142. }
  143. }
  144. else
  145. {
  146. Logger.Error(
  147. "Wrong authentication credentials for {username} / {endpoint}",
  148. username, context.Channel.RemoteAddress.ToString());
  149. var ack = new CCMessage();
  150. ack.Write(false);
  151. ack.Write("Invalid length of username/password");
  152. RmiSend(context, 16, ack);
  153. }
  154. }
  155. }
  156. else
  157. {
  158. Logger.Error("Wrong login for {endpoint}",
  159. context.Channel.RemoteAddress.ToString());
  160. var ack = new CCMessage();
  161. ack.Write(false);
  162. ack.Write("Invalid loginpacket");
  163. RmiSend(context, 16, ack);
  164. }
  165. break;
  166. }
  167. case 17:
  168. context.CloseAsync();
  169. break;
  170. default:
  171. Logger.Error("Received unknown rmiId{rmi} from {endpoint}", rmiId,
  172. context.Channel.RemoteAddress.ToString());
  173. break;
  174. }
  175. break;
  176. case CCMessage.MessageType.Notify:
  177. context.CloseAsync();
  178. break;
  179. default:
  180. Logger.Error("Received unknown coreID{coreid} from {endpoint}", coreId,
  181. context.Channel.RemoteAddress.ToString());
  182. break;
  183. }
  184. }
  185. else
  186. {
  187. Logger.Error("Received invalid packetstruct from {endpoint}", context.Channel.RemoteAddress.ToString());
  188. context.CloseAsync();
  189. }
  190. }
  191.  
  192. public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
  193. {
  194. #if DEBUG
  195. Logger.Error("Exception: " + exception);
  196. #endif
  197. context.CloseAsync();
  198. }
  199.  
  200. private static void RmiSend(IChannelHandlerContext ctx, short rmiId, CCMessage message)
  201. {
  202. var rmiframe = new CCMessage();
  203. rmiframe.Write(CCMessage.MessageType.Rmi);
  204. rmiframe.Write(rmiId);
  205. rmiframe.Write(message);
  206. SendA(ctx, rmiframe);
  207. }
  208.  
  209. private static void SendA(IChannelHandlerContext ctx, CCMessage data)
  210. {
  211. var coreframe = new CCMessage();
  212. coreframe.Write(Magic);
  213. coreframe.WriteScalar(data.Length);
  214. coreframe.Write(data);
  215.  
  216. var buffer = Unpooled.Buffer(coreframe.Length);
  217. buffer.WriteBytes(coreframe.Buffer);
  218. ctx.WriteAndFlushAsync(buffer);
  219. }
  220. }
  221. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement