0

Scenario: upload file than try zip it using DotNetZip with password protection, password is generated with Membership.GeneratePassword() method. Everything is working fine except that sometimes user is not able to unzip files with generated password. Wired thing is that this happens only sometimes let's say 1 out of 15 times. Generate password:

public static String FilePassword()
{
    while (_filePassword.Length < 12)
    {
        _filePassword += string.Concat(Membership.GeneratePassword(1, 0).Where(char.IsLetterOrDigit));
    }

    return _filePassword;
}

Save file:

if (FileUploadControl.HasFile)
{

    fileName = Path.GetFileName(FileUploadControl.FileName);
    FileUploadControl.SaveAs(FileSavePath + fileName);

        // Archive uploaded file to zip.
        using (ZipFile zip = new ZipFile())
        {
            // File to be archived.
            var file = FileUploadControl.PostedFile;

            // Enable encryption of file
            zip.Encryption = EncryptionAlgorithm.PkzipWeak;

            // Set password.
            zip.Password = Settings.FilePassword();

            // Set temporary folder path for archive process.
            zip.TempFileFolder = tempPath;

            // Add file to archive with its path.
            zip.AddFile(FileSavePath + file.FileName, "");

            File objFile = new File(file.FileName, FileSavePath); 

            // Save zip file with the name as file ID.
            zip.Save(FileSavePath + file.FileName);
        }
}

I logged password while creating in method and also while protecting zip file with password, they are always matching, I cannot see what's wrong, why sometimes while unzipping file it shows wrong password.

imsome1
  • 1,182
  • 4
  • 22
  • 37
Mony
  • 93
  • 1
  • 11

1 Answers1

1

Why do you use the static global variable _filePassword in FilePassword() instead of one in scope?

This way it could be modified from outside, or possible even still contain the last used value. Also it isn't thread safe without lock.

Settle with a local variable and it should be fine.

public static String FilePassword()
{
    string retString = string.Empty;
    while (retString.Length < 12)
    {
        retString += string.Concat(Membership.GeneratePassword(1, 0).Where(char.IsLetterOrDigit));
    }    
    return retString;
}

You can log a return Value too.


Sample for understanding

if (FileUploadControl.HasFile)
{

    fileName = Path.GetFileName(FileUploadControl.FileName);
    FileUploadControl.SaveAs(FileSavePath + fileName);
    string filePassword = Settings.FilePassword(); // Contains the Password

    using (ZipFile zip = new ZipFile())
    {
        var file = FileUploadControl.PostedFile;
        zip.Encryption = EncryptionAlgorithm.PkzipWeak;            
        zip.Password = filePassword; // <-- Set password for ZIP
        zip.TempFileFolder = tempPath;
        zip.AddFile(FileSavePath + file.FileName, "");
        File objFile = new File(file.FileName, FileSavePath);
        zip.Save(FileSavePath + file.FileName);
    }

    // Log this value!
    Log(filePassword);
}
  • good point. It was from previous code when password was generated directly with `GeneratePassword` method so it was also with special characters. Will give your suggestion a try to see if it helps. – Mony Oct 04 '17 at 09:21
  • @Mony You could try if your issue happens, if two users simultaneous requesting a Zip File. – Smartis has left SO again Oct 04 '17 at 09:23
  • your change generates 4 different passwords and non of them is correct for unzipping file. my log: `10/4/2017 11:22:55 AM => Password from FilePassword method: iowSYgGB4Nbi 10/4/2017 11:22:55 AM => Password from FilePassword method: mmnZeM1sz3ln 10/4/2017 11:22:55 AM => Password from zipping file: mmnZeM1sz3ln 10/4/2017 11:22:57 AM => Password from FilePassword method: 3xUeKXkWveIv 10/4/2017 11:22:58 AM => Password from FilePassword method: nKNZW67O6yi1` notice the zipping file password which was used while zipping, even this one is not working – Mony Oct 04 '17 at 09:30
  • @Mony Did you use the same variable for Zipping and Logging? – Smartis has left SO again Oct 04 '17 at 09:32
  • yes I did, only way how to have same value all the time is my original way of generating password. Because password is used on multiple places not only while zipping. – Mony Oct 04 '17 at 10:02
  • 1
    @Mony The use of a static is almost certainly the cause of your issues. You need to use a local variable and pass it around rather than use a static. Or use `HttpContext.Items` http://odetocode.com/Articles/111.aspx – mjwills Oct 05 '17 at 21:50