예제 #1
0
 public function testPassword(HereAuth $main, $password)
 {
     $hash = HereAuth::hash($password, $this->name);
     if (strlen($this->passwordHash) === strlen($hash)) {
         return $hash === $this->passwordHash;
     }
     $salt = strtolower($this->name);
     if (isset($this->multiHash["nonhash:salt"])) {
         $salt = $this->multiHash["nonhash:salt"];
     }
     foreach ($this->multiHash as $type => $value) {
         if ($type === "nonhash:salt") {
             continue;
         }
         $array = explode(";", $type);
         $name = $array[0];
         $suffix = isset($array[1]) ? $array[1] : "";
         $iHash = $main->getImportedHash($name);
         if ($iHash === null) {
             continue;
         }
         if ($iHash->hash($password, $salt, $suffix) === $value) {
             $this->multiHash = [];
             $this->passwordHash = $hash;
             return true;
         }
     }
     return false;
 }
예제 #2
0
 public function __construct(HereAuth $main)
 {
     $this->main = $main;
     $this->path = $main->getConfig()->getNested("Database.JSON.DataFolder", "accounts");
     if ($this->path[0] !== "/") {
         $this->path = $main->getDataFolder() . $this->path;
     }
     if (!is_dir($this->path)) {
         mkdir($this->path, 0777, true);
     }
     if (!is_dir($this->path)) {
         throw new \RuntimeException("Could not create data directory at {$this->path}");
     }
     $this->path = realpath($this->path) . "/";
     $this->indexEnabled = $main->getConfig()->getNested("Database.JSON.EnableLeadingIndex", false);
     if (is_file($hadb = $this->path . ".hadb")) {
         $data = json_decode(file_get_contents($hadb), true);
     } else {
         $data = ["#" => "This is a HereAuth JSON-based account database.", "created" => time(), "lastClosed" => time()];
     }
     $data["lastOpened"] = time();
     $data["version"] = $this->main->getDescription()->getVersion();
     file_put_contents($hadb, json_encode($data, JSON_PRETTY_PRINT | JSON_BIGINT_AS_STRING | JSON_UNESCAPED_SLASHES));
     $this->sql = new SQLite3($this->path . "reg.db");
     $this->sql->exec("CREATE TABLE IF NOT EXISTS reg (ip TEXT, name TEXT PRIMARY KEY, time INTEGER)");
     var_dump($this->sql->busyTimeout(1));
     // outputs bool(true)
 }
예제 #3
0
 public function __construct(HereAuth $main)
 {
     parent::__construct($this->main = $main);
     $period = (int) ($main->getConfig()->getNested("RemindLogin.Interval", 0.5) * 20);
     $this->type = strtolower($main->getConfig()->getNested("RemindLogin.Type", "popup"));
     if ($this->type === "none") {
         return;
     }
     $main->getServer()->getScheduler()->scheduleDelayedRepeatingTask($this, $period, $period);
 }
 public function onSubmit($value)
 {
     if ($this->validatePassword($this->user, $value)) {
         $this->user->getRegistration()->setTempHash(HereAuth::hash($value, $this->user->getPlayer()));
         return true;
     }
     return false;
 }
예제 #5
0
 public function __construct(HereAuth $main)
 {
     $this->main = $main;
     if ($this->main->getConfig()->getNested("MultiSesCtrl.Enabled", true)) {
         $this->registerHandler(PlayerPreLoginEvent::class, "onPreLogin", EventPriority::NORMAL, true);
     }
     $this->registerHandler(PlayerLoginEvent::class, "onLogin", EventPriority::MONITOR, true);
     $this->registerHandler(PlayerQuitEvent::class, "onQuit", EventPriority::MONITOR, true);
     $this->registerHandler(PlayerCommandPreprocessEvent::class, "onMessage", EventPriority::LOWEST, false);
     $this->registerHandler(PlayerRespawnEvent::class, "onRespawn", EventPriority::HIGHEST, false);
     $this->registerHandler(DataPacketSendEvent::class, "onSend", EventPriority::HIGH, true);
     $events = ["DropItem", "Pick", "Eat"];
     $class = new \ReflectionClass($this);
     foreach ($events as $event) {
         if ($main->getConfig()->getNested("Blocking.{$event}", true)) {
             $method = $class->getMethod("on" . $event);
             if ($method === null) {
                 throw new \RuntimeException("Missing method on{$event}");
             }
             $this->registerHandler($method->getParameters()[0]->getClass()->getName(), $method->getName(), EventPriority::LOW, true);
         }
     }
     if ($main->getConfig()->getNested("Blocking.Damage", true) or $main->getConfig()->getNested("Blocking.Attack", true)) {
         $this->registerHandler(EntityDamageEvent::class, "onDamage", EventPriority::LOW, true);
     }
     if ($main->getConfig()->getNested("Blocking.Move.Locomotion", true) or $main->getConfig()->getNested("Blocking.Move.Rotation", true)) {
         $this->registerHandler(PlayerMoveEvent::class, "onMove", EventPriority::LOW, true);
     }
     if ($main->getConfig()->getNested("Blocking.Touch", true)) {
         $this->registerHandler(PlayerInteractEvent::class, "onTouch", EventPriority::LOW, true);
         $this->registerHandler(BlockBreakEvent::class, "onBreak", EventPriority::LOW, true);
     }
 }
