aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.ServerApplication
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2015-02-09 16:58:30 -0500
committerLuke <luke.pulverenti@gmail.com>2015-02-09 16:58:30 -0500
commit4cc3b2f0ccd7c092a4acf72db4903415e175037a (patch)
treef9f90f8665b726253b8b357674f2f141aa43abc9 /MediaBrowser.ServerApplication
parente7037a9b80843c127712f11430239f8fa3cb4aed (diff)
parent3d7089a7dbabb652730c892206ca050f52f832b1 (diff)
Merge pull request #1005 from MediaBrowser/dev
3.0.5518.0
Diffstat (limited to 'MediaBrowser.ServerApplication')
-rw-r--r--MediaBrowser.ServerApplication/BackgroundServiceInstaller.cs2
-rw-r--r--MediaBrowser.ServerApplication/MainStartup.cs3
-rw-r--r--MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj5
-rw-r--r--MediaBrowser.ServerApplication/Native/Autorun.cs8
-rw-r--r--MediaBrowser.ServerApplication/Native/WindowsApp.cs12
-rw-r--r--MediaBrowser.ServerApplication/Networking/CertificateGenerator.cs244
-rw-r--r--MediaBrowser.ServerApplication/Networking/NativeMethods.cs156
-rw-r--r--MediaBrowser.ServerApplication/Networking/NetworkManager.cs10
-rw-r--r--MediaBrowser.ServerApplication/packages.config1
9 files changed, 427 insertions, 14 deletions
diff --git a/MediaBrowser.ServerApplication/BackgroundServiceInstaller.cs b/MediaBrowser.ServerApplication/BackgroundServiceInstaller.cs
index 27ddfeb95..15cab6c19 100644
--- a/MediaBrowser.ServerApplication/BackgroundServiceInstaller.cs
+++ b/MediaBrowser.ServerApplication/BackgroundServiceInstaller.cs
@@ -25,7 +25,7 @@ namespace MediaBrowser.ServerApplication
Description = "The windows background service for Media Browser Server.",
// Will ensure the network is available
- ServicesDependedOn = new[] { "LanmanServer" }
+ ServicesDependedOn = new[] { "LanmanServer", "Tcpip" }
};
// Microsoft didn't add the ability to add a
diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs
index adc8eecb1..6e8774eea 100644
--- a/MediaBrowser.ServerApplication/MainStartup.cs
+++ b/MediaBrowser.ServerApplication/MainStartup.cs
@@ -203,7 +203,7 @@ namespace MediaBrowser.ServerApplication
{
var fileSystem = new NativeFileSystem(logManager.GetLogger("FileSystem"), false);
- var nativeApp = new WindowsApp
+ var nativeApp = new WindowsApp(fileSystem)
{
IsRunningAsService = runService
};
@@ -213,7 +213,6 @@ namespace MediaBrowser.ServerApplication
options,
fileSystem,
"MBServer",
- true,
nativeApp);
var initProgress = new Progress<double>();
diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
index af96dc265..8df2d3ab0 100644
--- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
+++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
@@ -63,10 +63,6 @@
<Reference Include="MediaBrowser.IsoMounter">
<HintPath>..\packages\MediaBrowser.IsoMounting.3.0.69\lib\net45\MediaBrowser.IsoMounter.dll</HintPath>
</Reference>
- <Reference Include="NLog, Version=3.1.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\NLog.3.1.0.0\lib\net45\NLog.dll</HintPath>
- </Reference>
<Reference Include="pfmclrapi">
<HintPath>..\packages\MediaBrowser.IsoMounting.3.0.69\lib\net45\pfmclrapi.dll</HintPath>
</Reference>
@@ -113,6 +109,7 @@
<Compile Include="Native\Standby.cs" />
<Compile Include="Native\ServerAuthorization.cs" />
<Compile Include="Native\WindowsApp.cs" />
+ <Compile Include="Networking\CertificateGenerator.cs" />
<Compile Include="Networking\NativeMethods.cs" />
<Compile Include="Networking\NetworkManager.cs" />
<Compile Include="Networking\NetworkShares.cs" />
diff --git a/MediaBrowser.ServerApplication/Native/Autorun.cs b/MediaBrowser.ServerApplication/Native/Autorun.cs
index 0262f711e..593bb7955 100644
--- a/MediaBrowser.ServerApplication/Native/Autorun.cs
+++ b/MediaBrowser.ServerApplication/Native/Autorun.cs
@@ -1,4 +1,5 @@
-using System;
+using MediaBrowser.Common.IO;
+using System;
using System.IO;
namespace MediaBrowser.ServerApplication.Native
@@ -12,7 +13,8 @@ namespace MediaBrowser.ServerApplication.Native
/// Configures the specified autorun.
/// </summary>
/// <param name="autorun">if set to <c>true</c> [autorun].</param>
- public static void Configure(bool autorun)
+ /// <param name="fileSystem">The file system.</param>
+ public static void Configure(bool autorun, IFileSystem fileSystem)
{
var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Media Browser 3", "Media Browser Server.lnk");
@@ -26,7 +28,7 @@ namespace MediaBrowser.ServerApplication.Native
else
{
//Remove our shortcut from the startup folder for this user
- File.Delete(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "MBstartup.lnk"));
+ fileSystem.DeleteFile(Path.Combine(startupPath, Path.GetFileName(shortcutPath) ?? "MBstartup.lnk"));
}
}
}
diff --git a/MediaBrowser.ServerApplication/Native/WindowsApp.cs b/MediaBrowser.ServerApplication/Native/WindowsApp.cs
index 45070e6ec..476fb58b9 100644
--- a/MediaBrowser.ServerApplication/Native/WindowsApp.cs
+++ b/MediaBrowser.ServerApplication/Native/WindowsApp.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Net;
using MediaBrowser.IsoMounter;
using MediaBrowser.Model.Logging;
using MediaBrowser.Server.Startup.Common;
@@ -10,6 +11,13 @@ namespace MediaBrowser.ServerApplication.Native
{
public class WindowsApp : INativeApp
{
+ private readonly IFileSystem _fileSystem;
+
+ public WindowsApp(IFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+
public List<Assembly> GetAssembliesWithParts()
{
var list = new List<Assembly>();
@@ -89,7 +97,7 @@ namespace MediaBrowser.ServerApplication.Native
public void ConfigureAutoRun(bool autorun)
{
- Autorun.Configure(autorun);
+ Autorun.Configure(autorun, _fileSystem);
}
public INetworkManager CreateNetworkManager(ILogger logger)
diff --git a/MediaBrowser.ServerApplication/Networking/CertificateGenerator.cs b/MediaBrowser.ServerApplication/Networking/CertificateGenerator.cs
new file mode 100644
index 000000000..a7b0d6c32
--- /dev/null
+++ b/MediaBrowser.ServerApplication/Networking/CertificateGenerator.cs
@@ -0,0 +1,244 @@
+using MediaBrowser.Model.Logging;
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace MediaBrowser.ServerApplication.Networking
+{
+ // Copied from: http://blogs.msdn.com/b/dcook/archive/2014/05/16/9143036.aspx
+ // In case anybody is interested, source code is attached and is free for use by anybody as long as you don't hold me or Microsoft liable for it --
+ // I have no idea whether this is actually the right or best way to do this. Give it the X500 distinguished name, validity start and end dates,
+ // and an optional password for encrypting the key data, and it will give you the PFX file data. Let me know if you find any bugs or have any suggestions.
+ internal class CertificateGenerator
+ {
+ internal static void CreateSelfSignCertificatePfx(
+ string fileName,
+ string hostname,
+ ILogger logger)
+ {
+ if (string.IsNullOrWhiteSpace(fileName))
+ {
+ throw new ArgumentNullException("fileName");
+ }
+
+ string x500 = string.Format("CN={0}", hostname);
+
+ DateTime startTime = DateTime.Now.AddDays(-2);
+ DateTime endTime = DateTime.Now.AddYears(10);
+
+ byte[] pfxData = CreateSelfSignCertificatePfx(
+ x500,
+ startTime,
+ endTime);
+
+ File.WriteAllBytes(fileName, pfxData);
+ }
+
+ private static byte[] CreateSelfSignCertificatePfx(
+ string x500,
+ DateTime startTime,
+ DateTime endTime)
+ {
+ byte[] pfxData;
+
+ if (x500 == null)
+ {
+ x500 = "";
+ }
+
+ SystemTime startSystemTime = ToSystemTime(startTime);
+ SystemTime endSystemTime = ToSystemTime(endTime);
+ string containerName = Guid.NewGuid().ToString();
+
+ GCHandle dataHandle = new GCHandle();
+ IntPtr providerContext = IntPtr.Zero;
+ IntPtr cryptKey = IntPtr.Zero;
+ IntPtr certContext = IntPtr.Zero;
+ IntPtr certStore = IntPtr.Zero;
+ IntPtr storeCertContext = IntPtr.Zero;
+ IntPtr passwordPtr = IntPtr.Zero;
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ Check(NativeMethods.CryptAcquireContextW(
+ out providerContext,
+ containerName,
+ null,
+ 1, // PROV_RSA_FULL
+ 8)); // CRYPT_NEWKEYSET
+
+ Check(NativeMethods.CryptGenKey(
+ providerContext,
+ 1, // AT_KEYEXCHANGE
+ 1 | 2048 << 16, // CRYPT_EXPORTABLE 2048 bit key
+ out cryptKey));
+
+ IntPtr errorStringPtr;
+ int nameDataLength = 0;
+ byte[] nameData;
+
+ // errorStringPtr gets a pointer into the middle of the x500 string,
+ // so x500 needs to be pinned until after we've copied the value
+ // of errorStringPtr.
+ dataHandle = GCHandle.Alloc(x500, GCHandleType.Pinned);
+
+ if (!NativeMethods.CertStrToNameW(
+ 0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
+ dataHandle.AddrOfPinnedObject(),
+ 3, // CERT_X500_NAME_STR = 3
+ IntPtr.Zero,
+ null,
+ ref nameDataLength,
+ out errorStringPtr))
+ {
+ string error = Marshal.PtrToStringUni(errorStringPtr);
+ throw new ArgumentException(error);
+ }
+
+ nameData = new byte[nameDataLength];
+
+ if (!NativeMethods.CertStrToNameW(
+ 0x00010001, // X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
+ dataHandle.AddrOfPinnedObject(),
+ 3, // CERT_X500_NAME_STR = 3
+ IntPtr.Zero,
+ nameData,
+ ref nameDataLength,
+ out errorStringPtr))
+ {
+ string error = Marshal.PtrToStringUni(errorStringPtr);
+ throw new ArgumentException(error);
+ }
+
+ dataHandle.Free();
+
+ dataHandle = GCHandle.Alloc(nameData, GCHandleType.Pinned);
+ CryptoApiBlob nameBlob = new CryptoApiBlob(
+ nameData.Length,
+ dataHandle.AddrOfPinnedObject());
+
+ CryptKeyProviderInformation kpi = new CryptKeyProviderInformation();
+ kpi.ContainerName = containerName;
+ kpi.ProviderType = 1; // PROV_RSA_FULL
+ kpi.KeySpec = 1; // AT_KEYEXCHANGE
+
+ CryptAlgorithmIdentifier sha256Identifier = new CryptAlgorithmIdentifier();
+ sha256Identifier.pszObjId = "1.2.840.113549.1.1.11";
+
+ certContext = NativeMethods.CertCreateSelfSignCertificate(
+ providerContext,
+ ref nameBlob,
+ 0,
+ ref kpi,
+ ref sha256Identifier,
+ ref startSystemTime,
+ ref endSystemTime,
+ IntPtr.Zero);
+ Check(certContext != IntPtr.Zero);
+ dataHandle.Free();
+
+ certStore = NativeMethods.CertOpenStore(
+ "Memory", // sz_CERT_STORE_PROV_MEMORY
+ 0,
+ IntPtr.Zero,
+ 0x2000, // CERT_STORE_CREATE_NEW_FLAG
+ IntPtr.Zero);
+ Check(certStore != IntPtr.Zero);
+
+ Check(NativeMethods.CertAddCertificateContextToStore(
+ certStore,
+ certContext,
+ 1, // CERT_STORE_ADD_NEW
+ out storeCertContext));
+
+ NativeMethods.CertSetCertificateContextProperty(
+ storeCertContext,
+ 2, // CERT_KEY_PROV_INFO_PROP_ID
+ 0,
+ ref kpi);
+
+ CryptoApiBlob pfxBlob = new CryptoApiBlob();
+ Check(NativeMethods.PFXExportCertStoreEx(
+ certStore,
+ ref pfxBlob,
+ passwordPtr,
+ IntPtr.Zero,
+ 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
+
+ pfxData = new byte[pfxBlob.DataLength];
+ dataHandle = GCHandle.Alloc(pfxData, GCHandleType.Pinned);
+ pfxBlob.Data = dataHandle.AddrOfPinnedObject();
+ Check(NativeMethods.PFXExportCertStoreEx(
+ certStore,
+ ref pfxBlob,
+ passwordPtr,
+ IntPtr.Zero,
+ 7)); // EXPORT_PRIVATE_KEYS | REPORT_NO_PRIVATE_KEY | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
+ dataHandle.Free();
+ }
+ finally
+ {
+ if (passwordPtr != IntPtr.Zero)
+ {
+ Marshal.ZeroFreeCoTaskMemUnicode(passwordPtr);
+ }
+
+ if (dataHandle.IsAllocated)
+ {
+ dataHandle.Free();
+ }
+
+ if (certContext != IntPtr.Zero)
+ {
+ NativeMethods.CertFreeCertificateContext(certContext);
+ }
+
+ if (storeCertContext != IntPtr.Zero)
+ {
+ NativeMethods.CertFreeCertificateContext(storeCertContext);
+ }
+
+ if (certStore != IntPtr.Zero)
+ {
+ NativeMethods.CertCloseStore(certStore, 0);
+ }
+
+ if (cryptKey != IntPtr.Zero)
+ {
+ NativeMethods.CryptDestroyKey(cryptKey);
+ }
+
+ if (providerContext != IntPtr.Zero)
+ {
+ NativeMethods.CryptReleaseContext(providerContext, 0);
+ NativeMethods.CryptAcquireContextW(
+ out providerContext,
+ containerName,
+ null,
+ 1, // PROV_RSA_FULL
+ 0x10); // CRYPT_DELETEKEYSET
+ }
+ }
+
+ return pfxData;
+ }
+
+ private static SystemTime ToSystemTime(DateTime dateTime)
+ {
+ long fileTime = dateTime.ToFileTime();
+ SystemTime systemTime;
+ Check(NativeMethods.FileTimeToSystemTime(ref fileTime, out systemTime));
+ return systemTime;
+ }
+
+ private static void Check(bool nativeCallSucceeded)
+ {
+ if (!nativeCallSucceeded)
+ {
+ int error = Marshal.GetHRForLastWin32Error();
+ Marshal.ThrowExceptionForHR(error);
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/Networking/NativeMethods.cs b/MediaBrowser.ServerApplication/Networking/NativeMethods.cs
index 20f7ac23d..037b1f75b 100644
--- a/MediaBrowser.ServerApplication/Networking/NativeMethods.cs
+++ b/MediaBrowser.ServerApplication/Networking/NativeMethods.cs
@@ -47,9 +47,108 @@ namespace MediaBrowser.ServerApplication.Networking
/// <returns>System.Int32.</returns>
[DllImport("Netapi32", SetLastError = true),
SuppressUnmanagedCodeSecurity]
-
public static extern int NetApiBufferFree(
IntPtr pBuf);
+
+ [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool FileTimeToSystemTime(
+ [In] ref long fileTime,
+ out SystemTime systemTime);
+
+ [DllImport("AdvApi32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CryptAcquireContextW(
+ out IntPtr providerContext,
+ [MarshalAs(UnmanagedType.LPWStr)] string container,
+ [MarshalAs(UnmanagedType.LPWStr)] string provider,
+ int providerType,
+ int flags);
+
+ [DllImport("AdvApi32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CryptReleaseContext(
+ IntPtr providerContext,
+ int flags);
+
+ [DllImport("AdvApi32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CryptGenKey(
+ IntPtr providerContext,
+ int algorithmId,
+ int flags,
+ out IntPtr cryptKeyHandle);
+
+ [DllImport("AdvApi32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CryptDestroyKey(
+ IntPtr cryptKeyHandle);
+
+ [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CertStrToNameW(
+ int certificateEncodingType,
+ IntPtr x500,
+ int strType,
+ IntPtr reserved,
+ [MarshalAs(UnmanagedType.LPArray)] [Out] byte[] encoded,
+ ref int encodedLength,
+ out IntPtr errorString);
+
+ [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
+ public static extern IntPtr CertCreateSelfSignCertificate(
+ IntPtr providerHandle,
+ [In] ref CryptoApiBlob subjectIssuerBlob,
+ int flags,
+ [In] ref CryptKeyProviderInformation keyProviderInformation,
+ [In] ref CryptAlgorithmIdentifier algorithmIdentifier,
+ [In] ref SystemTime startTime,
+ [In] ref SystemTime endTime,
+ IntPtr extensions);
+
+ [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CertFreeCertificateContext(
+ IntPtr certificateContext);
+
+ [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
+ public static extern IntPtr CertOpenStore(
+ [MarshalAs(UnmanagedType.LPStr)] string storeProvider,
+ int messageAndCertificateEncodingType,
+ IntPtr cryptProvHandle,
+ int flags,
+ IntPtr parameters);
+
+ [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CertCloseStore(
+ IntPtr certificateStoreHandle,
+ int flags);
+
+ [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CertAddCertificateContextToStore(
+ IntPtr certificateStoreHandle,
+ IntPtr certificateContext,
+ int addDisposition,
+ out IntPtr storeContextPtr);
+
+ [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool CertSetCertificateContextProperty(
+ IntPtr certificateContext,
+ int propertyId,
+ int flags,
+ [In] ref CryptKeyProviderInformation data);
+
+ [DllImport("Crypt32.dll", SetLastError = true, ExactSpelling = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool PFXExportCertStoreEx(
+ IntPtr certificateStoreHandle,
+ ref CryptoApiBlob pfxBlob,
+ IntPtr password,
+ IntPtr reserved,
+ int flags);
}
//create a _SERVER_INFO_100 STRUCTURE
@@ -69,4 +168,59 @@ namespace MediaBrowser.ServerApplication.Networking
[MarshalAs(UnmanagedType.LPWStr)]
internal string sv100_name;
}
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct SystemTime
+ {
+ public short Year;
+ public short Month;
+ public short DayOfWeek;
+ public short Day;
+ public short Hour;
+ public short Minute;
+ public short Second;
+ public short Milliseconds;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct CryptObjIdBlob
+ {
+ public uint cbData;
+ public IntPtr pbData;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct CryptAlgorithmIdentifier
+ {
+ [MarshalAs(UnmanagedType.LPStr)]
+ public String pszObjId;
+ public CryptObjIdBlob Parameters;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct CryptoApiBlob
+ {
+ public int DataLength;
+ public IntPtr Data;
+
+ public CryptoApiBlob(int dataLength, IntPtr data)
+ {
+ this.DataLength = dataLength;
+ this.Data = data;
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct CryptKeyProviderInformation
+ {
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string ContainerName;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string ProviderName;
+ public int ProviderType;
+ public int Flags;
+ public int ProviderParameterCount;
+ public IntPtr ProviderParameters; // PCRYPT_KEY_PROV_PARAM
+ public int KeySpec;
+ }
}
diff --git a/MediaBrowser.ServerApplication/Networking/NetworkManager.cs b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs
index fc4d26363..978a29db0 100644
--- a/MediaBrowser.ServerApplication/Networking/NetworkManager.cs
+++ b/MediaBrowser.ServerApplication/Networking/NetworkManager.cs
@@ -156,6 +156,16 @@ namespace MediaBrowser.ServerApplication.Networking
}
/// <summary>
+ /// Generates a self signed certificate at the locatation specified by <paramref name="certificatePath"/>.
+ /// </summary>
+ /// <param name="certificatePath">The path to generate the certificate.</param>
+ /// <param name="hostname">The common name for the certificate.</param>
+ public void GenerateSelfSignedSslCertificate(string certificatePath, string hostname)
+ {
+ CertificateGenerator.CreateSelfSignCertificatePfx(certificatePath, hostname, Logger);
+ }
+
+ /// <summary>
/// Gets the network prefix.
/// </summary>
/// <value>The network prefix.</value>
diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config
index cc5b794ab..db8524463 100644
--- a/MediaBrowser.ServerApplication/packages.config
+++ b/MediaBrowser.ServerApplication/packages.config
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MediaBrowser.IsoMounting" version="3.0.69" targetFramework="net45" />
- <package id="NLog" version="3.1.0.0" targetFramework="net45" />
<package id="System.Data.SQLite.Core" version="1.0.94.0" targetFramework="net45" />
</packages> \ No newline at end of file