public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { ShareData data = value as ShareData; if (data == null) { throw new ArgumentException("invalid data to serialize"); } writer.WriteStartArray(); writer.WriteStartArray(); writer.WriteValue(data.NodeId); writer.WriteEndArray(); writer.WriteStartArray(); foreach (var item in data.Items) { writer.WriteValue(item.NodeId); } writer.WriteEndArray(); writer.WriteStartArray(); int counter = 0; foreach (var item in data.Items) { writer.WriteValue(0); writer.WriteValue(counter++); writer.WriteValue(Crypto.EncryptKey(item.Data, item.Key).ToBase64()); } writer.WriteEndArray(); writer.WriteEndArray(); }
public ShareNodeRequest(INode node, byte[] masterKey, IEnumerable <INode> nodes) : base("s2") { this.Id = node.Id; this.Options = new object[] { new { r = 0, u = "EXP" } }; INodeCrypto nodeCrypto = (INodeCrypto)node; byte[] uncryptedSharedKey = nodeCrypto.SharedKey; if (uncryptedSharedKey == null) { uncryptedSharedKey = Crypto.CreateAesKey(); } this.SharedKey = Crypto.EncryptKey(uncryptedSharedKey, masterKey).ToBase64(); if (nodeCrypto.SharedKey == null) { this.Share = new ShareData(node.Id); this.Share.AddItem(node.Id, nodeCrypto.FullKey, uncryptedSharedKey); // Add all children IEnumerable <INode> allChildren = this.GetRecursiveChildren(nodes.ToArray(), node); foreach (var child in allChildren) { this.Share.AddItem(child.Id, ((INodeCrypto)child).FullKey, uncryptedSharedKey); } } byte[] handle = (node.Id + node.Id).ToBytes(); this.HandleAuth = Crypto.EncryptKey(handle, masterKey).ToBase64(); }
/// <summary> /// Upload a stream on Mega.co.nz and attach created node to selected parent /// </summary> /// <param name="stream">Data to upload</param> /// <param name="name">Created node name</param> /// <param name="parent">Node to attach the uploaded file (all types except <see cref="NodeType.File" /> are supported)</param> /// <returns>Created node</returns> /// <exception cref="NotSupportedException">Not logged in</exception> /// <exception cref="ApiException">Mega.co.nz service reports an error</exception> /// <exception cref="ArgumentNullException">stream or name or parent is null</exception> /// <exception cref="ArgumentException">parent is not valid (all types except <see cref="NodeType.File" /> are supported)</exception> public INode Upload(Stream stream, string name, INode parent) { if (stream == null) { throw new ArgumentNullException("stream"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (parent == null) { throw new ArgumentNullException("parent"); } if (parent.Type == NodeType.File) { throw new ArgumentException("Invalid parent node"); } this.EnsureLoggedIn(); // Retrieve upload URL UploadUrlRequest uploadRequest = new UploadUrlRequest(stream.Length); UploadUrlResponse uploadResponse = this.Request <UploadUrlResponse>(uploadRequest); using (MegaAesCtrStreamCrypter encryptedStream = new MegaAesCtrStreamCrypter(stream)) { string completionHandle = this._webClient.PostRequestRaw(new Uri(uploadResponse.Url), encryptedStream); // Encrypt attributes byte[] cryptedAttributes = Crypto.EncryptAttributes(new Attributes(name), encryptedStream.FileKey); // Compute the file key byte[] fileKey = new byte[32]; for (int i = 0; i < 8; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.Iv[i]); fileKey[i + 16] = encryptedStream.Iv[i]; } for (int i = 8; i < 16; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.MetaMac[i - 8]); fileKey[i + 16] = encryptedStream.MetaMac[i - 8]; } byte[] encryptedKey = Crypto.EncryptKey(fileKey, this._masterKey); CreateNodeRequest createNodeRequest = CreateNodeRequest.CreateFileNodeRequest(parent, cryptedAttributes.ToBase64(), encryptedKey.ToBase64(), fileKey, completionHandle); GetNodesResponse createNodeResponse = this.Request <GetNodesResponse>(createNodeRequest, this._masterKey); return(createNodeResponse.Nodes[0]); } }
// Token: 0x0600094C RID: 2380 RVA: 0x0004BE18 File Offset: 0x0004A018 public INode Upload(Stream stream, string name, INode parent, DateTime?modificationDate = null, CancellationToken?cancellationToken = null) { if (stream == null) { throw new ArgumentNullException("stream"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (parent == null) { throw new ArgumentNullException("parent"); } if (parent.Type == NodeType.File) { throw new ArgumentException("Invalid parent node"); } this.EnsureLoggedIn(); if (cancellationToken != null) { stream = new CancellableStream(stream, cancellationToken.Value); } string text = string.Empty; int num = 0; TimeSpan retryDelay; while (this.options.ComputeApiRequestRetryWaitDelay(++num, out retryDelay)) { UploadUrlRequest request = new UploadUrlRequest(stream.Length); UploadUrlResponse uploadUrlResponse = this.Request <UploadUrlResponse>(request, null); ApiResultCode apiResultCode = ApiResultCode.Ok; using (MegaAesCtrStreamCrypter megaAesCtrStreamCrypter = new MegaAesCtrStreamCrypter(stream)) { long num2 = 0L; int[] array = this.ComputeChunksSizesToUpload(megaAesCtrStreamCrypter.ChunksPositions, megaAesCtrStreamCrypter.Length).ToArray <int>(); Uri url = null; for (int i = 0; i < array.Length; i++) { text = string.Empty; int num3 = array[i]; byte[] buffer = new byte[num3]; megaAesCtrStreamCrypter.Read(buffer, 0, num3); using (MemoryStream memoryStream = new MemoryStream(buffer)) { url = new Uri(uploadUrlResponse.Url + "/" + num2); num2 += (long)num3; try { text = this.webClient.PostRequestRaw(url, memoryStream); long num4; if (string.IsNullOrEmpty(text)) { apiResultCode = ApiResultCode.Ok; } else if (text.FromBase64().Length != 27 && long.TryParse(text, out num4)) { apiResultCode = (ApiResultCode)num4; break; } } catch (Exception exception) { apiResultCode = ApiResultCode.RequestFailedRetry; EventHandler <ApiRequestFailedEventArgs> apiRequestFailed = this.ApiRequestFailed; if (apiRequestFailed != null) { apiRequestFailed(this, new ApiRequestFailedEventArgs(url, num, retryDelay, apiResultCode, exception)); } break; } } } if (apiResultCode == ApiResultCode.Ok) { byte[] data = Crypto.EncryptAttributes(new Attributes(name, stream, modificationDate), megaAesCtrStreamCrypter.FileKey); byte[] array2 = new byte[32]; for (int j = 0; j < 8; j++) { array2[j] = (megaAesCtrStreamCrypter.FileKey[j] ^ megaAesCtrStreamCrypter.Iv[j]); array2[j + 16] = megaAesCtrStreamCrypter.Iv[j]; } for (int k = 8; k < 16; k++) { array2[k] = (megaAesCtrStreamCrypter.FileKey[k] ^ megaAesCtrStreamCrypter.MetaMac[k - 8]); array2[k + 16] = megaAesCtrStreamCrypter.MetaMac[k - 8]; } byte[] data2 = Crypto.EncryptKey(array2, this.masterKey); CreateNodeRequest request2 = CreateNodeRequest.CreateFileNodeRequest(parent, data.ToBase64(), data2.ToBase64(), array2, text); return(this.Request <GetNodesResponse>(request2, this.masterKey).Nodes[0]); } EventHandler <ApiRequestFailedEventArgs> apiRequestFailed2 = this.ApiRequestFailed; if (apiRequestFailed2 != null) { apiRequestFailed2(this, new ApiRequestFailedEventArgs(url, num, retryDelay, apiResultCode, text)); } if (apiResultCode != ApiResultCode.RequestFailedRetry && apiResultCode != ApiResultCode.RequestFailedPermanetly) { if (apiResultCode != ApiResultCode.TooManyRequests) { throw new ApiException(apiResultCode); } } this.Wait(retryDelay); stream.Seek(0L, SeekOrigin.Begin); } } throw new UploadException(text); }
public INode Upload(Stream stream, string name, INode parent, DateTime?modificationDate = null, CancellationToken?cancellationToken = null) #endif { if (stream == null) { throw new ArgumentNullException("stream"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (parent == null) { throw new ArgumentNullException("parent"); } if (parent.Type == NodeType.File) { throw new ArgumentException("Invalid parent node"); } this.EnsureLoggedIn(); #if !NET35 if (cancellationToken.HasValue) { stream = new CancellableStream(stream, cancellationToken.Value); } #endif string completionHandle = string.Empty; int requestDelay = this.options.ApiRequestDelay; int remainingRetry = this.options.ApiRequestAttempts; while (remainingRetry-- > 0) { // Retrieve upload URL UploadUrlRequest uploadRequest = new UploadUrlRequest(stream.Length); UploadUrlResponse uploadResponse = this.Request <UploadUrlResponse>(uploadRequest); ApiResultCode apiResult = ApiResultCode.Ok; using (MegaAesCtrStreamCrypter encryptedStream = new MegaAesCtrStreamCrypter(stream)) { var chunkStartPosition = 0; var chunksSizesToUpload = this.ComputeChunksSizesToUpload(encryptedStream.ChunksPositions, encryptedStream.Length).ToArray(); Uri uri = null; for (int i = 0; i < chunksSizesToUpload.Length; i++) { completionHandle = string.Empty; int chunkSize = chunksSizesToUpload[i]; byte[] chunkBuffer = new byte[chunkSize]; encryptedStream.Read(chunkBuffer, 0, chunkSize); using (MemoryStream chunkStream = new MemoryStream(chunkBuffer)) { uri = new Uri(uploadResponse.Url + "/" + chunkStartPosition); chunkStartPosition += chunkSize; try { completionHandle = this.webClient.PostRequestRaw(uri, chunkStream); if (string.IsNullOrEmpty(completionHandle)) { apiResult = ApiResultCode.Ok; continue; } long retCode; if (completionHandle.FromBase64().Length != 27 && long.TryParse(completionHandle, out retCode)) { apiResult = (ApiResultCode)retCode; break; } } catch (Exception ex) { apiResult = ApiResultCode.RequestFailedRetry; this.ApiRequestFailed?.Invoke(this, new ApiRequestFailedEventArgs(uri, remainingRetry, requestDelay, apiResult, ex)); break; } } } if (apiResult != ApiResultCode.Ok) { this.ApiRequestFailed?.Invoke(this, new ApiRequestFailedEventArgs(uri, remainingRetry, requestDelay, apiResult, completionHandle)); if (apiResult == ApiResultCode.RequestFailedRetry || apiResult == ApiResultCode.RequestFailedPermanetly || apiResult == ApiResultCode.TooManyRequests) { // Restart upload from the beginning requestDelay = this.Wait(requestDelay); // Reset steam position stream.Seek(0, SeekOrigin.Begin); continue; } throw new ApiException(apiResult); } // Encrypt attributes byte[] cryptedAttributes = Crypto.EncryptAttributes(new Attributes(name, stream, modificationDate), encryptedStream.FileKey); // Compute the file key byte[] fileKey = new byte[32]; for (int i = 0; i < 8; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.Iv[i]); fileKey[i + 16] = encryptedStream.Iv[i]; } for (int i = 8; i < 16; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.MetaMac[i - 8]); fileKey[i + 16] = encryptedStream.MetaMac[i - 8]; } byte[] encryptedKey = Crypto.EncryptKey(fileKey, this.masterKey); CreateNodeRequest createNodeRequest = CreateNodeRequest.CreateFileNodeRequest(parent, cryptedAttributes.ToBase64(), encryptedKey.ToBase64(), fileKey, completionHandle); GetNodesResponse createNodeResponse = this.Request <GetNodesResponse>(createNodeRequest, this.masterKey); return(createNodeResponse.Nodes[0]); } } throw new UploadException(completionHandle); }
/// <summary> /// Upload a stream on Mega.co.nz and attach created node to selected parent /// </summary> /// <param name="stream">Data to upload</param> /// <param name="name">Created node name</param> /// <param name="parent">Node to attach the uploaded file (all types except <see cref="NodeType.File" /> are supported)</param> /// <returns>Created node</returns> /// <exception cref="NotSupportedException">Not logged in</exception> /// <exception cref="ApiException">Mega.co.nz service reports an error</exception> /// <exception cref="ArgumentNullException">stream or name or parent is null</exception> /// <exception cref="ArgumentException">parent is not valid (all types except <see cref="NodeType.File" /> are supported)</exception> public INode Upload(Stream stream, string name, INode parent) { if (stream == null) { throw new ArgumentNullException("stream"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (parent == null) { throw new ArgumentNullException("parent"); } if (parent.Type == NodeType.File) { throw new ArgumentException("Invalid parent node"); } this.EnsureLoggedIn(); // Retrieve upload URL UploadUrlRequest uploadRequest = new UploadUrlRequest(stream.Length); UploadUrlResponse uploadResponse = this.Request <UploadUrlResponse>(uploadRequest); using (MegaAesCtrStreamCrypter encryptedStream = new MegaAesCtrStreamCrypter(stream)) { string completionHandle = null; for (int i = 0; i < encryptedStream.ChunksPositions.Length; i++) { long currentChunkPosition = encryptedStream.ChunksPositions[i]; long nextChunkPosition = i == encryptedStream.ChunksPositions.Length - 1 ? encryptedStream.Length : encryptedStream.ChunksPositions[i + 1]; int chunkSize = (int)(nextChunkPosition - currentChunkPosition); byte[] chunkBuffer = new byte[chunkSize]; encryptedStream.Read(chunkBuffer, 0, chunkSize); using (MemoryStream chunkStream = new MemoryStream(chunkBuffer)) { int remainingRetry = ApiRequestAttempts; string result = null; UploadException lastException = null; while (remainingRetry-- > 0) { Uri uri = new Uri(uploadResponse.Url + "/" + encryptedStream.ChunksPositions[i]); result = this.webClient.PostRequestRaw(uri, chunkStream); if (result.StartsWith("-")) { lastException = new UploadException(result); Thread.Sleep(ApiRequestDelay); continue; } lastException = null; break; } if (lastException != null) { throw lastException; } completionHandle = result; } } // Encrypt attributes byte[] cryptedAttributes = Crypto.EncryptAttributes(new Attributes(name), encryptedStream.FileKey); // Compute the file key byte[] fileKey = new byte[32]; for (int i = 0; i < 8; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.Iv[i]); fileKey[i + 16] = encryptedStream.Iv[i]; } for (int i = 8; i < 16; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.MetaMac[i - 8]); fileKey[i + 16] = encryptedStream.MetaMac[i - 8]; } byte[] encryptedKey = Crypto.EncryptKey(fileKey, this.masterKey); CreateNodeRequest createNodeRequest = CreateNodeRequest.CreateFileNodeRequest(parent, cryptedAttributes.ToBase64(), encryptedKey.ToBase64(), fileKey, completionHandle); GetNodesResponse createNodeResponse = this.Request <GetNodesResponse>(createNodeRequest, this.masterKey); return(createNodeResponse.Nodes[0]); } }
/// <summary> /// Upload a stream on Mega.co.nz and attach created node to selected parent /// </summary> /// <param name="stream">Data to upload</param> /// <param name="name">Created node name</param> /// <param name="parent">Node to attach the uploaded file (all types except <see cref="NodeType.File" /> are supported)</param> /// <returns>Created node</returns> /// <exception cref="NotSupportedException">Not logged in</exception> /// <exception cref="ApiException">Mega.co.nz service reports an error</exception> /// <exception cref="ArgumentNullException">stream or name or parent is null</exception> /// <exception cref="ArgumentException">parent is not valid (all types except <see cref="NodeType.File" /> are supported)</exception> public INode Upload(Stream stream, string name, INode parent) { if (stream == null) { throw new ArgumentNullException("stream"); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (parent == null) { throw new ArgumentNullException("parent"); } if (parent.Type == NodeType.File) { throw new ArgumentException("Invalid parent node"); } this.EnsureLoggedIn(); string completionHandle = "-"; int remainingRetry = ApiRequestAttempts; while (remainingRetry-- > 0) { // Retrieve upload URL UploadUrlRequest uploadRequest = new UploadUrlRequest(stream.Length); UploadUrlResponse uploadResponse = this.Request <UploadUrlResponse>(uploadRequest); using (MegaAesCtrStreamCrypter encryptedStream = new MegaAesCtrStreamCrypter(stream)) { var chunkStartPosition = 0; var chunksSizesToUpload = this.ComputeChunksSizesToUpload(encryptedStream.ChunksPositions, encryptedStream.Length).ToArray(); for (int i = 0; i < chunksSizesToUpload.Length; i++) { int chunkSize = chunksSizesToUpload[i]; byte[] chunkBuffer = new byte[chunkSize]; encryptedStream.Read(chunkBuffer, 0, chunkSize); using (MemoryStream chunkStream = new MemoryStream(chunkBuffer)) { Uri uri = new Uri(uploadResponse.Url + "/" + chunkStartPosition); chunkStartPosition += chunkSize; try { completionHandle = this.webClient.PostRequestRaw(uri, chunkStream); if (completionHandle.StartsWith("-")) { break; } } catch (Exception ex) { Console.WriteLine(ex); break; } } } if (completionHandle.StartsWith("-")) { // Restart upload from the beginning Thread.Sleep(ApiRequestDelay); // Reset steam position stream.Position = 0; continue; } // Encrypt attributes byte[] cryptedAttributes = Crypto.EncryptAttributes(new Attributes(name), encryptedStream.FileKey); // Compute the file key byte[] fileKey = new byte[32]; for (int i = 0; i < 8; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.Iv[i]); fileKey[i + 16] = encryptedStream.Iv[i]; } for (int i = 8; i < 16; i++) { fileKey[i] = (byte)(encryptedStream.FileKey[i] ^ encryptedStream.MetaMac[i - 8]); fileKey[i + 16] = encryptedStream.MetaMac[i - 8]; } byte[] encryptedKey = Crypto.EncryptKey(fileKey, this.masterKey); CreateNodeRequest createNodeRequest = CreateNodeRequest.CreateFileNodeRequest(parent, cryptedAttributes.ToBase64(), encryptedKey.ToBase64(), fileKey, completionHandle); GetNodesResponse createNodeResponse = this.Request <GetNodesResponse>(createNodeRequest, this.masterKey); return(createNodeResponse.Nodes[0]); } } throw new UploadException(completionHandle); }