mirror of
https://github.com/SpigotMC/BungeeCord.git
synced 2024-11-24 03:05:49 +01:00
Thread login auth properly.
This commit is contained in:
parent
9ad9003974
commit
9e0ae0a70d
@ -1,17 +1,10 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
@ -32,7 +25,7 @@ public class EncryptionUtil
|
||||
{
|
||||
|
||||
private static final Random random = new Random();
|
||||
private static KeyPair keys;
|
||||
public static KeyPair keys;
|
||||
|
||||
public static PacketFDEncryptionRequest encryptRequest() throws NoSuchAlgorithmException
|
||||
{
|
||||
@ -66,30 +59,6 @@ public class EncryptionUtil
|
||||
return new SecretKeySpec( secret, "AES" );
|
||||
}
|
||||
|
||||
public static boolean isAuthenticated(String username, String connectionHash, SecretKey shared) throws NoSuchAlgorithmException, IOException
|
||||
{
|
||||
String encName = URLEncoder.encode( username, "UTF-8" );
|
||||
|
||||
MessageDigest sha = MessageDigest.getInstance( "SHA-1" );
|
||||
for ( byte[] bit : new byte[][]
|
||||
{
|
||||
connectionHash.getBytes( "ISO_8859_1" ), shared.getEncoded(), keys.getPublic().getEncoded()
|
||||
} )
|
||||
{
|
||||
sha.update( bit );
|
||||
}
|
||||
|
||||
String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" );
|
||||
String authURL = "http://session.minecraft.net/game/checkserver.jsp?user=" + encName + "&serverId=" + encodedHash;
|
||||
String reply;
|
||||
try ( BufferedReader in = new BufferedReader( new InputStreamReader( new URL( authURL ).openStream() ) ) )
|
||||
{
|
||||
reply = in.readLine();
|
||||
}
|
||||
|
||||
return "YES".equals( reply );
|
||||
}
|
||||
|
||||
public static Cipher getCipher(int opMode, Key shared) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException
|
||||
{
|
||||
Cipher cip = Cipher.getInstance( "AES/CFB8/NoPadding" );
|
||||
|
@ -2,7 +2,14 @@ package net.md_5.bungee.connection;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.channel.Channel;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.crypto.Cipher;
|
||||
@ -11,8 +18,8 @@ import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.EncryptionUtil;
|
||||
import net.md_5.bungee.KickException;
|
||||
import net.md_5.bungee.UserConnection;
|
||||
import net.md_5.bungee.Util;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
@ -104,37 +111,79 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketFCEncryptionResponse encryptResponse) throws Exception
|
||||
public void handle(final PacketFCEncryptionResponse encryptResponse) throws Exception
|
||||
{
|
||||
Preconditions.checkState( thisState == State.ENCRYPT, "Not expecting ENCRYPT" );
|
||||
|
||||
SecretKey shared = EncryptionUtil.getSecret( encryptResponse, request );
|
||||
if ( BungeeCord.getInstance().config.isOnlineMode() && !EncryptionUtil.isAuthenticated( handshake.username, request.serverId, shared ) )
|
||||
// TODO: This is shit
|
||||
new Thread( "Login Verifier - " + getName() )
|
||||
{
|
||||
throw new KickException( "Not authenticated with minecraft.net" );
|
||||
}
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
SecretKey shared = EncryptionUtil.getSecret( encryptResponse, request );
|
||||
if ( BungeeCord.getInstance().config.isOnlineMode() )
|
||||
{
|
||||
String reply = null;
|
||||
try
|
||||
{
|
||||
String encName = URLEncoder.encode( InitialHandler.this.getName(), "UTF-8" );
|
||||
|
||||
// Check for multiple connections
|
||||
ProxiedPlayer old = bungee.getPlayer( handshake.username );
|
||||
if ( old != null )
|
||||
{
|
||||
old.disconnect( "You are already connected to the server" );
|
||||
}
|
||||
MessageDigest sha = MessageDigest.getInstance( "SHA-1" );
|
||||
for ( byte[] bit : new byte[][]
|
||||
{
|
||||
request.serverId.getBytes( "ISO_8859_1" ), shared.getEncoded(), EncryptionUtil.keys.getPublic().getEncoded()
|
||||
} )
|
||||
{
|
||||
sha.update( bit );
|
||||
}
|
||||
|
||||
// fire login event
|
||||
LoginEvent event = new LoginEvent( this );
|
||||
if ( bungee.getPluginManager().callEvent( event ).isCancelled() )
|
||||
{
|
||||
disconnect( event.getCancelReason() );
|
||||
}
|
||||
String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" );
|
||||
String authURL = "http://session.minecraft.net/game/checkserver.jsp?user=" + encName + "&serverId=" + encodedHash;
|
||||
|
||||
ch.write( new PacketFCEncryptionResponse() );
|
||||
try ( BufferedReader in = new BufferedReader( new InputStreamReader( new URL( authURL ).openStream() ) ) )
|
||||
{
|
||||
reply = in.readLine();
|
||||
}
|
||||
} catch ( IOException ex )
|
||||
{
|
||||
}
|
||||
|
||||
Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, shared );
|
||||
Cipher encrypt = EncryptionUtil.getCipher( Cipher.ENCRYPT_MODE, shared );
|
||||
ch.pipeline().addBefore( "decoder", "cipher", new CipherCodec( encrypt, decrypt ) );
|
||||
if ( !"YES".equals( reply ) )
|
||||
{
|
||||
disconnect( "Not authenticated with Minecraft.net" );
|
||||
}
|
||||
|
||||
thisState = State.LOGIN;
|
||||
// Check for multiple connections
|
||||
ProxiedPlayer old = bungee.getPlayer( handshake.username );
|
||||
if ( old != null )
|
||||
{
|
||||
old.disconnect( "You are already connected to the server" );
|
||||
}
|
||||
|
||||
// fire login event
|
||||
LoginEvent event = new LoginEvent( InitialHandler.this );
|
||||
if ( bungee.getPluginManager().callEvent( event ).isCancelled() )
|
||||
{
|
||||
disconnect( event.getCancelReason() );
|
||||
}
|
||||
}
|
||||
|
||||
ch.write( new PacketFCEncryptionResponse() );
|
||||
|
||||
Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, shared );
|
||||
Cipher encrypt = EncryptionUtil.getCipher( Cipher.ENCRYPT_MODE, shared );
|
||||
ch.pipeline().addBefore( "decoder", "cipher", new CipherCodec( encrypt, decrypt ) );
|
||||
|
||||
thisState = InitialHandler.State.LOGIN;
|
||||
} catch ( Exception ex )
|
||||
{
|
||||
disconnect( "[Report to md_5 / Server Owner] " + Util.exception( ex ) );
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user