/* Create the container described by the filename FNAME and the keyblob information in TUPLES. */ gpg_error_t be_encfs_create_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples, unsigned int *r_id) { gpg_error_t err; int dummy; char *containername = NULL; char *mountpoint = NULL; err = be_encfs_get_detached_name (fname, &containername, &dummy); if (err) goto leave; mountpoint = xtrystrdup ("/tmp/.#g13_XXXXXX"); if (!mountpoint) { err = gpg_error_from_syserror (); goto leave; } if (!gnupg_mkdtemp (mountpoint)) { err = gpg_error_from_syserror (); log_error (_("can't create directory '%s': %s\n"), "/tmp/.#g13_XXXXXX", gpg_strerror (err)); goto leave; } err = run_encfs_tool (ctrl, ENCFS_CMD_CREATE, containername, mountpoint, tuples, r_id); /* In any case remove the temporary mount point. */ if (rmdir (mountpoint)) log_error ("error removing temporary mount point '%s': %s\n", mountpoint, gpg_strerror (gpg_error_from_syserror ())); leave: xfree (containername); xfree (mountpoint); return err; }
/* Mount the container with name FILENAME at MOUNTPOINT. */ gpg_error_t g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint) { gpg_error_t err; dotlock_t lock; void *enckeyblob = NULL; size_t enckeybloblen; void *keyblob = NULL; size_t keybloblen; tupledesc_t tuples = NULL; size_t n; const unsigned char *value; int conttype; unsigned int rid; char *mountpoint_buffer = NULL; /* A quick check to see whether the container exists. */ if (access (filename, R_OK)) return gpg_error_from_syserror (); if (!mountpoint) { mountpoint_buffer = xtrystrdup ("/tmp/g13-XXXXXX"); if (!mountpoint_buffer) return gpg_error_from_syserror (); if (!gnupg_mkdtemp (mountpoint_buffer)) { err = gpg_error_from_syserror (); log_error (_("can't create directory '%s': %s\n"), "/tmp/g13-XXXXXX", gpg_strerror (err)); xfree (mountpoint_buffer); return err; } mountpoint = mountpoint_buffer; } /* Try to take a lock. */ lock = dotlock_create (filename, 0); if (!lock) { xfree (mountpoint_buffer); return gpg_error_from_syserror (); } if (dotlock_take (lock, 0)) { err = gpg_error_from_syserror (); goto leave; } else err = 0; /* Check again that the file exists. */ { struct stat sb; if (stat (filename, &sb)) { err = gpg_error_from_syserror (); goto leave; } } /* Read the encrypted keyblob. */ err = read_keyblob (filename, &enckeyblob, &enckeybloblen); if (err) goto leave; /* Decrypt that keyblob and store it in a tuple descriptor. */ err = decrypt_keyblob (ctrl, enckeyblob, enckeybloblen, &keyblob, &keybloblen); if (err) goto leave; xfree (enckeyblob); enckeyblob = NULL; err = create_tupledesc (&tuples, keyblob, keybloblen); if (!err) keyblob = NULL; else { if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED) log_error ("unknown keyblob version\n"); goto leave; } if (opt.verbose) dump_keyblob (tuples); value = find_tuple (tuples, KEYBLOB_TAG_CONTTYPE, &n); if (!value || n != 2) conttype = 0; else conttype = (value[0] << 8 | value[1]); if (!be_is_supported_conttype (conttype)) { log_error ("content type %d is not supported\n", conttype); err = gpg_error (GPG_ERR_NOT_SUPPORTED); goto leave; } err = be_mount_container (ctrl, conttype, filename, mountpoint, tuples, &rid); if (!err) { err = mountinfo_add_mount (filename, mountpoint, conttype, rid, !!mountpoint_buffer); /* Fixme: What shall we do if this fails? Add a provisional mountinfo entry first and remove it on error? */ if (!err) { char *tmp = percent_plus_escape (mountpoint); if (!tmp) err = gpg_error_from_syserror (); else { g13_status (ctrl, STATUS_MOUNTPOINT, tmp, NULL); xfree (tmp); } } } leave: destroy_tupledesc (tuples); xfree (keyblob); xfree (enckeyblob); dotlock_destroy (lock); xfree (mountpoint_buffer); return err; }
/* Makes a temp directory and filenames */ static int make_tempdir(struct exec_info *info) { char *tmp=opt.temp_dir,*namein=info->name,*nameout; if(!namein) namein=info->flags.binary?"tempin" EXTSEP_S "bin":"tempin" EXTSEP_S "txt"; nameout=info->flags.binary?"tempout" EXTSEP_S "bin":"tempout" EXTSEP_S "txt"; /* Make up the temp dir and files in case we need them */ if(tmp==NULL) { #if defined (_WIN32) int err; tmp=xmalloc(MAX_PATH+2); err=GetTempPath(MAX_PATH+1,tmp); if(err==0 || err>MAX_PATH+1) strcpy(tmp,"c:\\windows\\temp"); else { int len=strlen(tmp); /* GetTempPath may return with \ on the end */ while(len>0 && tmp[len-1]=='\\') { tmp[len-1]='\0'; len--; } } #else /* More unixish systems */ tmp=getenv("TMPDIR"); if(tmp==NULL) { tmp=getenv("TMP"); if(tmp==NULL) { #ifdef __riscos__ tmp="<Wimp$ScrapDir>.GnuPG"; mkdir(tmp,0700); /* Error checks occur later on */ #else tmp="/tmp"; #endif } } #endif } info->tempdir=xmalloc(strlen(tmp)+strlen(DIRSEP_S)+10+1); sprintf(info->tempdir,"%s" DIRSEP_S "gpg-XXXXXX",tmp); #if defined (_WIN32) xfree(tmp); #endif if (!gnupg_mkdtemp(info->tempdir)) log_error(_("can't create directory '%s': %s\n"), info->tempdir,strerror(errno)); else { info->flags.madedir=1; info->tempfile_in=xmalloc(strlen(info->tempdir)+ strlen(DIRSEP_S)+strlen(namein)+1); sprintf(info->tempfile_in,"%s" DIRSEP_S "%s",info->tempdir,namein); if(!info->flags.writeonly) { info->tempfile_out=xmalloc(strlen(info->tempdir)+ strlen(DIRSEP_S)+strlen(nameout)+1); sprintf(info->tempfile_out,"%s" DIRSEP_S "%s",info->tempdir,nameout); } } return info->flags.madedir? 0 : GPG_ERR_GENERAL; }