예제 #6
0
 public function __construct(HereAuth $main)
 {
     $this->main = $main;
     $this->registerHandler(PlayerLoginEvent::class, "onLogin", EventPriority::MONITOR, true);
     $this->registerHandler(PlayerQuitEvent::class, "onQuit", EventPriority::MONITOR, true);
     $this->registerHandler(PlayerCommandPreprocessEvent::class, "onMessage", EventPriority::LOWEST, false);
     $events = ["DropItem", "Touch", "Pick", "Eat"];
     $class = new \ReflectionClass($this);
     foreach ($events as $event) {
         if ($main->getConfig()->getNested("Blocking.{$event}", true)) {
             $method = $class->getMethod("on" . $event);
             if ($method === null) {
                 throw new \RuntimeException("Missing method on{$event}");
             }
             $this->registerHandler($method->getParameters()[0]->getClass()->getName(), $method->getName(), EventPriority::LOW, true);
         }
     }
 }
예제 #7
0
 public function onCompletion(Server $server)
 {
     $main = HereAuth::getInstance($server);
     if ($main === null) {
         return;
     }
     $hook = $main->getFridge()->get($this->hook);
     $hook($this->success);
 }
 public function onCompletion(Server $server)
 {
     if (!$this->passed) {
         $main = HereAuth::getInstance($server);
         if ($main !== null) {
             $player = $main->getPlayerById($this->identifier);
             $player->kick("You created too many accounts!", false);
         }
     }
 }
 public function onCompletion(Server $server)
 {
     $main = HereAuth::getInstance($server);
     if ($main !== null) {
         $hook = $main->getFridge()->get($this->hookId);
         if (is_callable($hook)) {
             $hook($this->success);
         }
     }
 }
 public function onSubmit($value)
 {
     $hash = HereAuth::hash($value, $this->user->getPlayer());
     $tempHash = $this->user->getRegistration()->getTempHash();
     $this->user->getRegistration()->setTempHash("");
     if ($hash !== $tempHash) {
         $this->user->getRegistration()->rewind();
         return false;
     }
     $this->user->getAccountInfo()->passwordHash = $hash;
     return true;
 }
예제 #11
0
 public function __construct(HereAuth $main)
 {
     $dir = rtrim($main->getConfig()->getNested("AuditLogger.LogFolder", "audit"), "/") . "/";
     if ($dir[0] !== "/" and strpos($dir, "://") === false) {
         $dir = $main->getDataFolder() . $dir;
     }
     if (!is_dir($dir)) {
         mkdir($dir, 0777, true);
     }
     foreach ($entries = ["register", "login", "push", "bump", "invalid", "timeout", "factor"] as $entry) {
         $value = $main->getConfig()->getNested("AuditLogger.Log." . ucfirst($entry), ($isWin = Utils::getOS() === "win") ? "/NUL" : "/dev/null");
         if ($value === "/NUL" and !$isWin or $value === "/dev/null" and $isWin) {
             $main->getLogger()->warning("Your OS is " . ($isWin ? "Windows" : "not Windows") . ", where {$value} is not a special file! HereAuth will attempt to create that file!");
         }
         if ($value[0] !== "/") {
             $value = $dir . $value;
         }
         $this->{$entry} = $stream = $this->getStream($value);
         //			fwrite($stream, date(self::DATE_FORMAT) . " Start logging $entry\n");
     }
 }
예제 #12
0
 public function onCompletion(Server $server)
 {
     $main = HereAuth::getInstance($server);
     if ($main !== null) {
         if ($this->output !== null) {
             $output = new AccountInfo();
             $output->unserialize($this->output);
         } else {
             $output = null;
         }
         $main->onUserStart($this->identifier, $output);
     }
 }
 public function onSubmit($value)
 {
     $hash = HereAuth::hash($value, $this->user->getPlayer());
     $tempHash = $this->user->getRegistration()->getTempHash();
     $this->user->getRegistration()->setTempHash("");
     if ($hash !== $tempHash) {
         $this->user->getPlayer()->sendMessage($this->user->getMain()->getConfig()->getNested("Messages.Register.PasswordMismatch", "Incorrect password"));
         $this->user->getRegistration()->rewind();
         return false;
     }
     $this->user->getAccountInfo()->passwordHash = $hash;
     return true;
 }
예제 #14
0
 /**
  * @param MySQLCredentials $crd
  * @param HereAuth         $main
  *
  * @return \mysqli
  */
 public static function createMysqliInstance(MySQLCredentials $crd, HereAuth $main = null)
 {
     /** @noinspection PhpUsageOfSilenceOperatorInspection */
     $db = @new \mysqli($crd->host, $crd->username, $crd->password, $crd->schema, $crd->port, $crd->socket);
     if ($db->connect_error === "Unknown database '{$crd->schema}'") {
         /** @noinspection PhpUsageOfSilenceOperatorInspection */
         $db = @new \mysqli($crd->host, $crd->username, $crd->password, "", $crd->port, $crd->socket);
         $createSchema = true;
     }
     if ($db->connect_error) {
         throw new \InvalidKeyException($db->connect_error);
     }
     if (isset($createSchema)) {
         if ($main !== null) {
             $main->getLogger()->notice("Creating nonexistent `{$crd->schema}`...");
         }
         $db->query("CREATE SCHEMA `{$crd->schema}`");
         if (isset($db->error)) {
             throw new \InvalidKeyException("Schema does not exist and cannot be created");
         }
     }
     return $db;
 }
예제 #15
0
 public function onCompletion(Server $server)
 {
     $main = HereAuth::getInstance($server);
     if ($main === null) {
         return;
     }
     $result = $this->getResult();
     if (is_array($result)) {
         $info = AccountInfo::fromDatabaseRow($result);
     } else {
         $info = null;
     }
     $main->onUserStart($this->identifier, $info);
 }
예제 #16
0
 public static function defaultInstance(HereAuth $main)
 {
     $opts = new self();
     $opts->autoSecret = $main->getConfig()->getNested("DefaultSettings.AutoAuth.ClientSecretAuth", true);
     $opts->autoIp = $main->getConfig()->getNested("DefaultSettings.AutoAuth.IPAuth", false);
     $opts->autoUuid = $main->getConfig()->getNested("DefaultSettings.AutoAuth.UUIDAuth", false);
     $opts->maskLoc = $main->getConfig()->getNested("DefaultSettings.Masking.Location.Enabled", false);
     $opts->maskLocPos = $main->getConfig()->getNested("DefaultSettings.Masking.Location.Value", "?spawn?@?current?");
     if (!preg_match('#^((\\?spawn\\?)|((\\-)?[0-9]+,(\\-)?[0-9]+,(\\-)?[0-9]+))@[^/\\\\]+$#', $opts->maskLocPos)) {
         $main->getLogger()->alert("Incorrect syntax for location-masking position (DefaultSettings.Masking.Location.Value)! Assuming as \"?spawn?@?current?\".");
         $opts->maskLocPos = "?spawn?@?current?";
     }
     return $opts;
 }
예제 #17
0
 public function onCompletion(Server $server)
 {
     if (!$this->isReg or $this->time === -1) {
         return;
     }
     $main = HereAuth::getInstance($server);
     if ($main === null) {
         return;
     }
     $db = $main->getDataBase();
     if (!$db instanceof JsonDatabase) {
         return;
     }
     $stmt = $db->getSQLite3()->prepare("INSERT OR REPLACE INTO reg (ip, name, time) VALUES (:ip, :name, :time)");
     $stmt->bindValue(":ip", $this->ip, SQLITE3_TEXT);
     $stmt->bindValue(":name", strtolower($this->name), SQLITE3_TEXT);
     $stmt->bindValue(":time", $this->time, SQLITE3_INTEGER);
     $stmt->execute();
 }
예제 #18
0
 protected function onRun(array $args, User $user)
 {
     if (!isset($args[0])) {
         return "Usage: " . $this->getUsage();
     }
     $password = $args[0];
     $hash = HereAuth::hash($password, $user->getPlayer());
     $firstHash = $user->getChangepwHash();
     if ($firstHash !== null) {
         $user->setChangepwHash(null);
         if ($firstHash === $hash) {
             $user->getAccountInfo()->passwordHash = $hash;
             return $this->getMessage("Commands.ChangePassword.Success", "Your password has been changed.");
         }
         return $this->getMessage("Commands.ChangePassword.DoubleCheckFailure", "Your password is different this time! Aborted.");
     }
     if (!PasswordInputRegistrationStep::validatePassword($user, $password)) {
         return false;
     }
     $user->setChangepwHash($hash);
     return $this->getMessage("Commands.ChangePassword.RequestRepeat", "Please run this command again to confirm.");
 }
예제 #19
0
 public function handle($value)
 {
     /** @noinspection PhpInternalEntityUsedInspection */
     if (!$this->current() instanceof PasswordRegistrationStep) {
         if (HereAuth::hash($value, $this->user->getPlayer()) === $this->user->getAccountInfo()->passwordHash) {
             $this->user->getPlayer()->sendMessage("[HereAuth] If the message above is asking you to enter your password, it is not a message from HereAuth! Please beware your password being stolen!");
             return;
         }
     }
     if ($this->current()->onSubmit($value)) {
         if ($this->next()) {
             return;
         }
     }
     $this->user->getPlayer()->sendMessage($this->current()->getMessage());
 }
예제 #20
0
 protected function onRun(array $args, User $user)
 {
     if (!isset($args[1])) {
         $page = isset($args[0]) ? (int) $args[0] + 1 : 1;
         return HereAuth::page($this->getHelpMessage($user), $page);
     }
     $opts = $user->getAccountInfo()->opts;
     $type = array_shift($args);
     $value = array_shift($args);
     $boolVal = $this->parseBool($value);
     $action = $boolVal ? "Enabled" : "Disabled";
     switch ($type) {
         case "autosecret":
         case "as":
             if (!$user->getPlayer()->hasPermission("hereauth.auth.autoauth.clientsecret")) {
                 return "You don't have permission to do this!";
             }
             $opts->autoSecret = $boolVal;
             return "{$action} client secret AutoAuth";
         case "autouuid":
         case "au":
             if (!$user->getPlayer()->hasPermission("hereauth.auth.autoauth.uuid")) {
                 return "You don't have permission to do this!";
             }
             $opts->autoUuid = $boolVal;
             return "{$action} UUID AutoAuth";
         case "autoip":
         case "ai":
             if (!$user->getPlayer()->hasPermission("hereauth.auth.autoauth.ip")) {
                 return "You don't have permission to do this!";
             }
             $opts->autoIp = $boolVal;
             return "{$action} IP AutoAuth";
         case "maskloc":
         case "ml":
             if (!$user->getPlayer()->hasPermission("hereauth.auth.masking.location.toggle")) {
                 return "You don't have permission to do this!";
             }
             $opts->maskLoc = $boolVal;
             return "{$action} location masking";
         case "maskinv":
         case "mi":
             if (!$user->getPlayer()->hasPermission("hereauth.auth.masking.inventory")) {
                 return "You don't have permission to do this!";
             }
             $opts->maskInv = $boolVal;
             return "{$action} inventory masking";
         case "mafskin":
         case "mafs":
             if (!$user->getPlayer()->hasPermission("hereauth.auth.multiauth.skin")) {
                 return "You don't have permission to do this!";
             }
             $opts->multiSkin = $boolVal;
             return "{$action} skin MAF";
         case "mafip":
         case "mafi":
             if (!$user->getPlayer()->hasPermission("hereauth.auth.multiauth.ip")) {
                 return "You don't have permission to do this!";
             }
             $opts->multiIp = $boolVal;
             return "{$action} IP MAF";
     }
     return "Unknown option \"{$type}\"";
 }
