diff options
author | molotkov-and <[email protected]> | 2023-08-18 17:20:47 +0300 |
---|---|---|
committer | molotkov-and <[email protected]> | 2023-08-18 19:42:07 +0300 |
commit | 73215359bc33e76f5b94d1832a377072bf245cfc (patch) | |
tree | 9cb8ad61d8c3cd107353d42951560ff3cf1b966d /contrib/libs/sasl/common | |
parent | 1cbfd34a55732f7b1d407986b45e40853f01f2c2 (diff) |
KIKIMR-18220: Enrich token with groups from LDAP
Add ldap functions wrapper and separate in different files for compatibility with different OS.
Add user groups fetching from ldap server.
Limitations:
- Fixed 'memberOf' attribute
- No tests to check how filter for search created
- Fetched groups are returned in event as is.
Diffstat (limited to 'contrib/libs/sasl/common')
-rw-r--r-- | contrib/libs/sasl/common/plugin_common.c | 920 | ||||
-rw-r--r-- | contrib/libs/sasl/common/plugin_common.h | 230 |
2 files changed, 1150 insertions, 0 deletions
diff --git a/contrib/libs/sasl/common/plugin_common.c b/contrib/libs/sasl/common/plugin_common.c new file mode 100644 index 00000000000..94d4479245f --- /dev/null +++ b/contrib/libs/sasl/common/plugin_common.c @@ -0,0 +1,920 @@ +/* Generic SASL plugin utility functions + * Rob Siemborski + */ +/* + * Copyright (c) 1998-2016 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 + * Carnegie Mellon University + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * + * 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 <winsock2.h> +# include <versionhelpers.h> +#else +# 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> + +#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; +#ifdef s6_addr32 + addr = *(uint32_t *)&sin6->sin6_addr.s6_addr32[3]; +#else + memcpy(&addr, &sin6->sin6_addr.s6_addr[12], 4); +#endif + 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 + 1 >= 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 = (socklen_t) 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) { + if (utils) 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) { + unsigned 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 = 0; + + if(!utils || !in || !out) { + if(utils) PARAMERROR(utils); + return SASL_BADPARAM; + } + + len = strlen(in); + + *out = utils->malloc(len + 1); + if (!*out) { + MEMERROR(utils); + return SASL_NOMEM; + } + + strcpy((char *) *out, in); + + if (outlen) + *outlen = (int) 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, (unsigned int) 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 in _plug_get_simple"); + return SASL_BADPARAM; + } + + *result = prompt->result; + return SASL_OK; + } + + /* Try to get the callback... */ + ret = utils->getcallback(utils->conn, id, (sasl_callback_ft *)&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 in _plug_get_password"); + 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, + (sasl_callback_ft *)&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 in _plug_challenge_prompt"); + return SASL_BADPARAM; + } + + *result = prompt->result; + return SASL_OK; + } + + /* Try to get the callback... */ + ret = utils->getcallback(utils->conn, id, + (sasl_callback_ft *)&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) { + PARAMERROR(utils); + return SASL_BADPARAM; + } + } + + return ret; +} + +/* + * Retrieve the client realm. + */ +int _plug_get_realm(const sasl_utils_t *utils, const char **availrealms, + const char **realm, sasl_interact_t **prompt_need) +{ + int ret = SASL_FAIL; + sasl_getrealm_t *realm_cb; + void *realm_context; + sasl_interact_t *prompt; + + *realm = NULL; + + /* see if we were given the result in the prompt */ + prompt = _plug_find_prompt(prompt_need, SASL_CB_GETREALM); + if (prompt != NULL) { + /* We prompted, and got.*/ + + if (!prompt->result) { + SETERROR(utils, "Unexpectedly missing a prompt result in _plug_get_realm"); + return SASL_BADPARAM; + } + + *realm = prompt->result; + return SASL_OK; + } + + /* Try to get the callback... */ + ret = utils->getcallback(utils->conn, SASL_CB_GETREALM, + (sasl_callback_ft *)&realm_cb, &realm_context); + + if (ret == SASL_OK && realm_cb) { + ret = realm_cb(realm_context, SASL_CB_GETREALM, availrealms, realm); + if (ret != SASL_OK) + return ret; + + if (!*realm) { + PARAMERROR(utils); + return SASL_BADPARAM; + } + } + + return ret; +} + +/* + * Make the requested prompts. (prompt==NULL means we don't want it) + */ +int _plug_make_prompts(const sasl_utils_t *utils, + sasl_interact_t **prompts_res, + 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 num = 1; + int alloc_size; + sasl_interact_t *prompts; + + if (user_prompt) num++; + if (auth_prompt) num++; + if (pass_prompt) num++; + if (echo_prompt) num++; + if (realm_prompt) num++; + + if (num == 1) { + SETERROR( utils, "make_prompts() called with no actual prompts" ); + return SASL_FAIL; + } + + alloc_size = sizeof(sasl_interact_t)*num; + prompts = utils->malloc(alloc_size); + if (!prompts) { + MEMERROR( utils ); + return SASL_NOMEM; + } + memset(prompts, 0, alloc_size); + + *prompts_res = prompts; + + if (user_prompt) { + (prompts)->id = SASL_CB_USER; + (prompts)->challenge = "Authorization Name"; + (prompts)->prompt = user_prompt; + (prompts)->defresult = user_def; + + prompts++; + } + + if (auth_prompt) { + (prompts)->id = SASL_CB_AUTHNAME; + (prompts)->challenge = "Authentication Name"; + (prompts)->prompt = auth_prompt; + (prompts)->defresult = auth_def; + + prompts++; + } + + if (pass_prompt) { + (prompts)->id = SASL_CB_PASS; + (prompts)->challenge = "Password"; + (prompts)->prompt = pass_prompt; + (prompts)->defresult = pass_def; + + prompts++; + } + + if (echo_prompt) { + (prompts)->id = SASL_CB_ECHOPROMPT; + (prompts)->challenge = echo_chal; + (prompts)->prompt = echo_prompt; + (prompts)->defresult = echo_def; + + prompts++; + } + + if (realm_prompt) { + (prompts)->id = SASL_CB_GETREALM; + (prompts)->challenge = realm_chal; + (prompts)->prompt = realm_prompt; + (prompts)->defresult = realm_def; + + prompts++; + } + + /* add the ending one */ + (prompts)->id = SASL_CB_LIST_END; + (prompts)->challenge = NULL; + (prompts)->prompt = NULL; + (prompts)->defresult = NULL; + + return SASL_OK; +} + +void _plug_decode_init(decode_context_t *text, + const sasl_utils_t *utils, unsigned int in_maxbuf) +{ + memset(text, 0, sizeof(decode_context_t)); + + text->utils = utils; + text->needsize = 4; + text->in_maxbuf = in_maxbuf; +} + +/* + * Decode as much of the input as possible (possibly none), + * using decode_pkt() to decode individual packets. + */ +int _plug_decode(decode_context_t *text, + const char *input, unsigned inputlen, + char **output, /* output buffer */ + unsigned *outputsize, /* current size of output buffer */ + unsigned *outputlen, /* length of data in output buffer */ + int (*decode_pkt)(void *rock, + const char *input, unsigned inputlen, + char **output, unsigned *outputlen), + void *rock) +{ + unsigned int tocopy; + unsigned diff; + char *tmp; + unsigned tmplen; + int ret; + + *outputlen = 0; + + while (inputlen) { /* more input */ + if (text->needsize) { /* need to get the rest of the 4-byte size */ + + /* copy as many bytes (up to 4) as we have into size buffer */ + tocopy = (inputlen > text->needsize) ? text->needsize : inputlen; + memcpy(text->sizebuf + 4 - text->needsize, input, tocopy); + text->needsize -= tocopy; + + input += tocopy; + inputlen -= tocopy; + + if (!text->needsize) { /* we have the entire 4-byte size */ + memcpy(&(text->size), text->sizebuf, 4); + text->size = ntohl(text->size); + text->cursize = 0; + } else { + /* We do NOT have the entire 4-byte size... + * wait for more data */ + return SASL_OK; + } + } + + if (!text->size) /* should never happen */ + return SASL_FAIL; + + if (text->size > text->in_maxbuf) { + text->utils->log(NULL, SASL_LOG_ERR, + "encoded packet size too big (%d > %d)", + text->size, text->in_maxbuf); + return SASL_FAIL; + } + + if (!text->buffer) { + text->buffer = text->utils->malloc(text->in_maxbuf); + if (text->buffer == NULL) return SASL_NOMEM; + } + + diff = text->size - text->cursize; /* bytes needed for full packet */ + + if (inputlen < diff) { /* not a complete packet, need more input */ + memcpy(text->buffer + text->cursize, input, inputlen); + text->cursize += inputlen; + return SASL_OK; + } + + /* copy the rest of the packet */ + memcpy(text->buffer + text->cursize, input, diff); + input += diff; + inputlen -= diff; + + /* decode the packet (no need to free tmp) */ + ret = decode_pkt(rock, text->buffer, text->size, &tmp, &tmplen); + if (ret != SASL_OK) return ret; + + /* append the decoded packet to the output */ + ret = _plug_buf_alloc(text->utils, output, outputsize, + *outputlen + tmplen + 1); /* +1 for NUL */ + if (ret != SASL_OK) return ret; + + memcpy(*output + *outputlen, tmp, tmplen); + *outputlen += tmplen; + + /* protect stupid clients */ + *(*output + *outputlen) = '\0'; + + /* reset for the next packet */ + text->needsize = 4; + } + + return SASL_OK; +} + +void _plug_decode_free(decode_context_t *text) +{ + if (text->buffer) text->utils->free(text->buffer); +} + +/* returns the realm we should pretend to be in */ +int _plug_parseuser(const sasl_utils_t *utils, + char **user, char **realm, const char *user_realm, + const char *serverFQDN, const char *input) +{ + int ret; + char *r; + + if(!user || !serverFQDN) { + PARAMERROR( utils ); + return SASL_BADPARAM; + } + + r = strchr(input, '@'); + if (!r) { + /* hmmm, the user didn't specify a realm */ + if(user_realm && user_realm[0]) { + ret = _plug_strdup(utils, user_realm, realm, NULL); + } else { + /* Default to serverFQDN */ + ret = _plug_strdup(utils, serverFQDN, realm, NULL); + } + + if (ret == SASL_OK) { + ret = _plug_strdup(utils, input, user, NULL); + } + } else { + r++; + ret = _plug_strdup(utils, r, realm, NULL); + *--r = '\0'; + *user = utils->malloc(r - input + 1); + if (*user) { + strncpy(*user, input, r - input +1); + } else { + MEMERROR( utils ); + ret = SASL_NOMEM; + } + *r = '@'; + } + + return ret; +} + +int _plug_make_fulluser(const sasl_utils_t *utils, + char **fulluser, + const char * useronly, + const char *realm) +{ + if(!fulluser || !useronly || !realm) { + PARAMERROR( utils ); + return (SASL_BADPARAM); + } + + *fulluser = utils->malloc (strlen(useronly) + strlen(realm) + 2); + if (*fulluser == NULL) { + MEMERROR( utils ); + return (SASL_NOMEM); + } + + strcpy (*fulluser, useronly); + strcat (*fulluser, "@"); + strcat (*fulluser, realm); + + return (SASL_OK); +} + +char * _plug_get_error_message (const sasl_utils_t *utils, +#ifdef WIN32 + DWORD error +#else + int error +#endif + ) +{ + char * return_value; +#ifdef WIN32 + LPVOID lpMsgBuf; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + + if (_plug_strdup (utils, lpMsgBuf, &return_value, NULL) != SASL_OK) { + return_value = NULL; + } + + LocalFree( lpMsgBuf ); +#else /* !WIN32 */ + if (_plug_strdup (utils, strerror(error), &return_value, NULL) != SASL_OK) { + return_value = NULL; + } +#endif /* WIN32 */ + return (return_value); +} + +void _plug_snprintf_os_info (char * osbuf, int osbuf_len) +{ +#ifdef WIN32 + char *sysname; + sysname = "Unknown Windows"; + +/* Let's suppose it's still compilable with win2k sdk. So define everythig missing */ +#ifndef _WIN32_WINNT_WINXP +# define _WIN32_WINNT_WINXP 0x0501 +#endif +#ifndef _WIN32_WINNT_WS03 +# define _WIN32_WINNT_WS03 0x0502 +#endif +#ifndef _WIN32_WINNT_WIN6 +# define _WIN32_WINNT_WIN6 0x0600 +#endif +#ifndef _WIN32_WINNT_VISTA +# define _WIN32_WINNT_VISTA 0x0600 +#endif +#ifndef _WIN32_WINNT_WS08 +# define _WIN32_WINNT_WS08 0x0600 +#endif +#ifndef _WIN32_WINNT_LONGHORN +# define _WIN32_WINNT_LONGHORN 0x0600 +#endif +#ifndef _WIN32_WINNT_WIN7 +# define _WIN32_WINNT_WIN7 0x0601 +#endif +#ifndef _WIN32_WINNT_WIN8 +# define _WIN32_WINNT_WIN8 0x0602 +#endif +#ifndef _WIN32_WINNT_WINBLUE +# define _WIN32_WINNT_WINBLUE 0x0603 +#endif +#ifndef _WIN32_WINNT_WIN10 +# define _WIN32_WINNT_WIN10 0x0A00 +#endif + + /* and use IsWindowsVersionOrGreater instead of convenient wrappers by the same reason */ + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN10), LOBYTE(_WIN32_WINNT_WIN10), 0)) { + sysname = "Windows 10 or greater"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0)) { + sysname = "Windows 8.1"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0)) { + sysname = "Windows 8"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1)) { + sysname = "Windows 7 SP1"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0)) { + sysname = "Windows 7"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2)) { + sysname = "Windows Vista SP2"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1)) { + sysname = "Windows Vista SP1"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0)) { + sysname = "Windows Vista"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3)) { + sysname = "Windows XP SP3"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2)) { + sysname = "Windows XP SP2"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1)) { + sysname = "Windows XP SP1"; + } else + if (IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0)) { + sysname = "Windows XP"; + } + + snprintf(osbuf, osbuf_len, "%s", sysname); + +#else /* !WIN32 */ + struct utsname os; + + uname(&os); + snprintf(osbuf, osbuf_len, "%s %s", os.sysname, os.release); +#endif /* WIN32 */ +} + +#if defined(WIN32) +unsigned int plug_sleep (unsigned int seconds) +{ + long dwSec = seconds*1000; + Sleep (dwSec); + return 0; +} +#endif diff --git a/contrib/libs/sasl/common/plugin_common.h b/contrib/libs/sasl/common/plugin_common.h new file mode 100644 index 00000000000..60f1dcd3a29 --- /dev/null +++ b/contrib/libs/sasl/common/plugin_common.h @@ -0,0 +1,230 @@ + +/* Generic SASL plugin utility functions + * Rob Siemborski + */ +/* + * Copyright (c) 1998-2016 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 + * Carnegie Mellon University + * Center for Technology Transfer and Enterprise Creation + * 4615 Forbes Avenue + * Suite 302 + * Pittsburgh, PA 15213 + * (412) 268-7393, fax: (412) 268-7395 + * + * 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 _PLUGIN_COMMON_H_ +#define _PLUGIN_COMMON_H_ + +#include <config.h> + +#ifndef macintosh +#ifdef WIN32 +# include <winsock2.h> +#else +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif /* WIN32 */ +#endif /* macintosh */ + +#include <sasl.h> +#include <saslutil.h> +#include <saslplug.h> + +#ifdef WIN32 +#define PLUG_API __declspec(dllexport) +#else +#define PLUG_API extern +#endif + +#define SASL_CLIENT_PLUG_INIT( x ) \ +extern sasl_client_plug_init_t x##_client_plug_init; \ +PLUG_API int sasl_client_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_client_plug_t **pluglist, \ + int *plugcount) { \ + return x##_client_plug_init(utils, maxversion, out_version, \ + pluglist, plugcount); \ +} + +#define SASL_SERVER_PLUG_INIT( x ) \ +extern sasl_server_plug_init_t x##_server_plug_init; \ +PLUG_API int sasl_server_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_server_plug_t **pluglist, \ + int *plugcount) { \ + return x##_server_plug_init(utils, maxversion, out_version, \ + pluglist, plugcount); \ +} + +#define SASL_AUXPROP_PLUG_INIT( x ) \ +extern sasl_auxprop_init_t x##_auxprop_plug_init; \ +PLUG_API int sasl_auxprop_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_auxprop_plug_t **plug, \ + const char *plugname) {\ + return x##_auxprop_plug_init(utils, maxversion, out_version, \ + plug, plugname); \ +} + +#define SASL_CANONUSER_PLUG_INIT( x ) \ +extern sasl_canonuser_init_t x##_canonuser_plug_init; \ +PLUG_API int sasl_canonuser_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_canonuser_plug_t **plug, \ + const char *plugname) {\ + return x##_canonuser_plug_init(utils, maxversion, out_version, \ + plug, plugname); \ +} + +/* note: msg cannot include additional variables, so if you want to + * do a printf-format string, then you need to call seterror yourself */ +#define SETERROR( utils, msg ) (utils)->seterror( (utils)->conn, 0, (msg) ) + +#ifndef MEMERROR +#define MEMERROR( utils ) \ + (utils)->seterror( (utils)->conn, 0, \ + "Out of Memory in " __FILE__ " near line %d", __LINE__ ) +#endif + +#ifndef PARAMERROR +#define PARAMERROR( utils ) \ + (utils)->seterror( (utils)->conn, 0, \ + "Parameter Error in " __FILE__ " near line %d", __LINE__ ) +#endif + +#ifndef SASLINT_H +typedef struct buffer_info +{ + char *data; + unsigned curlen; /* Current length of data in buffer */ + unsigned reallen; /* total length of buffer (>= curlen) */ +} buffer_info_t; + +#ifndef HAVE_GETHOSTNAME +#ifdef sun +/* gotta define gethostname ourselves on suns */ +extern int gethostname(char *, int); +#endif +#endif /* HAVE_GETHOSTNAME */ + +#endif /* SASLINT_H */ + +#ifdef __cplusplus +extern "C" { +#endif + +int _plug_ipfromstring(const sasl_utils_t *utils, const char *addr, + struct sockaddr *out, socklen_t outlen); +int _plug_iovec_to_buf(const sasl_utils_t *utils, const struct iovec *vec, + unsigned numiov, buffer_info_t **output); +int _plug_buf_alloc(const sasl_utils_t *utils, char **rwbuf, + unsigned *curlen, unsigned newlen); +int _plug_strdup(const sasl_utils_t * utils, const char *in, + char **out, int *outlen); +void _plug_free_string(const sasl_utils_t *utils, char **str); +void _plug_free_secret(const sasl_utils_t *utils, sasl_secret_t **secret); + +#define _plug_get_userid(utils, result, prompt_need) \ + _plug_get_simple(utils, SASL_CB_USER, 0, result, prompt_need) +#define _plug_get_authid(utils, result, prompt_need) \ + _plug_get_simple(utils, SASL_CB_AUTHNAME, 1, result, prompt_need) +int _plug_get_simple(const sasl_utils_t *utils, unsigned int id, int required, + const char **result, sasl_interact_t **prompt_need); + +int _plug_get_password(const sasl_utils_t *utils, sasl_secret_t **secret, + unsigned int *iscopy, sasl_interact_t **prompt_need); + +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 _plug_get_realm(const sasl_utils_t *utils, const char **availrealms, + const char **realm, sasl_interact_t **prompt_need); + +int _plug_make_prompts(const sasl_utils_t *utils, + sasl_interact_t **prompts_res, + 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); + +typedef struct decode_context { + const sasl_utils_t *utils; + unsigned int needsize; /* How much of the 4-byte size do we need? */ + char sizebuf[4]; /* Buffer to accumulate the 4-byte size */ + unsigned int size; /* Absolute size of the encoded packet */ + char *buffer; /* Buffer to accumulate an encoded packet */ + unsigned int cursize; /* Amount of packet data in the buffer */ + unsigned int in_maxbuf; /* Maximum allowed size of an incoming encoded packet */ +} decode_context_t; + +void _plug_decode_init(decode_context_t *text, + const sasl_utils_t *utils, unsigned int in_maxbuf); + +int _plug_decode(decode_context_t *text, + const char *input, unsigned inputlen, + char **output, unsigned *outputsize, unsigned *outputlen, + int (*decode_pkt)(void *rock, + const char *input, unsigned inputlen, + char **output, unsigned *outputlen), + void *rock); + +void _plug_decode_free(decode_context_t *text); + +int _plug_parseuser(const sasl_utils_t *utils, + char **user, char **realm, const char *user_realm, + const char *serverFQDN, const char *input); + +int _plug_make_fulluser(const sasl_utils_t *utils, + char **fulluser, const char * useronly, const char *realm); + +char * _plug_get_error_message (const sasl_utils_t *utils, +#ifdef WIN32 + DWORD error +#else + int error +#endif + ); +void _plug_snprintf_os_info (char * osbuf, int osbuf_len); + +#ifdef __cplusplus +} +#endif + +#endif /* _PLUGIN_COMMON_H_ */ |