btcpayserver/BTCPayServer/Services/TorServices.cs

129 lines
4.8 KiB
C#
Raw Normal View History

using System;
2019-03-17 21:07:24 +09:00
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Configuration;
2019-03-17 21:07:24 +09:00
using BTCPayServer.Logging;
namespace BTCPayServer.Services
{
public class TorServices
{
2019-05-07 13:58:55 +09:00
private readonly BTCPayNetworkProvider _networks;
BTCPayServerOptions _Options;
2019-05-07 13:58:55 +09:00
public TorServices(BTCPayServer.BTCPayNetworkProvider networks, BTCPayServerOptions options)
{
2019-05-07 13:58:55 +09:00
_networks = networks;
_Options = options;
}
2019-03-17 21:07:24 +09:00
public TorService[] Services { get; internal set; } = Array.Empty<TorService>();
internal async Task Refresh()
{
if (string.IsNullOrEmpty(_Options.TorrcFile) || !File.Exists(_Options.TorrcFile))
2019-03-17 21:07:24 +09:00
{
if (!string.IsNullOrEmpty(_Options.TorrcFile))
Logs.PayServer.LogWarning("Torrc file is not found");
Services = Array.Empty<TorService>();
return;
}
List<TorService> result = new List<TorService>();
try
{
var torrcContent = await File.ReadAllTextAsync(_Options.TorrcFile);
if (!Torrc.TryParse(torrcContent, out var torrc))
2019-03-17 21:07:24 +09:00
{
Logs.PayServer.LogWarning("Torrc file could not be parsed");
Services = Array.Empty<TorService>();
return;
}
2019-11-08 16:10:49 +09:00
var torrcDir = Path.GetDirectoryName(_Options.TorrcFile);
var services = torrc.ServiceDirectories.SelectMany(d => d.ServicePorts.Select(p => (Directory: GetDirectory(d, torrcDir), VirtualPort: p.VirtualPort)))
2019-03-17 21:07:24 +09:00
.Select(d => (ServiceName: d.Directory.Name,
ReadingLines: System.IO.File.ReadAllLinesAsync(Path.Combine(d.Directory.FullName, "hostname")),
VirtualPort: d.VirtualPort))
.ToArray();
foreach (var service in services)
{
try
{
var onionHost = (await service.ReadingLines)[0].Trim();
var torService = new TorService()
{
Name = service.ServiceName,
OnionHost = onionHost,
VirtualPort = service.VirtualPort
};
if (service.ServiceName.Equals("BTCPayServer", StringComparison.OrdinalIgnoreCase))
torService.ServiceType = TorServiceType.BTCPayServer;
2019-11-07 14:33:10 +09:00
else if (TryParseP2PService(service.ServiceName, out var network, out var serviceType))
2019-05-07 13:58:55 +09:00
{
2019-11-07 14:33:10 +09:00
torService.ServiceType = serviceType;
2019-05-07 13:58:55 +09:00
torService.Network = network;
}
result.Add(torService);
}
2019-03-17 21:07:24 +09:00
catch (Exception ex)
{
2019-03-17 21:07:24 +09:00
Logs.PayServer.LogWarning(ex, $"Error while reading hidden service {service.ServiceName} configuration");
}
}
}
2019-03-17 21:07:24 +09:00
catch (Exception ex)
{
2019-03-17 21:07:24 +09:00
Logs.PayServer.LogWarning(ex, $"Error while reading torrc file");
}
2019-03-17 21:07:24 +09:00
Services = result.ToArray();
}
2019-05-07 13:58:55 +09:00
2019-11-08 16:10:49 +09:00
private static DirectoryInfo GetDirectory(HiddenServiceDir hs, string relativeTo)
{
if (Path.IsPathRooted(hs.DirectoryPath))
return new DirectoryInfo(hs.DirectoryPath);
return new DirectoryInfo(Path.Combine(relativeTo, hs.DirectoryPath));
}
2019-11-07 14:33:10 +09:00
private bool TryParseP2PService(string name, out BTCPayNetworkBase network, out TorServiceType serviceType)
2019-05-07 13:58:55 +09:00
{
network = null;
2019-11-07 14:33:10 +09:00
serviceType = TorServiceType.Other;
2019-05-07 13:58:55 +09:00
var splitted = name.Trim().Split('-');
2019-11-07 15:58:03 +09:00
if (splitted.Length == 2 && splitted[1] == "P2P")
2019-11-07 14:33:10 +09:00
{
serviceType = TorServiceType.P2P;
}
2019-11-07 15:58:03 +09:00
else if (splitted.Length == 2 && splitted[1] == "RPC")
2019-11-07 14:33:10 +09:00
{
serviceType = TorServiceType.RPC;
}
else
{
2019-05-07 13:58:55 +09:00
return false;
2019-11-07 14:33:10 +09:00
}
network = _networks.GetNetwork<BTCPayNetworkBase>(splitted[0]);
2019-05-07 13:58:55 +09:00
return network != null;
}
}
public class TorService
{
public TorServiceType ServiceType { get; set; } = TorServiceType.Other;
public BTCPayNetworkBase Network { get; set; }
public string Name { get; set; }
public string OnionHost { get; set; }
public int VirtualPort { get; set; }
}
public enum TorServiceType
{
BTCPayServer,
2019-05-07 13:58:55 +09:00
P2P,
2019-11-07 14:33:10 +09:00
RPC,
Other
}
}