예제 #21
0
 public function onMessage(PlayerCommandPreprocessEvent $event)
 {
     $message = $event->getMessage();
     $hash = HereAuth::hash($message, $this->getPlayer());
     if ($this->state === self::STATE_PENDING_LOGIN) {
         if ($hash === $this->accountInfo->passwordHash) {
             $this->onAuth();
         } else {
             $this->loginAttempts++;
             $chances = $this->main->getConfig()->getNested("Login.MaxAttempts", 5);
             $left = $chances - $this->loginAttempts;
             if ($left <= 0) {
                 $this->getPlayer()->kick("Failed to login in {$chances} attempts", false);
             }
             $msg = $this->getMain()->getConfig()->getNested("Messages.Login.WrongPass", "wrong pass");
             $msg = str_replace('$CHANCES', $left, $msg);
             $this->getPlayer()->sendMessage($msg);
         }
         $event->setCancelled();
         $event->setMessage("");
     } elseif ($this->state === self::STATE_PLAYING) {
         if ($hash === $this->accountInfo->passwordHash and $this->getMain()->getConfig()->getNested("BlockPasswordChat", true)) {
             $event->setCancelled();
             $event->setMessage("");
         }
     } elseif ($this->state === self::STATE_REGISTERING) {
         $this->registration->handle($message);
         $event->setCancelled();
         $event->setMessage("");
     }
 }
예제 #22
0
 public function hash($password, $salt, $suffix)
 {
     return HereAuth::hash($password, $suffix);
 }
예제 #23
0
 public function onMessage(PlayerCommandPreprocessEvent $event)
 {
     $message = $event->getMessage();
     $hash = HereAuth::hash($message, $this->getPlayer());
     if ($this->state === self::STATE_PENDING_LOGIN) {
         if ($this->accountInfo->testPassword($this->main, $message) and $this->callLogin(HereAuthLoginEvent::METHOD_PASSWORD)) {
             $this->main->getAuditLogger()->logLogin(strtolower($this->player->getName()), $this->player->getAddress(), "password");
             $this->onAuth();
         } else {
             $this->main->getAuditLogger()->logInvalid(strtolower($this->player->getName()), $this->player->getAddress());
             $this->loginAttempts++;
             $chances = $this->main->getConfig()->getNested("Login.MaxAttempts", 5);
             $left = $chances - $this->loginAttempts;
             if ($left <= 0) {
                 $this->getPlayer()->kick("Failed to login in {$chances} attempts", false);
                 $event->setCancelled();
                 $event->setMessage("");
                 $blockSecs = $this->main->getConfig()->getNested("Login.MaxAttemptsBlock", 600);
                 if ($blockSecs > 0) {
                     $this->main->getServer()->getNetwork()->blockAddress($this->player->getAddress(), $blockSecs);
                 }
                 return;
             }
             $msg = $this->getMain()->getMessages()->getNested("Login.WrongPass", "wrong pass");
             $msg = str_replace('$CHANCES', $left, $msg);
             $this->getPlayer()->sendMessage($msg);
         }
         $event->setCancelled();
         $event->setMessage("");
     } elseif ($this->state === self::STATE_PLAYING) {
         if ($hash === $this->accountInfo->passwordHash and $this->getMain()->getConfig()->getNested("BlockPasswordChat", true)) {
             $event->setCancelled();
             $event->setMessage("");
             $this->getPlayer()->sendMessage($this->getMain()->getMessages()->getNested("Chat.DirectPass", "Don't tell your password"));
         }
     } elseif ($this->state === self::STATE_REGISTERING) {
         $this->registration->handle($message);
         $event->setCancelled();
         $event->setMessage("");
     }
 }
 public function hash($password, $salt, $suffix)
 {
     return bin2hex(HereAuth::hash($password, $salt));
 }
예제 #25
0
 public function handle($value)
 {
     /** @noinspection PhpInternalEntityUsedInspection */
     if (!$this->current() instanceof PasswordRegistrationStep) {
         if (HereAuth::hash($value, $this->user->getPlayer()) === $this->user->getAccountInfo()->passwordHash) {
             if ($this->current()->onSubmit($value)) {
                 if ($this->next()) {
                     return;
                 }
             }
         }
     }
     $this->user->getPlayer()->sendMessage($this->current()->getMessage());
 }