mirror of
https://github.com/ip7z/7zip.git
synced 2026-03-07 19:43:51 +01:00
Support for reading passwords from a specified fd
This initial work adds the -pfd[N] flag to the 7z command so that an
alternate file descriptor (fd) may be specified for reading the password
instead of standard input (stdin).
By adding this flag it becomes possible for 7z to accept data from stdin
for use with the -si flag while also being being able to decrypt a
password protected achieve without revealing the password on the
command line.
For example, generating a secret key and storing it in an encrypted archive
without the need to expose any of the data to a filesystem:
age-keygen | 7z a -pfd9 9< <(pass show archive) -siid.age archive.7z
As a side effect the password is not echoed to the terminal, however
this PR should not conflict with the work in #33.
Note that the -p flag is necessary if the archive does not exist but
should not be used if it does.
This commit is contained in:
parent
5e96a82794
commit
2c37f6565d
|
|
@ -120,6 +120,15 @@ static bool StringToUInt32(const wchar_t *s, UInt32 &v)
|
|||
return *end == 0;
|
||||
}
|
||||
|
||||
static bool StringToInt32(const wchar_t *s, Int32 &v)
|
||||
{
|
||||
if (*s == 0)
|
||||
return false;
|
||||
const wchar_t *end;
|
||||
v = ConvertStringToInt32(s, &end);
|
||||
return *end == 0;
|
||||
}
|
||||
|
||||
|
||||
namespace NKey {
|
||||
enum Enum
|
||||
|
|
@ -209,6 +218,7 @@ enum Enum
|
|||
|
||||
#ifndef Z7_NO_CRYPTO
|
||||
, kPassword
|
||||
, kPasswordFd
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -360,6 +370,7 @@ static const CSwitchForm kSwitchForms[] =
|
|||
|
||||
#ifndef Z7_NO_CRYPTO
|
||||
, { "p", SWFRM_STRING }
|
||||
, { "pfd", SWFRM_STRING }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -1460,6 +1471,22 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
|
|||
options.PasswordEnabled = parser[NKey::kPassword].ThereIs;
|
||||
if (options.PasswordEnabled)
|
||||
options.Password = parser[NKey::kPassword].PostStrings[0];
|
||||
|
||||
options.PasswordFd = 0;
|
||||
|
||||
if (parser[NKey::kPasswordFd].ThereIs)
|
||||
{
|
||||
const UString &s = parser[NKey::kPasswordFd].PostStrings[0];
|
||||
if (s.IsEmpty())
|
||||
throw CArcCmdLineException("No file descriptor given to -pfd", s);
|
||||
else
|
||||
{
|
||||
Int32 v;
|
||||
if (!StringToInt32(s, v))
|
||||
throw CArcCmdLineException("A file descriptor is required for -pfd", s);
|
||||
options.PasswordFd = (int)v;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
options.ShowDialog = parser[NKey::kShowDialog].ThereIs;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ struct CArcCmdLineOptions
|
|||
#ifndef Z7_NO_CRYPTO
|
||||
bool PasswordEnabled;
|
||||
UString Password;
|
||||
int PasswordFd;
|
||||
#endif
|
||||
|
||||
UStringVector HashMethods;
|
||||
|
|
|
|||
|
|
@ -1081,7 +1081,7 @@ HRESULT ListArchives(
|
|||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
bool enableHeaders, bool techMode,
|
||||
#ifndef Z7_NO_CRYPTO
|
||||
bool &passwordEnabled, UString &password,
|
||||
bool &passwordEnabled, UString &password, int &passwordFd,
|
||||
#endif
|
||||
#ifndef Z7_SFX
|
||||
const CObjectVector<CProperty> *props,
|
||||
|
|
@ -1161,6 +1161,7 @@ HRESULT ListArchives(
|
|||
|
||||
openCallback.PasswordIsDefined = passwordEnabled;
|
||||
openCallback.Password = password;
|
||||
openCallback.PasswordFd = passwordFd;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ HRESULT ListArchives(
|
|||
const NWildcard::CCensorNode &wildcardCensor,
|
||||
bool enableHeaders, bool techMode,
|
||||
#ifndef Z7_NO_CRYPTO
|
||||
bool &passwordEnabled, UString &password,
|
||||
bool &passwordEnabled, UString &password, int &passwordFd,
|
||||
#endif
|
||||
#ifndef Z7_SFX
|
||||
const CObjectVector<CProperty> *props,
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ static const char * const kHelpString =
|
|||
" -o{Directory} : set Output directory\n"
|
||||
#ifndef Z7_NO_CRYPTO
|
||||
" -p{Password} : set Password\n"
|
||||
" -pfd{N} : read Password from fd\n"
|
||||
#endif
|
||||
" -r[-|0] : Recurse subdirectories for name search\n"
|
||||
" -sa{a|e|s} : set Archive name mode\n"
|
||||
|
|
@ -1333,6 +1334,7 @@ int Main2(
|
|||
#ifndef Z7_NO_CRYPTO
|
||||
ecs->PasswordIsDefined = options.PasswordEnabled;
|
||||
ecs->Password = options.Password;
|
||||
ecs->PasswordFd = options.PasswordFd;
|
||||
#endif
|
||||
|
||||
ecs->Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents);
|
||||
|
|
@ -1517,6 +1519,7 @@ int Main2(
|
|||
#ifndef Z7_NO_CRYPTO
|
||||
options.PasswordEnabled,
|
||||
options.Password,
|
||||
options.PasswordFd,
|
||||
#endif
|
||||
&options.Properties,
|
||||
numErrors, numWarnings);
|
||||
|
|
@ -1551,6 +1554,7 @@ int Main2(
|
|||
(options.PasswordEnabled && !options.Password.IsEmpty());
|
||||
openCallback.PasswordIsDefined = passwordIsDefined;
|
||||
openCallback.Password = options.Password;
|
||||
openCallback.PasswordFd = options.PasswordFd;
|
||||
#endif
|
||||
|
||||
CUpdateCallbackConsole callback;
|
||||
|
|
@ -1564,6 +1568,7 @@ int Main2(
|
|||
callback.PasswordIsDefined = passwordIsDefined;
|
||||
callback.AskPassword = (options.PasswordEnabled && options.Password.IsEmpty());
|
||||
callback.Password = options.Password;
|
||||
callback.PasswordFd = options.PasswordFd;
|
||||
#endif
|
||||
|
||||
callback.StdOutMode = uo.StdOutMode;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,15 @@ HRESULT COpenCallbackConsole::Open_CryptoGetTextPassword(BSTR *password)
|
|||
if (!PasswordIsDefined)
|
||||
{
|
||||
ClosePercents();
|
||||
if (PasswordFd) {
|
||||
FILE *_file = fdopen(PasswordFd, "r");
|
||||
|
||||
if (!_file)
|
||||
return S_FALSE;
|
||||
|
||||
g_StdIn = CStdInStream(_file);
|
||||
}
|
||||
|
||||
RINOK(GetPassword_HRESULT(_so, Password))
|
||||
PasswordIsDefined = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ public:
|
|||
bool PasswordIsDefined;
|
||||
// bool PasswordWasAsked;
|
||||
UString Password;
|
||||
int PasswordFd;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -828,6 +828,16 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined,
|
|||
|
||||
if (!PasswordIsDefined)
|
||||
{
|
||||
if (PasswordFd) {
|
||||
FILE *_file = fdopen(PasswordFd, "r");
|
||||
|
||||
if (!_file)
|
||||
return S_FALSE;
|
||||
|
||||
g_StdIn = CStdInStream(_file);
|
||||
}
|
||||
|
||||
|
||||
if (AskPassword)
|
||||
{
|
||||
RINOK(GetPassword_HRESULT(_so, Password))
|
||||
|
|
@ -857,6 +867,15 @@ HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)
|
|||
if (!PasswordIsDefined)
|
||||
{
|
||||
{
|
||||
if (PasswordFd) {
|
||||
FILE *_file = fdopen(PasswordFd, "r");
|
||||
|
||||
if (!_file)
|
||||
return S_FALSE;
|
||||
|
||||
g_StdIn = CStdInStream(_file);
|
||||
}
|
||||
|
||||
RINOK(GetPassword_HRESULT(_so, Password))
|
||||
PasswordIsDefined = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ public:
|
|||
bool PasswordIsDefined;
|
||||
bool AskPassword;
|
||||
UString Password;
|
||||
int PasswordFd;
|
||||
#endif
|
||||
|
||||
CUpdateCallbackConsole():
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#ifndef ZIP7_INC_USER_INPUT_UTILS_H
|
||||
#define ZIP7_INC_USER_INPUT_UTILS_H
|
||||
|
||||
#include "../../../Common/StdInStream.h"
|
||||
#include "../../../Common/StdOutStream.h"
|
||||
|
||||
namespace NUserAnswerMode {
|
||||
|
|
|
|||
Loading…
Reference in a new issue