public async Task <IActionResult> ViewPaste(string type, string url, string password) { Models.Paste paste = _dbContext.Pastes.Where(p => p.Url == url).FirstOrDefault(); if (paste != null) { ViewBag.Title = (string.IsNullOrEmpty(paste.Title)) ? "Untitled Paste" : paste.Title + " | Pastebin"; ViewBag.Description = "Paste your code or text easily and securely. Set an expiration, set a password, or leave it open for the world to see."; // Increment Views paste.Views += 1; _dbContext.Entry(paste).State = EntityState.Modified; _dbContext.SaveChanges(); // Check Expiration if (PasteHelper.CheckExpiration(paste)) { DeleteFile(paste); return(new StatusCodeResult(StatusCodes.Status404NotFound)); } PasteViewModel model = new PasteViewModel(); model.Url = url; model.Title = paste.Title; model.Syntax = paste.Syntax; model.DatePosted = paste.DatePosted; model.Username = paste.User?.Username; if (User.Identity.IsAuthenticated && type.ToLower() == "full") { Users.Models.User user = UserHelper.GetUser(_dbContext, User.Identity.Name); if (user != null) { model.Vaults = user.Vaults.ToList(); } } byte[] ivBytes = (string.IsNullOrEmpty(paste.IV)) ? new byte[paste.BlockSize] : Encoding.Unicode.GetBytes(paste.IV); byte[] keyBytes = (string.IsNullOrEmpty(paste.Key)) ? new byte[paste.KeySize] : AesCounterManaged.CreateKey(paste.Key, ivBytes, paste.KeySize); // The paste has a password set if (!string.IsNullOrEmpty(paste.HashedPassword)) { if (string.IsNullOrEmpty(password)) { // Try to get the password from the session password = GetCachedPassword(url); } string hash = string.Empty; if (!string.IsNullOrEmpty(password)) { hash = PasteHelper.HashPassword(paste.Key, password); keyBytes = AesCounterManaged.CreateKey(password, ivBytes, paste.KeySize); } if (string.IsNullOrEmpty(password) || hash != paste.HashedPassword) { PasswordViewModel passModel = new PasswordViewModel(); passModel.ActionUrl = Url.SubRouteUrl("p", "Paste.View"); passModel.Url = url; passModel.Type = type; if (!string.IsNullOrEmpty(password) && hash != paste.HashedPassword) { passModel.Error = true; passModel.ErrorMessage = "Invalid Password"; } // Redirect them to the password request page return(View("~/Areas/Paste/Views/Paste/PasswordNeeded.cshtml", passModel)); } } // Save the password to the cache CachePassword(url, password); // Read in the file if (string.IsNullOrEmpty(paste.FileName)) { return(new StatusCodeResult(StatusCodes.Status404NotFound)); } string subDir = paste.FileName[0].ToString(); string filePath = Path.Combine(_config.PasteConfig.PasteDirectory, subDir, paste.FileName); if (!System.IO.File.Exists(filePath)) { return(new StatusCodeResult(StatusCodes.Status404NotFound)); } using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (AesCounterStream cs = new AesCounterStream(fs, false, keyBytes, ivBytes)) using (StreamReader sr = new StreamReader(cs, Encoding.Unicode)) { model.Content = await sr.ReadToEndAsync(); } switch (type.ToLower()) { case "full": return(View("~/Areas/Paste/Views/Paste/Full.cshtml", model)); case "simple": return(View("~/Areas/Paste/Views/Paste/Simple.cshtml", model)); case "raw": return(Content(model.Content, "text/plain")); case "download": //Create File var cd = new System.Net.Mime.ContentDisposition { FileName = url + ".txt", Inline = true }; Response.Headers.Add("Content-Disposition", cd.ToString()); FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); return(new BufferedFileStreamResult("application/octet-stream", async(response) => await ResponseHelper.StreamToOutput(response, true, new AesCounterStream(fs, false, keyBytes, ivBytes), (int)fs.Length, _config.PasteConfig.ChunkSize), false)); default: return(View("~/Areas/Paste/Views/Paste/Full.cshtml", model)); } } return(new StatusCodeResult(StatusCodes.Status404NotFound)); }
private static async Task <bool> ScanUpload(Config config, TeknikEntities db, Upload upload, int totalCount, int currentCount) { bool virusDetected = false; string subDir = upload.FileName[0].ToString(); string filePath = Path.Combine(config.UploadConfig.UploadDirectory, subDir, upload.FileName); if (File.Exists(filePath)) { // If the IV is set, and Key is set, then scan it if (!string.IsNullOrEmpty(upload.Key) && !string.IsNullOrEmpty(upload.IV)) { byte[] keyBytes = Encoding.UTF8.GetBytes(upload.Key); byte[] ivBytes = Encoding.UTF8.GetBytes(upload.IV); long maxUploadSize = config.UploadConfig.MaxUploadSize; if (upload.User != null) { maxUploadSize = config.UploadConfig.MaxUploadSizeBasic; IdentityUserInfo userInfo = await IdentityHelper.GetIdentityUserInfo(config, upload.User.Username); if (userInfo.AccountType == AccountType.Premium) { maxUploadSize = config.UploadConfig.MaxUploadSizePremium; } } using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) using (AesCounterStream aesStream = new AesCounterStream(fs, false, keyBytes, ivBytes)) { ClamClient clam = new ClamClient(config.UploadConfig.ClamServer, config.UploadConfig.ClamPort); clam.MaxStreamSize = maxUploadSize; ClamScanResult scanResult = await clam.SendAndScanFileAsync(fs); switch (scanResult.Result) { case ClamScanResults.Clean: string cleanMsg = string.Format("[{0}] Clean Scan: {1}/{2} Scanned | {3} - {4}", DateTime.Now, currentCount, totalCount, upload.Url, upload.FileName); Output(cleanMsg); break; case ClamScanResults.VirusDetected: string msg = string.Format("[{0}] Virus Detected: {1} - {2} - {3}", DateTime.Now, upload.Url, upload.FileName, scanResult.InfectedFiles.First().VirusName); Output(msg); lock (scanStatsLock) { virusDetected = true; File.AppendAllLines(virusFile, new List <string> { msg }); } lock (dbLock) { string urlName = upload.Url; // Delete from the DB db.Uploads.Remove(upload); // Delete the File if (File.Exists(filePath)) { File.Delete(filePath); } // Add to transparency report if any were found Takedown report = new Takedown(); report.Requester = TAKEDOWN_REPORTER; report.RequesterContact = config.SupportEmail; report.DateRequested = DateTime.Now; report.Reason = "Malware Found"; report.ActionTaken = string.Format("Upload removed: {0}", urlName); report.DateActionTaken = DateTime.Now; db.Takedowns.Add(report); // Save Changes db.SaveChanges(); } break; case ClamScanResults.Error: string errorMsg = string.Format("[{0}] Scan Error: {1}", DateTime.Now, scanResult.RawResult); File.AppendAllLines(errorFile, new List <string> { errorMsg }); Output(errorMsg); break; case ClamScanResults.Unknown: string unkMsg = string.Format("[{0}] Unknown Scan Result: {1}", DateTime.Now, scanResult.RawResult); File.AppendAllLines(errorFile, new List <string> { unkMsg }); Output(unkMsg); break; } } } } return(virusDetected); }
public async Task <IActionResult> Edit(string url, string password) { Models.Paste paste = _dbContext.Pastes.Where(p => p.Url == url).FirstOrDefault(); if (paste != null) { if (paste.User?.Username != User.Identity.Name) { return(new StatusCodeResult(StatusCodes.Status403Forbidden)); } ViewBag.Title = "Edit Paste"; ViewBag.Description = "Edit your paste's content."; // Check Expiration if (PasteHelper.CheckExpiration(paste)) { DeleteFile(paste); return(new StatusCodeResult(StatusCodes.Status404NotFound)); } PasteViewModel model = new PasteViewModel(); model.Url = url; model.Title = paste.Title; model.Syntax = paste.Syntax; model.DatePosted = paste.DatePosted; model.Username = paste.User?.Username; byte[] ivBytes = (string.IsNullOrEmpty(paste.IV)) ? new byte[paste.BlockSize] : Encoding.Unicode.GetBytes(paste.IV); byte[] keyBytes = (string.IsNullOrEmpty(paste.Key)) ? new byte[paste.KeySize] : AesCounterManaged.CreateKey(paste.Key, ivBytes, paste.KeySize); // The paste has a password set if (!string.IsNullOrEmpty(paste.HashedPassword)) { if (string.IsNullOrEmpty(password)) { // Try to get the password from the session password = GetCachedPassword(url); } string hash = string.Empty; if (!string.IsNullOrEmpty(password)) { hash = PasteHelper.HashPassword(paste.Key, password); keyBytes = AesCounterManaged.CreateKey(password, ivBytes, paste.KeySize); } if (string.IsNullOrEmpty(password) || hash != paste.HashedPassword) { PasswordViewModel passModel = new PasswordViewModel(); passModel.ActionUrl = Url.SubRouteUrl("p", "Paste.Edit"); passModel.Url = url; if (!string.IsNullOrEmpty(password) && hash != paste.HashedPassword) { passModel.Error = true; passModel.ErrorMessage = "Invalid Password"; } // Redirect them to the password request page return(View("~/Areas/Paste/Views/Paste/PasswordNeeded.cshtml", passModel)); } } // Cache the password CachePassword(url, password); // Read in the file if (string.IsNullOrEmpty(paste.FileName)) { return(new StatusCodeResult(StatusCodes.Status404NotFound)); } string subDir = paste.FileName[0].ToString(); string filePath = Path.Combine(_config.PasteConfig.PasteDirectory, subDir, paste.FileName); if (!System.IO.File.Exists(filePath)) { return(new StatusCodeResult(StatusCodes.Status404NotFound)); } using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (AesCounterStream cs = new AesCounterStream(fs, false, keyBytes, ivBytes)) using (StreamReader sr = new StreamReader(cs, Encoding.Unicode)) { model.Content = await sr.ReadToEndAsync(); } return(View("~/Areas/Paste/Views/Paste/Edit.cshtml", model)); } return(new StatusCodeResult(StatusCodes.Status404NotFound)); }
public async Task <IActionResult> ViewVault(string id) { Models.Vault foundVault = _dbContext.Vaults.Where(v => v.Url == id).FirstOrDefault(); if (foundVault != null) { // Update view count foundVault.Views += 1; _dbContext.Entry(foundVault).State = EntityState.Modified; _dbContext.SaveChanges(); ViewBag.Title = foundVault.Title + " | Vault"; VaultViewModel model = new VaultViewModel(); model.CurrentSub = Subdomain; model.Url = foundVault.Url; model.UserId = foundVault.UserId; model.User = foundVault.User; model.Title = foundVault.Title; model.Description = foundVault.Description; model.DateCreated = foundVault.DateCreated; model.DateEdited = foundVault.DateEdited; if (foundVault.VaultItems.Any()) { foreach (VaultItem item in foundVault.VaultItems.OrderBy(v => v.Index)) { if (item.GetType().BaseType == typeof(UploadVaultItem)) { UploadVaultItem upload = (UploadVaultItem)item; // Increment Views upload.Upload.Downloads += 1; _dbContext.Entry(upload.Upload).State = EntityState.Modified; _dbContext.SaveChanges(); UploadItemViewModel uploadModel = new UploadItemViewModel(); uploadModel.VaultItemId = item.VaultItemId; uploadModel.Title = item.Title; uploadModel.Description = item.Description; uploadModel.DateAdded = item.DateAdded; uploadModel.Upload = upload.Upload; model.Items.Add(uploadModel); } else if (item.GetType().BaseType == typeof(PasteVaultItem)) { PasteVaultItem paste = (PasteVaultItem)item; // Increment Views paste.Paste.Views += 1; _dbContext.Entry(paste.Paste).State = EntityState.Modified; _dbContext.SaveChanges(); // Check Expiration if (PasteHelper.CheckExpiration(paste.Paste)) { _dbContext.Pastes.Remove(paste.Paste); _dbContext.SaveChanges(); break; } PasteItemViewModel pasteModel = new PasteItemViewModel(); pasteModel.VaultItemId = item.VaultItemId; pasteModel.Title = item.Title; pasteModel.Description = item.Description; pasteModel.DateAdded = item.DateAdded; pasteModel.PasteId = paste.Paste.PasteId; pasteModel.Url = paste.Paste.Url; pasteModel.DatePosted = paste.Paste.DatePosted; pasteModel.Syntax = paste.Paste.Syntax; pasteModel.HasPassword = !string.IsNullOrEmpty(paste.Paste.HashedPassword); if (!pasteModel.HasPassword) { // Read in the file string subDir = paste.Paste.FileName[0].ToString(); string filePath = Path.Combine(_config.PasteConfig.PasteDirectory, subDir, paste.Paste.FileName); if (!System.IO.File.Exists(filePath)) { continue; } byte[] ivBytes = Encoding.Unicode.GetBytes(paste.Paste.IV); byte[] keyBytes = AesCounterManaged.CreateKey(paste.Paste.Key, ivBytes, paste.Paste.KeySize); using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (AesCounterStream cs = new AesCounterStream(fs, false, keyBytes, ivBytes)) using (StreamReader sr = new StreamReader(cs, Encoding.Unicode)) { pasteModel.Content = await sr.ReadToEndAsync(); } } model.Items.Add(pasteModel); } } } return(View(model)); } return(new StatusCodeResult(StatusCodes.Status404NotFound)); }