⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plugin_common.c

📁 代理服务器源代码 供大家学习使用,希望大家喜欢
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef BUILD_GSSAPI_PLUGIN/* Generic SASL plugin utility functions * Rob Siemborski * $Id: plugin_common.c,v 1.20 2004/06/23 18:43:37 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 *    the documentation and/or other materials provided with the *    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. */#ifndef macintosh#ifdef WIN32# include <winsock2.h>#else# include <sys/types.h># include <sys/uio.h># include <sys/socket.h># include <netinet/in.h># include <arpa/inet.h># include <netdb.h># include <sys/utsname.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>#include <stdio.h>#include <string.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  struct sockaddr *sa, socklen_t *len#else  struct sockaddr *sa __attribute__((unused)),  socklen_t *len __attribute__((unused))#endif){#ifdef IN6_IS_ADDR_V4MAPPED    struct sockaddr_in6 *sin6;    struct sockaddr_in *sin4;    uint32_t addr;    int port;    if (sa->sa_family != AF_INET6)	return;    sin6 = (struct sockaddr_in6 *)sa;    if (!IN6_IS_ADDR_V4MAPPED((&sin6->sin6_addr)))	return;    sin4 = (struct sockaddr_in *)sa;    addr = *(uint32_t *)&sin6->sin6_addr.s6_addr[12];    port = sin6->sin6_port;    memset(sin4, 0, sizeof(struct sockaddr_in));    sin4->sin_addr.s_addr = addr;    sin4->sin_port = port;    sin4->sin_family = AF_INET;#ifdef HAVE_SOCKADDR_SA_LEN    sin4->sin_len = sizeof(struct sockaddr_in);#endif    *len = sizeof(struct sockaddr_in);#else    return;#endif}int _plug_ipfromstring(const sasl_utils_t *utils, const char *addr,		       struct sockaddr *out, socklen_t outlen) {    int i, j;    socklen_t len;    struct sockaddr_storage ss;    struct addrinfo hints, *ai = NULL;    char hbuf[NI_MAXHOST];        if(!utils || !addr || !out) {	if(utils) PARAMERROR( utils );	return SASL_BADPARAM;    }    /* Parse the address */    for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) {	if (i >= NI_MAXHOST) {	    if(utils) PARAMERROR( utils );	    return SASL_BADPARAM;	}	hbuf[i] = addr[i];    }    hbuf[i] = '\0';    if (addr[i] == ';')	i++;    /* XXX/FIXME: Do we need this check? */    for (j = i; addr[j] != '\0'; j++)	if (!isdigit((int)(addr[j]))) {	    PARAMERROR( utils );	    return SASL_BADPARAM;	}    memset(&hints, 0, sizeof(hints));    hints.ai_family = PF_UNSPEC;    hints.ai_socktype = SOCK_STREAM;    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;    if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0) {		PARAMERROR( utils );	return SASL_BADPARAM;    }    len = ai->ai_addrlen;    memcpy(&ss, ai->ai_addr, len);    freeaddrinfo(ai);    sockaddr_unmapped((struct sockaddr *)&ss, &len);    if (outlen < len) {	PARAMERROR( utils );	return SASL_BUFOVER;    }    memcpy(out, &ss, len);    return SASL_OK;}int _plug_iovec_to_buf(const sasl_utils_t *utils, const struct iovec *vec,		       unsigned numiov, buffer_info_t **output) {    unsigned i;    int ret;    buffer_info_t *out;    char *pos;    if(!utils || !vec || !output) {	if(utils) PARAMERROR( utils );	return SASL_BADPARAM;    }        if(!(*output)) {	*output = utils->malloc(sizeof(buffer_info_t));	if(!*output) {	    MEMERROR(utils);	    return SASL_NOMEM;	}	memset(*output,0,sizeof(buffer_info_t));    }    out = *output;        out->curlen = 0;    for(i=0; i<numiov; i++)	out->curlen += vec[i].iov_len;    ret = _plug_buf_alloc(utils, &out->data, &out->reallen, out->curlen);    if(ret != SASL_OK) {	MEMERROR(utils);	return SASL_NOMEM;    }        memset(out->data, 0, out->reallen);    pos = out->data;        for(i=0; i<numiov; i++) {	memcpy(pos, vec[i].iov_base, vec[i].iov_len);	pos += vec[i].iov_len;    }    return SASL_OK;}/* Basically a conditional call to realloc(), if we need more */int _plug_buf_alloc(const sasl_utils_t *utils, char **rwbuf,		    unsigned *curlen, unsigned newlen) {    if(!utils || !rwbuf || !curlen) {	PARAMERROR(utils);	return SASL_BADPARAM;    }    if(!(*rwbuf)) {	*rwbuf = utils->malloc(newlen);	if (*rwbuf == NULL) {	    *curlen = 0;	    MEMERROR(utils);	    return SASL_NOMEM;	}	*curlen = newlen;    } else if(*rwbuf && *curlen < newlen) {	size_t needed = 2*(*curlen);	while(needed < newlen)	    needed *= 2;	*rwbuf = utils->realloc(*rwbuf, needed);	if (*rwbuf == NULL) {	    *curlen = 0;	    MEMERROR(utils);	    return SASL_NOMEM;	}	*curlen = needed;    }     return SASL_OK;}/* copy a string */int _plug_strdup(const sasl_utils_t * utils, const char *in,		 char **out, int *outlen){  size_t len = strlen(in);  if(!utils || !in || !out) {      if(utils) PARAMERROR(utils);      return SASL_BADPARAM;  }  *out = utils->malloc(len + 1);  if (!*out) {      MEMERROR(utils);      return SASL_NOMEM;  }  strcpy((char *) *out, in);  if (outlen)      *outlen = len;  return SASL_OK;}void _plug_free_string(const sasl_utils_t *utils, char **str){  size_t len;  if (!utils || !str || !(*str)) return;  len = strlen(*str);  utils->erasebuffer(*str, len);  utils->free(*str);  *str=NULL;}void _plug_free_secret(const sasl_utils_t *utils, sasl_secret_t **secret) {    if(!utils || !secret || !(*secret)) return;    utils->erasebuffer((char *)(*secret)->data, (*secret)->len);    utils->free(*secret);    *secret = NULL;}/*  * Trys to find the prompt with the lookingfor id in the prompt list * Returns it if found. NULL otherwise */sasl_interact_t *_plug_find_prompt(sasl_interact_t **promptlist,				   unsigned int lookingfor){    sasl_interact_t *prompt;    if (promptlist && *promptlist) {	for (prompt = *promptlist; prompt->id != SASL_CB_LIST_END; ++prompt) {	    if (prompt->id==lookingfor)		return prompt;	}    }    return NULL;}/* * Retrieve the simple string given by the callback id. */int _plug_get_simple(const sasl_utils_t *utils, unsigned int id, int required,		     const char **result, sasl_interact_t **prompt_need){    int ret = SASL_FAIL;    sasl_getsimple_t *simple_cb;    void *simple_context;    sasl_interact_t *prompt;    *result = NULL;    /* see if we were given the result in the prompt */    prompt = _plug_find_prompt(prompt_need, id);    if (prompt != NULL) {	/* We prompted, and got.*/		if (required && !prompt->result) {	    SETERROR(utils, "Unexpectedly missing a prompt result");	    return SASL_BADPARAM;	}	*result = prompt->result;	return SASL_OK;    }      /* Try to get the callback... */    ret = utils->getcallback(utils->conn, id, &simple_cb, &simple_context);    if (ret == SASL_FAIL && !required)	return SASL_OK;    if (ret == SASL_OK && simple_cb) {	ret = simple_cb(simple_context, id, result, NULL);	if (ret != SASL_OK)	    return ret;	if (required && !*result) {	    PARAMERROR(utils);	    return SASL_BADPARAM;	}    }      return ret;}/* * Retrieve the user password. */int _plug_get_password(const sasl_utils_t *utils, sasl_secret_t **password,		       unsigned int *iscopy, sasl_interact_t **prompt_need){    int ret = SASL_FAIL;    sasl_getsecret_t *pass_cb;    void *pass_context;    sasl_interact_t *prompt;    *password = NULL;    *iscopy = 0;    /* see if we were given the password in the prompt */    prompt = _plug_find_prompt(prompt_need, SASL_CB_PASS);    if (prompt != NULL) {	/* We prompted, and got.*/		if (!prompt->result) {	    SETERROR(utils, "Unexpectedly missing a prompt result");	    return SASL_BADPARAM;	}      	/* copy what we got into a secret_t */	*password = (sasl_secret_t *) utils->malloc(sizeof(sasl_secret_t) +						    prompt->len + 1);	if (!*password) {	    MEMERROR(utils);	    return SASL_NOMEM;	}      	(*password)->len=prompt->len;	memcpy((*password)->data, prompt->result, prompt->len);	(*password)->data[(*password)->len]=0;	*iscopy = 1;	return SASL_OK;    }    /* Try to get the callback... */    ret = utils->getcallback(utils->conn, SASL_CB_PASS,			     &pass_cb, &pass_context);    if (ret == SASL_OK && pass_cb) {	ret = pass_cb(utils->conn, pass_context, SASL_CB_PASS, password);	if (ret != SASL_OK)	    return ret;	if (!*password) {	    PARAMERROR(utils);	    return SASL_BADPARAM;	}    }    return ret;}/* * Retrieve the string given by the challenge prompt id. */int _plug_challenge_prompt(const sasl_utils_t *utils, unsigned int id,			   const char *challenge, const char *promptstr,			   const char **result, sasl_interact_t **prompt_need){    int ret = SASL_FAIL;    sasl_chalprompt_t *chalprompt_cb;    void *chalprompt_context;    sasl_interact_t *prompt;    *result = NULL;    /* see if we were given the password in the prompt */    prompt = _plug_find_prompt(prompt_need, id);    if (prompt != NULL) {	/* We prompted, and got.*/		if (!prompt->result) {	    SETERROR(utils, "Unexpectedly missing a prompt result");	    return SASL_BADPARAM;	}      	*result = prompt->result;	return SASL_OK;    }    /* Try to get the callback... */    ret = utils->getcallback(utils->conn, id,			     &chalprompt_cb, &chalprompt_context);    if (ret == SASL_OK && chalprompt_cb) {	ret = chalprompt_cb(chalprompt_context, id,			    challenge, promptstr, NULL, result, NULL);	if (ret != SASL_OK)	    return ret;	if (!*result) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -