diff --git a/Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj b/Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj
index c8871b0e0..27a9e9cd4 100644
--- a/Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj
+++ b/Duplicati/Library/Backend/Mega/Duplicati.Library.Backend.Mega.csproj
@@ -31,12 +31,15 @@
false
-
- ..\..\..\..\packages\MegaApiClient.1.7.1\lib\net46\MegaApiClient.dll
+
+ ..\..\..\..\packages\MegaApiClient.1.9.0\lib\net46\MegaApiClient.dll..\..\..\..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll
+
+ ..\..\..\..\packages\Otp.NET.1.2.2\lib\net45\Otp.NET.dll
+
diff --git a/Duplicati/Library/Backend/Mega/MegaBackend.cs b/Duplicati/Library/Backend/Mega/MegaBackend.cs
index 184a63769..c3878b1e1 100644
--- a/Duplicati/Library/Backend/Mega/MegaBackend.cs
+++ b/Duplicati/Library/Backend/Mega/MegaBackend.cs
@@ -22,6 +22,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using OtpNet;
namespace Duplicati.Library.Backend.Mega
{
@@ -31,6 +32,7 @@ namespace Duplicati.Library.Backend.Mega
{
private readonly string m_username = null;
private readonly string m_password = null;
+ private readonly string m_twoFactorKey = null;
private Dictionary> m_filecache;
private INode m_currentFolder = null;
private readonly string m_prefix = null;
@@ -48,7 +50,13 @@ namespace Duplicati.Library.Backend.Mega
if (m_client == null)
{
var cl = new MegaApiClient();
- cl.Login(m_username, m_password);
+ if (m_twoFactorKey == null)
+ cl.Login(m_username, m_password);
+ else
+ {
+ var totp = new Totp(Base32Encoding.ToBytes(m_twoFactorKey)).ComputeTotp();
+ cl.Login(m_username, m_password, totp);
+ }
m_client = cl;
}
@@ -64,6 +72,8 @@ namespace Duplicati.Library.Backend.Mega
m_username = options["auth-username"];
if (options.ContainsKey("auth-password"))
m_password = options["auth-password"];
+ if (options.ContainsKey("auth-two-factor-key"))
+ m_twoFactorKey = options["auth-two-factor-key"];
if (!string.IsNullOrEmpty(uri.Username))
m_username = uri.Username;
@@ -253,6 +263,7 @@ namespace Duplicati.Library.Backend.Mega
return new List(new ICommandLineArgument[] {
new CommandLineArgument("auth-password", CommandLineArgument.ArgumentType.Password, Strings.MegaBackend.AuthPasswordDescriptionShort, Strings.MegaBackend.AuthPasswordDescriptionLong),
new CommandLineArgument("auth-username", CommandLineArgument.ArgumentType.String, Strings.MegaBackend.AuthUsernameDescriptionShort, Strings.MegaBackend.AuthUsernameDescriptionLong),
+ new CommandLineArgument("auth-two-factor-key", CommandLineArgument.ArgumentType.Password, Strings.MegaBackend.AuthTwoFactorKeyDescriptionShort, Strings.MegaBackend.AuthTwoFactorKeyDescriptionLong),
});
}
}
diff --git a/Duplicati/Library/Backend/Mega/Strings.cs b/Duplicati/Library/Backend/Mega/Strings.cs
index d52089191..3009798e1 100644
--- a/Duplicati/Library/Backend/Mega/Strings.cs
+++ b/Duplicati/Library/Backend/Mega/Strings.cs
@@ -6,8 +6,10 @@ namespace Duplicati.Library.Backend.Strings {
public static string AuthPasswordDescriptionShort { get { return LC.L(@"Supplies the password used to connect to the server"); } }
public static string AuthUsernameDescriptionLong { get { return LC.L(@"The username used to connect to the server. This may also be supplied as the environment variable ""AUTH_USERNAME""."); } }
public static string AuthUsernameDescriptionShort { get { return LC.L(@"Supplies the username used to connect to the server"); } }
+ public static string AuthTwoFactorKeyDescriptionShort { get { return LC.L(@"The shared secret used to generate two-factor TOTP codes."); } }
+ public static string AuthTwoFactorKeyDescriptionLong { get { return LC.L(@"For accounts with two-factor authentication enabled, this is the shared secret used to generate the two-factor TOTP codes."); } }
public static string NoPasswordError { get { return LC.L(@"No password given"); } }
public static string NoUsernameError { get { return LC.L(@"No username given"); } }
public static string Description { get { return LC.L(@"This backend can read and write data to Mega.co.nz. Allowed formats are: ""mega://folder/subfolder"""); } }
}
-}
+}
\ No newline at end of file
diff --git a/Duplicati/Library/Backend/Mega/packages.config b/Duplicati/Library/Backend/Mega/packages.config
index 06ff32662..c90fbddd1 100644
--- a/Duplicati/Library/Backend/Mega/packages.config
+++ b/Duplicati/Library/Backend/Mega/packages.config
@@ -1,5 +1,6 @@
-
+
-
+
+
\ No newline at end of file
diff --git a/Duplicati/License/Duplicati.License.csproj b/Duplicati/License/Duplicati.License.csproj
index c579b5450..c91efec0f 100644
--- a/Duplicati/License/Duplicati.License.csproj
+++ b/Duplicati/License/Duplicati.License.csproj
@@ -70,6 +70,18 @@
licenses\gpg\License.txt
PreserveNewest
+
+ licenses\Otp.NET\Homepage.txt
+ PreserveNewest
+
+
+ licenses\Otp.NET\license.txt
+ PreserveNewest
+
+
+ licenses\Otp.NET\licensedata.json
+ PreserveNewest
+
licenses\SharpCompress\download.txt
PreserveNewest
diff --git a/thirdparty/Otp.NET/Homepage.txt b/thirdparty/Otp.NET/Homepage.txt
new file mode 100644
index 000000000..1f46ecb7e
--- /dev/null
+++ b/thirdparty/Otp.NET/Homepage.txt
@@ -0,0 +1 @@
+https://github.com/kspearrin/Otp.NET
\ No newline at end of file
diff --git a/thirdparty/Otp.NET/license.txt b/thirdparty/Otp.NET/license.txt
new file mode 100755
index 000000000..0b41517cb
--- /dev/null
+++ b/thirdparty/Otp.NET/license.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Kyle Spearrin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/thirdparty/Otp.NET/licensedata.json b/thirdparty/Otp.NET/licensedata.json
new file mode 100644
index 000000000..3c098b67f
--- /dev/null
+++ b/thirdparty/Otp.NET/licensedata.json
@@ -0,0 +1,7 @@
+{
+ "name": "Otp.NET",
+ "description": "An implementation TOTP RFC 6238 and HOTP RFC 4226 in C#.",
+ "link": "https://github.com/kspearrin/Otp.NET",
+ "license": "MIT",
+ "notes": ""
+}
\ No newline at end of file