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

📄 gssapi.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 2007  Frediano Ziglio * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#if HAVE_CONFIG_H#include <config.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#include <ctype.h>#if HAVE_STRING_H#include <string.h>#endif /* HAVE_STRING_H */#if HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#if HAVE_NETDB_H#include <netdb.h>#endif /* HAVE_NETDB_H */#if HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif /* HAVE_SYS_SOCKET_H */#if HAVE_SYS_TYPES_H#include <sys/types.h>#endif /* HAVE_SYS_TYPES_H */#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif /* HAVE_NETINET_IN_H */#if HAVE_ARPA_INET_H#include <arpa/inet.h>#endif /* HAVE_ARPA_INET_H */#ifdef ENABLE_KRB5#include <gssapi/gssapi_generic.h>#include <gssapi/gssapi_krb5.h>#include "tds.h"#include "tdsstring.h"#include "replacements.h"#ifdef DMALLOC#include <dmalloc.h>#endifTDS_RCSID(var, "$Id: gssapi.c,v 1.10 2007/11/13 09:14:57 freddy77 Exp $");/** * \ingroup libtds * \defgroup auth Authentication * Functions for handling authentication. *//** * \addtogroup auth * @{  */typedef struct tds_gss_auth{	TDSAUTHENTICATION tds_auth;	gss_ctx_id_t gss_context;	gss_name_t target_name;	char *sname;} TDSGSSAUTH;static inttds_gss_free(TDSSOCKET * tds, struct tds_authentication * tds_auth){	TDSGSSAUTH *auth = (TDSGSSAUTH *) tds_auth;	OM_uint32 min_stat;	if (auth->tds_auth.packet) {		gss_buffer_desc send_tok;		send_tok.value = (void *) auth->tds_auth.packet;		send_tok.length = auth->tds_auth.packet_len;		gss_release_buffer(&min_stat, &send_tok);	}	gss_release_name(&min_stat, &auth->target_name);	free(auth->sname);	if (auth->gss_context != GSS_C_NO_CONTEXT)		gss_delete_sec_context(&min_stat, &auth->gss_context, GSS_C_NO_BUFFER);	free(auth);	return TDS_SUCCEED;}static inttds_gss_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t len){	return TDS_FAIL;}/** * Build a GSSAPI packet to send to server * @param tds     A pointer to the TDSSOCKET structure managing a client/server operation. * @param packet  GSSAPI packet build from function * @return size of packet */TDSAUTHENTICATION * tds_gss_get_auth(TDSSOCKET * tds){	/*	 * TODO	 * There are some differences between this implementation and MS on	 * - MS use SPNEGO with 3 mechnisms (MS KRB5, KRB5, NTLMSSP)	 * - MS seems to use MUTUAL flag	 * - name type is "Service and Instance (2)" and not "Principal (1)"	 * check for memory leaks	 * check for errors in many functions	 * a bit more verbose	 * dinamically load library ??	 */	gss_buffer_desc send_tok, *token_ptr;	OM_uint32 maj_stat, min_stat;	/* same as GSS_KRB5_NT_PRINCIPAL_NAME but do not require .so library */	static gss_OID_desc nt_principal = { 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01" };	OM_uint32 ret_flags;	const char *server_name;	/* Storage for reentrant getaddrby* calls */	char buffer[4096];	struct tds_gss_auth *auth = (struct tds_gss_auth *) calloc(1, sizeof(struct tds_gss_auth));	if (!auth || !tds->connection)		return NULL;	auth->tds_auth.free = tds_gss_free;	auth->tds_auth.handle_next = tds_gss_handle_next;	server_name = tds_dstr_cstr(&tds->connection->server_host_name);	if (strchr(server_name, '.') == NULL) {		struct hostent result;		int h_errnop;		struct hostent *host = tds_gethostbyname_r(server_name, &result, buffer, sizeof(buffer), &h_errnop);		if (host && strchr(host->h_name, '.') != NULL)			server_name = host->h_name;	}	if (asprintf(&auth->sname, "MSSQLSvc/%s:%d", server_name, tds->connection->port) < 0) {		tds_gss_free(tds, (TDSAUTHENTICATION *) auth);		return NULL;	}	tdsdump_log(TDS_DBG_NETWORK, "kerberos name %s\n", auth->sname);	/*	 * Import the name into target_name.  Use send_tok to save	 * local variable space.	 */	send_tok.value = auth->sname;	send_tok.length = strlen(auth->sname);	maj_stat = gss_import_name(&min_stat, &send_tok, &nt_principal, &auth->target_name);	if (maj_stat != GSS_S_COMPLETE) {		tds_gss_free(tds, (TDSAUTHENTICATION *) auth);		return NULL;	}	send_tok.value = NULL;	send_tok.length = 0;	/*	 * Perform the context-establishement loop.	 *	 * On each pass through the loop, token_ptr points to the token	 * to send to the server (or GSS_C_NO_BUFFER on the first pass).	 * Every generated token is stored in send_tok which is then	 * transmitted to the server; every received token is stored in	 * recv_tok, which token_ptr is then set to, to be processed by	 * the next call to gss_init_sec_context.	 * 	 * GSS-API guarantees that send_tok's length will be non-zero	 * if and only if the server is expecting another token from us,	 * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if	 * and only if the server has another token to send us.	 */	token_ptr = GSS_C_NO_BUFFER;	auth->gss_context = GSS_C_NO_CONTEXT;	maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL, &auth->gss_context, auth->target_name, 					/* GSS_C_DELEG_FLAG GSS_C_MUTUAL_FLAG ?? */					GSS_C_NULL_OID, GSS_C_REPLAY_FLAG, 0, NULL,	/* no channel bindings */					token_ptr, NULL,	/* ignore mech type */					&send_tok, &ret_flags, NULL);	/* ignore time_rec *//*	if (token_ptr != GSS_C_NO_BUFFER)		free(recv_tok.value);*//*	if (send_tok.length != 0) {		if (send_token(s, v1_format ? 0 : TOKEN_CONTEXT, &send_tok) < 0) {			(void) gss_release_buffer(&min_stat, &send_tok);			(void) gss_release_name(&min_stat, &target_name);			return -1;		}*//*	(void) gss_release_buffer(&min_stat, &send_tok); */	if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {		gss_release_buffer(&min_stat, &send_tok);		tds_gss_free(tds, (TDSAUTHENTICATION *) auth);		return NULL;	}/*	if (maj_stat == GSS_S_CONTINUE_NEEDED) {		if (recv_token(s, &token_flags, &recv_tok) < 0) {			(void) gss_release_name(&min_stat, &target_name);			return -1;		}		token_ptr = &recv_tok;	}*/	auth->tds_auth.packet = (TDS_UCHAR *) send_tok.value;	auth->tds_auth.packet_len = send_tok.length;	return (TDSAUTHENTICATION *) auth;}#endif/** @} */

⌨️ 快捷键说明

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