예제 #1
0
int main(int argc, char *const argv[]) {

    const char *fullName = "Robert Lee Mitchel";
    const char *masterPassword = "******";
    const char *siteName = "masterpasswordapp.com";
    const uint32_t siteCounter = 1;
    const MPSiteType siteType = MPSiteTypeGeneratedLong;
    const MPSiteVariant siteVariant = MPSiteVariantPassword;
    const char *siteContext = NULL;
    struct timeval startTime;

    // Start MPW
    unsigned int iterations = 100;
    mpw_getTime( &startTime );
    for (int i = 0; i < iterations; ++i) {
        const uint8_t *masterKey = mpw_masterKeyForUser(
                fullName, masterPassword, MPAlgorithmVersionCurrent );
        if (!masterKey)
            ftl( "Could not allocate master key: %d\n", errno );
        free( (void *)mpw_passwordForSite(
                masterKey, siteName, siteType, siteCounter, siteVariant, siteContext, MPAlgorithmVersionCurrent ) );
        free( (void *)masterKey );

        if (i % ( iterations / 100 ) == 0)
            fprintf( stderr, "\rmpw: iteration %d / %d (%d%%)..", i, iterations, i * 100 / iterations );
    }
    const double mpwSpeed = mpw_showSpeed( startTime, iterations, "mpw" );

    // Start SHA-256
    iterations = 45000000;
    uint8_t hash[32];
    mpw_getTime( &startTime );
    for (int i = 0; i < iterations; ++i) {
        SHA256_Buf( masterPassword, strlen( masterPassword ), hash );

        if (i % ( iterations / 100 ) == 0)
            fprintf( stderr, "\rsha256: iteration %d / %d (%d%%)..", i, iterations, i * 100 / iterations );
    }
    const double sha256Speed = mpw_showSpeed( startTime, iterations, "sha256" );

    // Start BCrypt
    int bcrypt_cost = 9;
    iterations = 1000;
    mpw_getTime( &startTime );
    for (int i = 0; i < iterations; ++i) {
        crypt( masterPassword, crypt_gensalt( "$2b$", bcrypt_cost, fullName, strlen( fullName ) ) );

        if (i % ( iterations / 100 ) == 0)
            fprintf( stderr, "\rbcrypt (cost %d): iteration %d / %d (%d%%)..", bcrypt_cost, i, iterations, i * 100 / iterations );
    }
    const double bcrypt9Speed = mpw_showSpeed( startTime, iterations, "bcrypt9" );

    // Summarize.
    fprintf( stdout, "\n== SUMMARY ==\nOn this machine,\n" );
    fprintf( stdout, " - mpw is %f times slower than sha256 (reference: 320000 on an MBP Late 2013).\n", sha256Speed / mpwSpeed );
    fprintf( stdout, " - mpw is %f times slower than bcrypt (cost 9) (reference: 22 on an MBP Late 2013).\n", bcrypt9Speed / mpwSpeed );

    return 0;
}
예제 #2
0
int main (int argc, char **argv)
{
	char *pass;
	char *salt;
	char *secret;
	struct passwd *pwd;

	if (argc !=2)
		err_quit ("Usage: new_crypt username");

	if ((pwd = getpwnam (argv [1])) == NULL)
		err_quit ("%s: No such user", argv [1]);

	pass = getpassphrase ("Password: "******"Password = \"%s\"\n", pass);
	printf ("Salt = \"%s\"\n", salt);
	printf ("Secret = \"%s\"\n", secret);

	return (0);
}
예제 #3
0
파일: bcrypt.cpp 프로젝트: opncms/opncms
std::string bcrypt_salt(unsigned long count)
{
	BOOSTER_LOG(debug,__FUNCTION__);
	char entropy[16];

	std::ifstream f(RANDOM_DEVICE);
	f.read(entropy, sizeof(entropy));
	if (f.gcount() != sizeof(entropy)) {
		BOOSTER_LOG(error,__FUNCTION__) << "Unable to get an entropy";
		f.close();
		return "";
	}
	f.close();
	
	char* retval = crypt_gensalt(CRYPT_PREFIX, count, entropy, sizeof(entropy));
	
	if ( (retval == NULL) || ((retval != NULL) && (retval[0] == '\0')))
	{
		BOOSTER_LOG(error,__FUNCTION__) << "Unable to generate a salt";
		return "";
	}
	return std::string(retval);
}
예제 #4
0
파일: mkpasswd.c 프로젝트: freddy36/whois
int main(int argc, char *argv[])
{
    int ch, i;
    int password_fd = -1;
    unsigned int salt_minlen = 0;
    unsigned int salt_maxlen = 0;
    unsigned int rounds_support = 0;
    const char *salt_prefix = NULL;
    const char *salt_arg = NULL;
    unsigned int rounds = 0;
    char *salt = NULL;
    char rounds_str[30];
    char *password = NULL;

#ifdef ENABLE_NLS
    setlocale(LC_ALL, "");
    bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
    textdomain(NLS_CAT_NAME);
#endif

    /* prepend options from environment */
    argv = merge_args(getenv("MKPASSWD_OPTIONS"), argv, &argc);

    while ((ch = GETOPT_LONGISH(argc, argv, "hH:m:5P:R:sS:V", longopts, 0))
	    > 0) {
	switch (ch) {
	case '5':
	    optarg = (char *) "md5";
	    /* fall through */
	case 'm':
	case 'H':
	    if (!optarg || strcaseeq("help", optarg)) {
		display_methods();
		exit(0);
	    }
	    for (i = 0; methods[i].method != NULL; i++)
		if (strcaseeq(methods[i].method, optarg)) {
		    salt_prefix = methods[i].prefix;
		    salt_minlen = methods[i].minlen;
		    salt_maxlen = methods[i].maxlen;
		    rounds_support = methods[i].rounds;
		    break;
		}
	    if (!salt_prefix) {
		fprintf(stderr, _("Invalid method '%s'.\n"), optarg);
		exit(1);
	    }
	    break;
	case 'P':
	    {
		char *p;
		password_fd = strtol(optarg, &p, 10);
		if (p == NULL || *p != '\0' || password_fd < 0) {
		    fprintf(stderr, _("Invalid number '%s'.\n"), optarg);
		    exit(1);
		}
	    }
	    break;
	case 'R':
	    {
		char *p;
		long r;

		r = strtol(optarg, &p, 10);
		if (p == NULL || *p != '\0' || r < 0) {
		    fprintf(stderr, _("Invalid number '%s'.\n"), optarg);
		    exit(1);
		}
		rounds = r;
	    }
	    break;
	case 's':
	    password_fd = 0;
	    break;
	case 'S':
	    salt_arg = optarg;
	    break;
	case 'V':
	    display_version();
	    exit(0);
	case 'h':
	    display_help(EXIT_SUCCESS);
	default:
	    fprintf(stderr, _("Try '%s --help' for more information.\n"),
		    argv[0]);
	    exit(1);
	}
    }
    argc -= optind;
    argv += optind;

    if (argc == 2 && !salt_arg) {
	password = argv[0];
	salt_arg = argv[1];
    } else if (argc == 1) {
	password = argv[0];
    } else if (argc == 0) {
    } else {
	display_help(EXIT_FAILURE);
    }

    /* default: DES password */
    if (!salt_prefix) {
	salt_minlen = methods[0].minlen;
	salt_maxlen = methods[0].maxlen;
	salt_prefix = methods[0].prefix;
    }

    if (streq(salt_prefix, "$2a$") || streq(salt_prefix, "$2y$")) {
	/* OpenBSD Blowfish and derivatives */
	if (rounds <= 5)
	    rounds = 5;
	/* actually for 2a/2y it is the logarithm of the number of rounds */
	snprintf(rounds_str, sizeof(rounds_str), "%02u$", rounds);
    } else if (rounds_support && rounds)
	snprintf(rounds_str, sizeof(rounds_str), "rounds=%u$", rounds);
    else
	rounds_str[0] = '\0';

    if (salt_arg) {
	unsigned int c = strlen(salt_arg);
	if (c < salt_minlen || c > salt_maxlen) {
	    if (salt_minlen == salt_maxlen)
		fprintf(stderr, ngettext(
			"Wrong salt length: %d byte when %d expected.\n",
			"Wrong salt length: %d bytes when %d expected.\n", c),
			c, salt_maxlen);
	    else
		fprintf(stderr, ngettext(
			"Wrong salt length: %d byte when %d <= n <= %d"
			" expected.\n",
			"Wrong salt length: %d bytes when %d <= n <= %d"
			" expected.\n", c),
			c, salt_minlen, salt_maxlen);
	    exit(1);
	}
	while (c-- > 0) {
	    if (strchr(valid_salts, salt_arg[c]) == NULL) {
		fprintf(stderr, _("Illegal salt character '%c'.\n"),
			salt_arg[c]);
		exit(1);
	    }
	}

	salt = NOFAIL(malloc(strlen(salt_prefix) + strlen(rounds_str)
		+ strlen(salt_arg) + 1));
	*salt = '\0';
	strcat(salt, salt_prefix);
	strcat(salt, rounds_str);
	strcat(salt, salt_arg);
    } else {
#ifdef HAVE_SOLARIS_CRYPT_GENSALT
	salt = crypt_gensalt(salt_prefix, NULL);
	if (!salt)
		perror("crypt_gensalt");
#elif defined HAVE_LINUX_CRYPT_GENSALT
	void *entropy = get_random_bytes(64);

	salt = crypt_gensalt(salt_prefix, rounds, entropy, 64);
	if (!salt) {
		fprintf(stderr, "crypt_gensalt failed.\n");
		exit(2);
	}
	free(entropy);
#else
	unsigned int salt_len = salt_maxlen;

	if (salt_minlen != salt_maxlen) { /* salt length can vary */
	    srand(time(NULL) + getpid());
	    salt_len = rand() % (salt_maxlen - salt_minlen + 1) + salt_minlen;
	}

	salt = NOFAIL(malloc(strlen(salt_prefix) + strlen(rounds_str)
		+ salt_len + 1));
	*salt = '\0';
	strcat(salt, salt_prefix);
	strcat(salt, rounds_str);
	generate_salt(salt + strlen(salt), salt_len);
#endif
    }

    if (password) {
    } else if (password_fd != -1) {
	FILE *fp;
	char *p;

	if (isatty(password_fd))
	    fprintf(stderr, _("Password: "******"r");
	if (!fp) {
	    perror("fdopen");
	    exit(2);
	}
	if (!fgets(password, 128, fp)) {
	    perror("fgets");
	    exit(2);
	}

	p = strpbrk(password, "\n\r");
	if (p)
	    *p = '\0';
    } else {
	password = getpass(_("Password: "******"getpass");
	    exit(2);
	}
    }

    {
	const char *result;
	result = crypt(password, salt);
	/* xcrypt returns "*0" on errors */
	if (!result || result[0] == '*') {
	    fprintf(stderr, "crypt failed.\n");
	    exit(2);
	}
	/* yes, using strlen(salt_prefix) on salt. It's not
	 * documented whether crypt_gensalt may change the prefix */
	if (!strneq(result, salt, strlen(salt_prefix))) {
	    fprintf(stderr, _("Method not supported by crypt(3).\n"));
	    exit(2);
	}
	printf("%s\n", result);
    }

    exit(0);
}
예제 #5
0
/*ARGSUSED*/
int
files_update(attrlist *items, pwu_repository_t *rep, void *buf)
{
	struct pwbuf *pwbuf = (struct pwbuf *)buf;
	struct passwd *pw;
	struct spwd *spw;
	attrlist *p;
	int aging_needed = 0;
	int aging_set = 0;
	int disable_aging;
	char *pword;
	int len;

	pw = pwbuf->pwd;
	spw = pwbuf->spwd;
	pwbuf->update_history = 0;

	/*
	 * if sp_max==0 : disable passwd aging after updating the password
	 */
	disable_aging = (spw != NULL && spw->sp_max == 0);

	for (p = items; p != NULL; p = p->next) {
		switch (p->type) {
		case ATTR_NAME:
			break;	/* We are able to handle this, but... */
		case ATTR_UID:
			pw->pw_uid = (uid_t)p->data.val_i;
			break;
		case ATTR_GID:
			pw->pw_gid = (gid_t)p->data.val_i;
			break;
		case ATTR_AGE:
			pw->pw_age = p->data.val_s;
			break;
		case ATTR_COMMENT:
			pw->pw_comment = p->data.val_s;
			break;
		case ATTR_GECOS:
			pw->pw_gecos = p->data.val_s;
			break;
		case ATTR_HOMEDIR:
			pw->pw_dir = p->data.val_s;
			break;
		case ATTR_SHELL:
			pw->pw_shell = p->data.val_s;
			break;

		/*
		 * Nothing special needs to be done for
		 * server policy
		 */
		case ATTR_PASSWD:
		case ATTR_PASSWD_SERVER_POLICY:
			/*
			 * There is a special case only for files: if the
			 * password is to be deleted (-d to passwd),
			 * p->data.val_s will be NULL.
			 */
			if (p->data.val_s == NULL) {
				spw->sp_pwdp = "";
			} else {
				char *salt = NULL;
				char *hash = NULL;

				salt = crypt_gensalt(spw->sp_pwdp, pw);

				if (salt == NULL) {
					if (errno == ENOMEM)
						return (PWU_NOMEM);
					/* algorithm problem? */
					syslog(LOG_AUTH | LOG_ALERT,
					    "passwdutil: crypt_gensalt %m");
					return (PWU_UPDATE_FAILED);
				}
				hash = crypt(p->data.val_s, salt);
				free(salt);
				if (hash == NULL) {
					errno = ENOMEM;
					return (PWU_NOMEM);
				}
				pword = strdup(hash);
				if (pword == NULL) {
					errno = ENOMEM;
					return (PWU_NOMEM);
				}

				if (pwbuf->new_sp_pwdp)
					free(pwbuf->new_sp_pwdp);
				pwbuf->new_sp_pwdp = pword;
				spw->sp_pwdp = pword;
				aging_needed = 1;
				pwbuf->update_history = 1;
			}
			spw->sp_flag &= ~FAILCOUNT_MASK; /* reset count */
			spw->sp_lstchg = DAY_NOW_32;
			break;
		case ATTR_LOCK_ACCOUNT:
			if (spw->sp_pwdp == NULL) {
				spw->sp_pwdp = LOCKSTRING;
			} else if ((strncmp(spw->sp_pwdp, LOCKSTRING,
			    sizeof (LOCKSTRING)-1) != 0) &&
			    (strcmp(spw->sp_pwdp, NOLOGINSTRING) != 0)) {
				len = sizeof (LOCKSTRING)-1 +
				    strlen(spw->sp_pwdp) + 1;
				pword = malloc(len);
				if (pword == NULL) {
					errno = ENOMEM;
					return (PWU_NOMEM);
				}
				(void) strlcpy(pword, LOCKSTRING, len);
				(void) strlcat(pword, spw->sp_pwdp, len);
				if (pwbuf->new_sp_pwdp)
					free(pwbuf->new_sp_pwdp);
				pwbuf->new_sp_pwdp = pword;
				spw->sp_pwdp = pword;
			}
			spw->sp_lstchg = DAY_NOW_32;
			break;
		case ATTR_UNLOCK_ACCOUNT:
			if (spw->sp_pwdp != NULL &&
			    strncmp(spw->sp_pwdp, LOCKSTRING,
			    sizeof (LOCKSTRING)-1) == 0) {
				(void) strcpy(spw->sp_pwdp, spw->sp_pwdp +
				    sizeof (LOCKSTRING)-1);
			}
			spw->sp_lstchg = DAY_NOW_32;
			break;
		case ATTR_NOLOGIN_ACCOUNT:
			spw->sp_pwdp = NOLOGINSTRING;
			if (pwbuf->new_sp_pwdp) {
				free(pwbuf->new_sp_pwdp);
				pwbuf->new_sp_pwdp = NULL;
			}
			spw->sp_lstchg = DAY_NOW_32;
			break;
		case ATTR_EXPIRE_PASSWORD:
			spw->sp_lstchg = 0;
			break;
		case ATTR_LSTCHG:
			spw->sp_lstchg = p->data.val_i;
			break;
		case ATTR_MIN:
			if (spw->sp_max == -1 &&
			    p->data.val_i != -1 && max_present(p->next) == 0)
				return (PWU_AGING_DISABLED);
			spw->sp_min = p->data.val_i;
			aging_set = 1;
			break;
		case ATTR_MAX:
			if (p->data.val_i == -1) {
				/* Turn aging off -> Reset min and warn too */

				spw->sp_min = -1;
				spw->sp_warn = -1;
			} else {
				/* Turn aging on */

				if (spw->sp_min == -1) {
					/*
					 * If minage has not been set with
					 * a command-line option, we set it
					 * to zero.
					 */
					spw->sp_min = 0;
				}

				/*
				 * If aging was turned off, we update lstchg.
				 *
				 * We take care not to update lstchg if the
				 * user has no password, otherwise the user
				 * might not be required to provide a password
				 * the next time they log-in.
				 *
				 * Also, if lstchg != -1 (i.e., not set in
				 * /etc/shadow), we keep the old value.
				 */
				if (spw->sp_max == -1 &&
				    spw->sp_pwdp != NULL && *spw->sp_pwdp &&
				    spw->sp_lstchg == -1) {
					spw->sp_lstchg = DAY_NOW_32;
				}
			}

			spw->sp_max = p->data.val_i;

			aging_set = 1;

			break;
		case ATTR_WARN:
			if (spw->sp_max == -1 && p->data.val_i != -1 &&
			    max_present(p->next) == 0)
				return (PWU_AGING_DISABLED);
			spw->sp_warn =  p->data.val_i;
			break;
		case ATTR_INACT:
			spw->sp_inact = p->data.val_i;
			break;
		case ATTR_EXPIRE:
			spw->sp_expire = p->data.val_i;
			break;
		case ATTR_FLAG:
			spw->sp_flag = p->data.val_i;
			break;
		case ATTR_INCR_FAILED_LOGINS:
			{
			int count = (spw->sp_flag & FAILCOUNT_MASK) + 1;
			spw->sp_flag &= ~FAILCOUNT_MASK;
			spw->sp_flag |= min(FAILCOUNT_MASK, count);
			p->data.val_i = count;
			}
			break;
		case ATTR_RST_FAILED_LOGINS:
			p->data.val_i = spw->sp_flag & FAILCOUNT_MASK;
			spw->sp_flag &= ~FAILCOUNT_MASK;
			break;
		default:
			break;
		}
	}

	/*
	 * What should the new aging values look like?
	 *
	 * There are a number of different conditions
	 *
	 *  a) aging is already configured: don't touch it
	 *
	 *  b) disable_aging is set: disable aging
	 *
	 *  c) aging is not configured: turn on default aging;
	 *
	 *  b) and c) of course only if aging_needed and !aging_set.
	 *  (i.e., password changed, and aging values not changed)
	 */

	if (spw != NULL && spw->sp_max <= 0) {
		/* a) aging not yet configured */
		if (aging_needed && !aging_set) {
			if (disable_aging) {
				/* b) turn off aging */
				spw->sp_min = spw->sp_max = spw->sp_warn = -1;
			} else {
				/* c) */
				turn_on_default_aging(spw);
			}
		}
	}

	return (PWU_SUCCESS);
}