Exemplo n.º 1
0
    public ThinWebClientProfile CloneAsDefault()
    {
        ThinWebClientProfile ret = this._CloneWithJson();

        ret.Pcid = "";

        ret.Preference = ret.Preference.CloneAsDefault();

        ret.Normalize();

        return(ret);
    }
Exemplo n.º 2
0
    public void Add(ThinWebClientProfile profile)
    {
        var clone = profile._CloneWithJson();

        clone.Normalize();
        if (clone.Pcid._IsEmpty())
        {
            return;
        }

        var deleteList = this.Items.Where(x => x.Pcid._IsSamei(clone.Pcid)).ToList();

        deleteList.ForEach(x => this.Items.Remove(x));

        this.Items.Add(clone);

        while (this.Items.Count >= 1 && this.Items.Count > ThinWebClientConsts.MaxHistory)
        {
            this.Items.RemoveAt(0);
        }
    }
Exemplo n.º 3
0
    public async Task AcceptWebSocketAsync(string?id, string?width, string?height)
    {
        await using (TaskUtil.CreateCombinedCancellationToken(out CancellationToken cancel, this._GetRequestCancellationToken(), this.Client.GrandCancel))
        {
            if (HttpContext.WebSockets.IsWebSocketRequest)
            {
                // 指定されたセッション ID を元に検索
                var session = this.Client.SessionManager.GetSessionById(id._NonNull());

                if (session != null)
                {
                    ThinClientConnectOptions connectOptions = (ThinClientConnectOptions)session.Param !;
                    ThinWebClientProfile     profile        = (ThinWebClientProfile)connectOptions.AppParams !;

                    if (connectOptions.DebugGuacMode == false)
                    {
                        throw new CoresLibException("connectOptions.DebugGuacMode == false");
                    }

                    var req = session.GetFinalAnswerRequest();

                    if (req?.RequestData is ThinClientAcceptReadyNotification ready)
                    {
                        var pref = profile.Preference._CloneWithJson();

                        // ws 接続時に width と height がパラメータとして指定されていた場合は、preference の内容を更新する
                        int widthInt  = width._ToInt();
                        int heightInt = height._ToInt();

                        if (widthInt >= 1 && heightInt >= 1)
                        {
                            pref.ScreenWidth  = widthInt;
                            pref.ScreenHeight = heightInt;
                        }

                        await using var guaClient = new GuaClient(
                                        new GuaClientSettings(
                                            Client.SettingsFastSnapshot.Debug_GuacdMode_GuacdHostname,
                                            Client.SettingsFastSnapshot.Debug_GuacdPort,
                                            ready.FirstConnection !.SvcType.ToString().StrToGuaProtocol(),
                                            "", ready.ListenEndPoint !.Port,
                                            //"pc37.sec.softether.co.jp", 3333, // testtest
                                            pref,
                                            connectOptions.IsWebpSupported,
                                            ready.FirstConnection.Caps.Bit(ThinServerCaps.AudioInSupported)));

                        var readyPacket = await guaClient.StartAsync(cancel);

                        await using var gcStream = guaClient.Stream._NullCheck();

                        using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync("guacamole");

                        //if (true)
                        //{
                        //    MemoryStream ms = new MemoryStream();
                        //    await readyPacket.SendPacketAsync(ms);
                        //    //var tmp = ms.ToArray();
                        //    var tmp = "6.hello;"._GetBytes_Ascii();
                        //    await webSocket.SendAsync(tmp, WebSocketMessageType.Text, true, cancel);
                        //}

                        await GuaWebSocketUtil.RelayBetweenWebSocketAndStreamDuplex(gcStream, webSocket, cancel : cancel);

                        return;
                    }
                }
            }

            HttpContext.Response.StatusCode = 400;
        }
    }
