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

📄 socket.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
							 gensec_socket->read_buffer.data, 							 uint8_t, 							 gensec_socket->read_buffer.length);	if (gensec_socket->read_buffer.length && 	    gensec_socket->in_extra_read == 0 && 	    gensec_socket->recv_handler) {		/* Manually call a read event, to get this moving		 * again (as the socket should be dry, so the normal		 * event handler won't trigger) */		event_add_timed(gensec_socket->ev, gensec_socket, timeval_zero(), 				gensec_socket_trigger_read, gensec_socket);	}	return NT_STATUS_OK;}/* Completed SASL packet callback.  When we have a 'whole' SASL * packet, decrypt it, and add it to the read buffer * * This function (and anything under it) MUST NOT call the event system */static NTSTATUS gensec_socket_unwrap(void *private, DATA_BLOB blob){	struct gensec_socket *gensec_socket = talloc_get_type(private, struct gensec_socket);	DATA_BLOB unwrapped;	NTSTATUS nt_status;	TALLOC_CTX *mem_ctx;	size_t packet_size;	mem_ctx = talloc_new(gensec_socket);	if (!mem_ctx) {		return NT_STATUS_NO_MEMORY;	}	nt_status = gensec_unwrap_packets(gensec_socket->gensec_security, 					  mem_ctx,					  &blob, &unwrapped, 					  &packet_size);	if (!NT_STATUS_IS_OK(nt_status)) {		talloc_free(mem_ctx);		return nt_status;	}	if (packet_size != blob.length) {		DEBUG(0, ("gensec_socket_unwrap: Did not consume entire packet!\n"));		talloc_free(mem_ctx);		return NT_STATUS_INTERNAL_ERROR;	}	/* We could change this into a linked list, and have	 * gensec_socket_recv() and gensec_socket_pending() walk the	 * linked list */	if (!data_blob_append(gensec_socket, &gensec_socket->read_buffer, 				     unwrapped.data, unwrapped.length)) {		talloc_free(mem_ctx);		return NT_STATUS_NO_MEMORY;	}	talloc_free(mem_ctx);	return NT_STATUS_OK;}/* when the data is sent, we know we have not been interrupted */static void send_callback(void *private) {	struct gensec_socket *gensec_socket = talloc_get_type(private, struct gensec_socket);	gensec_socket->interrupted = false;}/*  send data, but only as much as we allow in one packet.    If this returns STATUS_MORE_ENTRIES, the caller must retry with  exactly the same data, or a NULL blob.*/static NTSTATUS gensec_socket_send(struct socket_context *sock, 				   const DATA_BLOB *blob, size_t *sendlen){	NTSTATUS nt_status;	struct gensec_socket *gensec_socket = talloc_get_type(sock->private_data, struct gensec_socket);	DATA_BLOB wrapped;	TALLOC_CTX *mem_ctx;	if (!gensec_socket->wrap) {		return socket_send(gensec_socket->socket, blob, sendlen);	}	*sendlen = 0;	/* We have have been interupted, so the caller should be	 * giving us the same data again.  */	if (gensec_socket->interrupted) {		packet_queue_run(gensec_socket->packet);		if (!NT_STATUS_IS_OK(gensec_socket->error)) {			return gensec_socket->error;		} else if (gensec_socket->interrupted) {			return STATUS_MORE_ENTRIES;		} else {			*sendlen = gensec_socket->orig_send_len;			gensec_socket->orig_send_len = 0;			return NT_STATUS_OK;		}	}	mem_ctx = talloc_new(gensec_socket);	if (!mem_ctx) {		return NT_STATUS_NO_MEMORY;	}	nt_status = gensec_wrap_packets(gensec_socket->gensec_security, 					mem_ctx,					blob, &wrapped, 					&gensec_socket->orig_send_len);	if (!NT_STATUS_IS_OK(nt_status)) {		talloc_free(mem_ctx);		return nt_status;	}		gensec_socket->interrupted = true;	gensec_socket->error = NT_STATUS_OK;	nt_status = packet_send_callback(gensec_socket->packet, 					 wrapped,					 send_callback, gensec_socket);	talloc_free(mem_ctx);	packet_queue_run(gensec_socket->packet);	if (!NT_STATUS_IS_OK(gensec_socket->error)) {		return gensec_socket->error;	} else if (gensec_socket->interrupted) {		return STATUS_MORE_ENTRIES;	} else {		*sendlen = gensec_socket->orig_send_len;		gensec_socket->orig_send_len = 0;		return NT_STATUS_OK;	}}/* Turn a normal socket into a potentially GENSEC wrapped socket */NTSTATUS gensec_socket_init(struct gensec_security *gensec_security,			    struct socket_context *current_socket,			    struct event_context *ev,			    void (*recv_handler)(void *, uint16_t),			    void *recv_private,			    struct socket_context **new_socket){	struct gensec_socket *gensec_socket;	struct socket_context *new_sock;	NTSTATUS nt_status;	nt_status = socket_create_with_ops(current_socket, &gensec_socket_ops, &new_sock, 					   SOCKET_TYPE_STREAM, current_socket->flags | SOCKET_FLAG_ENCRYPT);	if (!NT_STATUS_IS_OK(nt_status)) {		*new_socket = NULL;		return nt_status;	}	new_sock->state = current_socket->state;	gensec_socket = talloc(new_sock, struct gensec_socket);	if (gensec_socket == NULL) {		*new_socket = NULL;		return NT_STATUS_NO_MEMORY;	}	new_sock->private_data       = gensec_socket;	gensec_socket->socket        = current_socket;	if (talloc_reference(gensec_socket, current_socket) == NULL) {		*new_socket = NULL;		return NT_STATUS_NO_MEMORY;	}	/* Nothing to do here, if we are not actually wrapping on this socket */	if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) &&	    !gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {				gensec_socket->wrap = false;		*new_socket = new_sock;		return NT_STATUS_OK;	}	gensec_socket->gensec_security = gensec_security;	gensec_socket->wrap          = true;	gensec_socket->eof           = false;	gensec_socket->error         = NT_STATUS_OK;	gensec_socket->interrupted   = false;	gensec_socket->in_extra_read = 0;	gensec_socket->read_buffer   = data_blob(NULL, 0);	gensec_socket->recv_handler  = recv_handler;	gensec_socket->recv_private  = recv_private;	gensec_socket->ev            = ev;	gensec_socket->packet = packet_init(gensec_socket);	if (gensec_socket->packet == NULL) {		*new_socket = NULL;		return NT_STATUS_NO_MEMORY;	}	packet_set_private(gensec_socket->packet, gensec_socket);	packet_set_socket(gensec_socket->packet, gensec_socket->socket);	packet_set_callback(gensec_socket->packet, gensec_socket_unwrap);	packet_set_full_request(gensec_socket->packet, gensec_socket_full_request);	packet_set_error_handler(gensec_socket->packet, gensec_socket_error_handler);	packet_set_serialise(gensec_socket->packet);	/* TODO: full-request that knows about maximum packet size */	*new_socket = new_sock;	return NT_STATUS_OK;}static NTSTATUS gensec_socket_set_option(struct socket_context *sock, const char *option, const char *val){	set_socket_options(socket_get_fd(sock), option);	return NT_STATUS_OK;}static char *gensec_socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx){	struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket);	return socket_get_peer_name(gensec->socket, mem_ctx);}static struct socket_address *gensec_socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx){	struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket);	return socket_get_peer_addr(gensec->socket, mem_ctx);}static struct socket_address *gensec_socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx){	struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket);	return socket_get_my_addr(gensec->socket, mem_ctx);}static int gensec_socket_get_fd(struct socket_context *sock){	struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket);	return socket_get_fd(gensec->socket);}static const struct socket_ops gensec_socket_ops = {	.name			= "gensec",	.fn_init		= gensec_socket_init_fn,	.fn_recv		= gensec_socket_recv,	.fn_send		= gensec_socket_send,	.fn_pending		= gensec_socket_pending,	.fn_set_option		= gensec_socket_set_option,	.fn_get_peer_name	= gensec_socket_get_peer_name,	.fn_get_peer_addr	= gensec_socket_get_peer_addr,	.fn_get_my_addr		= gensec_socket_get_my_addr,	.fn_get_fd		= gensec_socket_get_fd};

⌨️ 快捷键说明

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