1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-23 10:29:58 +01:00

agent: Keep some permissions of private-keys-v1.d.

* common/sysutils.c (modestr_to_mode): Re-implement.
(gnupg_chmod): Support keeping of permissions.
--

GnuPG-bug-id: 2312
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-09-09 20:33:06 +02:00
parent 5b6cfef620
commit 7de9ed521e
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 55 additions and 27 deletions

View File

@ -2314,10 +2314,20 @@ create_private_keys_directory (const char *home)
fname, strerror (errno) ); fname, strerror (errno) );
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")) if (gnupg_chmod (fname, "-rwx"))
log_error (_("can't set permissions of '%s': %s\n"), log_error (_("can't set permissions of '%s': %s\n"),
fname, strerror (errno)); fname, strerror (errno));
}
else
{
/* The file exists or another error. Make sure we have sensible
* permissions. We enforce rwx for user but keep existing group
* permissions. Permissions for other are always cleared. */
if (gnupg_chmod (fname, "-rwx...---"))
log_error (_("can't set permissions of '%s': %s\n"),
fname, strerror (errno));
}
xfree (fname); xfree (fname);
} }

View File

@ -722,32 +722,37 @@ gnupg_rename_file (const char *oldname, const char *newname, int *block_signals)
#ifndef HAVE_W32_SYSTEM #ifndef HAVE_W32_SYSTEM
static mode_t static mode_t
modestr_to_mode (const char *modestr) modestr_to_mode (const char *modestr, mode_t oldmode)
{ {
static struct {
char letter;
mode_t value;
} table[] = { { '-', 0 },
{ 'r', S_IRUSR }, { 'w', S_IWUSR }, { 'x', S_IXUSR },
{ 'r', S_IRGRP }, { 'w', S_IWGRP }, { 'x', S_IXGRP },
{ 'r', S_IROTH }, { 'w', S_IWOTH }, { 'x', S_IXOTH } };
int idx;
mode_t mode = 0; mode_t mode = 0;
if (modestr && *modestr) /* For now we only support a string as used by ls(1) and no octal
* numbers. The first character must be a dash. */
for (idx=0; idx < 10 && *modestr; idx++, modestr++)
{ {
modestr++; if (*modestr == table[idx].letter)
if (*modestr && *modestr++ == 'r') mode |= table[idx].value;
mode |= S_IRUSR; else if (*modestr == '.')
if (*modestr && *modestr++ == 'w') {
mode |= S_IWUSR; if (!idx)
if (*modestr && *modestr++ == 'x') ; /* Skip the dummy. */
mode |= S_IXUSR; else if ((oldmode & table[idx].value))
if (*modestr && *modestr++ == 'r') mode |= (oldmode & table[idx].value);
mode |= S_IRGRP; else
if (*modestr && *modestr++ == 'w') mode &= ~(oldmode & table[idx].value);
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;
} }
else if (*modestr != '-')
break;
}
return mode; return mode;
} }
@ -790,7 +795,7 @@ gnupg_mkdir (const char *name, const char *modestr)
because this sets ERRNO. */ because this sets ERRNO. */
return mkdir (name); return mkdir (name);
#else #else
return mkdir (name, modestr_to_mode (modestr)); return mkdir (name, modestr_to_mode (modestr, 0));
#endif #endif
#else #else
/* Note that gpgrt_mkdir also sets ERRNO in addition to returing an /* Note that gpgrt_mkdir also sets ERRNO in addition to returing an
@ -818,7 +823,8 @@ gnupg_chdir (const char *name)
/* A wrapper around chmod which takes a string for the mode argument. /* A wrapper around chmod 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 the same defined on all systems. The format of the modestring is the same
as for gnupg_mkdir. */ as for gnupg_mkdir with extra feature that a '.' keeps the original
mode bit. */
int int
gnupg_chmod (const char *name, const char *modestr) gnupg_chmod (const char *name, const char *modestr)
{ {
@ -827,7 +833,19 @@ gnupg_chmod (const char *name, const char *modestr)
(void)modestr; (void)modestr;
return 0; return 0;
#else #else
return chmod (name, modestr_to_mode (modestr)); mode_t oldmode;
if (strchr (modestr, '.'))
{
/* Get the old mode so that a '.' can copy that bit. */
struct stat st;
if (stat (name, &st))
return -1;
oldmode = st.st_mode;
}
else
oldmode = 0;
return chmod (name, modestr_to_mode (modestr, oldmode));
#endif #endif
} }