Apache HTTPD
lua_passwd.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "lua_passwd.h"
18#include "apr_strings.h"
19#include "apr_errno.h"
20
21#if APR_HAVE_STDIO_H
22#include <stdio.h>
23#endif
24
25#include "apr_md5.h"
26#include "apr_sha1.h"
27
28#if APR_HAVE_TIME_H
29#include <time.h>
30#endif
31#if APR_HAVE_CRYPT_H
32#include <crypt.h>
33#endif
34#if APR_HAVE_STDLIB_H
35#include <stdlib.h>
36#endif
37#if APR_HAVE_STRING_H
38#include <string.h>
39#endif
40#if APR_HAVE_UNISTD_H
41#include <unistd.h>
42#endif
43#if APR_HAVE_IO_H
44#include <io.h>
45#endif
46
47static int generate_salt(char *s, size_t size, const char **errstr,
49{
50 unsigned char rnd[32];
51 static const char itoa64[] =
52 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
54 unsigned int val = 0, bits = 0;
55 apr_status_t rv;
56
57 n = (size * 6 + 7)/8;
58 if (n > sizeof(rnd)) {
59 *errstr = apr_psprintf(pool, "generate_salt(): BUG: Buffer too small");
60 return ERR_RANDOM;
61 }
63 if (rv) {
64 *errstr = apr_psprintf(pool, "Unable to generate random bytes: %pm",
65 &rv);
66 return ERR_RANDOM;
67 }
68 n = 0;
69 while (size > 0) {
70 if (bits < 6) {
71 val |= (rnd[n++] << bits);
72 bits += 8;
73 }
74 *s++ = itoa64[val & 0x3f];
75 size--;
76 val >>= 6;
77 bits -= 6;
78 }
79 *s = '\0';
80 return 0;
81}
82
83/*
84 * Make a password record from the given information. A zero return
85 * indicates success; on failure, ctx->errstr points to the error message.
86 */
88{
89 char *pw;
90 char salt[16];
91 apr_status_t rv;
92 int ret = 0;
93#if CRYPT_ALGO_SUPPORTED
94 char *cbuf;
95#endif
96
97 pw = ctx->passwd;
98 switch (ctx->alg) {
99 case ALG_APSHA:
100 /* XXX out >= 28 + strlen(sha1) chars - fixed len SHA */
101 apr_sha1_base64(pw, strlen(pw), ctx->out);
102 break;
103
104 case ALG_APMD5:
105 ret = generate_salt(salt, 8, &ctx->errstr, ctx->pool);
106 if (ret != 0) {
108 break;
109 }
110 rv = apr_md5_encode(pw, salt, ctx->out, ctx->out_len);
111 if (rv != APR_SUCCESS) {
112 ctx->errstr = apr_psprintf(ctx->pool,
113 "could not encode password: %pm", &rv);
115 }
116 break;
117
118#if CRYPT_ALGO_SUPPORTED
119 case ALG_CRYPT:
120 ret = generate_salt(salt, 8, &ctx->errstr, ctx->pool);
121 if (ret != 0)
122 break;
123 cbuf = crypt(pw, salt);
124 if (cbuf == NULL) {
126 ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm", &rv);
128 break;
129 }
130
131 apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1);
132 if (strlen(pw) > 8) {
133 char *truncpw = apr_pstrdup(ctx->pool, pw);
134 truncpw[8] = '\0';
135 if (!strcmp(ctx->out, crypt(truncpw, salt))) {
136 ctx->errstr = apr_psprintf(ctx->pool,
137 "Warning: Password truncated to 8 "
138 "characters by CRYPT algorithm.");
139 }
140 memset(truncpw, '\0', strlen(pw));
141 }
142 break;
143#endif /* CRYPT_ALGO_SUPPORTED */
144
145#if BCRYPT_ALGO_SUPPORTED
146 case ALG_BCRYPT:
147 rv = apr_generate_random_bytes((unsigned char*)salt, 16);
148 if (rv != APR_SUCCESS) {
149 ctx->errstr = apr_psprintf(ctx->pool, "Unable to generate random "
150 "bytes: %pm", &rv);
151 ret = ERR_RANDOM;
152 break;
153 }
154
155 if (ctx->cost == 0)
156 ctx->cost = BCRYPT_DEFAULT_COST;
157 rv = apr_bcrypt_encode(pw, ctx->cost, (unsigned char*)salt, 16,
158 ctx->out, ctx->out_len);
159 if (rv != APR_SUCCESS) {
160 ctx->errstr = apr_psprintf(ctx->pool, "Unable to encode with "
161 "bcrypt: %pm", &rv);
163 break;
164 }
165 break;
166#endif /* BCRYPT_ALGO_SUPPORTED */
167
168 default:
169 ctx->errstr = apr_psprintf(ctx->pool,
170 "mk_password_hash(): unsupported algorithm %d",
171 ctx->alg);
173 }
174 memset(pw, '\0', strlen(pw));
175 return ret;
176}
177
178
int n
Definition ap_regex.h:278
APR Error Codes.
APR MD5 Routines.
APR-UTIL SHA1 library.
APR Strings library.
const char * salt
Definition apr_md5.h:139
apr_brigade_flush void * ctx
apr_size_t size
apr_uint32_t val
Definition apr_atomic.h:66
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_FROM_OS_ERROR(e)
Definition apr_errno.h:1214
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
const char * s
Definition apr_strings.h:95
static int generate_salt(char *s, size_t size, const char **errstr, apr_pool_t *pool)
Definition lua_passwd.c:47
int mk_password_hash(passwd_ctx *ctx)
Definition lua_passwd.c:87
#define ERR_GENERAL
Definition lua_passwd.h:48
#define ALG_APSHA
Definition lua_passwd.h:34
#define ALG_APMD5
Definition lua_passwd.h:33
#define ALG_BCRYPT
Definition lua_passwd.h:35
#define ERR_PWMISMATCH
Definition lua_passwd.h:42
#define ERR_RANDOM
Definition lua_passwd.h:47
#define ALG_CRYPT
Definition lua_passwd.h:36
#define BCRYPT_DEFAULT_COST
Definition lua_passwd.h:38
return NULL
Definition mod_so.c:359