public static ServerAuth.StartAuthSessionResult StartAuthSession(byte[] authTicketData, ulong clientSteamID) { if (instance == null || !instance.isInitialized || instance.server == null) { return(ServerAuth.StartAuthSessionResult.ServerNotConnectedToSteam); } DebugConsole.Log("SteamManager authenticating Steam client " + clientSteamID); ServerAuth.StartAuthSessionResult startResult = instance.server.Auth.StartSession(authTicketData, clientSteamID); if (startResult != ServerAuth.StartAuthSessionResult.OK) { DebugConsole.Log("Authentication failed: failed to start auth session (" + startResult.ToString() + ")"); } return(startResult); }
private void ReadConnectionInitializationStep(PendingClient pendingClient, NetIncomingMessage inc) { if (netServer == null) { return; } pendingClient.TimeOut = NetworkConnection.TimeoutThreshold; ConnectionInitialization initializationStep = (ConnectionInitialization)inc.ReadByte(); //DebugConsole.NewMessage(initializationStep+" "+pendingClient.InitializationStep); if (pendingClient.InitializationStep != initializationStep) { return; } pendingClient.UpdateTime = Timing.TotalTime + Timing.Step; switch (initializationStep) { case ConnectionInitialization.SteamTicketAndVersion: string name = Client.SanitizeName(inc.ReadString()); int ownKey = inc.ReadInt32(); UInt64 steamId = inc.ReadUInt64(); UInt16 ticketLength = inc.ReadUInt16(); byte[] ticket = inc.ReadBytes(ticketLength); if (!Client.IsValidName(name, serverSettings)) { if (OwnerConnection != null || !IPAddress.IsLoopback(pendingClient.Connection.RemoteEndPoint.Address.MapToIPv4()) && ownerKey == null || ownKey == 0 && ownKey != ownerKey) { RemovePendingClient(pendingClient, DisconnectReason.InvalidName, "The name \"" + name + "\" is invalid"); return; } } string version = inc.ReadString(); bool isCompatibleVersion = NetworkMember.IsCompatible(version, GameMain.Version.ToString()) ?? false; if (!isCompatibleVersion) { RemovePendingClient(pendingClient, DisconnectReason.InvalidVersion, $"DisconnectMessage.InvalidVersion~[version]={GameMain.Version.ToString()}~[clientversion]={version}"); GameServer.Log(name + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (incompatible game version)", ServerLog.MessageType.Error); DebugConsole.NewMessage(name + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (incompatible game version)", Microsoft.Xna.Framework.Color.Red); return; } Int32 contentPackageCount = inc.ReadVariableInt32(); List <ClientContentPackage> contentPackages = new List <ClientContentPackage>(); for (int i = 0; i < contentPackageCount; i++) { string packageName = inc.ReadString(); string packageHash = inc.ReadString(); contentPackages.Add(new ClientContentPackage(packageName, packageHash)); } List <ContentPackage> missingPackages = new List <ContentPackage>(); foreach (ContentPackage contentPackage in GameMain.SelectedPackages) { if (!contentPackage.HasMultiplayerIncompatibleContent) { continue; } bool packageFound = false; for (int i = 0; i < contentPackageCount; i++) { if (contentPackages[i].Name == contentPackage.Name && contentPackages[i].Hash == contentPackage.MD5hash.Hash) { packageFound = true; break; } } if (!packageFound) { missingPackages.Add(contentPackage); } } if (missingPackages.Count == 1) { RemovePendingClient(pendingClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(missingPackages[0])}"); GameServer.Log(name + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (missing content package " + GetPackageStr(missingPackages[0]) + ")", ServerLog.MessageType.Error); return; } else if (missingPackages.Count > 1) { List <string> packageStrs = new List <string>(); missingPackages.ForEach(cp => packageStrs.Add(GetPackageStr(cp))); RemovePendingClient(pendingClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackages~[missingcontentpackages]={string.Join(", ", packageStrs)}"); GameServer.Log(name + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (missing content packages " + string.Join(", ", packageStrs) + ")", ServerLog.MessageType.Error); return; } if (pendingClient.SteamID == null) { bool requireSteamAuth = GameMain.Config.RequireSteamAuthentication; #if DEBUG requireSteamAuth = false; #endif //steam auth cannot be done (SteamManager not initialized or no ticket given), //but it's not required either -> let the client join without auth if ((!Steam.SteamManager.IsInitialized || ticket.Length == 0) && !requireSteamAuth) { pendingClient.Name = name; pendingClient.OwnerKey = ownKey; pendingClient.InitializationStep = ConnectionInitialization.Success; } else { ServerAuth.StartAuthSessionResult authSessionStartState = Steam.SteamManager.StartAuthSession(ticket, steamId); if (authSessionStartState != ServerAuth.StartAuthSessionResult.OK) { RemovePendingClient(pendingClient, DisconnectReason.SteamAuthenticationFailed, "Steam auth session failed to start: " + authSessionStartState.ToString()); return; } pendingClient.SteamID = steamId; pendingClient.Name = name; pendingClient.OwnerKey = ownKey; pendingClient.AuthSessionStarted = true; } } else //TODO: could remove since this seems impossible { if (pendingClient.SteamID != steamId) { RemovePendingClient(pendingClient, DisconnectReason.SteamAuthenticationFailed, "SteamID mismatch"); return; } } break; case ConnectionInitialization.Password: int pwLength = inc.ReadByte(); byte[] incPassword = new byte[pwLength]; inc.ReadBytes(incPassword, 0, pwLength); if (pendingClient.PasswordSalt == null) { DebugConsole.ThrowError("Received password message from client without salt"); return; } if (serverSettings.IsPasswordCorrect(incPassword, pendingClient.PasswordSalt.Value)) { pendingClient.InitializationStep = ConnectionInitialization.Success; } else { pendingClient.Retries++; if (pendingClient.Retries >= 3) { string banMsg = "Failed to enter correct password too many times"; if (pendingClient.SteamID != null) { serverSettings.BanList.BanPlayer(pendingClient.Name, pendingClient.SteamID.Value, banMsg, null); } serverSettings.BanList.BanPlayer(pendingClient.Name, pendingClient.Connection.RemoteEndPoint.Address, banMsg, null); RemovePendingClient(pendingClient, DisconnectReason.Banned, banMsg); return; } } pendingClient.UpdateTime = Timing.TotalTime; break; } }