aboutsummaryrefslogtreecommitdiffstats
path: root/g10/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/misc.c')
-rw-r--r--g10/misc.c54
1 files changed, 40 insertions, 14 deletions
diff --git a/g10/misc.c b/g10/misc.c
index 9240f12e7..acbd78d88 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -339,35 +339,53 @@ openpgp_md_test_algo( int algo )
}
int
-check_permissions(const char *path,int checkonly)
+check_permissions(const char *path,int extension,int checkonly)
{
#if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
-
+ char *tmppath;
struct stat statbuf;
+ int ret=1;
int isdir=0;
if(opt.no_perm_warn)
return 0;
+ if(extension && path[0]!=DIRSEP_C)
+ {
+ if(strchr(path,DIRSEP_C))
+ tmppath=make_filename(path,NULL);
+ else
+ tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
+ }
+ else
+ tmppath=m_strdup(path);
+
/* It's okay if the file doesn't exist */
- if(stat(path,&statbuf)!=0)
- return 0;
+ if(stat(tmppath,&statbuf)!=0)
+ {
+ ret=0;
+ goto end;
+ }
isdir=S_ISDIR(statbuf.st_mode);
- /* The user doesn't own the file */
- if(statbuf.st_uid != getuid())
+ /* Per-user files must be owned by the user. Extensions must be
+ owned by the user or root. */
+ if((!extension && statbuf.st_uid != getuid()) ||
+ (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid()))
{
if(!checkonly)
log_info(_("Warning: unsafe ownership on %s \"%s\"\n"),
- isdir?"directory":"file",path);
- return 1;
+ isdir?"directory":extension?"extension":"file",path);
+ goto end;
}
/* This works for both directories and files - basically, we don't
care what the owner permissions are, so long as the group and
- other permissions are 0. */
- if((statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0)
+ other permissions are 0 for per-user files, and non-writable for
+ extensions. */
+ if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) ||
+ (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0))
{
char *dir;
@@ -377,22 +395,30 @@ check_permissions(const char *path,int checkonly)
directory /, but for the sake of sanity, I'm stopping at one
level down. */
- dir=make_dirname(path);
+ dir=make_dirname(tmppath);
if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() &&
S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
{
m_free(dir);
- return 0;
+ ret=0;
+ goto end;
}
m_free(dir);
if(!checkonly)
log_info(_("Warning: unsafe permissions on %s \"%s\"\n"),
- isdir?"directory":"file",path);
- return 1;
+ isdir?"directory":extension?"extension":"file",path);
+ goto end;
}
+ ret=0;
+
+ end:
+ m_free(tmppath);
+
+ return ret;
+
#endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
return 0;