Unable to scan Outlook Attachment for encryption - c#

I am trying to detect an encrypted attachment using ICSharpCode.SharpZipLib,
but the code breaks while debugging on this line:
FileStream fileStreamIn = new FileStream(attachtype, FileMode.Open, FileAccess.Read);
Is there any other way through which I can get Outlook attachment and scan for encryption?
if (attachments.Count != 0)
{
for (int i = 1; i <= mail.Attachments.Count; i++)
{
String attachtype = mail.Attachments[i].FileName.ToLower();
if (extensionsArray.Any(attachtype.Contains))
{
FileStream fileStreamIn = new FileStream(attachtype, FileMode.Open, FileAccess.Read);
ZipInputStream zipInStream = new ZipInputStream(fileStreamIn);
ZipEntry entry = zipInStream.GetNextEntry();
MessageBox.Show("IsCrypted: " + entry.IsCrypted);
}
}
}

I'm assuming you are using Microsoft.Office.Interop.Outlook namespaces.
According to the MSDN the Filename property does the following (source):
Returns a String (string in C#) representing the file name of the
attachment. Read-only.
So the value is only the name of the file, not the location (it does not exist on disk as a accessible file). When supplying just the filaneme into a FileStream it will attempt to open a file with that name in the local directory (which probably does not exist).
It seems from the documentation you'll need to store it using the SaveAsFile method (source) into a temporary file and load a FileStream from that.
So something like:
// Location to store file so we can access the data.
var tempFile = Path.GetTempFileName();
try {
// Save attachment into our file
mail.Attachments[i].SaveToFile(tempFile);
using(var stream = File.OpenRead(tempFile)) {
// Do stuff
}
} finally {
// Cleanup the temp file
File.Delete(tempFile);
}

Related

Mvc - Download multiple files as Zip Error as "Unreadable content" while opening downloaded zipped file

I am Using MVC.Net application and I want to download multiple files as zipped. I have written code with memory stream and ZipArchive in my controller action method. With that code I am able to successfully download the files as zipped folder. But when I unzipped those and trying to open them then I am getting the error as below
opening word document with Microsoft word - Word found unreadable content error
opening image file(.png) - dont support file format error
Here is my controller method code to zip the files
if (sendApplicationFiles != null && sendApplicationFiles.Any())
{
using (var compressedFileStream = new MemoryStream())
{
// Create an archive and store the stream in memory.
using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, true))
{
foreach (var file in sendApplicationFiles)
{
// Create a zip entry for each attachment
var zipEntry = zipArchive.CreateEntry(file.FileName);
// Get the stream of the attachment
using (var originalFileStream = new MemoryStream(file.FileData))
using (var zipEntryStream = zipEntry.Open())
{
// Copy the attachment stream to the zip entry stream
originalFileStream.CopyTo(zipEntryStream);
}
}
}
return new FileContentResult(compressedFileStream.ToArray(), "application/zip") { FileDownloadName = "Filename.zip" };
}
}
Expecting the document content should load without error
I did not investigate your code, but this link might help. There are few examples.
https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-compress-and-extract-files

Zip created but no files in it

Can someone tell me what's wrong with my code? I want to zip multiple xml into one file yet the result file is always empty.
using (MemoryStream zipStream = new MemoryStream())
{
using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
string[] xmls = Directory.GetFiles(#"c:\temp\test", "*.xml");
foreach (string xml in xmls)
{
var file = zip.CreateEntry(xml);
using (var entryStream = file.Open())
using (var streamWriter = new StreamWriter(entryStream))
{
streamWriter.Write(xml);
}
}
}
using (FileStream fs = new FileStream(#"C:\Temp\test.zip", FileMode.Create))
{
zipStream.Position = 0;
zipStream.CopyTo(fs);
}
}
See the remarks in the documentation (emphasis mine):
The entryName string should reflect the relative path of the entry you want to create within the zip archive. There is no restriction on the string you provide. However, if it is not formatted as a relative path, the entry is created, but you may get an exception when you extract the contents of the zip archive. If an entry with the specified path and name already exists in the archive, a second entry is created with the same path and name.
You are using an absolute path here:
var file = zip.CreateEntry(xml);
My guess is that when you try to open the archive, it is failing silently to show the entries.
Change your code to use the names of the files without their path:
var file = zip.CreateEntry(Path.GetFileName(xml));
As a separate issue, notice that you're just writing the name of the file to the ZIP entry, rather than the actual file. I imagine you want something like this instead:
var zipEntry = zip.CreateEntry(Path.GetFileName(xml));
using (var entryStream = file.Open())
{
using var fileStream = File.OpenRead(xml);
fileStream.CopyTo(entryStream);
}

sharpziplib FastZip extract rar error cannot find central directory c#

i want to extract RAR file using FastZip, here is my code :
FastZip fastZip = new FastZip();
fastZip.CreateEmptyDirectories = true;
if (password != "")
{
fastZip.Password = password;
}
string fileFilter = null;
fastZip.ExtractZip(CompressedFilePathValue, OutputFolderPathValue, fileFilter);
but i always get error:
cannot find central directory
the RAR file is ok,i open it with WinRAR without error, so how to extract RAR file using sharpziplib with FastZip or without FastZip?
Note: I do not want to use SharpCompress because i dose not support password.
Any way to extract RAR file using sharpziplib?
Thanks for help
here is how to extract RAR file ,without error cannot find central directory:
using (Stream fs = File.OpenRead(CompressedFilePathValue))
using (var zf = new ZipFile(fs))
{
if (!String.IsNullOrEmpty(password))
{
// AES encrypted entries are handled automatically
zf.Password = password;
}
foreach (ZipEntry zipEntry in zf)
{
if (!zipEntry.IsFile)
{
// Ignore directories
continue;
}
String entryFileName = zipEntry.Name;
// to remove the folder from the entry:
//entryFileName = Path.GetFileName(entryFileName);
// Optionally match entrynames against a selection list here
// to skip as desired.
// The unpacked length is available in the zipEntry.Size property.
// Manipulate the output filename here as desired.
var fullZipToPath = Path.Combine(OutputFolderPathValue, entryFileName);
var directoryName = Path.GetDirectoryName(fullZipToPath);
if (directoryName.Length > 0)
{
Directory.CreateDirectory(directoryName);
}
// 4K is optimum
var buffer = new byte[4096];
// Unzip file in buffered chunks. This is just as fast as unpacking
// to a buffer the full size of the file, but does not waste memory.
// The "using" will close the stream even if an exception occurs.
using (var zipStream = zf.GetInputStream(zipEntry))
using (Stream fsOutput = File.Create(fullZipToPath))
{
StreamUtils.Copy(zipStream, fsOutput, buffer);
}
}
}
To be honest this work only with rar file created with sharpziplib , it does not open rar created with winrar

Unzip a zip file that is inside another zip with SharpZipLib

I 'm trying to unzip a zip file that is inside another zip. When I try to get the FileStream of the second zip it gives me an error. How I could view the content?
This is my code:
try
{
FileStream fs = File.OpenRead(location);
ZipFile zipArchive = new ZipFile(fs);
foreach (ZipEntry elementInsideZip in zipArchive)
{
String ZipArchiveName = elementInsideZip.Name;
if (ZipArchiveName.Equals("MyZMLFile.xml"))
{
// I NEED XML FILES
Stream zipStream = zipArchive.GetInputStream(elementInsideZip);
doc.Load(zipStream);
break;
}
// HERE!! I FOUND ZIP FILE
else if (ZipArchiveName.Contains(".zip"))
{
// I NEED XML FILES INSIDE THIS ZIP
string filePath2 = System.IO.Path.GetFullPath(ZipArchiveName);
ZipFile zipArchive2 = null;
FileStream fs2 = File.OpenRead(filePath2);// HERE I GET ERROR: Could not find a part of the path
zipArchive2 = new ZipFile(fs2);
}
}
}
At that point, the zip archive name is not a file on disk. It is just a file inside the zip archive just like the xml files. You should GetInputStream() for this as you do for the xml files, Stream zipStream = zipArchive.GetInputStream(elementInsideZip); Then you can recurse the method to extract this zip again.
You need to extract the zip file first and then should recursively call the same function (Because that zip file can also contain a zip file):
private static void ExtractAndLoadXml(string zipFilePath, XmlDocument doc)
{
using(FileStream fs = File.OpenRead(zipFilePath))
{
ExtractAndLoadXml(fs, doc);
}
}
private static void ExtractAndLoadXml(Stream fs, XmlDocument doc)
{
ZipFile zipArchive = new ZipFile(fs);
foreach (ZipEntry elementInsideZip in zipArchive)
{
String ZipArchiveName = elementInsideZip.Name;
if (ZipArchiveName.Equals("MyZMLFile.xml"))
{
Stream zipStream = zipArchive.GetInputStream(elementInsideZip);
doc.Load(zipStream);
break;
}
else if (ZipArchiveName.Contains(".zip"))
{
Stream zipStream = zipArchive.GetInputStream(elementInsideZip);
string zipFileExtractPath = Path.GetTempFileName();
FileStream extractedZipFile = File.OpenWrite(zipFileExtractPath);
zipStream.CopyTo(extractedZipFile);
extractedZipFile.Flush();
extractedZipFile.Close();
try
{
ExtractAndLoadXml(zipFileExtractPath, doc);
}
finally
{
File.Delete(zipFileExtractPath);
}
}
}
}
public static void Main(string[] args)
{
string location = null;
XmlDocument xmlDocument = new XmlDocument();
ExtractAndLoadXml(location, xmlDocument);
}
I'm not sure if this is possible. Let me explain:
Reading a ZIP file requires random access file IO to read the headers, the file table, the directory table, etc. A compressed ZIP (File) stream doesn't provide you with a random access stream, but with a sequential stream -- that's just the way algorithms like Deflate work.
To load a zip file in a zip file, you need to store the inner zip file somewhere first. For that you can use a temporary file or a simple MemoryStream (if it's not too big). That basically provides you with the random access requirement, thereby solving the problem.

How I can display Stream on the page?

I have a WCF method that I am calling, the method suppose to create a file but it create an exception. I try to find what is in the stream request that I am passing to this method. How I can alert or write this stream so I can find the content. That is my method:
Stream UploadImage(Stream request)
{
Stream requestTest = request;
HttpMultipartParser parser = new HttpMultipartParser(request, "data");
string filePath = "";
string passed = "";
if (parser.Success)
{
// Save the file somewhere
//File.WriteAllBytes(FILE_PATH + title + FILE_EXT, parser.FileContents);
// Save the file
//SaveFile( mtp.Filename, mtp.ContentType, mtp.FileContents);
FileStream fileStream = null;
BinaryWriter writer = null;
try
{
filePath = HttpContext.Current.Server.MapPath("Uploded\\test.jpg"); // BuildFilePath(strFileName, true);
filePath = filePath.Replace("SSGTrnService\\", "");
fileStream = new FileStream(filePath, FileMode.Create);
it produces an error on this line :
fileStream = new FileStream(filePath, FileMode.Create);
that I try to understand why file can not created.
Given the information you gave, I can only assume that your code tries to create the file test.jpg somewhere where your application is not allowed to write. A common mistake would be somewhere in the Program files folder. In modern Windows versions, that is specially protected.

Categories

Resources