Exemplo n.º 4
0
    public async Task <IActionResult> SessionAsync(string?id, string?requestid, string?formtype, string?password, string?username, string?otp, string?pcid)
    {
        var cancel = Request._GetRequestCancellationToken();

        id = id._NonNullTrim();

        // 指定されたセッション ID を元に検索
        var session = this.Client.SessionManager.GetSessionById(id);

        if (session == null)
        {
            // セッション ID が見つからない。トップページに戻る
            return(Redirect("/" + (pcid._IsFilled() ? "?pcid=" + pcid._MakeVerySafeAsciiOnlyNonSpaceString() : "")));
        }
        else
        {
            ThinClientConnectOptions connectOptions = (ThinClientConnectOptions)session.Param !;
            ThinWebClientProfile     profile        = (ThinWebClientProfile)connectOptions.AppParams !;

            if (requestid._IsFilled() && formtype._IsFilled())
            {
                IDialogResponseData?responseData = null;
                switch (formtype)
                {
                case "SessionAuthPassword":
                    responseData = new ThinClientAuthResponse {
                        Username = "", Password = password._NonNull()
                    };
                    break;

                case "SessionAuthAdvanced":
                    responseData = new ThinClientAuthResponse {
                        Username = username._NonNull(), Password = password._NonNull()
                    };
                    break;

                case "SessionOtp":
                    responseData = new ThinClientOtpResponse {
                        Otp = otp._NonNull()
                    };
                    break;
                }
                if (responseData != null)
                {
                    session.SetResponseData(requestid, responseData);
                }
            }

L_GET_NEXT:
            var req = await session.GetNextRequestAsync(cancel : cancel);

            if (req != null)
            {
                session.SendHeartBeat(req.RequestId);

                switch (req.RequestData)
                {
                case ThinClientAuthRequest authReq:
                    switch (authReq.AuthType)
                    {
                    case ThinAuthType.None:
                        session.SetResponseData(req.RequestId, new ThinClientAuthResponse());
                        goto L_GET_NEXT;

                    case ThinAuthType.Password:
                        ThinWebClientModelSessionAuthPassword page = new ThinWebClientModelSessionAuthPassword
                        {
                            SessionId      = session.SessionId,
                            RequestId      = req.RequestId,
                            ConnectOptions = connectOptions,
                            Request        = authReq,
                            Profile        = profile._CloneWithJson(),
                        };

                        return(View("SessionAuthPassword", page));

                    case ThinAuthType.Advanced:
                        ThinWebClientModelSessionAuthPassword page2 = new ThinWebClientModelSessionAuthPassword
                        {
                            SessionId      = session.SessionId,
                            RequestId      = req.RequestId,
                            ConnectOptions = connectOptions,
                            Request        = authReq,
                            Profile        = profile._CloneWithJson(),
                        };

                        return(View("SessionAuthAdvanced", page2));

                    default:
                        throw new CoresException($"authReq.AuthType = {authReq.AuthType}: Unsupported auth type.");
                    }

                case ThinClientOtpRequest otpReq:
                    ThinWebClientModelOtp page3 = new ThinWebClientModelOtp
                    {
                        SessionId      = session.SessionId,
                        RequestId      = req.RequestId,
                        ConnectOptions = connectOptions,
                        Profile        = profile._CloneWithJson(),
                    };

                    return(View("SessionOtp", page3));

                case ThinClientAcceptReadyNotification ready:
                    if (ready.IsStandaloneMode)
                    {
                        if (Request.Headers._GetStrFirst("X-Original-For")._IsEmpty())
                        {
                            var ss = Page.Stb["THINWEB_STANDALONE_MUST_VIA_PROXY"];
                            throw new CoresException(ss);
                        }
                    }

                    if (connectOptions.DebugGuacMode)
                    {
                        connectOptions.UpdateConnectedSvcType(ready.FirstConnection !.SvcType);
                        connectOptions.UpdateWatermarkStr(ready.FirstConnection !.WatermarkStr1, ready.FirstConnection !.WatermarkStr2);
                        connectOptions.UpdateMiscParams(ready.FirstConnection.Misc);
                        connectOptions.UpdateCaps(ready.FirstConnection.Caps);
                    }
                    else
                    {
                        connectOptions.UpdateConnectedSvcType(ready.SvcType !.Value);
                        ready.WebSocketFullUrl._NotEmptyCheck();
                        connectOptions.UpdateWebSocketUrl(ready.WebSocketFullUrl);
                        connectOptions.UpdateConnectPacketData(ready.ConnectPacketData);
                        connectOptions.UpdateWatermarkStr(ready.WatermarkStr1, ready.WatermarkStr2);
                        connectOptions.UpdateMiscParams(ready.Misc);
                        connectOptions.UpdateCaps(ready.Caps);
                    }

                    if (ready.WebSocketFullUrl._IsFilled())
                    {
                        $"ready.WebSocketFullUrl = {ready.WebSocketFullUrl?.ToString()}"._Debug();
                    }
                    else
                    {
                        $"ready.ListenEndPoint = {ready.ListenEndPoint?.ToString()}"._Debug();
                    }
                    req.SetResponseDataEmpty();

                    return(Redirect($"/ThinWebClient/Remote/{session.SessionId}/" + (pcid._IsFilled() ? "?pcid=" + pcid._MakeVerySafeAsciiOnlyNonSpaceString() : "")));

                case ThinClientInspectRequest inspect:
                    ThinClientInspectResponse insRes = new ThinClientInspectResponse
                    {
                        AntiVirusOk     = true,
                        Ticket          = "",
                        WindowsUpdateOk = true,
                        MacAddressList  = Str.NormalizeMac(profile.Preference.MacAddress, style: MacAddressStyle.Windows),
                    };

                    session.SetResponseData(req.RequestId, insRes);
                    goto L_GET_NEXT;

                default:
                    throw new CoresException($"Unknown request data: {req.RequestData.GetType().ToString()}");
                }
            }
            else
            {
                Dbg.Where();
            }
        }

        return(Redirect("/" + (pcid._IsFilled() ? "?pcid=" + pcid._MakeVerySafeAsciiOnlyNonSpaceString() : "")));
    }
