/// <summary> /// 生成并保存RSA秘钥对 /// </summary> public static void GenKey(MimirContext db) { RSACryptoServiceProvider key = new RSACryptoServiceProvider(4096); var publicKey = RSACryptoServiceProviderExtensions.ToXmlString(key); var privateKey = RSACryptoServiceProviderExtensions.ToXmlString(key, true); foreach (var option in db.Options) { if (option.Option == "PublicKeyXml") { option.Value = publicKey; } if (option.Option == "PrivateKeyXml") { option.Value = privateKey; } if (option.Option == "PublicKey") { option.Value = PublicKeyToJavaFormat(privateKey); } } db.SaveChanges(); }
/// <summary> /// 从角色Uuid获取角色名 /// </summary> /// <param name="uuid">角色Uuid</param> /// <returns>角色名</returns> public static string GetNameFormUuid(MimirContext db, Guid uuid, bool isOnline = false) { if (isOnline) { var request = (HttpWebRequest)WebRequest.Create($"https://sessionserver.mojang.com/session/minecraft/profile/{uuid.ToString("N")}"); var response = (HttpWebResponse)request.GetResponse(); using (var stream = response.GetResponseStream()) { using (var reader = new StreamReader(stream)) { return(JsonConvert.DeserializeObject <Profile>(reader.ReadToEnd()).name); } } } else { var profile = from p in db.Profiles where p.Uuid == uuid.ToString("N") select p; if (profile.Count() != 1) { return(null); } else { return(profile.First().Name); } } }
/// <summary> /// 获取角色信息 /// </summary> /// <param name="db">数据库上下文对象</param> /// <param name="uuid">角色UUID</param> /// <param name="containProperties">是否包含属性</param> /// <param name="isUnsigned">是否不签名</param> /// <returns>角色信息</returns> public static Profile?GetProfile(MimirContext db, Guid uuid, bool containProperties = false, bool isUnsigned = true) { var name = GetNameFormUuid(db, uuid); if (name == null) { return(null); } return(GetProfile(db, name, containProperties, isUnsigned)); }
public LoginController(MimirContext context) { db = context; }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, MimirContext db) { if (env.IsDevelopment()) { log.Info("LittleC is a potato!"); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/error"); } // Load logic configs. log.Info("Loading logic configs."); try { Program.ServerName = (from o in db.Options where o.Option == "ServerName" select o.Value).First(); if ((from o in db.Options where o.Option == "PrivateKeyXml" select o.Value).First() == string.Empty) { SignatureWorker.GenKey(db); } RSACryptoServiceProviderExtensions.FromXmlString(Program.PrivateKeyProvider, (from o in db.Options where o.Option == "PrivateKeyXml" select o.Value).First()); Program.PublicKey = (from o in db.Options where o.Option == "PublicKey" select o.Value).First(); Program.ServerDomain = (from o in db.Options where o.Option == "ServerDomain" select o.Value).First(); int.TryParse((from o in db.Options where o.Option == "SecurityLoginTryTimes" select o.Value).First(), out Program.SecurityLoginTryTimes); bool.TryParse((from o in db.Options where o.Option == "IsEnableMultiProfiles" select o.Value).First(), out Program.IsEnableMultiProfiles); int.TryParse((from o in db.Options where o.Option == "MaxTokensPerProfile" select o.Value).First(), out Program.MaxTokensPerProfile); int.TryParse((from o in db.Options where o.Option == "TokensExpireDaysLimit" select o.Value).First(), out Program.TokensExpireDaysLimit); long.TryParse((from o in db.Options where o.Option == "SessionsExpireSeconds" select o.Value).First(), out Program.SessionsExpireSeconds); Program.SkinDomains = (from o in db.Options where o.Option == "SkinDomains" select o.Value).First().Split(","); int.TryParse((from o in db.Options where o.Option == "MaxProfileCountPerQuery" select o.Value).First(), out Program.MaxProfileCountPerQuery); bool.TryParse((from o in db.Options where o.Option == "IsEnableLandingPage" select o.Value).First(), out Program.IsEnableLandingPage); bool.TryParse((from o in db.Options where o.Option == "IsEnableSmtp" select o.Value).First(), out Program.IsEnableSmtp); Program.SmtpDomain = (from o in db.Options where o.Option == "SmtpDomain" select o.Value).First(); int.TryParse((from o in db.Options where o.Option == "SmtpPort" select o.Value).First(), out Program.SmtpPort); Program.SmtpEmail = (from o in db.Options where o.Option == "SmtpEmail" select o.Value).First(); Program.SmtpName = (from o in db.Options where o.Option == "SmtpName" select o.Value).First(); Program.SmtpPassword = (from o in db.Options where o.Option == "SmtpPassword" select o.Value).First(); bool.TryParse((from o in db.Options where o.Option == "SmtpIsSsl" select o.Value).First(), out Program.SmtpIsSsl); int.TryParse((from o in db.Options where o.Option == "MaxProfileCountPerUser" select o.Value).First(), out Program.MaxProfileCountPerUser); bool.TryParse((from o in db.Options where o.Option == "IsHttps" select o.Value).First(), out Program.IsHttps); } catch (Exception) { log.Fatal("Bad database."); throw; } log.Info("Logic configs loaded."); app.UseSession(); //app.UseHttpsRedirection(); app.UseStaticFiles(new StaticFileOptions() { ServeUnknownFileTypes = true, DefaultContentType = "image/png" }); app.Use(next => { return(async context => { context.Response.OnStarting(() => { // Add ALI. if (Program.IsHttps) { context.Response.Headers.Add("X-Authlib-Injector-API-Location", "https://" + Program.ServerDomain + "/api/"); } else { context.Response.Headers.Add("X-Authlib-Injector-API-Location", "http://" + Program.ServerDomain + "/api/"); } context.Response.Headers["Server"] = "Mimir"; context.Response.Headers.Add("Author", "Romonov"); return Task.CompletedTask; }); await next(context); }); }); app.UseMvc(routes => { routes.MapRoute( name: "yggdrasil_sessionserver_get_profile", template: "api/sessionserver/session/minecraft/profile/{uuid}", defaults: new { controller = "SessionServer", action = "Profile" }); routes.MapRoute( name: "yggdrasil_sessionserver_join", template: "api/sessionserver/session/minecraft/join", defaults: new { controller = "SessionServer", action = "Join" }); routes.MapRoute( name: "yggdrasil_sessionserver_has_joined", template: "api/sessionserver/session/minecraft/hasJoined", defaults: new { controller = "SessionServer", action = "HasJoined" }); routes.MapRoute( name: "yggdrasil_api_profiles_query", template: "api/api/profiles/minecraft", defaults: new { controller = "Api", action = "Profiles" }); routes.MapRoute( name: "yggdrasil_authserver", template: "api/authserver/{action}", defaults: new { controller = "AuthServer" }); routes.MapRoute( name: "yggdrasil_index", template: "api", defaults: new { controller = "Api", action = "Index" }); routes.MapRoute( name: "default", template: "{controller=Index}/{action=Index}/{id?}"); }); }
public SessionServerController(MimirContext context) { db = context; log = LogManager.GetLogger("SessionServer"); }
public UserController(MimirContext context) { db = context; }
public ProfileController(MimirContext context) { db = context; }
public RegisterController(MimirContext context) { db = context; }
public AuthServerController(MimirContext context) { db = context; log = LogManager.GetLogger("AuthServer"); }
public ApiController(MimirContext context) { db = context; log = LogManager.GetLogger("Yggdrasil"); }
/// <summary> /// 获取角色信息 /// </summary> /// <param name="db">数据库上下文对象</param> /// <param name="name">角色名</param> /// <param name="containProperties">是否包含属性</param> /// <param name="isUnsigned">是否不签名</param> /// <returns>角色信息</returns> public static Profile?GetProfile(MimirContext db, string name, bool containProperties = false, bool isUnsigned = true) { var profiles = from p in db.Profiles where p.Name == name select p; if (profiles.Count() != 1) { return(null); } var result = new Profile(); var profile = profiles.First(); result.id = profile.Uuid; result.name = profile.Name; if (containProperties) { var textures = new Textures(); var properties = new Properties(); if (profile.SkinUrl != null && profile.SkinUrl != string.Empty) { textures.SKIN = new Skin(); if (profile.SkinModel == 1) { var metadata = new Metadata(); metadata.model = "slim"; textures.SKIN.metadata = metadata; } if (Program.IsHttps) { textures.SKIN.url = $"https://{Program.ServerDomain}/textures/{profile.SkinUrl}"; } else { textures.SKIN.url = $"http://{Program.ServerDomain}/textures/{profile.SkinUrl}"; } if (profile.CapeUrl != null && profile.CapeUrl != string.Empty) { var cape = new Skin(); if (Program.IsHttps) { cape.url = $"https://{Program.ServerDomain}/textures/{profile.CapeUrl}"; } else { cape.url = $"http://{Program.ServerDomain}/textures/{profile.CapeUrl}"; } textures.CAPE = cape; } var texture = new Texture(); texture.timestamp = long.Parse(TimeWorker.GetTimeStamp13()); texture.profileId = profile.Uuid; texture.profileName = profile.Name; texture.textures = textures; properties.name = "textures"; var value = EncodeWorker.Base64Encoder(JsonConvert.SerializeObject(texture, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore })); properties.value = value; if (!isUnsigned) { properties.signature = SignatureWorker.Sign(value); } } result.properties = new Properties?[] { properties }; } else { result.properties = new Properties?[] { new Properties() }; } return(result); }