📄 cryptmount.c
字号:
bail_out: if (mntdev != NULL) free((void*)mntdev); return eflag;}int do_passwd(const cment_t *cment){ unsigned char *key=NULL; int keylen=0,eflag=ERR_NOERROR; char *newfname=NULL,*oldfname=NULL; struct stat sbuff; size_t sz; FILE *fp; if (!is_keysafe(&cment->key)) { fprintf(stderr, _("key-file for \"%s\" isn't password-protected\n"), cment->ident); eflag = WRN_NOPASSWD; goto bail_out; } eflag = get_key(cment->ident, &cment->key, &key, &keylen); if (eflag != ERR_NOERROR) goto bail_out; sz = strlen(cment->key.filename) + 16; oldfname = (char*)malloc(2 * sz); newfname = oldfname + sz; snprintf(oldfname, sz, "%s-old", cment->key.filename); snprintf(newfname, sz, "%s-new", cment->key.filename); fp = fopen(newfname, "wb"); if (fp == NULL) { fprintf(stderr, _("cannot open \"%s\" for writing\n"), newfname); eflag = ERR_BADFILE; goto bail_out; } eflag = put_key(cment->ident, &cment->key, key, keylen, fp); fclose(fp); if (eflag == ERR_NOERROR) { /* FIXME - check return codes */ (void)stat(cment->key.filename, &sbuff); (void)rename(cment->key.filename, oldfname); (void)chown(oldfname, 0, 0); (void)chmod(oldfname, S_IRUSR | S_IWUSR); (void)rename(newfname, cment->key.filename); (void)chown(cment->key.filename, sbuff.st_uid, sbuff.st_gid); (void)chmod(cment->key.filename, sbuff.st_mode); newfname = NULL; fprintf(stderr, _("backup of previous key is in \"%s\"\n"), oldfname); } bail_out: if (newfname != NULL) { unlink(newfname); } if (oldfname != NULL) free((void*)oldfname); return eflag;}int do_keygen(const cment_t *cment, const char *params){ unsigned char *key=NULL; int keylen=0,eflag=ERR_NOERROR; char *fname=NULL; size_t sz; struct stat sbuff; FILE *fp; if (params == NULL || sscanf(params, "%i", &keylen) != 1 || keylen < 0) { fprintf(stderr, _("bad key-length parameter")); eflag = ERR_BADPARAM; goto bail_out; } if (stat(cment->key.filename, &sbuff) == 0) { fprintf(stderr,_("key-file \"%s\" already exists for target \"%s\"\n"), cment->key.filename, cment->ident); eflag = ERR_BADFILE; goto bail_out; } fprintf(stderr, _("generating random key; please be patient...\n")); key = (unsigned char*)sec_realloc(NULL, (size_t)keylen); eflag = get_randkey(key, (unsigned)keylen); if (eflag != ERR_NOERROR) { fprintf(stderr, _("failed to generate new key\n")); goto bail_out; } if (!is_keysafe(&cment->key)) { fprintf(stderr, _("key-file for \"%s\" isn't password-protected\n"), cment->ident); eflag = WRN_NOPASSWD; goto bail_out; } sz = strlen(cment->key.filename) + 16; fname = (char*)malloc(sz); snprintf(fname, sz, "%s-new", cment->key.filename); fp = fopen(fname, "wb"); if (fp == NULL) { fprintf(stderr, _("cannot open \"%s\" for writing\n"), fname); eflag = ERR_BADFILE; goto bail_out; } eflag = put_key(cment->ident, &cment->key, key, keylen, fp); fclose(fp); if (eflag == ERR_NOERROR) { /* FIXME - check return codes */ (void)rename(fname, cment->key.filename); (void)chown(cment->key.filename, 0, 0); (void)chmod(cment->key.filename, S_IRUSR | S_IWUSR); } bail_out: if (fname != NULL) free((void*)fname); if (key != NULL) sec_free((void*)key); return eflag;}int check_priv(const cment_t *cment) /* check if ordinary user is allowed to perform privileged actions */{ if ((cment->flags & FLG_USER) == 0 && getuid() != 0) { fprintf(stderr, _("only root can configure \"%s\"\n"), cment->ident); return ERR_BADPRIV; } return ERR_NOERROR;}int execute_list(enum mode_t mode, const char *params, const struct targelt_t *eltlist){ const struct targelt_t *elt; int prio=0,eflag=ERR_NOERROR; struct passwd *pwent; const char *username,*syslogmsg=NULL; pwent = getpwuid(getuid()); username = (pwent != NULL ? pwent->pw_name : "UNKNOWN");#if defined(HAVE_SYSLOG) && !defined(TESTING) openlog(PACKAGE, LOG_PID, LOG_AUTHPRIV);#endif /* limit only basic actions to be setuid-root: */ if (mode != M_MOUNT && mode != M_UNMOUNT && mode != M_LIST && mode != M_PASSWORD && mode != M_HELP && mode != M_VERSION) { seteuid(getuid()); } /* execute user-selected task: */ if (mode == M_VERSION) { fprintf(stderr, "%s-%s\n", PACKAGE_NAME, PACKAGE_VERSION); } else { for (elt=eltlist; elt!=NULL && eflag<ERR_threshold; elt=elt->nx) { syslogmsg = NULL; prio = LOG_AUTHPRIV | LOG_NOTICE; switch (mode) { case M_LIST: eflag = do_list(elt->entry); break; case M_PREPARE: syslogmsg = "prepare of \"%s\" by %s %s"; eflag = do_devsetup(elt->entry, NULL); break; case M_RELEASE: syslogmsg = "release of \"%s\" by %s %s"; prio = LOG_AUTHPRIV | LOG_NOTICE; eflag = do_devshutdown(elt->entry); if (eflag == WRN_UNCONFIG) syslogmsg = NULL; break; case M_MOUNT: if ((eflag = check_priv(elt->entry)) != ERR_NOERROR) break; syslogmsg = "mount of \"%s\" by %s %s"; eflag = do_mount(elt->entry); break; case M_UNMOUNT: if ((eflag = check_priv(elt->entry)) != ERR_NOERROR) break; syslogmsg = "unmount of \"%s\" by %s %s"; eflag = do_unmount(elt->entry); if (eflag == WRN_UNCONFIG) syslogmsg = NULL; break; case M_SWAPON: syslogmsg = "swapon \"%s\" by %s %s"; eflag = do_swapon(elt->entry); break; case M_SWAPOFF: syslogmsg = "swapoff \"%s\" by %s %s"; eflag = do_swapoff(elt->entry); if (eflag == WRN_UNCONFIG) syslogmsg = NULL; break; case M_PASSWORD: if ((eflag = check_priv(elt->entry)) != ERR_NOERROR) break; syslogmsg = "changing password for \"%s\" by %s %s"; eflag = do_passwd(elt->entry); break; case M_KEYGEN: if ((eflag = check_priv(elt->entry)) != ERR_NOERROR) break; syslogmsg = "key generation for \"%s\" by %s %s"; eflag = do_keygen(elt->entry, params); break; default: break; }#if defined(HAVE_SYSLOG) && !defined(TESTING) if (syslogmsg != NULL) { syslog(prio, syslogmsg, elt->entry->ident, username, (eflag == ERR_NOERROR ? "succeeded" : "failed")); }#endif } }#ifdef HAVE_SYSLOG closelog();#endif return eflag;}mode_t get_defaultmode(int argc, char *argv[]) /* translate program-name into default action (or just assume M_MOUNT) */{ mode_t mode = M_MOUNT;#ifdef WITH_ARGV0 struct modename { mode_t mode; const char *name; } modetable[] = { { M_MOUNT, "cryptmount" }, { M_UNMOUNT, "cryptumount" }, { M_UNMOUNT, "cryptunmount" },#if WITH_CSWAP { M_SWAPON, "cryptswapon" }, { M_SWAPOFF, "cryptswapoff", },#endif { M_PREPARE, "cryptprepare" }, { M_RELEASE, "cryptrelease" }, { M_DEFAULT, NULL } }, *mp; const char *base; if (argc >= 1) { base = strrchr(argv[0], '/'); if (base != NULL) ++base; else base = argv[0]; for (mp=modetable; mp->name!=NULL; ++mp) { if (strcmp(base, mp->name) == 0) { mode = mp->mode; break; } } }#endif return mode;}int main(int argc, char *argv[]){ enum mode_t mode=M_DEFAULT; enum { F_ALL=0x1 } flags=0;#ifdef _GNU_SOURCE struct option opttable[] = { { "all", no_argument, NULL, (int)'a' }, { "change-password", no_argument, NULL, (int)'c' }, { "generate-key", required_argument, NULL, (int)'g' }, { "help", no_argument, NULL, (int)'h' }, { "list", no_argument, NULL, (int)'l' }, { "mount", no_argument, NULL, (int)'m' }, { "prepare", no_argument, NULL, (int)'p' }, { "release", no_argument, NULL, (int)'r' }, { "swapon", no_argument, NULL, (int)'s' }, { "swapoff", no_argument, NULL, (int)'x' }, { "unmount", no_argument, NULL, (int)'u' }, { "version", no_argument, NULL, (int)'v' },# ifdef TESTING { "config-dir", required_argument, NULL, (int)'D' }, { "password", required_argument, NULL, (int)'W' }, { "newpassword", required_argument, NULL, (int)'N' }, { "self-test", no_argument, NULL, (int)'T' },# endif { NULL, 0, NULL, 0 } };#endif const char *params=NULL, *optlist="acg:lmuv"; char *cmtab=NULL; int val,idx,eflag=ERR_NOERROR; cment_t *cmtable=NULL; const cment_t *ent=NULL; struct targelt_t *eltlist=NULL,**eltptr=&eltlist;#ifdef HAVE_GETTEXT /* setup internationalization of message-strings via gettext(): */ setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE);#endif#ifdef TESTING fprintf(stderr, "WARNING!!! cryptmount has been compiled for TESTING only - DO NOT INSTALL\n");#endif if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { fprintf(stderr, _("memory-locking failed...\n")); } /* parse command-line options: */ for (;;) {#ifdef _GNU_SOURCE val = getopt_long(argc, argv, optlist, opttable, &idx);#else val = getopt(argc, argv, optlist);#endif if (val == -1) break; switch (val) { case 'a': flags |= F_ALL; break; case 'c': mode = M_PASSWORD; break; case 'g': mode = M_KEYGEN; params = optarg; break; case 'h': mode = M_HELP; break; case 'l': mode = M_LIST; break; case 'm': mode = M_MOUNT; break; case 'p': mode = M_PREPARE; break; case 'r': mode = M_RELEASE; break; case 's': mode = M_SWAPON; break; case 'x': mode = M_SWAPOFF; break; case 'u': mode = M_UNMOUNT; break; case 'v': mode = M_VERSION; break;#ifdef TESTING case 'D': argconfigdir = optarg; break; case 'W': argpassword[0] = optarg; break; case 'N': argpassword[1] = optarg; break; case 'T': return cm_run_tests(); break;#endif case '?': fprintf(stderr, "%s", _(USAGE_STRING)); exit(1); break; default: break; } } (void)cm_path(&cmtab, "cmtab"); if (mode == M_DEFAULT) mode = get_defaultmode(argc, argv); if (mode == M_HELP) { fprintf(stderr, "%s", _(USAGE_STRING)); exit(0); } /* (check &) read-in configuration file: */#ifndef TESTING if (sycheck_cmtab(cmtab) != ERR_NOERROR) { fprintf(stderr, _("security failure\n")); exit(2); }#endif cmtable = parse_config(cmtab); free((void*)cmtab); if (mode == M_LIST && optind >= argc) flags |= F_ALL; /* if '--all' given, assemble list of targets from entire config-file */ if ((flags & F_ALL) != 0) { if (optind < argc) { fprintf(stderr, _("trailing command-line arguments given with '--all' option\n")); exit(1); } for (ent=cmtable; ent!=NULL; ent=ent->nx) { *eltptr = (struct targelt_t*)malloc(sizeof(struct targelt_t)); (*eltptr)->entry = ent; (*eltptr)->nx = NULL; eltptr = &((*eltptr)->nx); } } /* assemble list of targets from remaining command-line arguments: */ while (optind < argc) { ent = get_cment(cmtable, argv[optind]); if (ent != NULL) { *eltptr = (struct targelt_t*)malloc(sizeof(struct targelt_t)); (*eltptr)->entry = ent; (*eltptr)->nx = NULL; eltptr = &((*eltptr)->nx); } else { fprintf(stderr, _("target name \"%s\" is not recognized\n"), argv[optind]); } ++optind; } /* check security of all targets being processed: */ for (eltptr=&eltlist; *eltptr!=NULL; eltptr=&((*eltptr)->nx)) { if (sycheck_target((*eltptr)->entry) != ERR_NOERROR) { fprintf(stderr, _("target security failure\n")); exit(3); } } /* execute user-selected task: */ eflag = execute_list(mode, params, eltlist); free_keymanagers(); /* tidy-up: */ while (eltlist != NULL) { eltptr = &eltlist; eltlist = eltlist->nx; free((void*)*eltptr); } free_config(&cmtable); munlockall(); return eflag;}/* * cryptmount.c * (C)Copyright 2005-2006, RW Penney */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -