pspp-convert: Add -a and -l options to search for a password.
[pspp] / src / data / encrypted-file.c
index f1074b4c1d159d4ad805ea9b887f40400114e20f..e340d04fce61d9727043758b7abac9a350bfcc9a 100644 (file)
@@ -49,7 +49,6 @@ struct encrypted_file
     int Nr;
   };
 
-static bool try_password(struct encrypted_file *, const char *password);
 static bool decode_password (const char *input, char output[11]);
 static bool fill_buffer (struct encrypted_file *);
 
@@ -122,9 +121,9 @@ encrypted_file_unlock (struct encrypted_file *f, const char *password)
 {
   char decoded_password[11];
 
-  return (try_password (f, password)
+  return (encrypted_file_unlock__ (f, password)
           || (decode_password (password, decoded_password)
-              && try_password (f, decoded_password)));
+              && encrypted_file_unlock__ (f, decoded_password)));
 }
 
 /* Attempts to read N bytes of plaintext from F into BUF.  Returns the number
@@ -287,12 +286,10 @@ decode_password (const char *input, char output[11])
   return true;
 }
 
-/* If CIPHERTEXT is the first ciphertext block in an encrypted .sav file for
-   PASSWORD, initializes rk[] and returns an nonzero Nr value.
-
-   Otherwise, returns zero. */
-static bool
-try_password(struct encrypted_file *f, const char *password)
+/* Attempts to use plaintext password PASSWORD to unlock F.  Returns true if
+   successful, otherwise false. */
+bool
+encrypted_file_unlock__ (struct encrypted_file *f, const char *password)
 {
   /* NIST SP 800-108 fixed data. */
   static const uint8_t fixed[] = {
@@ -348,7 +345,12 @@ try_password(struct encrypted_file *f, const char *password)
   rijndaelDecrypt (f->rk, f->Nr,
                    CHAR_CAST (const char *, f->ciphertext),
                    CHAR_CAST (char *, f->plaintext));
-  return !memcmp (f->plaintext, f->type == SYSTEM ? "$FL" : "* E", 3);
+
+  const char *magic = f->type == SYSTEM ? "$FL?@(#)" : "* Encoding";
+  for (int i = 0; magic[i]; i++)
+    if (magic[i] != '?' && f->plaintext[i] != magic[i])
+      return false;
+  return true;
 }
 
 static bool