Exemplo n.º 5
0
    public async Task <IActionResult> RemoteAsync(string?id, string?pcid)
    {
        var cancel = Request._GetRequestCancellationToken();

        id = id._NonNullTrim();

        // 指定されたセッション ID を元に検索
        var session = this.Client.SessionManager.GetSessionById(id);

        if (session != null)
        {
            ThinClientConnectOptions connectOptions = (ThinClientConnectOptions)session.Param !;
            ThinWebClientProfile     profile        = (ThinWebClientProfile)connectOptions.AppParams !;

            var req = session.GetFinalAnswerRequest();

            if (req != null)
            {
                var misc2 = new ThinWebClientRemoteMisc2();

                var caps = connectOptions.Caps;

                // VNC の場合にメッセージを表示する
                if (connectOptions.ConnectedSvcType !.Value == ThinSvcType.Vnc)
                {
                    if (caps.Bit(ThinServerCaps.UrdpVeryLimited))
                    {
                        misc2.OnceMsg = Page.Stb["DU_ONCEMSG_1"];
                    }
                    else
                    {
                        if (caps.Bit(ThinServerCaps.WinRdpEnabled))
                        {
                            misc2.OnceMsg = Page.Stb["DU_ONCEMSG_3"];
                        }
                        else
                        {
                            misc2.OnceMsg = Page.Stb["DU_ONCEMSG_2"];
                        }
                    }
                    misc2.OnceMsg      = misc2.OnceMsg._FormatC(profile.Pcid);
                    misc2.OnceMsgTitle = "操作のヒント";
                }

                ThinWebClientModelRemote main = new ThinWebClientModelRemote()
                {
                    ConnectOptions    = connectOptions,
                    WebSocketUrl      = connectOptions.WebSocketUrl,
                    SessionId         = session.SessionId,
                    Profile           = profile,
                    SvcType           = connectOptions.ConnectedSvcType !.Value,
                    ConnectPacketData = connectOptions.ConnectPacketData,
                    WatermarkStr1     = connectOptions.WatermarkStr1,
                    WatermarkStr2     = connectOptions.WatermarkStr2,
                    Misc  = connectOptions.MiscParams,
                    Misc2 = misc2,
                };

                return(View(main));
            }
        }

        await TaskCompleted;

        return(Redirect("/" + (pcid._IsFilled() ? "?pcid=" + pcid._MakeVerySafeAsciiOnlyNonSpaceString() : "")));
    }
