passwd_common.c revision dbf5f584c62fe6030d81121fdddeb7588b78b867
8a77240a809197c92c0736c431b4b88947a7bac1Christian Maeder/* Licensed to the Apache Software Foundation (ASF) under one or more
8a77240a809197c92c0736c431b4b88947a7bac1Christian Maeder * contributor license agreements. See the NOTICE file distributed with
8a77240a809197c92c0736c431b4b88947a7bac1Christian Maeder * this work for additional information regarding copyright ownership.
adea2e45fa61f1097aadc490a0aeaf4831b729ccChristian Maeder * The ASF licenses this file to You under the Apache License, Version 2.0
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski * (the "License"); you may not use this file except in compliance with
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder * the License. You may obtain a copy of the License at
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski *
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu * http://www.apache.org/licenses/LICENSE-2.0
2eeec5240b424984e3ee26296da1eeab6c6d739eChristian Maeder *
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski * Unless required by applicable law or agreed to in writing, software
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski * distributed under the License is distributed on an "AS IS" BASIS,
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder * See the License for the specific language governing permissions and
0095c7efbddd0ffeed6aaf8ec015346be161d819Till Mossakowski * limitations under the License.
adea2e45fa61f1097aadc490a0aeaf4831b729ccChristian Maeder */
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#include "passwd_common.h"
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#include "apr_strings.h"
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#include "apr_errno.h"
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#if APR_HAVE_STDIO_H
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#include <stdio.h>
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#endif
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#include "apr_md5.h"
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#include "apr_sha1.h"
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#include <time.h>
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#if APR_HAVE_CRYPT_H
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder#include <crypt.h>
cf31aaf25d0fe96b0578755e7ee18b732e337343Christian Maeder#endif
ef9e8535c168d3f774d9e74368a2317a9eda5826Christian Maeder#if APR_HAVE_STDLIB_H
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#include <stdlib.h>
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#endif
d3c9318c22fcf44d9135a3b2c64f880b9a785babChristian Maeder#if APR_HAVE_STRING_H
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#include <string.h>
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#endif
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#if APR_HAVE_UNISTD_H
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#include <unistd.h>
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#endif
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski
adea2e45fa61f1097aadc490a0aeaf4831b729ccChristian Maeder#ifdef WIN32
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#include <conio.h>
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski#define unlink _unlink
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder#endif
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maederapr_file_t *errfile;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maederint abort_on_oom(int rc)
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder{
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder const char *buf = "Error: out of memory\n";
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder int written, count = strlen(buf);
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder do {
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski written = write(STDERR_FILENO, buf, count);
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (written == count)
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski break;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (written > 0) {
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski buf += written;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski count -= written;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski }
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski } while (written >= 0 || errno == EINTR);
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski abort();
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder /* NOTREACHED */
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder return 0;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder}
adea2e45fa61f1097aadc490a0aeaf4831b729ccChristian Maeder
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowskistatic int generate_salt(char *s, size_t size, const char **errstr,
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski apr_pool_t *pool)
adea2e45fa61f1097aadc490a0aeaf4831b729ccChristian Maeder{
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski unsigned char rnd[32];
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder static const char itoa64[] =
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski apr_size_t n;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski unsigned int val = 0, bits = 0;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski apr_status_t rv;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski n = (size * 6 + 7)/8;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (n > sizeof(rnd)) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_file_printf(errfile, "generate_salt(): BUG: Buffer too small");
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski abort();
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski }
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder rv = apr_generate_random_bytes(rnd, n);
adea2e45fa61f1097aadc490a0aeaf4831b729ccChristian Maeder if (rv) {
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder *errstr = apr_psprintf(pool, "Unable to generate random bytes: %pm",
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski &rv);
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski return ERR_RANDOM;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder n = 0;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski while (size > 0) {
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder if (bits < 6) {
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder val |= (rnd[n++] << bits);
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder bits += 8;
e7d2b3903c7b44db432538b0d720c21062c24823Christian Maeder }
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski *s++ = itoa64[val & 0x3f];
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski size--;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski val >>= 6;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder bits -= 6;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski }
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski *s = '\0';
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski return 0;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder}
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowskivoid putline(apr_file_t *f, const char *l)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder{
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski apr_status_t rv;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (f == NULL)
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski return;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski rv = apr_file_puts(l, f);
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (rv != APR_SUCCESS) {
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu apr_file_printf(errfile, "Error writing temp file: %pm", &rv);
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu apr_file_close(f);
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu exit(ERR_FILEPERM);
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski }
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski}
e7d2b3903c7b44db432538b0d720c21062c24823Christian Maeder
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maederint get_password(struct passwd_ctx *ctx)
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski{
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski char buf[MAX_STRING_LEN + 1];
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (ctx->passwd_src == PW_STDIN) {
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder apr_file_t *file_stdin;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski apr_size_t nread;
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (apr_file_open_stdin(&file_stdin, ctx->pool) != APR_SUCCESS) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->errstr = "Unable to read from stdin.";
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski return ERR_GENERAL;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (apr_file_read_full(file_stdin, buf, sizeof(buf) - 1,
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski &nread) != APR_EOF
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder || nread == sizeof(buf) - 1) {
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski goto err_too_long;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski buf[nread] = '\0';
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (nread >= 1 && buf[nread-1] == '\n') {
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski buf[nread-1] = '\0';
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski if (nread >= 2 && buf[nread-2] == '\r')
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder buf[nread-2] = '\0';
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_file_close(file_stdin);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->passwd = apr_pstrdup(ctx->pool, buf);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder else if (ctx->passwd_src == PW_PROMPT_VERIFY) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_size_t bufsize = sizeof(buf);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (apr_password_get("Enter password: ", buf, &bufsize) != 0)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder goto err_too_long;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->passwd = apr_pstrdup(ctx->pool, buf);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder else {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_size_t bufsize = sizeof(buf);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (apr_password_get("New password: ", buf, &bufsize) != 0)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder goto err_too_long;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder ctx->passwd = apr_pstrdup(ctx->pool, buf);
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder bufsize = sizeof(buf);
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder buf[0] = '\0';
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder apr_password_get("Re-type new password: ", buf, &bufsize);
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder if (strcmp(ctx->passwd, buf) != 0) {
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu ctx->errstr = "password verification error";
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder memset(ctx->passwd, '\0', strlen(ctx->passwd));
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder memset(buf, '\0', sizeof(buf));
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder return ERR_PWMISMATCH;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder memset(buf, '\0', sizeof(buf));
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder return 0;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maedererr_too_long:
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->errstr = apr_psprintf(ctx->pool,
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder "password too long (>%" APR_SIZE_T_FMT ")",
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->out_len - 1);
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder return ERR_OVERFLOW;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder}
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder/*
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder * Make a password record from the given information. A zero return
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder * indicates success; on failure, ctx->errstr points to the error message.
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder */
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maederint mkhash(struct passwd_ctx *ctx)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder{
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder char *pw;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder char salt[16];
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder apr_status_t rv;
4d7d53fec6b551333c79da6ae3b8ca2af0a741abChristian Maeder int ret = 0;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#if CRYPT_ALGO_SUPPORTED
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder char *cbuf;
3e8b136f23ed57d40ee617f49bcac37830b58cabChristian Maeder#endif
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
d3c9318c22fcf44d9135a3b2c64f880b9a785babChristian Maeder if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT) {
d3c9318c22fcf44d9135a3b2c64f880b9a785babChristian Maeder apr_file_printf(errfile,
d3c9318c22fcf44d9135a3b2c64f880b9a785babChristian Maeder "Warning: Ignoring -C argument for this algorithm." NL);
d3c9318c22fcf44d9135a3b2c64f880b9a785babChristian Maeder }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (ctx->passwd == NULL) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if ((ret = get_password(ctx)) != 0)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder return ret;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
cd6e5706893519bfcf24539afa252fcbed5097ddKlaus Luettich pw = ctx->passwd;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder switch (ctx->alg) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder case ALG_APSHA:
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder /* XXX out >= 28 + strlen(sha1) chars - fixed len SHA */
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_sha1_base64(pw, strlen(pw), ctx->out);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder case ALG_APMD5:
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ret = generate_salt(salt, 8, &ctx->errstr, ctx->pool);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (ret != 0)
e7d2b3903c7b44db432538b0d720c21062c24823Christian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder rv = apr_md5_encode(pw, salt, ctx->out, ctx->out_len);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (rv != APR_SUCCESS) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->errstr = apr_psprintf(ctx->pool,
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder "could not encode password: %pm", &rv);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ret = ERR_GENERAL;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
e8eb2b9d68adc3024eb1aa9899b902ed5a3fb460Christian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder case ALG_PLAIN:
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder /* XXX this len limitation is not in sync with any HTTPd len. */
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_cpystrn(ctx->out, pw, ctx->out_len);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#if CRYPT_ALGO_SUPPORTED
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder case ALG_CRYPT:
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ret = generate_salt(salt, 8, &ctx->errstr, ctx->pool);
cd6e5706893519bfcf24539afa252fcbed5097ddKlaus Luettich if (ret != 0)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder break;
e7d2b3903c7b44db432538b0d720c21062c24823Christian Maeder cbuf = crypt(pw, salt);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (cbuf == NULL) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder rv = APR_FROM_OS_ERROR(errno);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm", &rv);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ret = ERR_PWMISMATCH;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1);
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder if (strlen(pw) > 8) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder char *truncpw = apr_pstrdup(ctx->pool, pw);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder truncpw[8] = '\0';
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (!strcmp(ctx->out, crypt(truncpw, salt))) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_file_printf(errfile, "Warning: Password truncated to 8 "
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder "characters by CRYPT algorithm." NL);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder memset(truncpw, '\0', strlen(pw));
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder free(truncpw);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#endif /* CRYPT_ALGO_SUPPORTED */
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder#if BCRYPT_ALGO_SUPPORTED
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder case ALG_BCRYPT:
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder rv = apr_generate_random_bytes((unsigned char*)salt, 16);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (rv != APR_SUCCESS) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->errstr = apr_psprintf(ctx->pool, "Unable to generate random "
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder "bytes: %pm", &rv);
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu ret = ERR_RANDOM;
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu break;
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (ctx->cost == 0)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->cost = BCRYPT_DEFAULT_COST;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder rv = apr_bcrypt_encode(pw, ctx->cost, (unsigned char*)salt, 16,
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->out, ctx->out_len);
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if (rv != APR_SUCCESS) {
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->errstr = apr_psprintf(ctx->pool, "Unable to encode with "
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu "bcrypt: %pm", &rv);
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu ret = ERR_PWMISMATCH;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder break;
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#endif /* BCRYPT_ALGO_SUPPORTED */
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder
e7d2b3903c7b44db432538b0d720c21062c24823Christian Maeder default:
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_file_printf(errfile, "mkhash(): BUG: invalid algorithm %d",
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder ctx->alg);
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder abort();
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder }
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder memset(pw, '\0', strlen(pw));
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder return ret;
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder}
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maederint parse_common_options(struct passwd_ctx *ctx, char opt,
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder const char *opt_arg)
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder{
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder switch (opt) {
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder case 'b':
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->passwd_src = PW_ARG;
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder break;
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder case 'i':
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder ctx->passwd_src = PW_STDIN;
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder break;
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder case 'm':
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder ctx->alg = ALG_APMD5;
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder case 's':
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->alg = ALG_APSHA;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder case 'p':
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->alg = ALG_PLAIN;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#if !PLAIN_ALGO_SUPPORTED
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder /* Backward compatible behavior: Just print a warning */
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_file_printf(errfile,
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder "Warning: storing passwords as plain text might just "
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder "not work on this platform." NL);
e8eb2b9d68adc3024eb1aa9899b902ed5a3fb460Christian Maeder#endif
e8eb2b9d68adc3024eb1aa9899b902ed5a3fb460Christian Maeder break;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder case 'd':
e8eb2b9d68adc3024eb1aa9899b902ed5a3fb460Christian Maeder#if CRYPT_ALGO_SUPPORTED
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ctx->alg = ALG_CRYPT;
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder#else
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder /* Backward compatible behavior: Use MD5. OK since MD5 is more secure */
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder apr_file_printf(errfile,
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder "Warning: CRYPT algorithm not supported on this "
cd6e5706893519bfcf24539afa252fcbed5097ddKlaus Luettich "platform." NL
cd6e5706893519bfcf24539afa252fcbed5097ddKlaus Luettich "Automatically using MD5 format." NL);
c40a1fdc8ec6978bd27240d6780d0e0a7b6b0056Dominik Luecke ctx->alg = ALG_APMD5;
cd6e5706893519bfcf24539afa252fcbed5097ddKlaus Luettich#endif
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder break;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder case 'B':
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder#if BCRYPT_ALGO_SUPPORTED
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder ctx->alg = ALG_BCRYPT;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder#else
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder /* Don't fall back to something less secure */
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder ctx->errstr = "BCRYPT algorithm not supported on this platform";
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder return ERR_ALG_NOT_SUPP;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder#endif
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder break;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder case 'C': {
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder char *endptr;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder long num = strtol(opt_arg, &endptr, 10);
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder if (*endptr != '\0' || num <= 0) {
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder ctx->errstr = "argument to -C must be a positive integer";
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder return ERR_SYNTAX;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder }
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder ctx->cost = num;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder break;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder }
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder default:
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder apr_file_printf(errfile,
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder "parse_common_options(): BUG: invalid option %c",
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder opt);
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder abort();
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder }
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder return 0;
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder}
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder