Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change HTTPS proxy to work off redirects towards an external proxy #668

Merged
merged 4 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions Refresh.Common/Extensions/NameValueCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Collections.Specialized;
using System.Text;
using System.Web;

namespace Refresh.Common.Extensions;

public static class NameValueCollectionExtensions
{
public static string ToQueryString(this NameValueCollection queryParams)
{
StringBuilder builder = new();

if (queryParams.Count == 0)
return string.Empty;

builder.Append('?');
for (int i = 0; i < queryParams.Count; i++)
{
string? key = queryParams.GetKey(i);
string? val = queryParams.Get(i);

if (key == null)
continue;

builder.Append(HttpUtility.UrlEncode(key));
builder.Append('=');
if(val != null)
builder.Append(HttpUtility.UrlEncode(val));

if(i < queryParams.Count - 1)
builder.Append('&');
}

return builder.ToString();
}
}
12 changes: 9 additions & 3 deletions Refresh.GameServer/Middlewares/DigestMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,15 @@ public void HandleRequest(ListenerContext context, Lazy<IDatabaseContext> databa
}

// If the client asks for a particular digest index, use that digest
if (int.TryParse(context.RequestHeaders["Refresh-Ps3-Digest-Index"], out int ps3DigestIndex) &&
int.TryParse(context.RequestHeaders["Refresh-Ps4-Digest-Index"], out int ps4DigestIndex))
if (int.TryParse(context.Query["force_ps3_digest"], out int ps3DigestIndex) &&
int.TryParse(context.Query["force_ps4_digest"], out int ps4DigestIndex))
{
if (ps3DigestIndex >= this._config.Sha1DigestKeys.Length)
ps3DigestIndex = 0;

if (ps4DigestIndex >= this._config.HmacDigestKeys.Length)
ps4DigestIndex = 0;

string digest = isPs4
? this._config.HmacDigestKeys[ps4DigestIndex]
: this._config.Sha1DigestKeys[ps3DigestIndex];
Expand All @@ -128,7 +134,7 @@ public void HandleRequest(ListenerContext context, Lazy<IDatabaseContext> databa

if(token != null)
gameDatabase.SetTokenDigestInfo(token, digest, isPs4);

return;
}

Expand Down
2 changes: 1 addition & 1 deletion Refresh.GameServer/RefreshGameServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ protected override void SetupMiddlewares()
{
this.Server.AddMiddleware<WebsiteMiddleware>();
this.Server.AddMiddleware(new DeflateMiddleware(this._config!));
this.Server.AddMiddleware<LegacyAdapterMiddleware>();
// Digest middleware must be run before LegacyAdapterMiddleware, because digest is based on the raw route, not the fixed route
this.Server.AddMiddleware(new DigestMiddleware(this._config!));
this.Server.AddMiddleware<CrossOriginMiddleware>();
this.Server.AddMiddleware<PspVersionMiddleware>();
this.Server.AddMiddleware<LegacyAdapterMiddleware>();
this.Server.AddMiddleware(new PresenceAuthenticationMiddleware(this._integrationConfig!));
}

Expand Down
83 changes: 0 additions & 83 deletions Refresh.HttpsProxy/Middlewares/ProxyMiddleware.cs

This file was deleted.

27 changes: 27 additions & 0 deletions Refresh.HttpsProxy/Middlewares/RedirectMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Net;
using Bunkum.Core.Database;
using Bunkum.Core.Endpoints.Middlewares;
using Bunkum.Listener.Request;
using Refresh.Common.Extensions;
using Refresh.HttpsProxy.Config;

namespace Refresh.HttpsProxy.Middlewares;

public class RedirectMiddleware(ProxyConfig config) : IMiddleware
{
public void HandleRequest(ListenerContext context, Lazy<IDatabaseContext> database, Action next)
{
UriBuilder uri = new(config.TargetServerUrl)
{
Path = context.Uri.AbsolutePath,
};

context.Query["force_ps3_digest"] = config.Ps3DigestIndex.ToString();
context.Query["force_ps4_digest"] = config.Ps4DigestIndex.ToString();

uri.Query = context.Query.ToQueryString();

context.ResponseCode = HttpStatusCode.TemporaryRedirect;
context.ResponseHeaders["Location"] = uri.ToString();
}
}
2 changes: 1 addition & 1 deletion Refresh.HttpsProxy/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
Action<BunkumServer> initialize = s =>
{
ProxyConfig config = Config.LoadFromJsonFile<ProxyConfig>("proxy.json", s.Logger);
s.AddMiddleware(new ProxyMiddleware(config));
s.AddMiddleware(new RedirectMiddleware(config));
};

httpsServer.Initialize = initialize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,13 @@ public void DigestSelectionHeaderWorks(bool isHmac)

string serverDigest = DigestMiddleware.CalculateDigest(digest, endpoint, Encoding.ASCII.GetBytes(expectedResultStr), "", null, false, isHmac);

context.Http.DefaultRequestHeaders.Add("Refresh-Ps3-Digest-Index", "1");
context.Http.DefaultRequestHeaders.Add("Refresh-Ps4-Digest-Index", "1");

// TODO: once we model PS4 clients in our tokens, make the request come from an authenticated PS4 client.
if(isHmac)
context.Http.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "MM CHTTPClient LBP3 01.26");

// send a blank digest to make it have to guess
context.Http.DefaultRequestHeaders.Add("X-Digest-A", "");
HttpResponseMessage response = context.Http.GetAsync(endpoint).Result;
HttpResponseMessage response = context.Http.GetAsync(endpoint + "?force_ps3_digest=1&force_ps4_digest=1").Result;

Assert.Multiple(() =>
{
Expand Down
Loading