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

📄 armour.c

📁 Cryptmount是对Linux系统下的文件系统以及用户设备、文档等进行加密的系统.
💻 C
📖 第 1 页 / 共 3 页
字号:
    { NULL, 0,   NULL, NULL,   NULL, NULL,                NULL, NULL,   NULL, NULL, NULL, NULL }};keymanager_t *get_keymanager(const struct keyinfo *keyinfo)    /* search for keymanager that supports given key */{   keymanager_t *km;    int is_raw;    if (keyinfo == NULL) return NULL;    is_raw = (strcmp(keyinfo->cipheralg, "none") == 0);    for (km=keymgrs; km->ident!=NULL; ++km) {        if (is_raw && strcmp(km->ident, "raw") != 0) continue;        if (km->is_compat(keyinfo)) {            return init_keymanager(km);        }    }    return NULL;}keymanager_t *init_keymanager(keymanager_t *km){    if (km != NULL) {        if (!km->initialized) {            km->init_algs();    /* FIXME - check return status */            km->initialized = 1;        }    }    return km;}int free_keymanagers(){   keymanager_t *km;    for (km=keymgrs; km->ident!=NULL; ++km) {        if (km->initialized) {            km->free_algs();            km->initialized = 0;        }    }    return 0;}int km_get_passwd(const char *ident, char **passwd, int new, int verify)    /* read password from terminal, possibly asking for confirmation */{   enum { BUFFSZ=2048 };    char *tmppass,buff[BUFFSZ];    size_t plen;    int eflag=ERR_NOERROR;    snprintf(buff, sizeof(buff),            (new ? _("enter new password for target \"%s\": ")                : _("enter password for target \"%s\": ")),            ident);    tmppass = getpass(buff);    plen = strlen(tmppass);    *passwd = (char*)sec_realloc((void*)*passwd, (plen + 1));    strcpy(*passwd, tmppass);    mem_cleanse((unsigned char*)tmppass, plen + 1);    if (verify) {        snprintf(buff, sizeof(buff), _("confirm password: "));        tmppass = getpass(buff);        plen = strlen(tmppass);        if (strcmp(*passwd, tmppass) != 0) {            fprintf(stderr, _("password mismatch\n"));            sec_free(*passwd);            *passwd = NULL;            eflag = ERR_BADPASSWD;        }        mem_cleanse((unsigned char*)tmppass, plen);    }    return eflag;}int get_key(const char *ident, const keyinfo_t *keyinfo,            unsigned char **key, int *keylen){   keymanager_t *km;    FILE *fp=NULL;    int eflag=ERR_NOERROR;    if (keyinfo == NULL || keyinfo->filename == NULL) {        fprintf(stderr, _("missing key-file for target \"%s\"\n"), ident);        eflag = ERR_BADFILE;        goto bail_out;    }    if ((km = get_keymanager(keyinfo)) != NULL) {        if ((fp=fopen(keyinfo->filename, "rb")) == NULL) {            fprintf(stderr,                _("failed to open keyfile \"%s\" for target \"%s\"\n"),                keyinfo->filename, ident);            eflag = ERR_BADFILE;            goto bail_out;        }        eflag = km->get_key(ident, keyinfo, key, keylen, fp);    } else {        fprintf(stderr,                _("unrecognized key format for target \"%s\"\n"), ident);        eflag = ERR_BADKEYFORMAT;    }  bail_out:    if (fp != NULL) fclose(fp);    return eflag;}int put_key(const char *ident, const keyinfo_t *keyinfo,            const unsigned char *key, const int keylen, FILE *fp_key){   keymanager_t *km;    if (fp_key == NULL) {        fprintf(stderr, _("missing output stream for target \"%s\"\n"), ident);        return ERR_BADFILE;    }    if ((km = get_keymanager(keyinfo)) != NULL) {        return km->put_key(ident, keyinfo, key, keylen, fp_key);    }    return ERR_BADKEYFORMAT;}int is_keysafe(const keyinfo_t *keyinfo)    /* check whether key is stored in encrypted form */{    return (keyinfo != NULL && keyinfo->cipheralg != NULL && strcmp(keyinfo->cipheralg, "none") != 0);}int get_randkey(unsigned char *buff, unsigned len)    /* generate random string of bytes */{   struct rnddev {        const char *name;        unsigned devmaj, devmin;        FILE *fp; };    struct rnddev devs[] = {        { "/dev/hwrng",     MISC_MAJOR, 183,    NULL },        { "/dev/random",    MEM_MAJOR, 8,       NULL },        { "/dev/urandom",   MEM_MAJOR, 9,       NULL },        { NULL, 0, 0, NULL } };    keymanager_t *kmgr=NULL;    void *mdcontext=NULL;    unsigned char *mdval,*devbuff=NULL;    unsigned pos,sz,mdlen;    int i,cnt,eflag=ERR_NOERROR;    struct stat sbuff;    pid_t pid;    struct tms tbuff;    clock_t clk;    static unsigned seed=17;    /* assume first entry in key-manager list is decent quality: */    kmgr = init_keymanager(keymgrs);    /* try to find good-quality random-number devices: */    for (i=0,cnt=0; devs[i].name!=NULL; ++i) {        if (stat(devs[i].name, &sbuff) != 0) continue;        if ((unsigned)major(sbuff.st_rdev) != devs[i].devmaj          || (unsigned)minor(sbuff.st_rdev) != devs[i].devmin) continue;        if ((devs[i].fp = fopen(devs[i].name,"rb")) != NULL) ++cnt;    }    if (cnt == 0) {        fprintf(stderr, _("no random-number devices found"));        eflag = WRN_LOWENTROPY;    }    devbuff = (unsigned char*)sec_realloc(NULL, (size_t)len);    pid = getpid();    /*  combine multiple sources of entropy        (should still be effective if subset aren't viable): */    pos = 0;    while (pos < len) {        mdcontext = kmgr->md_prepare();        /* fold-in entropy from random-number devices: */        for (i=0; devs[i].name!=NULL; ++i) {            if (devs[i].fp == NULL) continue;            (void)fread((void*)devbuff, 1, (size_t)len, devs[i].fp);            kmgr->md_block(mdcontext, devbuff, len);        }        /* fold-in some (weak) sources of entropy: */        kmgr->md_block(mdcontext, (unsigned char*)&pid, sizeof(pid));        clk = times(&tbuff);        kmgr->md_block(mdcontext, (unsigned char*)&clk, sizeof(clk));        kmgr->md_block(mdcontext, (unsigned char*)&seed, sizeof(seed));        kmgr->md_block(mdcontext, (unsigned char*)&tbuff, sizeof(tbuff));        kmgr->md_final(mdcontext, &mdval, &mdlen);        sz = ((pos + mdlen) > len ? (len - pos) : mdlen);        memcpy((void*)(buff + pos),(const void*)mdval, (size_t)sz);        pos += sz;        seed = seed * 20 + 1;        kmgr->md_release(mdcontext);    }    sec_free((void*)devbuff);    for (i=0; devs[i].name!=NULL; ++i) {        if (devs[i].fp != NULL) fclose(devs[i].fp);    }    return eflag;}#ifdef TESTINGint km_test_keyrw()    /* test key read-writing (creation/extraction) */{   enum { MAXKEY=256 };    keymanager_t *km;    keyinfo_t keyinfo;    int i,keylen,keylen1;    char str[256];    unsigned char key0[MAXKEY],*key1=NULL;    FILE *fp;    CM_TEST_START("key read-write");    for (km=keymgrs; km->ident!=NULL; ++km) {        keyinfo.format = NULL;        keyinfo.filename = "NOWHERE";        keyinfo.digestalg = NULL;        keyinfo.cipheralg = NULL;        keyinfo.maxlen = -1;        km->mk_default(&keyinfo);        km->init_algs();        for (keylen=1; keylen<=MAXKEY; keylen<<=2) {            sprintf(str, "key read-write, %s, keylen=%d",                km->ident, keylen);            CM_TEST_IDENT(str);            /* generate (low-entropy) key: */            for (i=0; i<keylen; ++i) {                key0[i] = (i * 0x9d) ^ ((keylen * (unsigned long)km) % 253);            }            /* write key to file: */            fp = tmpfile();            if (fp == NULL) CM_TEST_ABORT();            i = km->put_key("TEST-OUT", &keyinfo, key0, keylen, fp);            CM_ASSERT_EQUAL(ERR_NOERROR, i);            key1 = NULL; keylen1 = -keylen;            /* try reading key back from file: */            rewind(fp);            i = km->get_key("TEST-IN", &keyinfo, &key1, &keylen1, fp);            CM_ASSERT_EQUAL(ERR_NOERROR, i);            CM_ASSERT_EQUAL(keylen, keylen1);            CM_ASSERT_DIFFERENT(key0, key1);            CM_ASSERT_DIFFERENT(NULL, key1);            for (i=0; i<keylen; ++i) {                CM_ASSERT_EQUAL(key0[i], key1[i]);            }            fclose(fp);            sec_free(key1);        }        km->free_algs();        free((void*)keyinfo.cipheralg);        free((void*)keyinfo.digestalg);    }    CM_TEST_OK();}#endif  /* TESTING *//* *  ==== miscellaneous routines ==== */void *sec_realloc(void *ptr, size_t size)    /* slightly more secure version of realloc() */{   unsigned char *addr=NULL;    addr = (unsigned char*)malloc(size + sizeof(size_t));    if (addr == NULL) {        fprintf(stderr, _("unable to allocated memory\n"));        abort();        return NULL;    }    /* prepend usable memory chunk with record of size of chunk: */    *((size_t*)addr) = size;    addr += sizeof(size_t);    if (ptr != NULL) {        unsigned char *old;        unsigned i,oldsz;        /* copy (usable) part of old memory block into new: */        old = (unsigned char*)ptr;        oldsz = *((size_t*)(old - sizeof(size_t)));        if (oldsz > size) oldsz = size;        for (i=0; i<oldsz; ++i) addr[i] = old[i];        /* dispose of old memory block: */        sec_free(ptr);    }    return (void*)addr;}void mem_cleanse(unsigned char *addr, size_t sz)    /* overwrite memory with (weak) pseudo-random numbers */{   size_t i;    static unsigned long salt=0x917c;    salt ^= (unsigned long)addr;    for (i=0; i<sz; ++i) {        addr[i] = (i % 21) ^ (salt % 221);        salt += 4;    }}void sec_free(void *ptr)    /* slightly more secure version of free() */{   unsigned char *addr;    size_t sz;    if (ptr == NULL) return;    addr = (unsigned char*)ptr;    sz = *((size_t*)(addr - sizeof(size_t)));    mem_cleanse(addr, sz);    free((void*)(addr - sizeof(size_t)));}int mk_key_string(const unsigned char *key, const int keylen, char *buff)    /* create text version of crypto key */{   int i;    for (i=0; i<keylen; ++i) {        sprintf(buff+2*i, "%02x", key[i]);    }    return (2 * keylen);}int sycheck_cmtab(const char *cmtab)    /* check that permissions on ${sysconfdir}/cryptmount/cmtab are sensible */{   struct stat sfile,sdir;    char *dirname=NULL;    int pos,eflag=ERR_NOERROR;    /* extract directory name from cmtab filename: */    pos = strlen(cmtab);    dirname = (char*)malloc((size_t)(pos + 1));    for ( ; pos>0 && cmtab[pos-1] != '/'; --pos) dirname[pos] = '\0';    while (--pos >= 0) dirname[pos] = cmtab[pos];    if (stat(cmtab,&sfile) != 0 || stat(dirname,&sdir) != 0) {        fprintf(stderr, "cannot open \"%s\" or \"%s\"\n", cmtab, dirname);        eflag = ERR_INSECURE;        goto bail_out;    }    /* check file/directory ownerships: */    if (sfile.st_uid != (uid_t)0 || sdir.st_uid != (uid_t)0) {        fprintf(stderr, "\"%s\" and \"%s\" must be owned by root\n",                cmtab, dirname);        eflag = ERR_INSECURE;        goto bail_out;    }    /* check that file isn't globally writable: */    if (!S_ISREG(sfile.st_mode) || (sfile.st_mode & S_IWOTH) != 0) {        fprintf(stderr, "lax permissions on \"%s\"\n", cmtab);        eflag = ERR_INSECURE;        goto bail_out;    }    /* check that directory isn't globally writable: */    if (!S_ISDIR(sdir.st_mode) || (sdir.st_mode & S_IWOTH) != 0) {        fprintf(stderr, "lax permissions on \"%s\"\n", dirname);        eflag = ERR_INSECURE;        goto bail_out;    }  bail_out:    if (dirname != NULL) free((void*)dirname);    return eflag;}static int sy_path(const char *path)    /* check whether pathname is considered secure */{    if (path == NULL) return ERR_NOERROR;    if (path[0] == '/') return ERR_NOERROR;    return ERR_INSECURE;}int sycheck_target(const cment_t *cment)    /* check that paths within target-specification are sensible */{   int eflag=ERR_NOERROR;    if (cment == NULL) return 0;    eflag |= sy_path(cment->dev);    eflag |= sy_path(cment->dir);    eflag |= sy_path(cment->key.filename);    if (eflag != ERR_NOERROR) {        fprintf(stderr, "specification for target \"%s\" contains non-absolute pathname\n", cment->ident);    }    return eflag;}/* *  ==== mutex-locking on configuration directory ==== */int cm_mutex_lock()    /* try to acquire lock on configuration directory (via symlink marker) */{   char *fname=NULL,ident[64];    int tries=3,eflag=1;    (void)cm_path(&fname, "_lock_");    sprintf(ident, "%u-%u", (unsigned)getpid(), (unsigned)getuid());    while (tries-->0) {        if (symlink(ident, fname) == 0) {            /* lock acquired */            eflag = 0; break;        } else {            if (errno == EEXIST) sleep(1);  /* try again later */            else break;     /* failed to make link for more peculiar reason */        }    }    if (eflag != 0) {        fprintf(stderr, "failed to create lock-file \"%s\"\n", fname);    }    free((void*)fname);    return eflag;}int cm_mutex_unlock()    /* release lock on configuration directory */{   char *fname=NULL;    struct stat sbuff;    int eflag=0;    (void)cm_path(&fname, "_lock_");    if (lstat(fname, &sbuff) != 0      || !S_ISLNK(sbuff.st_mode)      || unlink(fname) != 0) {        fprintf(stderr, "failed to remove lock-file \"%s\"\n", fname);        eflag = 1;    }    free((void*)fname);    return eflag;}/* *  (C)Copyright 2005-2006, RW Penney */

⌨️ 快捷键说明

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