/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* saslutil.c
* Rob Siemborski
* Tim Martin
* $Id: saslutil.c,v 1.41 2003/03/19 18:25:28 rjs3 Exp $
*/
/*
* Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* 3. The name "Carnegie Mellon University" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For permission or any other legal
* details, please contact
* Office of Technology Transfer
* Carnegie Mellon University
* 5000 Forbes Avenue
* Pittsburgh, PA 15213-3890
* (412) 268-4387, fax: (412) 268-7395
* tech-transfer@andrew.cmu.edu
*
* 4. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by Computing Services
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
*
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#include "saslint.h"
#include <saslutil.h>
/* Contains:
*
* sasl_decode64
* sasl_encode64
* sasl_mkchal
* sasl_utf8verify
* sasl_randcreate
* sasl_randfree
* sasl_randseed
* sasl_rand
* sasl_churn
*/
#ifndef _SUN_SDK_
char *encode_table;
char *decode_table;
#endif /* !_SUN_SDK_ */
struct sasl_rand_s {
/* since the init time might be really bad let's make this lazy */
int initialized;
};
static char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????";
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
};
/* base64 encode
* in -- input data
* inlen -- input data length
* out -- output buffer (will be NUL terminated)
* outmax -- max size of output buffer
* result:
* outlen -- gets actual length of output buffer (optional)
*
* Returns SASL_OK on success, SASL_BUFOVER if result won't fit
*/
{
unsigned char oval;
#ifndef _SUN_SDK_
char *blah;
#endif /* !_SUN_SDK_ */
unsigned olen;
/* check params */
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
/* Will it fit? */
if (outlen)
return SASL_BUFOVER;
/* Do the work... */
#ifndef _SUN_SDK_
#endif /* !_SUN_SDK_ */
while (inlen >= 3) {
/* user provided max buffer size; make sure we don't go over it */
in += 3;
inlen -= 3;
}
if (inlen > 0) {
/* user provided max buffer size; make sure we don't go over it */
*out++ = '=';
}
*out = '\0';
return SASL_OK;
}
/* base64 decode
* in -- input data
* inlen -- length of input data
* out -- output data (may be same as in, must have enough space)
* outmax -- max size of output buffer
* result:
* outlen -- actual output length
*
* returns:
* SASL_BADPROT on bad base64,
* SASL_BUFOVER if result won't fit,
* SASL_OK on success
*/
{
/* check parameters */
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
/* xxx these necessary? */
{
in += 4;
if (c3 != '=') {
if (c4 != '=') {
}
}
}
*out=0; /* terminate string */
return SASL_OK;
}
/* make a challenge string (NUL terminated)
* buf -- buffer for result
* maxlen -- max length of result
* hostflag -- 0 = don't include hostname, 1 = include hostname
* returns final length or 0 if not enough space
*/
char *buf,
unsigned maxlen,
unsigned hostflag)
{
#ifndef _SUN_SDK_
#endif /* !_SUN_SDK_ */
unsigned long randnum;
#ifndef _SUN_SDK_
int ret;
#endif /* !_SUN_SDK_ */
unsigned len;
#ifdef _SUN_SDK_
else
return 0;
#endif /* _SUN_SDK_ */
+ (2 * 20); /* 2 numbers, 20 => max size of 64bit
* ulong in base 10 */
return 0;
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
else
}
/* borrowed from larry. probably works :)
* probably is also in acap server somewhere
*/
{
unsigned i;
#ifdef _SUN_SDK_
#endif /* _SUN_SDK_ */
for (i = 0; i < len; i++) {
/* how many octets? */
int seqlen = 0;
#ifdef _SUN_SDK_
if (seqlen == 0) {
return SASL_BADPROT;
continue; /* this is a valid US-ASCII char */
}
#else
if (seqlen == 0) continue; /* this is a valid US-ASCII char */
#endif /* _SUN_SDK_ */
while (--seqlen)
#ifdef _SUN_SDK_
return SASL_BADPROT; /* needed an appropriate octet */
#else
#endif /* _SUN_SDK_ */
}
return SASL_OK;
}
/*
* To see why this is really bad see RFC 1750
*
* unfortunatly there currently is no way to make
* cryptographically secure pseudo random numbers
* without specialized hardware etc...
* thus, this is for nonce use only
*/
{
long curtime;
#ifdef DEV_RANDOM
{
int fd;
if(fd != -1) {
do {
else if(bytesread <= 0) break;
} while(bytesleft != 0);
}
}
#endif
#ifdef HAVE_GETPID
#endif
#ifdef HAVE_GETTIMEOFDAY
{
/* xxx autoconf macro */
#ifdef _SVID_GETTOD
if (!gettimeofday(&tv))
#else
#endif
{
/* longs are guaranteed to be at least 32 bits; we need
16 bits in each short */
return;
}
}
#endif /* HAVE_GETTIMEOFDAY */
/* if all else fails just use time() */
return;
}
{
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
/* init is lazy */
(*rpool)->initialized = 0;
return SASL_OK;
}
{
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
}
{
/* is it acceptable to just use the 1st 3 char's given??? */
unsigned int lup;
/* check params */
if (len > sizeof(unsigned short)*RPOOL_SIZE)
len = sizeof(unsigned short)*RPOOL_SIZE;
}
{
if (!rpool->initialized) {
#ifndef HAVE_JRAND48
{
/* xxx varies by platform */
}
#endif /* HAVE_JRAND48 */
#endif /* WIN32 */
}
}
{
unsigned int lup;
/* check params */
/* init if necessary */
#else /* WIN32 */
#ifdef HAVE_JRAND48
#else
#endif /* HAVE_JRAND48 */
#endif /* WIN32 */
}
/* this function is just a bad idea all around, since we're not trying to
implement a true random number generator */
{
unsigned int lup;
/* check params */
/* init if necessary */
}
}
#ifndef _SUN_SDK_
#ifdef WIN32
/*****************************************************************************
*
* MODULE NAME : GETOPT.C
*
* COPYRIGHTS:
* This module contains code made available by IBM
* Corporation on an AS IS basis. Any one receiving the
* module is considered to be licensed under IBM copyrights
* to use the IBM-provided source code in any way he or she
* deems fit, including copying it, compiling it, modifying
* it, and redistributing it, with or without
* modifications. No license under any IBM patents or
* patent applications is to be implied from this copyright
* license.
*
* A user of the module should understand that IBM cannot
* provide technical support for the module and will not be
* responsible for any consequences of use of the program.
*
* Any notices, including this one, are not to be removed
* from the module without the prior written consent of
* IBM.
*
* AUTHOR: Original author:
* G. R. Blair (BOBBLAIR at AUSVM1)
* Internet: bobblair@bobblair.austin.ibm.com
*
* Extensively revised by:
* John Q. Walker II, Ph.D. (JOHHQ at RALVM6)
* Internet: johnq@ralvm6.vnet.ibm.com
*
*****************************************************************************/
/******************************************************************************
* getopt()
*
* The getopt() function is a command line parser. It returns the next
* option character in argv that matches an option character in opstring.
*
* The argv argument points to an array of argc+1 elements containing argc
* pointers to character strings followed by a null pointer.
*
* The opstring argument points to a string of option characters; if an
* option character is followed by a colon, the option is expected to have
* an argument that may or may not be separated from it by white space.
* The external variable optarg is set to point to the start of the option
* argument on return from getopt().
*
* The getopt() function places in optind the argv index of the next argument
* to be processed. The system initializes the external variable optind to
* 1 before the first call to getopt().
*
* When all options have been processed (that is, up to the first nonoption
* argument), getopt() returns EOF. The special option "--" may be used to
* delimit the end of the options; EOF will be returned, and "--" will be
* skipped.
*
* The getopt() function returns a question mark (?) when it encounters an
* option character not included in opstring. This error message can be
* disabled by setting opterr to zero. Otherwise, it returns the option
* character that was detected.
*
* If the special option "--" is detected, or all options have been
* processed, EOF is returned.
*
* Options are marked by either a minus sign (-) or a slash (/).
*
* No errors are defined.
*****************************************************************************/
#include <string.h> /* for strchr() */
/* static (global) variables that are specified as exported by getopt() */
/* handle possible future character set concerns by putting this in a macro */
{
if (pIndexPosition != NULL) {
/* we last left off inside an argv string */
if (*(++pIndexPosition)) {
/* there is more to come in the most recent argv */
}
}
if (pArgString == NULL) {
/* we didn't leave off in the middle of an argv string */
/* more command-line arguments than the argument count */
return EOF; /* used up all command-line arguments */
}
/*---------------------------------------------------------------------
* If the next argv[] is not an option, there can be no more options.
*-------------------------------------------------------------------*/
('-' != *pArgString)) {
--optind; /* point to current arg once we're done */
return EOF; /* used up all the command-line flags */
}
/* check for special end-of-flags markers */
return EOF; /* encountered the special flag */
}
pArgString++; /* look past the / or - */
}
/*---------------------------------------------------------------------
* Rare case: if opterr is non-zero, return a question mark;
* otherwise, just return the colon we're on.
*-------------------------------------------------------------------*/
}
/*---------------------------------------------------------------------
* The letter on the command-line wasn't any good.
*-------------------------------------------------------------------*/
}
else {
/*---------------------------------------------------------------------
* The letter on the command-line matches one we expect to see
*-------------------------------------------------------------------*/
/* It is a colon. Look for an argument string. */
}
else {
/*-------------------------------------------------------------
* The argument string must be in the next argv.
* But, what if there is none (bad input from the user)?
* In that case, return the letter, and optarg as NULL.
*-----------------------------------------------------------*/
else {
}
}
}
else {
/* it's not a colon, so just return the letter */
}
return (int)*pArgString; /* return the letter that matched */
}
}
#ifndef PASSWORD_MAX
#endif
#include <conio.h>
char *
const char *prompt;
{
register char *p;
register c;
*p++ = c;
}
*p = '\0';
return(pbuf);
}
#endif /* WIN32 */
#endif /* !_SUN_SDK_ */