static void try_make_homedir (const char *fname) { const char *defhome = standard_homedir (); /* Create the directory only if the supplied directory name is the same as the default one. This way we avoid to create arbitrary directories when a non-default home directory is used. To cope with HOME, we do compare only the suffix if we see that the default homedir does start with a tilde. */ if ( opt.dry_run || opt.no_homedir_creation ) return; if ( #ifdef HAVE_W32_SYSTEM ( !compare_filenames (fname, defhome) ) #else ( *defhome == '~' && (strlen(fname) >= strlen (defhome+1) && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) )) || (*defhome != '~' && !compare_filenames( fname, defhome ) ) #endif ) { if (gnupg_mkdir (fname, "-rwx")) log_info (_("can't create directory '%s': %s\n"), fname, strerror(errno) ); else if (!opt.quiet ) log_info (_("directory '%s' created\n"), fname); } }
/* Get and if needed create a string with the directory used to store openpgp revocations. */ char * get_openpgp_revocdir (const char *home) { char *fname; struct stat statbuf; fname = make_filename (home, GNUPG_OPENPGP_REVOC_DIR, NULL); if (stat (fname, &statbuf) && errno == ENOENT) { if (gnupg_mkdir (fname, "-rwx")) log_error (_("can't create directory '%s': %s\n"), fname, strerror (errno) ); else if (!opt.quiet) log_info (_("directory '%s' created\n"), fname); } return fname; }
void try_make_homedir (const char *fname) { const char *defhome = standard_homedir (); /* Create the directory only if the supplied directory name is the same as the default one. This way we avoid to create arbitrary directories when a non-default home directory is used. To cope with HOME, we do compare only the suffix if we see that the default homedir does start with a tilde. */ if ( opt.dry_run || opt.no_homedir_creation ) return; if ( #ifdef HAVE_W32_SYSTEM ( !compare_filenames (fname, defhome) ) #else ( *defhome == '~' && (strlen(fname) >= strlen (defhome+1) && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) )) || (*defhome != '~' && !compare_filenames( fname, defhome ) ) #endif ) { if (gnupg_mkdir (fname, "-rwx")) log_fatal ( _("can't create directory '%s': %s\n"), fname, strerror(errno) ); else if (!opt.quiet ) log_info ( _("directory '%s' created\n"), fname ); /* Note that we also copy a dirmngr.conf file here. This is because gpg is likely the first invoked tool and thus creates the directory. */ copy_options_file (fname, DIRMNGR_NAME); if (copy_options_file (fname, GPG_NAME)) log_info (_("WARNING: options in '%s'" " are not yet active during this run\n"), fname); } }
/* Helper for gnupg-socketdir. This is a global function, so that * gpgconf can use it for its --create-socketdir command. If * SKIP_CHECKS is set permission checks etc. are not done. The * function always returns a malloced directory name and stores these * bit flags at R_INFO: * * 1 := Internal error, stat failed, out of core, etc. * 2 := No /run/user directory. * 4 := Directory not owned by the user, not a directory * or wrong permissions. * 8 := Same as 4 but for the subdir. * 16 := mkdir failed * 32 := Non default homedir; checking subdir. * 64 := Subdir does not exist. * 128 := Using homedir as fallback. */ char * _gnupg_socketdir_internal (int skip_checks, unsigned *r_info) { #if defined(HAVE_W32_SYSTEM) || !defined(HAVE_STAT) char *name; (void)skip_checks; *r_info = 0; name = xstrdup (gnupg_homedir ()); #else /* Unix and stat(2) available. */ static const char * const bases[] = { "/run", "/var/run", NULL}; int i; struct stat sb; char prefix[13 + 1 + 20 + 6 + 1]; const char *s; char *name = NULL; *r_info = 0; /* First make sure that non_default_homedir can be set. */ gnupg_homedir (); /* It has been suggested to first check XDG_RUNTIME_DIR envvar. * However, the specs state that the lifetime of the directory MUST * be bound to the user being logged in. Now GnuPG may also be run * as a background process with no (desktop) user logged in. Thus * we better don't do that. */ /* Check whether we have a /run/user dir. */ for (i=0; bases[i]; i++) { snprintf (prefix, sizeof prefix, "%s/user/%u", bases[i], (unsigned int)getuid ()); if (!stat (prefix, &sb) && S_ISDIR(sb.st_mode)) break; } if (!bases[i]) { *r_info |= 2; /* No /run/user directory. */ goto leave; } if (sb.st_uid != getuid ()) { *r_info |= 4; /* Not owned by the user. */ if (!skip_checks) goto leave; } if (strlen (prefix) + 7 >= sizeof prefix) { *r_info |= 1; /* Ooops: Buffer too short to append "/gnupg". */ goto leave; } strcat (prefix, "/gnupg"); /* Check whether the gnupg sub directory has proper permissions. */ if (stat (prefix, &sb)) { if (errno != ENOENT) { *r_info |= 1; /* stat failed. */ goto leave; } /* Try to create the directory and check again. */ if (gnupg_mkdir (prefix, "-rwx")) { *r_info |= 16; /* mkdir failed. */ goto leave; } if (stat (prefix, &sb)) { *r_info |= 1; /* stat failed. */ goto leave; } } /* Check that it is a directory, owned by the user, and only the * user has permissions to use it. */ if (!S_ISDIR(sb.st_mode) || sb.st_uid != getuid () || (sb.st_mode & (S_IRWXG|S_IRWXO))) { *r_info |= 4; /* Bad permissions or not a directory. */ if (!skip_checks) goto leave; } /* If a non default homedir is used, we check whether an * corresponding sub directory below the socket dir is available * and use that. We has the non default homedir to keep the new * subdir short enough. */ if (non_default_homedir) { char sha1buf[20]; char *suffix; *r_info |= 32; /* Testing subdir. */ s = gnupg_homedir (); gcry_md_hash_buffer (GCRY_MD_SHA1, sha1buf, s, strlen (s)); suffix = zb32_encode (sha1buf, 8*15); if (!suffix) { *r_info |= 1; /* Out of core etc. */ goto leave; } name = strconcat (prefix, "/d.", suffix, NULL); xfree (suffix); if (!name) { *r_info |= 1; /* Out of core etc. */ goto leave; } /* Stat that directory and check constraints. Note that we * do not auto create such a directory because we would not * have a way to remove it. Thus the directory needs to be * pre-created. The command * gpgconf --create-socketdir * can be used tocreate that directory. */ if (stat (name, &sb)) { if (errno != ENOENT) *r_info |= 1; /* stat failed. */ else *r_info |= 64; /* Subdir does not exist. */ if (!skip_checks) { xfree (name); name = NULL; goto leave; } } else if (!S_ISDIR(sb.st_mode) || sb.st_uid != getuid () || (sb.st_mode & (S_IRWXG|S_IRWXO))) { *r_info |= 8; /* Bad permissions or subdir is not a directory. */ if (!skip_checks) { xfree (name); name = NULL; goto leave; } } } else name = xstrdup (prefix); leave: /* If nothing works fall back to the homedir. */ if (!name) { *r_info |= 128; /* Fallback. */ name = xstrdup (gnupg_homedir ()); } #endif /* Unix */ return name; }