⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cryptmount.c

📁 Cryptmount是对Linux系统下的文件系统以及用户设备、文档等进行加密的系统.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  cryptmount - a utility for user-level mounting of encrypted filesystems *  $Revision: 117 $, $Date: 2006-07-30 10:20:45 +0100 (Sun, 30 Jul 2006) $ *  Copyright 2005-2006 RW Penney *//*    This file is part of cryptmount    cryptmount is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    As a special exemption, permission is granted to link cryptmount    with the OpenSSL project's "OpenSSL" library and distribute    the linked code without invoking clause 2(b) of the GNU GPL version 2.    cryptmount is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with cryptmount; if not, write to the Free Software    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#include <config.h>#include <ctype.h>#include <fcntl.h>#include <getopt.h>#include <inttypes.h>#include <pwd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <sys/mount.h>#include <sys/stat.h>#include <sys/types.h>#ifdef HAVE_SYSLOG#  include <syslog.h>#endif#include "armour.h"#include "cryptmount.h"#include "delegates.h"#include "dmutils.h"#include "fsutils.h"#include "looputils.h"#include "tables.h"#ifdef TESTING#  include "cmtesting.h"#endifstruct targelt_t{    const cment_t *entry;    struct targelt_t *nx;};enum mode_t{    M_DEFAULT, M_HELP,    M_PREPARE, M_RELEASE,    M_MOUNT, M_UNMOUNT,    M_SWAPON, M_SWAPOFF,    M_LIST, M_PASSWORD, M_KEYGEN, M_VERSION};int execute_list(enum mode_t mode, const char *params,                const struct targelt_t *eltlist);int do_list(const cment_t *cment);int do_devsetup(const cment_t *cment, char **mntdev);int do_devshutdown(const cment_t *cment);int do_mount(const cment_t *cment);int do_unmount(const cment_t *cment);int do_swapon(const cment_t *cment);int do_swapoff(const cment_t *cment);int do_passwd(const cment_t *cment);int do_keygen(const cment_t *cment, const char *params);static const char *USAGE_STRING=N_("\usage: cryptmount [OPTION [target ...]]\n\\n\  available options are as follows:\n\\n\    -h | --help\n\    -a | --all\n\    -c | --change-password <target>\n\    -l | --list\n\    -m | --mount <target>\n\    -u | --unmount <target>\n\    --generate-key <key-size> <target>\n\    --prepare <target>\n\    --release <target>\n\    --swapon <target>\n\    --swapoff <target>\n\    --version\n\\n\  please report bugs to cryptmount@rwpenney.org.uk\n\");#ifdef TESTING/* allow config-file & password to be specified via command-line,    to enable automatic testing: */const char *argconfigdir=NULL;const char *argpassword[]={ NULL, NULL };#endifint do_list(const cment_t *cment)    /* print list of available filing-system targets */{    printf(_("%-16s  [to mount on \"%s\" as \"%s\"]\n"),            cment->ident, cment->dir, cment->fstype);    return ERR_NOERROR;}int do_devsetup(const cment_t *cment, char **mntdev)    /* setup all devices needed to access encrypted target */{   enum { BUFFMIN=1024 };    unsigned char *key=NULL;    int i,fd=-1,killloop=0,keylen=0,eflag=ERR_NOERROR;    long devlen=0,fslen=0;    struct stat sbuff;    char *dmparams=NULL,*tgtdev=NULL,*loopdev=NULL;    /* get crypto-key for filing system: */    eflag = get_key(cment->ident, &cment->key, &key, &keylen);    if (eflag != ERR_NOERROR) {        fprintf(stderr, _("failed to extract cipher key\n"));        goto bail_out;    }    if (cment->dev == NULL || stat(cment->dev, &sbuff) != 0) {        fprintf(stderr, _("cannot stat device \"%s\" for target \"%s\"\n"),                (cment->dev != NULL ? cment->dev : "(NULL)"), cment->ident);        eflag = ERR_BADDEVICE;        goto bail_out;    }    /* check whether using raw device or loopback to file: */    if (S_ISBLK(sbuff.st_mode)) {        tgtdev = cment->dev;    } else if (S_ISREG(sbuff.st_mode)) {        if (cment->loopdev != NULL && strcmp(cment->loopdev, "auto") != 0) {            loopdev = (char*)malloc((size_t)(strlen(cment->loopdev) + 1));            strcpy(loopdev, cment->loopdev);        } else {            loopdev = (char*)malloc((size_t)BUFFMIN);            if (loop_findfree(loopdev, BUFFMIN) != 0) {                fprintf(stderr, _("no available loopback devices\n"));                eflag = ERR_BADDEVICE;                goto bail_out;            }        }        eflag = loop_setup(loopdev, cment->dev,                        (is_readonlyfs(cment->dev) ? O_RDONLY : O_RDWR));        tgtdev = loopdev;    } else {        fprintf(stderr,            _("bad device type (%x) for \"%s\" (need block/file)\n"),            (unsigned)sbuff.st_mode, cment->dev);        tgtdev = NULL;        eflag = ERR_BADDEVICE;        goto bail_out;    }    /* get size in blocks of target device: */    fd = open(tgtdev, O_RDONLY);    if (ioctl(fd, BLKGETSIZE, &devlen) != 0) {        fprintf(stderr, _("failed to get size of \"%s\"\n"), tgtdev);        eflag = ERR_BADIOCTL;        goto bail_out;    }    if (cment->length < 0 || (cment->start + cment->length) > devlen) {        fslen = devlen - cment->start;    } else {        fslen = cment->length;    }    if (cment->start < 0 || fslen <= 0) {        fprintf(stderr, _("bad device-mapper start/length (%ld,%ld)\n"),                cment->start, cment->length);        eflag = ERR_BADDEVICE;        goto bail_out;    }    /* setup device-mapper crypt table (CIPHER KEY IV_OFFSET DEV START): */    dmparams = sec_realloc(dmparams, (size_t)(2 * keylen + BUFFMIN));    i = sprintf(dmparams, "%s ",                (cment->cipher != NULL ? cment->cipher : DFLT_CIPHER));    mk_key_string(key, keylen, dmparams + i);    sprintf(dmparams + strlen(dmparams), " %ld %s %ld",                cment->ivoffset, tgtdev, cment->start);    /* setup device-mapper target: */    eflag = devmap_create(cment->ident,            (uint64_t)0, (uint64_t)fslen, "crypt", dmparams);    if (eflag != ERR_NOERROR) {        fprintf(stderr,            _("device-mapper target-creation failed for \"%s\"\n"),            cment->ident);        killloop = 1;        goto bail_out;    }    if (mntdev != NULL) {        devmap_path(mntdev, cment->ident);    }  bail_out:    if (fd != -1) close(fd);    if (loopdev != NULL) {        if (killloop) loop_destroy(loopdev);    /* mounting failed? */        free((void*)loopdev);    }    sec_free(dmparams);    sec_free(key);    return eflag;}   /* do_devsetup() */int do_devshutdown(const cment_t *cment)    /* remove all devices attached to encrypted target */{   struct stat sbuff;    unsigned i,devcnt=0;    int eflag=ERR_NOERROR;    dev_t *devids=NULL;    char buff[256];    /* check if filing system has been configured at all: */    if (!is_configured(cment->ident, NULL)) {        fprintf(stderr, _("target \"%s\" does not appear to be configured\n"),                        cment->ident);        eflag = WRN_UNCONFIG;        goto bail_out;    }    /* find any underlying (e.g. loopback) devices for device-mapper target: */    (void)devmap_dependencies(cment->ident, &devcnt, &devids);#ifdef DEBUG    fprintf(stderr, "shutting down %s [%u dependencies]\n",            cment->ident, devcnt);#endif    if (stat(cment->dev, &sbuff) != 0) {        fprintf(stderr, _("cannot stat \"%s\"\n"), cment->dev);        eflag = ERR_BADDEVICE;        goto bail_out;    }    /* remove demice-mapper target: */    eflag = devmap_remove(cment->ident);    if (eflag != ERR_NOERROR) {        fprintf(stderr, _("failed to remove device-mapper target \"%s\"\n"),            cment->ident);        goto bail_out;    }    /* tidy-up any associated loopback devices: */    if (S_ISREG(sbuff.st_mode) && devids != NULL) {        for (i=0; i<devcnt; ++i) {            if (loop_ident(major(devids[i]),minor(devids[i]),buff,sizeof(buff)) || (loop_destroy(buff) != ERR_NOERROR)) {                fprintf(stderr, _("failed to free device (%d,%d)\n"),                        major(devids[i]), minor(devids[i]));            }        }    }  bail_out:    if (devids != NULL) free((void*)devids);    return eflag;}int do_mount(const cment_t *cment){   int freedev=0,eflag=ERR_NOERROR;    char *mntdev=NULL;    tgtstat_t *tstat;    if (is_mounted(cment)) {        fprintf(stderr, _("target \"%s\" is already mounted\n"), cment->ident);        eflag = ERR_BADMOUNT;        goto bail_out;    }    eflag = do_devsetup(cment, &mntdev);    if (eflag != ERR_NOERROR) goto bail_out;#if WITH_FSCK    if ((cment->flags & FLG_FSCK) != 0) {        if (fs_check(mntdev, cment) != ERR_NOERROR) {            freedev = 1; eflag = ERR_BADMOUNT;            goto bail_out;        }    }#endif    if (fs_mount(mntdev, cment) != ERR_NOERROR) {        freedev = 1; eflag = ERR_BADMOUNT;        goto bail_out;    }    tstat = alloc_tgtstatus(cment);    tstat->uid = (unsigned long)getuid();    put_tgtstatus(cment, tstat);    free_tgtstatus(tstat);  bail_out:    if (freedev) {        /* tidy-up debris if mount failed */        do_devshutdown(cment);    }    if (mntdev != NULL) free((void*)mntdev);    return eflag;}int do_unmount(const cment_t *cment){   int eflag=ERR_NOERROR;    struct passwd *pwent;    char *mntdev=NULL;    tgtstat_t *tstat;    /* check if filing system has been configured at all: */    if (!is_mounted(cment) || (tstat = get_tgtstatus(cment)) == NULL) {        fprintf(stderr, _("target \"%s\" does not appear to be mounted\n"),                        cment->ident);        eflag = WRN_UNCONFIG;        goto bail_out;    }    /* check if filing system has been mounted & locked by another user: */    if (getuid() != 0 && (uid_t)tstat->uid != getuid()) {        pwent = getpwuid((uid_t)tstat->uid);        if (pwent != NULL) {            fprintf(stderr, _("only \"%s\" can unmount \"%s\"\n"),                pwent->pw_name, cment->ident);        } else {            fprintf(stderr, _("only user-%lu can unmount \"%s\"\n"),                tstat->uid, cment->ident);        }        eflag = ERR_BADPRIV;        goto bail_out;    }    /* unmount filing system: */    if (fs_unmount(cment) != ERR_NOERROR) {        eflag = ERR_BADMOUNT;        goto bail_out;    }    put_tgtstatus(cment, NULL);    /* remove supporting device-mapper target etc */    if (do_devshutdown(cment) != ERR_NOERROR) {        eflag = ERR_BADDEVICE;    }  bail_out:    if (mntdev != NULL) free((void*)mntdev);    return eflag;}int do_swapon(const cment_t *cment){   int freedev=0,eflag=ERR_NOERROR;    char *mntdev=NULL;    tgtstat_t *tstat;#if WITH_CSWAP    eflag = do_devsetup(cment, &mntdev);    if (eflag != ERR_NOERROR) goto bail_out;    if (fs_swapon(mntdev, cment) != ERR_NOERROR) {        freedev = 1;        eflag = ERR_BADSWAP;        goto bail_out;    }    tstat = alloc_tgtstatus(cment);    tstat->uid = (unsigned long)getuid();    put_tgtstatus(cment, tstat);    free_tgtstatus(tstat);#else   /* !WITH_CSWAP */    fprintf(stderr, _("crypto-swap is not supported by this installation of cryptmount\n"));    eflag = ERR_BADSWAP;#endif  bail_out:    if (freedev) {        /* tidy-up debris if swapon failed */        do_devshutdown(cment);    }    if (mntdev != NULL) free((void*)mntdev);    return eflag;}int do_swapoff(const cment_t *cment){   int eflag=ERR_NOERROR;    char *mntdev=NULL;    tgtstat_t *tstat;#if WITH_CSWAP    /* check if device has been configured at all: */    if ((tstat = get_tgtstatus(cment)) == NULL) {        fprintf(stderr, _("target \"%s\" does not appear to be configured\n"),                        cment->ident);        eflag = WRN_UNCONFIG;        goto bail_out;    }    /* remove swap-partition: */    if (fs_swapoff(cment) != ERR_NOERROR) {        eflag = ERR_BADSWAP;        goto bail_out;    }    put_tgtstatus(cment, NULL);    /* remove supporting device-mapper target etc */    if (do_devshutdown(cment) != ERR_NOERROR) {        eflag = ERR_BADDEVICE;    }#else   /* !WITH_CSWAP */    fprintf(stderr, _("crypto-swap is not supported by this installation of cryptmount\n"));    eflag = ERR_BADSWAP;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -