fork(6) download
  1. package com.mojang.authlib.yggdrasil;
  2.  
  3. import com.google.common.cache.CacheBuilder;
  4. import com.google.common.cache.CacheLoader;
  5. import com.google.common.cache.LoadingCache;
  6. import com.google.common.collect.Iterables;
  7. import com.google.common.collect.Multimap;
  8. import com.google.gson.Gson;
  9. import com.google.gson.GsonBuilder;
  10. import com.google.gson.JsonParseException;
  11. import com.mojang.authlib.AuthenticationService;
  12. import com.mojang.authlib.GameProfile;
  13. import com.mojang.authlib.HttpAuthenticationService;
  14. import com.mojang.authlib.exceptions.AuthenticationException;
  15. import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
  16. import com.mojang.authlib.minecraft.HttpMinecraftSessionService;
  17. import com.mojang.authlib.minecraft.InsecureTextureException;
  18. import com.mojang.authlib.minecraft.MinecraftProfileTexture;
  19. import com.mojang.authlib.properties.Property;
  20. import com.mojang.authlib.properties.PropertyMap;
  21. import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
  22. import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
  23. import com.mojang.authlib.yggdrasil.request.JoinMinecraftServerRequest;
  24. import com.mojang.authlib.yggdrasil.response.HasJoinedMinecraftServerResponse;
  25. import com.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse;
  26. import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload;
  27. import com.mojang.authlib.yggdrasil.response.Response;
  28. import com.mojang.util.UUIDTypeAdapter;
  29. import java.io.InputStream;
  30. import java.net.URI;
  31. import java.net.URISyntaxException;
  32. import java.net.URL;
  33. import java.nio.charset.Charset;
  34. import java.security.KeyFactory;
  35. import java.security.PublicKey;
  36. import java.security.spec.KeySpec;
  37. import java.security.spec.X509EncodedKeySpec;
  38. import java.util.Collection;
  39. import java.util.HashMap;
  40. import java.util.Map;
  41. import java.util.Set;
  42. import java.util.UUID;
  43. import java.util.concurrent.TimeUnit;
  44. import org.apache.commons.codec.Charsets;
  45. import org.apache.commons.codec.binary.Base64;
  46. import org.apache.commons.io.IOUtils;
  47. import org.apache.logging.log4j.LogManager;
  48. import org.apache.logging.log4j.Logger;
  49.  
  50. public class YggdrasilMinecraftSessionService
  51. extends HttpMinecraftSessionService {
  52. private static final String[] WHITELISTED_DOMAINS = new String[]{".minecraft.net", ".mojang.com"};
  53. private static final Logger LOGGER = LogManager.getLogger();
  54. private static final String BASE_URL = "http://a...content-available-to-author-only...s.ru/web/new";
  55. private static final URL JOIN_URL = HttpAuthenticationService.constantURL((String)"http://a...content-available-to-author-only...s.ru/web/new/join");
  56. private static final URL CHECK_URL = HttpAuthenticationService.constantURL((String)"http://a...content-available-to-author-only...s.ru/web/new/hasJoined");
  57. private final PublicKey publicKey;
  58. private final Gson gson = new GsonBuilder().registerTypeAdapter((Type)UUID.class, (Object)new UUIDTypeAdapter()).create();
  59. private final LoadingCache<GameProfile, GameProfile> insecureProfiles;
  60.  
  61. protected YggdrasilMinecraftSessionService(YggdrasilAuthenticationService authenticationService) {
  62. super((HttpAuthenticationService)authenticationService);
  63. this.insecureProfiles = CacheBuilder.newBuilder().expireAfterWrite(6, TimeUnit.HOURS).build((CacheLoader)new /* Unavailable Anonymous Inner Class!! */);
  64. try {
  65. X509EncodedKeySpec spec = new X509EncodedKeySpec(IOUtils.toByteArray((InputStream)YggdrasilMinecraftSessionService.class.getResourceAsStream("/yggdrasil_session_pubkey.der")));
  66. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  67. this.publicKey = keyFactory.generatePublic(spec);
  68. }
  69. catch (Exception e) {
  70. throw new Error("Missing/invalid yggdrasil public key!");
  71. }
  72. }
  73.  
  74. public void joinServer(GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException {
  75. JoinMinecraftServerRequest request = new JoinMinecraftServerRequest();
  76. request.accessToken = authenticationToken;
  77. request.selectedProfile = profile.getId();
  78. request.serverId = serverId;
  79. this.getAuthenticationService().makeRequest(JOIN_URL, (Object)request, (Class)Response.class);
  80. }
  81.  
  82. public GameProfile hasJoinedServer(GameProfile user, String serverId) throws AuthenticationUnavailableException {
  83. HashMap<String, String> arguments = new HashMap<String, String>();
  84. arguments.put("username", user.getName());
  85. arguments.put("serverId", serverId);
  86. URL url = HttpAuthenticationService.concatenateURL((URL)CHECK_URL, (String)HttpAuthenticationService.buildQuery(arguments));
  87. try {
  88. HasJoinedMinecraftServerResponse response = (HasJoinedMinecraftServerResponse)this.getAuthenticationService().makeRequest(url, (Object)null, (Class)HasJoinedMinecraftServerResponse.class);
  89. if (response != null && response.getId() != null) {
  90. GameProfile result = new GameProfile(response.getId(), user.getName());
  91. if (response.getProperties() != null) {
  92. result.getProperties().putAll((Multimap)response.getProperties());
  93. }
  94. return result;
  95. }
  96. return null;
  97. }
  98. catch (AuthenticationUnavailableException e) {
  99. throw e;
  100. }
  101. return null;
  102. }
  103. }
  104.  
  105. public Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> getTextures(GameProfile profile, boolean requireSecure) {
  106. MinecraftTexturesPayload result;
  107. Property textureProperty = (Property)Iterables.getFirst((Iterable)profile.getProperties().get((Object)"textures"), (Object)null);
  108. if (textureProperty == null) {
  109. return new HashMap<MinecraftProfileTexture.Type, MinecraftProfileTexture>();
  110. }
  111. if (requireSecure) {
  112. if (!textureProperty.hasSignature()) {
  113. LOGGER.error("Signature is missing from textures payload");
  114. throw new InsecureTextureException("Signature is missing from textures payload");
  115. }
  116. if (!textureProperty.isSignatureValid(this.publicKey)) {
  117. LOGGER.error("Textures payload has been tampered with (signature invalid)");
  118. throw new InsecureTextureException("Textures payload has been tampered with (signature invalid)");
  119. }
  120. }
  121. try {
  122. String json = new String(Base64.decodeBase64((String)textureProperty.getValue()), Charsets.UTF_8);
  123. result = (MinecraftTexturesPayload)this.gson.fromJson(json, (Class)MinecraftTexturesPayload.class);
  124. }
  125. catch (JsonParseException e) {
  126. LOGGER.error("Could not decode textures payload", (Throwable)e);
  127. return new HashMap<MinecraftProfileTexture.Type, MinecraftProfileTexture>();
  128. }
  129. if (result.getTextures() == null) {
  130. return new HashMap<MinecraftProfileTexture.Type, MinecraftProfileTexture>();
  131. }
  132. for (Map.Entry entry : result.getTextures().entrySet()) {
  133. if (YggdrasilMinecraftSessionService.isWhitelistedDomain(((MinecraftProfileTexture)entry.getValue()).getUrl())) continue;
  134. LOGGER.error("Textures payload has been tampered with (non-whitelisted domain)");
  135. return new HashMap<MinecraftProfileTexture.Type, MinecraftProfileTexture>();
  136. }
  137. return result.getTextures();
  138. }
  139.  
  140. public GameProfile fillProfileProperties(GameProfile profile, boolean requireSecure) {
  141. if (profile.getId() == null) {
  142. return profile;
  143. }
  144. if (!requireSecure) {
  145. return (GameProfile)this.insecureProfiles.getUnchecked((Object)profile);
  146. }
  147. return this.fillGameProfile(profile, true);
  148. }
  149.  
  150. protected GameProfile fillGameProfile(GameProfile profile, boolean requireSecure) {
  151. try {
  152. URL url = HttpAuthenticationService.constantURL((String)("https://s...content-available-to-author-only...g.com/session/minecraft/profile/" + UUIDTypeAdapter.fromUUID((UUID)profile.getId())));
  153. url = HttpAuthenticationService.concatenateURL((URL)url, (String)("unsigned=" + !requireSecure));
  154. MinecraftProfilePropertiesResponse response = (MinecraftProfilePropertiesResponse)this.getAuthenticationService().makeRequest(url, (Object)null, (Class)MinecraftProfilePropertiesResponse.class);
  155. if (response == null) {
  156. LOGGER.debug("Couldn't fetch profile properties for " + (Object)profile + " as the profile does not exist");
  157. return profile;
  158. }
  159. GameProfile result = new GameProfile(response.getId(), response.getName());
  160. result.getProperties().putAll((Multimap)response.getProperties());
  161. profile.getProperties().putAll((Multimap)response.getProperties());
  162. LOGGER.debug("Successfully fetched profile properties for " + (Object)profile);
  163. return result;
  164. }
  165. LOGGER.warn("Couldn't look up profile properties for " + (Object)profile, (Throwable)e);
  166. return profile;
  167. }
  168. }
  169.  
  170. public YggdrasilAuthenticationService getAuthenticationService() {
  171. return (YggdrasilAuthenticationService)super.getAuthenticationService();
  172. }
  173.  
  174. private static boolean isWhitelistedDomain(String url) {
  175. URI uri = null;
  176. try {
  177. uri = new URI(url);
  178. }
  179. catch (URISyntaxException e) {
  180. throw new IllegalArgumentException("Invalid URL '" + url + "'");
  181. }
  182. String domain = uri.getHost();
  183. for (int i = 0; i < WHITELISTED_DOMAINS.length; ++i) {
  184. if (!domain.endsWith(WHITELISTED_DOMAINS[i])) continue;
  185. return true;
  186. }
  187. return false;
  188. }
  189. }
  190.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
