/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements . See the NOTICE file distributed with
* this work for additional information regarding copyright ownership .
* The ASF licenses this file to You under the Apache License , Version 2 . 0
* ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
#include "lua_passwd.h"
#include "apr_strings.h"
#include "apr_errno.h"
#if APR_HAVE_STDIO_H
#include <stdio.h>
#endif
#include "apr_md5.h"
#include "apr_sha1.h"
#if APR_HAVE_TIME_H
#include <time.h>
#endif
#if APR_HAVE_CRYPT_H
#include <crypt.h>
#endif
#if APR_HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if APR_HAVE_STRING_H
#include <string.h>
#endif
#if APR_HAVE_UNISTD_H
#include <unistd.h>
#endif
#if APR_HAVE_IO_H
#include <io.h>
#endif
static int generate_salt(char *s, size_t size, const char **errstr,
apr_pool_t *pool)
{
unsigned char rnd[32 ];
static const char itoa64[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ;
apr_size_t n;
unsigned int val = 0 , bits = 0 ;
apr_status_t rv;
n = (size * 6 + 7 )/8 ;
if (n > sizeof (rnd)) {
*errstr = apr_psprintf(pool, "generate_salt(): BUG: Buffer too small" );
return ERR_RANDOM;
}
rv = apr_generate_random_bytes(rnd, n);
if (rv) {
*errstr = apr_psprintf(pool, "Unable to generate random bytes: %pm" ,
&rv);
return ERR_RANDOM;
}
n = 0 ;
while (size > 0 ) {
if (bits < 6 ) {
val |= (rnd[n++] << bits);
bits += 8 ;
}
*s++ = itoa64[val & 0 x3f];
size--;
val >>= 6 ;
bits -= 6 ;
}
*s = '\0' ;
return 0 ;
}
/*
* Make a password record from the given information . A zero return
* indicates success ; on failure , ctx - > errstr points to the error message .
*/
int mk_password_hash(passwd_ctx *ctx)
{
char *pw;
char salt[16 ];
apr_status_t rv;
int ret = 0 ;
#if CRYPT_ALGO_SUPPORTED
char *cbuf;
#endif
pw = ctx->passwd;
switch (ctx->alg) {
case ALG_APSHA:
/* XXX out >= 28 + strlen(sha1) chars - fixed len SHA */
apr_sha1_base64(pw, strlen(pw), ctx->out);
break ;
case ALG_APMD5:
ret = generate_salt(salt, 8 , &ctx->errstr, ctx->pool);
if (ret != 0 ) {
ret = ERR_GENERAL;
break ;
}
rv = apr_md5_encode(pw, salt, ctx->out, ctx->out_len);
if (rv != APR_SUCCESS) {
ctx->errstr = apr_psprintf(ctx->pool,
"could not encode password: %pm" , &rv);
ret = ERR_GENERAL;
}
break ;
#if CRYPT_ALGO_SUPPORTED
case ALG_CRYPT:
ret = generate_salt(salt, 8 , &ctx->errstr, ctx->pool);
if (ret != 0 )
break ;
cbuf = crypt(pw, salt);
if (cbuf == NULL) {
rv = APR_FROM_OS_ERROR(errno);
ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm" , &rv);
ret = ERR_PWMISMATCH;
break ;
}
apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1 );
if (strlen(pw) > 8 ) {
char *truncpw = apr_pstrdup(ctx->pool, pw);
truncpw[8 ] = '\0' ;
if (!strcmp(ctx->out, crypt(truncpw, salt))) {
ctx->errstr = apr_psprintf(ctx->pool,
"Warning: Password truncated to 8 "
"characters by CRYPT algorithm." );
}
memset(truncpw, '\0' , strlen(pw));
}
break ;
#endif /* CRYPT_ALGO_SUPPORTED */
#if BCRYPT_ALGO_SUPPORTED
case ALG_BCRYPT:
rv = apr_generate_random_bytes((unsigned char *)salt, 16 );
if (rv != APR_SUCCESS) {
ctx->errstr = apr_psprintf(ctx->pool, "Unable to generate random "
"bytes: %pm" , &rv);
ret = ERR_RANDOM;
break ;
}
if (ctx->cost == 0 )
ctx->cost = BCRYPT_DEFAULT_COST;
rv = apr_bcrypt_encode(pw, ctx->cost, (unsigned char *)salt, 16 ,
ctx->out, ctx->out_len);
if (rv != APR_SUCCESS) {
ctx->errstr = apr_psprintf(ctx->pool, "Unable to encode with "
"bcrypt: %pm" , &rv);
ret = ERR_PWMISMATCH;
break ;
}
break ;
#endif /* BCRYPT_ALGO_SUPPORTED */
default :
ctx->errstr = apr_psprintf(ctx->pool,
"mk_password_hash(): unsupported algorithm %d" ,
ctx->alg);
ret = ERR_GENERAL;
}
memset(pw, '\0' , strlen(pw));
return ret;
}
Messung V0.5 in Prozent C=97 H=97 G=96
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland