Beispiel #1
0
        public ActionResult <MilvanethProtocol> AuthStart(MilvanethProtocol data)
        {
            if (!(data?.Data is ClientChallenge challenge) || !challenge.Check())
            {
                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new ServerChallenge
                    {
                        Message = GlobalMessage.DATA_INVALID_INPUT,
                        ReportTime = _time.SafeNow,
                    }
                });
            }

            if (!_pow.Verify(challenge.ProofOfWork) && _pow.ConditionalGenerate(out var requirement))
            {
                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new ServerChallenge
                    {
                        Message = GlobalMessage.RATE_POW_REQUIRED,
                        ProofOfWork = requirement,
                        ReportTime = _time.SafeNow,
                    }
                });
            }

            try
            {
                var accountData = _context.AccountData.Include(x => x.PrivilegeLevelNavigation).SingleOrDefault(x => x.AccountName == challenge.Username);

                if (accountData == null)
                {
                    return(new MilvanethProtocol
                    {
                        Context = null,
                        Data = new ServerChallenge
                        {
                            Message = GlobalMessage.DATA_NO_SUCH_USER,
                            ReportTime = _time.SafeNow,
                        }
                    });
                }

                if (accountData.PrivilegeLevel == GlobalConfig.ACCOUNT_BLOCKED_LEVEL)
                {
                    return(new MilvanethProtocol
                    {
                        Context = null,
                        Data = new ServerChallenge
                        {
                            Message = GlobalMessage.OP_SANCTION,
                            ReportTime = _time.SafeNow,
                        }
                    });
                }

                if (accountData.HasSuspended() && accountData.SuspendUntil >= _time.UtcNow)
                {
                    return(new MilvanethProtocol
                    {
                        Context = null,
                        Data = new ServerChallenge
                        {
                            Message = GlobalMessage.OP_ACCOUNT_SUSPENDED,
                            ReportTime = _time.SafeNow,
                        }
                    });
                }

                if (accountData.PasswordRetry > GlobalConfig.ACCOUNT_PASSWORD_RETRY_TOLERANCE && accountData.LastRetry.HasValue &&
                    (_time.UtcNow - accountData.LastRetry.Value).Seconds < GlobalConfig.ACCOUNT_PASSWORD_RETRY_COOLDOWN)
                {
                    return(new MilvanethProtocol
                    {
                        Context = null,
                        Data = new ServerChallenge
                        {
                            Message = GlobalMessage.OP_PASSWORD_RETRY_TOO_MUCH,
                            ReportTime = _time.SafeNow,
                        }
                    });
                }

                _auth.EnsureAccount(accountData, new PrivilegeConfig {
                    Login = true
                }, GlobalOperation.AUTH_START, 0,
                                    "Start login via auth/start", _accessor.GetIp());

                var session = _srp.DoServerResponse(accountData.AccountId, accountData.GroupParam, accountData.Verifier, out var token);

                _context.AccountData.Update(accountData);

                _context.SaveChanges();

                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new ServerChallenge
                    {
                        GroupParam = accountData.GroupParam,
                        Message = GlobalMessage.OK_SUCCESS,
                        ReportTime = _time.SafeNow,
                        Salt = accountData.Salt,
                        ServerToken = token,
                        SessionId = session
                    }
                });
            }
            catch (Exception e)
            {
                Log.Error(e, "Error in AUTH/START");
                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new ServerChallenge
                    {
                        Message = GlobalMessage.OP_INVALID,
                        ReportTime = _time.SafeNow,
                    }
                });
            }
        }
Beispiel #2
0
        public ActionResult <MilvanethProtocol> SessionCreate(MilvanethProtocol data)
        {
            if (!(data?.Data is AuthRequest request) || !request.Check())
            {
                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new AuthResponse
                    {
                        Message = GlobalMessage.DATA_INVALID_INPUT,
                        ReportTime = _time.SafeNow,
                    }
                });
            }

            try
            {
                var key = _context.KeyStore
                          .Include(x => x.HoldingAccountNavigation)
                          .ThenInclude(x => x.PrivilegeLevelNavigation)
                          .Include(x => x.UsageNavigation)
                          .Single(x => x.Key.SequenceEqual(request.AuthToken));

                _auth.EnsureKey(key, new KeyUsage {
                    CreateSession = true
                }, GlobalOperation.SESSION_CREATE, 0, "Create session via session/create",
                                _accessor.GetIp());

                var account = key.HoldingAccountNavigation;

                _auth.EnsureAccount(account, new PrivilegeConfig {
                    AccessData = true
                }, GlobalOperation.SESSION_CREATE, 0,
                                    "Create session via session/create", _accessor.GetIp());

                var renew = _api.Sign(_renewToken, 1, account, _time.UtcNow,
                                      _time.UtcNow.AddSeconds(GlobalConfig.TOKEN_RENEW_LIFE_TIME));

                var access = _token.Sign(new TokenPayload(_time.UtcNow.AddSeconds(GlobalConfig.TOKEN_DATA_LIFE_TIME),
                                                          account.AccountId, TokenPurpose.AccessToken, renew.KeyId));

                _context.SaveChanges();

                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new AuthResponse
                    {
                        Message = GlobalMessage.OK_SUCCESS,
                        ReportTime = _time.SafeNow,
                        RenewToken = renew.Key,
                        SessionToken = access
                    }
                });
            }
            catch (Exception e)
            {
                Log.Error(e, "Error in SESSION/CREATE");
                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new ServerChallenge
                    {
                        Message = GlobalMessage.OP_INVALID,
                        ReportTime = _time.SafeNow,
                    }
                });
            }
        }
Beispiel #3
0
        public ActionResult <MilvanethProtocol> AccountCreate(MilvanethProtocol data)
        {
            if (!(data?.Data is RegisterForm form) || !form.Check())
            {
                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new ServerChallenge
                    {
                        Message = GlobalMessage.DATA_INVALID_INPUT,
                        ReportTime = _time.SafeNow,
                    }
                });
            }

            if (!_pow.Verify(form.ProofOfWork))
            {
                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new ServerChallenge
                    {
                        Message = GlobalMessage.RATE_POW_REQUIRED,
                        ProofOfWork = _pow.Generate((byte)Math.Max(GlobalConfig.POW_SENSITIVE_OPERATION, _pow.Difficulty)),
                        ReportTime = _time.SafeNow,
                    }
                });
            }

            try
            {
                if (_context.AccountData.Any(x => x.AccountName == form.Username))
                {
                    return(new MilvanethProtocol
                    {
                        Context = null,
                        Data = new ServerChallenge
                        {
                            Message = GlobalMessage.DATA_USERNAME_OCCUPIED,
                            ReportTime = _time.SafeNow,
                        }
                    });
                }

                //var accountData = _context.AccountData.CreateProxy();
                var accountData = new AccountData();
                {
                    accountData.AccountName              = form.Username;
                    accountData.DisplayName              = form.DisplayName;
                    accountData.Email                    = form.Email;
                    accountData.EmailConfirmed           = false;
                    accountData.Salt                     = form.Salt;
                    accountData.Verifier                 = form.Verifier;
                    accountData.GroupParam               = (short)form.GroupParam;
                    accountData.RegisterService          = form.Service.ServiceId;
                    accountData.RelatedService           = new long[] { form.Service.ServiceId };
                    accountData.PlayedCharacter          = null;
                    accountData.Trace                    = form.Trace;
                    accountData.Karma                    = 0;
                    accountData.PrivilegeLevelNavigation = _userPrivilege;
                    accountData.SuspendUntil             = null;
                    accountData.PasswordRetry            = 0;
                    accountData.LastRetry                = DateTime.UtcNow;
                }

                _context.AccountData.Add(accountData);

                _context.SaveChanges();

                _repo.Character.CommitRange(accountData.AccountId, form.Character.CharacterItems.Select(x => x.ToDb(accountData.RegisterService)), true);

                _auth.EnsureAccount(accountData, new PrivilegeConfig {
                    Login = true
                }, GlobalOperation.ACCOUNT_CREATE, GlobalConfig.USER_INITIAL_KARMA,
                                    "Registered new account via account/create", _accessor.GetIp());

                var session = _srp.DoServerResponse(accountData.AccountId, accountData.GroupParam, accountData.Verifier, out var token);

                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new ServerChallenge
                    {
                        GroupParam = accountData.GroupParam,
                        Message = GlobalMessage.OK_SUCCESS,
                        ReportTime = _time.SafeNow,
                        Salt = accountData.Salt,
                        ServerToken = token,
                        SessionId = session
                    }
                });
            }
            catch (Exception e)
            {
                Log.Error(e, "Error in ACCOUNT/CREATE");
                return(new MilvanethProtocol
                {
                    Context = null,
                    Data = new ServerChallenge
                    {
                        Message = GlobalMessage.OP_INVALID,
                        ReportTime = _time.SafeNow,
                    }
                });
            }
        }