freeipa/util/ipa_pwd_ntlm.c

106 lines
2.5 KiB
C
Raw Normal View History

2012-08-24 07:46:05 -05:00
/*
* Password related utils for FreeIPA
*
* Authors: Simo Sorce <ssorce@redhat.com>
*
* Copyright (C) 2011,2012 Simo Sorce, Red Hat
* see file 'COPYING' for use and warranty information
*
* This program is free software you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <iconv.h>
#include <openssl/des.h>
#include <openssl/md4.h>
#include <dirsrv/slapi-plugin.h>
#include "ipa_pwd.h"
#define KTF_DOS_CHARSET "CP850" /* same default as samba */
#define KTF_UTF8 "UTF-8"
#define KTF_UCS2 "UCS-2LE"
/* create the nt hash
2012-08-24 07:46:05 -05:00
newPassword: the clear text utf8 password
nt_key[out]: array with generated hash
2012-08-24 07:46:05 -05:00
*/
int encode_nt_key(char *newPasswd, uint8_t *nt_key)
2012-08-24 07:46:05 -05:00
{
int ret = 0;
iconv_t cd;
size_t cs, il, ol, sl;
char *inc, *outc;
char *ucs2Passwd;
MD4_CTX md4ctx;
/* TODO: must store the dos charset somewhere in the directory */
cd = iconv_open(KTF_UCS2, KTF_UTF8);
if (cd == (iconv_t)(-1)) {
ret = -1;
goto done;
}
2012-08-24 07:46:05 -05:00
il = strlen(newPasswd);
2012-08-24 07:46:05 -05:00
/* an ucs2 string can be at most double than an utf8 one */
sl = ol = (il+1)*2;
ucs2Passwd = calloc(ol, 1);
if (!ucs2Passwd) {
ret = -1;
2012-08-24 07:46:05 -05:00
iconv_close(cd);
goto done;
2012-08-24 07:46:05 -05:00
}
inc = newPasswd;
outc = ucs2Passwd;
cs = iconv(cd, &inc, &il, &outc, &ol);
if (cs == -1) {
ret = -1;
free(ucs2Passwd);
2012-08-24 07:46:05 -05:00
iconv_close(cd);
goto done;
}
2012-08-24 07:46:05 -05:00
/* done with it */
iconv_close(cd);
2012-08-24 07:46:05 -05:00
/* get the final ucs2 string length */
sl -= ol;
2012-08-24 07:46:05 -05:00
ret = MD4_Init(&md4ctx);
if (ret == 0) {
ret = -1;
free(ucs2Passwd);
goto done;
}
ret = MD4_Update(&md4ctx, ucs2Passwd, sl);
if (ret == 0) {
ret = -1;
free(ucs2Passwd);
goto done;
}
ret = MD4_Final(nt_key, &md4ctx);
if (ret == 0) {
ret = -1;
free(ucs2Passwd);
goto done;
2012-08-24 07:46:05 -05:00
}
ret = 0;
done:
return ret;
}