/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/* Generic SASL plugin utility functions
* Rob Siemborski
* $Id: plugin_common.c,v 1.13 2003/02/13 19:56:05 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>
#ifndef macintosh
#ifdef WIN32
# include <winsock.h>
#else
# include <netdb.h>
#endif /* WIN32 */
#endif /* macintosh */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <sasl.h>
#include <saslutil.h>
#include <saslplug.h>
#include <errno.h>
#include <ctype.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include "plugin_common.h"
/* translate IPv4 mapped IPv6 address to IPv4 address */
static void sockaddr_unmapped(
#ifdef IN6_IS_ADDR_V4MAPPED
#else
#endif
)
{
#ifdef IN6_IS_ADDR_V4MAPPED
#ifdef _SUN_SDK_
#else
int port;
#endif /* _SUN_SDK_ */
return;
/* LINTED pointer alignment */
return;
/* LINTED pointer alignment */
/* LINTED pointer alignment */
#ifdef HAVE_SOCKADDR_SA_LEN
#endif
*len = sizeof(struct sockaddr_in);
#else
return;
#endif
}
{
int i, j;
#ifdef WINNT /* _SUN_SDK_ */
#else
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
#endif /* _SUN_SDK_ */
return SASL_BADPARAM;
}
#ifdef _SUN_SDK_
/* This an rfc 2732 ipv6 address */
return SASL_BADPARAM;
}
hbuf[i++] = *p;
if (i >= NI_MAXHOST)
break;
}
if (p == NULL)
p = end + 1;
else
p = p + 1;
} else {
if (++i >= NI_MAXHOST)
break;
}
if (addr[i] == ';')
p = &addr[i+1];
else
p = &addr[i];
}
if (i >= NI_MAXHOST) {
return SASL_BADPARAM;
}
hbuf[i] = '\0';
for (j = 0; p[j] != '\0'; j++)
if (!isdigit((int)(p[j]))) {
PARAMERROR( utils );
return SASL_BADPARAM;
}
#else
/* Parse the address */
if (i >= NI_MAXHOST) {
return SASL_BADPARAM;
}
}
hbuf[i] = '\0';
if (addr[i] == ';')
i++;
for (j = i; addr[j] != '\0'; j++)
PARAMERROR( utils );
return SASL_BADPARAM;
}
#endif /* _SUN_SDK_ */
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
PARAMERROR( utils );
return SASL_BADPARAM;
}
#ifdef _SUN_SDK_
return (SASL_BUFOVER);
#endif /* _SUN_SDK_ */
PARAMERROR( utils );
return SASL_BUFOVER;
}
return SASL_OK;
}
{
unsigned i;
int ret;
char *pos;
return SASL_BADPARAM;
}
if(!(*output)) {
if(!*output) {
return SASL_NOMEM;
}
}
for(i=0; i<numiov; i++)
return SASL_NOMEM;
}
for(i=0; i<numiov; i++) {
}
return SASL_OK;
}
/* Basically a conditional call to realloc(), if we need more */
{
return SASL_BADPARAM;
}
if(!(*rwbuf)) {
*curlen = 0;
return SASL_NOMEM;
}
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
needed *= 2;
*curlen = 0;
return SASL_NOMEM;
}
}
return SASL_OK;
}
/* copy a string */
{
#ifdef _SUN_SDK_
int len;
#else
#endif /* _SUN_SDK_ */
return SASL_BADPARAM;
}
#ifdef _SUN_SDK_
#endif /* _SUN_SDK_ */
if (!*out) {
return SASL_NOMEM;
}
if (outlen)
return SASL_OK;
}
{
}
{
#ifdef _SUN_SDK_
#else
#endif /* _SUN_SDK_ */
}
/*
* Trys to find the prompt with the lookingfor id in the prompt list
* Returns it if found. NULL otherwise
*/
unsigned int lookingfor)
{
if (promptlist && *promptlist) {
return prompt;
}
}
return NULL;
}
/*
* Retrieve the simple string given by the callback id.
*/
{
void *simple_context;
/* see if we were given the result in the prompt */
/* We prompted, and got.*/
return SASL_BADPARAM;
}
return SASL_OK;
}
/* Try to get the callback... */
return SASL_OK;
return ret;
return SASL_BADPARAM;
}
}
return ret;
}
/*
* Retrieve the user password.
*/
{
void *pass_context;
*iscopy = 0;
/* see if we were given the password in the prompt */
/* We prompted, and got.*/
return SASL_BADPARAM;
}
/* copy what we got into a secret_t */
if (!*password) {
return SASL_NOMEM;
}
*iscopy = 1;
return SASL_OK;
}
/* Try to get the callback... */
&pass_cb, &pass_context);
return ret;
if (!*password) {
return SASL_BADPARAM;
}
}
return ret;
}
/*
* Retrieve the string given by the challenge prompt id.
*/
{
void *chalprompt_context;
/* see if we were given the password in the prompt */
/* We prompted, and got.*/
return SASL_BADPARAM;
}
return SASL_OK;
}
/* Try to get the callback... */
return ret;
if (!*result) {
return SASL_BADPARAM;
}
}
return ret;
}
/*
* Retrieve the client realm.
*/
{
void *realm_context;
/* see if we were given the result in the prompt */
/* We prompted, and got.*/
return SASL_BADPARAM;
}
return SASL_OK;
}
/* Try to get the callback... */
&realm_cb, &realm_context);
return ret;
if (!*realm) {
return SASL_BADPARAM;
}
}
return ret;
}
/*
* Make the requested prompts. (prompt==NULL means we don't want it)
*/
#ifdef _INTEGRATED_SOLARIS_
void **h,
#endif /* _INTEGRATED_SOLARIS_ */
const char *user_prompt, const char *user_def,
const char *auth_prompt, const char *auth_def,
const char *pass_prompt, const char *pass_def,
const char *echo_chal,
const char *echo_prompt, const char *echo_def,
const char *realm_chal,
const char *realm_prompt, const char *realm_def)
{
int alloc_size;
if (user_prompt) num++;
if (auth_prompt) num++;
if (pass_prompt) num++;
if (echo_prompt) num++;
if (realm_prompt) num++;
if (num == 1) {
return SASL_FAIL;
}
if (!prompts) {
return SASL_NOMEM;
}
*prompts_res = prompts;
if (user_prompt) {
#ifdef _INTEGRATED_SOLARIS_
gettext("Authorization Name"));
#else
#endif /* _INTEGRATED_SOLARIS_ */
prompts++;
}
if (auth_prompt) {
#ifdef _INTEGRATED_SOLARIS_
gettext( "Authentication Name"));
#else
#endif /* _INTEGRATED_SOLARIS_ */
prompts++;
}
if (pass_prompt) {
#ifdef _INTEGRATED_SOLARIS_
#else
#endif /* _INTEGRATED_SOLARIS_ */
prompts++;
}
if (echo_prompt) {
prompts++;
}
if (realm_prompt) {
prompts++;
}
/* add the ending one */
return SASL_OK;
}
/*
* Decode and concatenate multiple packets using the given function
* to decode each packet.
*/
void *context,
char **output, /* output buffer */
unsigned *outputsize, /* current size of output buffer */
unsigned *outputlen, /* length of data in output buffer */
int (*decode_pkt)(void *context,
{
unsigned tmplen = 0;
int ret;
*outputlen = 0;
while (inputlen!=0)
{
/* no need to free tmp */
{
/* Protect stupid clients */
}
}
return SASL_OK;
}
/* returns the realm we should pretend to be in */
const char *serverFQDN, const char *input)
{
int ret;
#ifdef _SUN_SDK_
const char *r;
#else
char *r;
#endif /* _SUN_SDK_ */
if(!user || !serverFQDN) {
PARAMERROR( utils );
return SASL_BADPARAM;
}
if (!r) {
/* hmmm, the user didn't specify a realm */
if(user_realm && user_realm[0]) {
} else {
/* Default to serverFQDN */
}
}
} else {
r++;
#ifdef _SUN_SDK_
if (*user) {
} else {
ret = SASL_NOMEM;
}
}
#else
*--r = '\0';
if (*user) {
} else {
ret = SASL_NOMEM;
}
*r = '@';
#endif /* _SUN_SDK_ */
}
return ret;
}
#ifdef _INTEGRATED_SOLARIS_
int
{
const char *s;
const char *begin;
const char *end;
return is_client;
for (;;) {
/* skip over leading whitespace and commas */
begin++;
if (*begin == '\0')
break;
/* Find the end of the language tag */
return 1;
return 0;
}
return is_client;
}
typedef struct prompt_list {
char *prompt;
} prompt_list;
const char *
{
void *simple_context;
const char *s_locale;
int ret;
char *buf;
const char *ret_buf;
return s;
if (s == NULL) {
}
*h = NULL;
return NULL;
}
} else
return s;
if (s == s_locale) {
return s;
}
} else {
*h = list;
}
}
return ret_buf;
}
#include <iconv.h>
#include <langinfo.h>
/*
* local_to_utf converts a string in the current codeset to utf-8.
* If no codeset is specified, then codeset 646 will be used.
* Upon successful completion, this function will return a non-NULL buffer
* that is allocated by local_to_utf.
*
* If utils is NULL, local_to_utf will use the standard memory allocation
* functions, otherwise the memory functions defined in sasl_utils_t will
* be used.
*
* local_to_utf will return NULL in the case of any error
*/
char *
{
const char *inptr;
char *outptr;
if (s == NULL)
return NULL;
code_set = "646";
else {
}
return buf;
}
return NULL;
else
(void) iconv_close(cd);
return NULL;
}
inptr = s;
for (;;) {
buf_size *= 2;
else
break;
}
continue;
}
break;
}
break;
ileft = 0;
}
if (oleft > 0) {
*outptr = '\0';
else
} else {
}
}
else
}
(void) iconv_close(cd);
return buf;
}
#endif /* _INTEGRATED_SOLARIS_ */