Exemplo n.º 6
0
    public async Task <IActionResult> IndexAsync(ThinWebClientModelIndex form, string?pcid, string?deleteAll, string?button_wol)
    {
        ThinWebClientProfile?historySelectedProfile = null;

        ThinWebClientProfile profile = form.CurrentProfile;

        profile.Normalize();

        ThinWebClientHistory history = ThinWebClientHistory.LoadFromCookie(this, this.Client.SettingsFastSnapshot.CookieEncryptPassword);

        if (this._IsPostBack())
        {
            if (profile.Pcid._IsFilled())
            {
                // 現在のプロファイルの保存
                this._EasySaveCookie("thin_current_profile", profile.CloneAsDefault(), GetCookieOption(), true, this.Client.SettingsFastSnapshot.CookieEncryptPassword);

                // ヒストリへの追加
                history.Add(profile);
                history.SaveToCookie(this, GetCookieOption(), this.Client.SettingsFastSnapshot.CookieEncryptPassword);

                // thin_last_pcid の保存
                this._EasySaveCookie("thin_last_pcid", profile.Pcid, GetCookieOption());

                var    clientIp   = Request.HttpContext.Connection.RemoteIpAddress._UnmapIPv4() !;
                var    clientPort = Request.HttpContext.Connection.RemotePort;
                string clientFqdn = await Client.DnsResolver.GetHostNameSingleOrIpAsync(clientIp);

                // Rate limit
                if (this.Client.RateLimit.TryInput(clientIp.ToString(), out _) == false)
                {
                    throw new CoresException(this.Page.Stb["THINWEB_RATELIMIT_EXCEEDED"]);
                }

                var tc = this.Client.CreateThinClient(this.StrTable);

                if (button_wol._ToBool() == false)
                {
                    // 普通の接続
                    WideTunnelClientOptions wideOptions = new WideTunnelClientOptions(WideTunnelClientFlags.None, clientIp.ToString(), clientFqdn, clientPort);

                    // セッションの開始
                    var session = tc.StartConnect(new ThinClientConnectOptions(profile.Pcid, clientIp, clientFqdn, this.Client.SettingsFastSnapshot.Debug_EnableGuacdMode, wideOptions, form.IsWebpSupported, profile.Preference, profile._CloneWithJson()),
                                                  this.Client.SettingsFastSnapshot.MaxConcurrentSessionsPerClientIp);
                    string sessionId = session.SessionId;

                    // セッション ID をもとにした URL にリダイレクト
                    return(Redirect($"/ThinWebClient/Session/{sessionId}/?pcid={profile.Pcid._MakeVerySafeAsciiOnlyNonSpaceString()}"));
                }
                else
                {
                    try
                    {
                        // WoL 信号の発射
                        WideTunnelClientOptions wideOptions = new WideTunnelClientOptions(WideTunnelClientFlags.WoL, clientIp.ToString(), clientFqdn, clientPort);

                        await tc.ExecuteWoLAsync(new ThinClientConnectOptions(profile.Preference.WoLTriggerPcid, clientIp, clientFqdn, false, wideOptions, form.IsWebpSupported, profile.Preference, profile._CloneWithJson()),
                                                 profile.Pcid, this._GetRequestCancellationToken());

                        // WoL OK メッセージ
                        form.WolOkMessage = this.Page.Stb["DU_WOL_MSG"]._FormatC(profile.Pcid, profile.Preference.WoLTriggerPcid);
                    }
                    catch (Exception ex)
                    {
                        // WoL エラーメッセージの文字列化
                        string msg = ThinWebClientErrorUtil.GetFriendlyErrorMessage(ex, this.Page);

                        form.WolErrorMessage = msg;

                        form.JumpToWol = true;
                    }
                }
            }
        }
        else
        {
            if (pcid._IsEmpty())
            {
                // Query String の pcid が空の場合、Cookie から読み出す
                pcid = this._EasyLoadCookie <string>("thin_last_pcid")._NonNullTrim();
            }

            if (deleteAll._ToBool())
            {
                // History をすべて消去するよう指示された
                // Cookie の History をすべて消去する
                history.Clear();
                history.SaveToCookie(this, GetCookieOption(), this.Client.SettingsFastSnapshot.CookieEncryptPassword);
                this._EasySaveCookie("thin_last_pcid", "", GetCookieOption());

                // トップページにリダイレクトする
                return(Redirect("/"));
            }
            else if (pcid._IsFilled())
            {
                // History から履歴を指定された。id を元に履歴からプロファイルを読み出す
                historySelectedProfile = history.Items.Where(h => h.Pcid._IsSamei(pcid)).FirstOrDefault();
            }

            if (historySelectedProfile == null)
            {
                // デフォルト値
                GuaKeyboardLayout defaultKeyboardLayout = GuaKeyboardLayout.Japanese;

                if (Page.CurrentLanguage.Key._IsSamei("ja") == false)
                {
                    // 日本語以外の環境では英語キーボードをデフォルトで選択する
                    defaultKeyboardLayout = GuaKeyboardLayout.EnglishUs;
                }

                profile = this._EasyLoadCookie <ThinWebClientProfile>("thin_current_profile", true, this.Client.SettingsFastSnapshot.CookieEncryptPassword) ?? new ThinWebClientProfile(defaultKeyboardLayout);
            }
            else
            {
                // History で選択された値
                profile = historySelectedProfile;
            }

            profile.Normalize();
            form.CurrentProfile = profile;

            // GET の場合は必ず PCID 入力ボックスをフォーカスする
            form.FocusToPcid = true;
        }

        form.FillHistory(history);

        if (historySelectedProfile != null)
        {
            form.SelectedHistory = form.HistoryItems.Where(x => x.Text._IsSamei(historySelectedProfile.Pcid)).FirstOrDefault()?.Value ?? "";
        }

        return(View(form));
    }