mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
agent: Sanitize permissions of the private key directory.
* agent/gpg-agent.c (create_private_keys_directory): Set permissions. * common/sysutils.c (modestr_to_mode): New function. (gnupg_mkdir): Use new function. (gnupg_chmod): New function. * common/sysutils.h (gnupg_chmod): New prototype. * tests/migrations/from-classic.test: Test migration with existing directory. GnuPG-bug-id: 2312 Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
parent
defbc70b4a
commit
f8adf1a323
@ -1908,9 +1908,13 @@ create_private_keys_directory (const char *home)
|
|||||||
else if (!opt.quiet)
|
else if (!opt.quiet)
|
||||||
log_info (_("directory '%s' created\n"), fname);
|
log_info (_("directory '%s' created\n"), fname);
|
||||||
}
|
}
|
||||||
|
if (gnupg_chmod (fname, "-rwx"))
|
||||||
|
log_error (_("can't set permissions of '%s': %s\n"),
|
||||||
|
fname, strerror (errno));
|
||||||
xfree (fname);
|
xfree (fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create the directory only if the supplied directory name is the
|
/* Create the directory only if the supplied directory name is the
|
||||||
same as the default one. This way we avoid to create arbitrary
|
same as the default one. This way we avoid to create arbitrary
|
||||||
directories when a non-default home directory is used. To cope
|
directories when a non-default home directory is used. To cope
|
||||||
|
@ -554,6 +554,40 @@ gnupg_remove (const char *fname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HAVE_W32_SYSTEM
|
||||||
|
static mode_t
|
||||||
|
modestr_to_mode (const char *modestr)
|
||||||
|
{
|
||||||
|
mode_t mode = 0;
|
||||||
|
|
||||||
|
if (modestr && *modestr)
|
||||||
|
{
|
||||||
|
modestr++;
|
||||||
|
if (*modestr && *modestr++ == 'r')
|
||||||
|
mode |= S_IRUSR;
|
||||||
|
if (*modestr && *modestr++ == 'w')
|
||||||
|
mode |= S_IWUSR;
|
||||||
|
if (*modestr && *modestr++ == 'x')
|
||||||
|
mode |= S_IXUSR;
|
||||||
|
if (*modestr && *modestr++ == 'r')
|
||||||
|
mode |= S_IRGRP;
|
||||||
|
if (*modestr && *modestr++ == 'w')
|
||||||
|
mode |= S_IWGRP;
|
||||||
|
if (*modestr && *modestr++ == 'x')
|
||||||
|
mode |= S_IXGRP;
|
||||||
|
if (*modestr && *modestr++ == 'r')
|
||||||
|
mode |= S_IROTH;
|
||||||
|
if (*modestr && *modestr++ == 'w')
|
||||||
|
mode |= S_IWOTH;
|
||||||
|
if (*modestr && *modestr++ == 'x')
|
||||||
|
mode |= S_IXOTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* A wrapper around mkdir which takes a string for the mode argument.
|
/* A wrapper around mkdir which takes a string for the mode argument.
|
||||||
This makes it easier to handle the mode argument which is not
|
This makes it easier to handle the mode argument which is not
|
||||||
defined on all systems. The format of the modestring is
|
defined on all systems. The format of the modestring is
|
||||||
@ -589,31 +623,22 @@ gnupg_mkdir (const char *name, const char *modestr)
|
|||||||
because this sets ERRNO. */
|
because this sets ERRNO. */
|
||||||
return mkdir (name);
|
return mkdir (name);
|
||||||
#else
|
#else
|
||||||
mode_t mode = 0;
|
return mkdir (name, modestr_to_mode (modestr));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (modestr && *modestr)
|
|
||||||
{
|
/* A wrapper around mkdir which takes a string for the mode argument.
|
||||||
modestr++;
|
This makes it easier to handle the mode argument which is not
|
||||||
if (*modestr && *modestr++ == 'r')
|
defined on all systems. The format of the modestring is the same
|
||||||
mode |= S_IRUSR;
|
as for gnupg_mkdir. */
|
||||||
if (*modestr && *modestr++ == 'w')
|
int
|
||||||
mode |= S_IWUSR;
|
gnupg_chmod (const char *name, const char *modestr)
|
||||||
if (*modestr && *modestr++ == 'x')
|
{
|
||||||
mode |= S_IXUSR;
|
#ifdef HAVE_W32_SYSTEM
|
||||||
if (*modestr && *modestr++ == 'r')
|
return 0;
|
||||||
mode |= S_IRGRP;
|
#else
|
||||||
if (*modestr && *modestr++ == 'w')
|
return chmod (name, modestr_to_mode (modestr));
|
||||||
mode |= S_IWGRP;
|
|
||||||
if (*modestr && *modestr++ == 'x')
|
|
||||||
mode |= S_IXGRP;
|
|
||||||
if (*modestr && *modestr++ == 'r')
|
|
||||||
mode |= S_IROTH;
|
|
||||||
if (*modestr && *modestr++ == 'w')
|
|
||||||
mode |= S_IWOTH;
|
|
||||||
if (*modestr && *modestr++ == 'x')
|
|
||||||
mode |= S_IXOTH;
|
|
||||||
}
|
|
||||||
return mkdir (name, mode);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ void gnupg_reopen_std (const char *pgmname);
|
|||||||
void gnupg_allow_set_foregound_window (pid_t pid);
|
void gnupg_allow_set_foregound_window (pid_t pid);
|
||||||
int gnupg_remove (const char *fname);
|
int gnupg_remove (const char *fname);
|
||||||
int gnupg_mkdir (const char *name, const char *modestr);
|
int gnupg_mkdir (const char *name, const char *modestr);
|
||||||
|
int gnupg_chmod (const char *name, const char *modestr);
|
||||||
char *gnupg_mkdtemp (char *template);
|
char *gnupg_mkdtemp (char *template);
|
||||||
int gnupg_setenv (const char *name, const char *value, int overwrite);
|
int gnupg_setenv (const char *name, const char *value, int overwrite);
|
||||||
int gnupg_unsetenv (const char *name);
|
int gnupg_unsetenv (const char *name);
|
||||||
|
@ -50,3 +50,18 @@ assert_migrated()
|
|||||||
setup_home
|
setup_home
|
||||||
trigger_migration
|
trigger_migration
|
||||||
assert_migrated
|
assert_migrated
|
||||||
|
|
||||||
|
# Test with an existing private-keys-v1.d.
|
||||||
|
setup_home
|
||||||
|
mkdir "$GNUPGHOME/private-keys-v1.d"
|
||||||
|
trigger_migration
|
||||||
|
assert_migrated
|
||||||
|
|
||||||
|
# Test with an existing private-keys-v1.d with weird permissions.
|
||||||
|
setup_home
|
||||||
|
mkdir "$GNUPGHOME/private-keys-v1.d"
|
||||||
|
chmod 0 "$GNUPGHOME/private-keys-v1.d"
|
||||||
|
trigger_migration
|
||||||
|
assert_migrated
|
||||||
|
|
||||||
|
# XXX Check a case where the migration fails.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user