public void Pipe_DataReceived(PipeConnection connection, int count) { try { var req = RequestBase.Parser.ParseFrom(connection.Buffer, 0, count); var resp = ResponseBase(true); var blockSensitive = connection is RemotePipeConnection; switch (req.Type) { case MessageID.UserLogin: { if (blockSensitive) { connection.RespondFailure("远程控制无法执行该操作"); return; } var result = Login(req.DataUserLogin.Token).WaitResult(); if (result != null) { connection.RespondFailure(result); return; } } break; case MessageID.UserLogout: { if (blockSensitive) { connection.RespondFailure("远程控制无法执行该操作"); return; } var result = Logout(); if (result != null) { connection.RespondFailure(result); return; } } break; case MessageID.UserInfo: lock (UserInfo) { if (AutoLogin) { resp.DataUser = UserInfo.Clone(); resp.DataUser.Status = UserStatus.Pending; } else { resp.DataUser = UserInfo; } } break; case MessageID.LogGet: resp.DataLog = new LogList(); lock (LogManager) { resp.DataLog.Data.Add(LogManager); } break; case MessageID.LogClear: LogManager.Clear(); break; case MessageID.ControlExit: if (blockSensitive) { connection.RespondFailure("远程控制无法执行该操作"); return; } Stop(); return; case MessageID.ControlConfigGet: if (blockSensitive) { connection.RespondFailure("远程控制无法执行该操作"); return; } resp.DataConfig = GetConfig(); break; case MessageID.ControlConfigSet: if (blockSensitive) { connection.RespondFailure("远程控制无法执行该操作"); return; } if (req.DataConfig.RemoteKeyNew != "") { RemoteManager.EncryptKey = Sodium.PasswordHash.ArgonHashBinary(Encoding.UTF8.GetBytes(req.DataConfig.RemoteKeyNew), RemoteManager.SALT, 3, 268435456, 32); } RemoteManager.Enabled = req.DataConfig.RemoteManagement; if (RemoteManager.Enabled && UserInfo.Status == UserStatus.LoggedIn) { RemoteManager.Start(); } else { RemoteManager.Stop(); } Natfrp.BypassProxy = req.DataConfig.BypassProxy; UpdateManager.UpdateInterval = req.DataConfig.UpdateInterval; Save(); PushConfig(); break; case MessageID.ControlCheckUpdate: if (blockSensitive) { connection.RespondFailure("远程控制无法执行该操作"); return; } resp.DataUpdate = UpdateManager.CheckUpdate().WaitResult(); break; case MessageID.ControlGetUpdate: if (blockSensitive) { connection.RespondFailure("远程控制无法执行该操作"); return; } resp.DataUpdate = UpdateManager.Status; break; default: // Login required ↓ lock (UserInfo) { if (UserInfo.Status != UserStatus.LoggedIn) { connection.RespondFailure("用户未登录"); return; } } switch (req.Type) { case MessageID.TunnelList: resp.DataTunnels = new TunnelList(); resp.DataTunnels.Tunnels.Add(TunnelManager.Values.Select(t => t.CreateProto())); break; case MessageID.TunnelReload: TunnelManager.UpdateTunnels().Wait(); break; case MessageID.TunnelUpdate: lock (TunnelManager) { if (!TunnelManager.TryGetValue(req.DataUpdateTunnel.Id, out Tunnel t)) { connection.RespondFailure("隧道不存在"); return; } t.Enabled = req.DataUpdateTunnel.Status == 1; TunnelManager.PushOne(t); } break; case MessageID.TunnelDelete: Natfrp.Request <Natfrp.ApiResponse>("delete_tunnel", "tunnel=" + req.DataId).WaitResult(); lock (TunnelManager) { TunnelManager.Remove(req.DataId); TunnelManager.Push(); } break; case MessageID.TunnelCreate: { var result = Natfrp.Request <Natfrp.CreateTunnel>("create_tunnel", new StringBuilder() .Append("type=").Append(req.DataCreateTunnel.Type) .Append("&name=").Append(req.DataCreateTunnel.Name) .Append("¬e=").Append(req.DataCreateTunnel.Note) .Append("&node=").Append(req.DataCreateTunnel.Node) .Append("&local_ip=").Append(req.DataCreateTunnel.LocalAddress) .Append("&local_port=").Append(req.DataCreateTunnel.LocalPort) .Append("&remote_port=").Append(req.DataCreateTunnel.RemotePort).ToString()).WaitResult(); var t = TunnelManager.CreateFromApi(result.Data); lock (TunnelManager) { TunnelManager[t.Id] = t; TunnelManager.Push(); } resp.Message = "#" + t.Id + " " + t.Name; } break; case MessageID.NodeList: resp.DataNodes = new NodeList(); resp.DataNodes.Nodes.Add(NodeManager.Values); break; case MessageID.NodeReload: NodeManager.UpdateNodes().Wait(); break; } break; } connection.SendProto(resp); } catch (AggregateException e) when(e.InnerExceptions.Count == 1) { connection.SendProto(ResponseBase(false, e.InnerExceptions[0].ToString())); } catch (Exception e) { connection.SendProto(ResponseBase(false, e.ToString())); } }
protected async Task <string> Login(string token, bool isAuto = false) { lock (UserInfo) { if (UserInfo.Status != UserStatus.NoLogin) { return(UserInfo.Status == UserStatus.Pending ? "操作进行中, 请稍候" : "用户已登录"); } if (token.Length != 16) { return("Token 无效"); } UserInfo.Status = UserStatus.Pending; PushUserInfo(); } LogManager.Log(1, "Service", "开始登录, Token: " + token.Substring(0, 4) + "********" + token.Substring(12)); try { Natfrp.Token = token; var user = await Natfrp.Request <Natfrp.GetUser>("get_user"); if (!user.Data.Login) { LogManager.Log(3, "Service", "服务器拒绝登录: " + user.Message); Logout(true); return(user.Message); } lock (UserInfo) { UserInfo.Id = user.Data.Id; UserInfo.Name = user.Data.Name; UserInfo.Meta = user.Data.Meta; UserInfo.Status = UserStatus.LoggedIn; AutoLogin = false; } Save(); NodeManager.Clear(); NodeManager.Start(); TunnelManager.Clear(); TunnelManager.Start(); PushUserInfo(); LogManager.Log(1, "Service", "用户登录成功"); RemoteManager.Start(); } catch (Exception e) { if (isAuto) { LogManager.Log(3, "Service", "自动登录失败, 将在稍后重试: " + e.ToString()); lock (UserInfo) { UserInfo.Status = UserStatus.NoLogin; } // Don't push here } else { LogManager.Log(3, "Service", "用户登录失败: " + e.ToString()); Logout(true); } return(e.ToString()); } return(null); }