public async Task <IActionResult> DownloadFileRaw(FileIdentifier id, string password, [Bind(Prefix = "_")] string?protectedPassword) { if (!this.ModelState.IsValid) { return(this.BadRequest()); } // Get file UploadedFile?uploadedFile = await this._uploadedFileRepository.GetFile(id); if (uploadedFile == null) { this._logger.LogWarning(LogEvents.UploadNotFound, "Unable to find uploaded file for download '{0}'", id); return(this.NotFound("404: File has not been found or download link has expired")); } // Decrypt password if given if (password == null && protectedPassword != null) { password = this._passwordProtector.Unprotect(protectedPassword); // Handle no password (protectedPassword might be expired) if (password == null) { DownloadPasswordModel passwordInfo = new DownloadPasswordModel(); this.ModelState.AddModelError(nameof(passwordInfo.Password), "Password authentication expired"); return(this.View("DownloadFilePassword", passwordInfo)); } } // Direct-download support if (uploadedFile.HasDownloadSecurity()) { if (password == null) { await this.MakeBadPasswordDelayTask(); return(this.StatusCode(401, "This resource is protected by a password")); } if (uploadedFile.Metadata.DownloadSecurity?.Verify(password) == false) { await this.MakeBadPasswordDelayTask(); this.HttpContext.RecordFail2BanFailure(); return(this.StatusCode(401, "This resource is protected by a password")); } this.HttpContext.RecordFail2BanSuccess(); } // Do download await this._fileAccessLogger.LogFileAccessAsync(uploadedFile, this.HttpContext.Features.Get <IHttpConnectionFeature>()?.RemoteIpAddress?.ToString() ?? "Unknown"); return(this.File(DownloadStreamFactory.GetDownloadStream(uploadedFile, password), "application/octet-stream", uploadedFile.Metadata.OriginalFileName)); }
public async Task <IActionResult> DownloadFileSplash(FileIdentifier id, DownloadPasswordModel passwordInfo) { await Task.Delay(500, this.HttpContext.RequestAborted); if (!this.ModelState.IsValid) { await Task.Delay(500, this.HttpContext.RequestAborted); return(this.View("DownloadFilePassword", passwordInfo)); } // Get the file UploadedFile?uploadedFile = await this._uploadedFileRepository.GetFile(id); if (uploadedFile == null || !uploadedFile.HasDownloadSecurity()) { // How? Don't know, but execute regular procedure. return(await this.DownloadFileSplash(id)); } // Directly validate password and return file for wget if (this.IsDirectDownloadClient()) { return(await this.DownloadFileRaw(id, passwordInfo.Password !, null)); } // In web browser case validate password and show regular download view bool passwordIsValid = uploadedFile.Metadata.DownloadSecurity?.Verify(passwordInfo.Password) != false; if (!passwordIsValid) { await this.MakeBadPasswordDelayTask(); this.ModelState.AddModelError(nameof(passwordInfo.Password), "Invalid password"); this.HttpContext.RecordFail2BanFailure(); return(this.View("DownloadFilePassword", passwordInfo)); } this.HttpContext.RecordFail2BanSuccess(); // Show download prompt, protect password to prevent reuse this.ViewBag.ProtectedPassword = this._passwordProtector.Protect(passwordInfo.Password !); return(this.View(uploadedFile)); }