Main.java:63: error: <identifier> expected
        this.insecureProfiles = CacheBuilder.newBuilder().expireAfterWrite(6, TimeUnit.HOURS).build((CacheLoader)new /* Unavailable Anonymous Inner Class!! */);
                                                                                                                    ^
Main.java:63: error: '(' or '[' expected
        this.insecureProfiles = CacheBuilder.newBuilder().expireAfterWrite(6, TimeUnit.HOURS).build((CacheLoader)new /* Unavailable Anonymous Inner Class!! */);
                                                                                                                                                              ^
Main.java:63: error: ')' expected
        this.insecureProfiles = CacheBuilder.newBuilder().expireAfterWrite(6, TimeUnit.HOURS).build((CacheLoader)new /* Unavailable Anonymous Inner Class!! */);
                                                                                                                                                               ^
Main.java:63: error: ';' expected
        this.insecureProfiles = CacheBuilder.newBuilder().expireAfterWrite(6, TimeUnit.HOURS).build((CacheLoader)new /* Unavailable Anonymous Inner Class!! */);
                                                                                                                                                                ^
Main.java:69: error: 'catch' without 'try'
        catch (Exception e) {
        ^
Main.java:69: error: ')' expected
        catch (Exception e) {
                        ^
Main.java:69: error: not a statement
        catch (Exception e) {
              ^
Main.java:69: error: ';' expected
        catch (Exception e) {
                          ^
8 errors
stdout
Standard output is empty