non-ascii password in kerberos authentication
Xu Qiang
Qiang.Xu at fujixerox.com
Mon Sep 17 04:26:21 EDT 2007
> -----Original Message-----
> From: Ken Raeburn [mailto:raeburn at MIT.EDU]
> Sent: Monday, September 17, 2007 12:12 PM
> To: Xu Qiang
> Cc: Paul Moore; krbdev at mit.edu
> Subject: Re: non-ascii password in kerberos authentication
>
> I can think of some workarounds, none especially pretty.
>
> * If you can be sure that RC4 is being used, convert to UCS-2LE
> before calling into the library in the first place.
>
> * Modify the MIT code you're using to be aware that you're always
> passing in UTF-8, and in the RC4 string-to-key code, always convert
> to UCS-2LE. Because of the transition issues and possible existing
> deployments using other approaches, I'm not sure if we would be able
> to incorporate a patch for this, but we can discuss it. I think it
> would get the job done for you, though.
A function is written to convert:
=========================================================
static char * character_converter(char *fromCode, char *toCode, const char *infield)
{
/*
** The UTF-8 character conversion can take up to 2 bytes of space, which is double
** the size of normal ascii character allocation for ldap attributes which is defined
** in MAX_ATTRIBUTE_LENGTH. This doubled plus 1 for the null terminator.
*/
char outbuf[MAX_ATTRIBUTE_LENGTH*2+1];
static char convertedBuf[MAX_ATTRIBUTE_LENGTH*2+1];
char* outptr = outbuf;
size_t outsize = sizeof(outbuf);
size_t result = 0;
const char *inptr = infield;
size_t insize = strlen(infield);
int saved_errno = 0;
iconv_t cd;
cd = iconv_open(toCode, fromCode);
if (cd == (iconv_t)(-1)) {
fprintf(stderr, "Failed to perform iconv_open\n");
return (NULL);
}
iconv(cd, NULL, NULL, NULL, NULL);
/*
** call the iconv library to perform the conversion.
*/
fprintf(stderr, "ENTER THE ICONV FUNCTION CALL!\n");
result = iconv(cd, (const char**)&inptr, &insize, &outptr, &outsize);
fprintf(stderr, "EXIT THE ICONV FUNCTION CALL!\n");
/*
** check for error conditions.
*/
if (result == (size_t)(-1)) {
fprintf(stderr, "\nIN THE CHARACTER CONVERTER\n");
if (errno == EILSEQ) {
fprintf(stderr, "iconv: %s: cannot convert\n", inptr);
iconv_close(cd);
return (NULL);
}
else if (errno == EINVAL) {
if (insize > (MAX_ATTRIBUTE_LENGTH*2+1)) {
fprintf(stderr, "iconv: %s: incomplete character or shift sequence\n", inptr);
iconv_close(cd);
return (NULL);
}
}
else if (errno != E2BIG) {
saved_errno = errno;
fprintf(stderr, "iconv: [%s]: \n", inptr);
errno = saved_errno;
perror("");
iconv_close(cd);
return (NULL);
}
}
/*
** Check to make certain that the returned size is correct. Not exactly sure what this comparison is
** doing for us. outptr vs outbuf was taken directly from the iconv source code as is. required
** for this to work.
*/
if (outptr != outbuf) {
int saved_errno = errno;
/*
** save off the result into the convertedBuf.
*/
memset(convertedBuf, '\0', (MAX_ATTRIBUTE_LENGTH*2+1));
strncpy(convertedBuf, outbuf, outptr-outbuf);
errno = saved_errno;
}
/*
** close descriptor.
*/
iconv_close(cd);
return (convertedBuf);
}
=========================================================
Originally, the function was written to convert ISO-8859-1 to UTF-8, but i think it should be OK to use it to convert to UCS-2LE. Essentially the function calls system library function "iconv()" to do the job.
I am calling it with:
=========================================================
#define UCS_2LE "UCS-2LE"
#define UTF_8 "UTF-8"
#define ISO_8859 "ISO-8859-1"
#define AUTH_PASSWORD_SIZE (256)
#define MAX_ATTRIBUTE_LENGTH (AUTH_PASSWORD_SIZE * 2)
char tmpPassword[AUTH_PASSWORD_SIZE];
char *tmpUcs2Password = NULL;
char *password;
......
fprintf(stderr, "before convert, password is [%s]\n", tmpPassword);
if ((tmpUcs2Password = character_converter(ISO_8859, UCS_2LE, tmpPassword)) != NULL)
{
password = tmpUcs2Password;
}
else
{
fprintf(stderr, "Fail to convert character!\n");
}
fprintf(stderr, "after convert, password is [%s]\n", password);
=========================================================
Look quite straightforward.
But although my passed in password is [eeFair123], the converted password is cut into only one char - [e]. It seems UCS-2LE is not supported by the system library function "iconv()"?
Need help here in conversion,
Xu Qiang
More information about the krbdev
mailing list