Esempio n. 1
0
 public ThinClientConnectOptions(string pcid, IPAddress clientIp, string clientFqdn, bool debugGuacMode, WideTunnelClientOptions clientOptions, bool isWebpSupported, GuaPreference?guaPreference = null, object?appParams = null)
 {
     this.Pcid            = pcid;
     this.ClientOptions   = clientOptions;
     this.ClientIpAddress = clientIp;
     this.ClientFqdn      = clientFqdn;
     this.AppParams       = appParams;
     this.DebugGuacMode   = debugGuacMode;
     this.GuaPreference   = guaPreference;
     this.IsWebpSupported = isWebpSupported;
 }
Esempio n. 2
0
    public async Task <WtcSocket> WideClientConnectAsync(string pcid, WideTunnelClientOptions clientOptions, bool noCache, CancellationToken cancel = default)
    {
        bool retryFlag = false;

L_RETRY:
        WtConnectParam connectParam = await WideClientConnectInnerAsync(pcid, clientOptions, noCache, cancel);

        $"WideClientConnect: pcid {pcid}: Redirecting to {connectParam.HostName}:{connectParam.Port} (CacheUsed = {connectParam.CacheUsed}) ..."._Debug();

        try
        {
            ConnSock tcpSock = await this.TcpIp.ConnectAsync(new TcpConnectParam(connectParam.HostName, connectParam.Port, AddressFamily.InterNetwork, connectTimeout : CoresConfig.WtcConfig.WpcTimeoutMsec, dnsTimeout : CoresConfig.WtcConfig.WpcTimeoutMsec), cancel);

            try
            {
                ConnSock targetSock = tcpSock;

                try
                {
                    PalSslClientAuthenticationOptions sslOptions = new PalSslClientAuthenticationOptions(connectParam.HostName, false, (cert) => this.CheckValidationCallback(this, cert.NativeCertificate, null, SslPolicyErrors.None));

                    SslSock sslSock = new SslSock(tcpSock);
                    try
                    {
                        await sslSock.StartSslClientAsync(sslOptions, cancel);

                        targetSock = sslSock;
                    }
                    catch
                    {
                        await sslSock._DisposeSafeAsync();

                        throw;
                    }

                    WtcSocket wtcSocket = new WtcSocket(targetSock, new WtcOptions(this, connectParam));

                    await wtcSocket.StartWtcAsync(cancel);

                    return(wtcSocket);
                }
                catch
                {
                    await targetSock._DisposeSafeAsync();

                    throw;
                }
            }
            catch
            {
                await tcpSock._DisposeSafeAsync();

                throw;
            }
        }
        catch
        {
            if (connectParam.CacheUsed && retryFlag == false)
            {
                retryFlag = true;

                // 接続キャッシュを使用して接続することに失敗した
                // 場合はキャッシュを消去して再試行する
                WideTunnel.ConnectParamCache.Delete(pcid);

                $"WideClientConnect: pcid {pcid}: Connect with Session Cache Failed. Retrying..."._Debug();
                goto L_RETRY;
            }

            throw;
        }
    }
Esempio n. 3
0
    async Task <WtConnectParam> WideClientConnectInnerAsync(string pcid, WideTunnelClientOptions clientOptions, bool noCache, CancellationToken cancel = default)
    {
        if (noCache == false)
        {
            WtConnectParam?cached = ConnectParamCache[pcid];
            if (cached != null)
            {
                var ret = cached._CloneDeep();
                ret.CacheUsed = true;
                return(ret);
            }
        }

        Pack r = new Pack();

        r.AddStr("SvcName", Options.SvcName);
        r.AddStr("Pcid", pcid);
        r.AddSInt("Ver", CoresConfig.WtcConfig.PseudoVer);
        r.AddSInt("Build", CoresConfig.WtcConfig.PseudoBuild);
        r.AddInt("ClientOptions", (uint)clientOptions.Flags);
        r.AddData("ClientId", Options.ClientId);

        var p = await WtWpcCall("ClientConnect", r, cancel);

        p.ThrowIfError();

        WtConnectParam c = new WtConnectParam
        {
            HostName                    = p["Hostname"].StrValueNonNullCheck,
            HostNameForProxy            = p["HostNameForProxy"].StrValueNonNullCheck,
            Port                        = p["Port"].SIntValue,
            SessionId                   = p["SessionId"].DataValueNonNull.ToArray(),
            ServerMask64                = p["ServerMask64"].Int64Value,
            WebSocketWildCardDomainName = p["WebSocketWildCardDomainName"].StrValueNonNull,
            ClientOptions               = clientOptions._CloneDeep(),
            IsStandaloneMode            = p["IsStandaloneMode"].BoolValue,
        };

        if (c.WebSocketWildCardDomainName._IsEmpty())
        {
            throw new CoresLibException("c.WebSocketWildCardDomainName is empty.");
        }

        if (c.HostName._IsSamei("<<!!samehost!!>>"))
        {
            string hostTmp = p["__remote_hostname"].StrValueNonNull;
            int    portTmp = p["__remote_port"].SIntValue;
            if (hostTmp._IsFilled() && portTmp != 0)
            {
                c.HostName = hostTmp;
                c.Port     = portTmp;
            }
        }

        c.CacheUsed = false;

        if (noCache == false)
        {
            WideTunnel.ConnectParamCache[pcid] = c._CloneDeep();
        }

        return(c);
    }
Esempio n. 4
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));
    }