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

📄 mail.c

📁 系统任务管理器
💻 C
📖 第 1 页 / 共 5 页
字号:
static gintread_select(gint fd, gchar *buf, size_t size, time_t timeout)	{	fd_set			readfds;	struct timeval	tv;	gint			n	= 0;	gint			s;	do	{	    FD_ZERO(&readfds);	    FD_SET(fd, &readfds);	    tv.tv_sec = timeout;	    tv.tv_usec = 0;	    if ((s = select(fd+1, &readfds, NULL, NULL, &tv)) > 0)#if defined(WIN32)		n = recv(fd, buf, size, 0);#else		n = read(fd, buf, size);#endif	} while (s < 0 && errno == EINTR);	return n;	}  /* Read \r\n terminated lines from a remote IMAP or POP3 mail server,  */static voidtcp_getline(ConnInfo *conn, Mailbox *mbox)	{	gchar	buf[256];	gint	n;	gchar	*s;	if (mbox->tcp_in)		mbox->tcp_in = g_string_truncate(mbox->tcp_in, 0);	else		mbox->tcp_in = g_string_new("");	s = buf;;	for (;;)		{#ifdef HAVE_SSL		if (conn->ssl)			n = SSL_read(conn->ssl, s, 1);		else#endif			n = read_select(conn->fd, s, 1, TCP_TIMEOUT);		if (n <= 0)			break;		*(s+1) = '\0';		if (*s++ == '\n')			break;		if (s >= buf + sizeof(buf) - 2)			{			g_string_append(mbox->tcp_in, buf);			s = buf;			}		}	if (s > buf)		g_string_append(mbox->tcp_in, buf);	if (_GK.debug_level & DEBUG_MAIL)		{		if (n < 0)			perror("tcp_getline: ");		format_remote_mbox_name(mbox, buf, sizeof(buf));		printf("server_response( %s )<%d>:%s\n", buf,			   (gint) mbox->tcp_in->len, mbox->tcp_in->str);		}	}static voidtcp_putline(ConnInfo *conn, gchar *line)	{#ifdef HAVE_SSL	if (conn->ssl)		SSL_write(conn->ssl, line, strlen(line));	else#endif		{#if defined(WIN32)		send(conn->fd, line, strlen(line), 0);#else		write(conn->fd, line, strlen (line));#endif		}	}  /* Get a server response line and verify the beginning of the line  |  matches a string.  */static gbooleanserver_response(ConnInfo *conn, Mailbox *mbox, gchar *match)	{	tcp_getline(conn, mbox);	return (!strncmp(match, mbox->tcp_in->str, strlen(match)) ? TRUE : FALSE);	}  /* Get a imap server completion result response for a tagged command.  |  Skip over any untagged responses the server may send.  */static gbooleanimap_completion_result(ConnInfo *conn, Mailbox *mbox, gchar *tag)	{	while (1)		{		tcp_getline(conn, mbox);		if (*(mbox->tcp_in->str) == '*')	/* untagged response */			continue;		return (!strncmp(tag, mbox->tcp_in->str, strlen(tag)) ? TRUE : FALSE);		}	}static voidserver_command(ConnInfo *conn, Mailbox *mbox, gchar *line)	{	gchar	buf[128];	tcp_putline(conn, line);	if (_GK.debug_level & DEBUG_MAIL)		{		format_remote_mbox_name(mbox, buf, sizeof(buf));		printf("server_command( %s ):%s", buf, line);		}	}static gchar	*tcp_error_message[]	=	{	N_("Unable to connect."),	N_("Bad response after connect."),	N_("Bad response after username."),	N_("Bad response after password."),	N_("Bad response after STAT or STATUS."),	N_("Bad response after UIDL."),	N_("Bad APOP response after connect."),	N_("Bad CRAM_MD5 response after connect."),	};static voidtcp_close(ConnInfo *conn)	{#ifdef HAVE_SSL#ifndef HAVE_GNUTLS	SSL_SESSION *session;#endif#endif	if (conn->fd != -1)		{#ifdef WIN32		closesocket(conn->fd);#else		close(conn->fd);#endif		conn->fd = -1;		}#ifdef HAVE_SSL	if (conn->ssl)		{#ifndef HAVE_GNUTLS		session = SSL_get_session(conn->ssl);		if (session)			SSL_CTX_remove_session(conn->ssl_ctx, session);#endif		SSL_free(conn->ssl);		conn->ssl = NULL;		}	if (conn->ssl_ctx)		{		SSL_CTX_free(conn->ssl_ctx);		conn->ssl_ctx = NULL;		}#endif}static gbooleantcp_warn(Mailbox *mbox, gchar *message, gboolean warn)	{	gchar	buf[128];  	if (_GK.debug_level & DEBUG_MAIL)		{		format_remote_mbox_name(mbox, buf, sizeof(buf));		g_print(_("Mail TCP Error: %s - %s\n"), buf, _(message));		}	if (warn && !mbox->warned)		{		g_free(mbox->warn_msg);		format_remote_mbox_name(mbox, buf, sizeof(buf));		mbox->warn_msg = g_strdup_printf("%s\n%s\n%s\n", buf,				_(message), mbox->tcp_in->str);		}	return FALSE;	}static gbooleantcp_shutdown(ConnInfo *conn, Mailbox *mbox, gchar *message, gboolean warn)	{	tcp_close(conn);	return tcp_warn(mbox, message, warn);	}#ifdef HAVE_SSLstatic gbooleanssl_negotiate(ConnInfo *conn, Mailbox *mbox)	{	SSL_METHOD	*ssl_method;	SSLeay_add_ssl_algorithms();	SSL_load_error_strings();	if (mbox->account->use_ssl == SSL_TRANSPORT)		ssl_method = SSLv23_client_method();	else		ssl_method = TLSv1_client_method();	if (ssl_method == NULL)		return tcp_shutdown(conn, mbox,				    N_("Cannot initialize SSL method."),				    FALSE);	if ((conn->ssl_ctx = SSL_CTX_new(ssl_method)) == NULL)		return tcp_shutdown(conn, mbox,				    N_("Cannot initialize SSL server certificate handler."),				    FALSE);	SSL_CTX_set_options(conn->ssl_ctx, SSL_OP_ALL);	SSL_CTX_set_verify(conn->ssl_ctx, SSL_VERIFY_NONE, NULL);	if ((conn->ssl = SSL_new(conn->ssl_ctx)) == NULL)		return tcp_shutdown(conn, mbox,				    N_("Cannot initialize SSL handler."),				    FALSE);#ifndef HAVE_GNUTLS	SSL_clear(conn->ssl);#endif	SSL_set_fd(conn->ssl, conn->fd);	SSL_set_connect_state(conn->ssl);	if (SSL_connect(conn->ssl) < 0)		return tcp_shutdown(conn, mbox, tcp_error_message[0], FALSE);	return TRUE;	}#endifstatic gbooleantcp_connect(ConnInfo *conn, Mailbox *mbox)	{	MailAccount		*account = mbox->account;	gchar			buf[128];	memset(conn, 0, sizeof(*conn));	if (_GK.debug_level & DEBUG_MAIL)		{		format_remote_mbox_name(mbox, buf, sizeof(buf));		printf("tcp_connect: connecting to %s\n", buf);		}	conn->fd = gkrellm_connect_to(account->server, account->port);	if (conn->fd < 0)		return tcp_warn(mbox, tcp_error_message[0], FALSE);#ifdef HAVE_SSL	if (account->use_ssl == SSL_TRANSPORT && !ssl_negotiate(conn, mbox))		return FALSE;#endif	return TRUE;	}extern void to64frombits(unsigned char *, const unsigned char *, int);extern int from64tobits(char *, const char *, int);static voidhmac_md5(unsigned char *password,  size_t pass_len,	 unsigned char *challenge, size_t chal_len,	 unsigned char *response,  size_t resp_len)	{	int i;	unsigned char ipad[64];	unsigned char opad[64];	unsigned char hash_passwd[16];	MD5_CTX ctx;	if (resp_len != 16)		return;	if (pass_len > sizeof(ipad))		{		MD5Init(&ctx);		MD5Update(&ctx, password, pass_len);		MD5Final(hash_passwd, &ctx);		password = hash_passwd;		pass_len = sizeof(hash_passwd);		}	memset(ipad, 0, sizeof(ipad));	memset(opad, 0, sizeof(opad));	memcpy(ipad, password, pass_len);	memcpy(opad, password, pass_len);	for (i = 0; i < 64; i++)		{		ipad[i] ^= 0x36;		opad[i] ^= 0x5c;		}	MD5Init(&ctx);	MD5Update(&ctx, ipad, sizeof(ipad));	MD5Update(&ctx, challenge, chal_len);	MD5Final(response, &ctx);	MD5Init(&ctx);	MD5Update(&ctx, opad, sizeof(opad));	MD5Update(&ctx, response, resp_len);	MD5Final(response, &ctx);	}/* authenticate as per RFC2195 */static intdo_cram_md5(ConnInfo *conn, char *command, Mailbox  *mbox, char *strip)	{	MailAccount	*account = mbox->account;	gint		len;	gchar		buf1[1024];	gchar		msg_id[768];	gchar		reply[1024];	gchar		*respdata;	guchar		response[16];	snprintf(buf1, sizeof(buf1), "%s CRAM-MD5\r\n", command);	server_command(conn, mbox, buf1);	/* From RFC2195:	 * The data encoded in the first ready response contains an	 * presumptively arbitrary string of random digits, a	 * timestamp, and the * fully-qualified primary host name of	 * the server.  The syntax of the * unencoded form must	 * correspond to that of an RFC 822 'msg-id' * [RFC822] as	 * described in [POP3].	 */	if (!server_response(conn, mbox, "+ "))		return FALSE;	/* caller may specify a response prefix we should strip if present */	respdata = mbox->tcp_in->str;	len = strlen(respdata);	if (respdata[len - 1] == '\n')		respdata[--len] = '\0';	if (respdata[len - 1] == '\r')		respdata[--len] = '\0';	if (strip && strncmp(respdata, strip, strlen(strip)) == 0)		respdata += strlen(strip);	len = from64tobits(msg_id, respdata, sizeof(msg_id));	if (len < 0)		{		if (_GK.debug_level & DEBUG_MAIL)			g_print(_("could not decode BASE64 challenge\n"));		return FALSE;		}	else if (len < sizeof(msg_id))		msg_id[len] = 0;	else		msg_id[sizeof(msg_id) - 1] = 0;	if (_GK.debug_level & DEBUG_MAIL)		g_print(_("decoded as %s\n"), msg_id);	/* The client makes note of the data and then responds with a string	 * consisting of the user name, a space, and a 'digest'.  The latter is	 * computed by applying the keyed MD5 algorithm from [KEYED-MD5] where	 * the key is a shared secret and the digested text is the timestamp	 * (including angle-brackets).	 */	hmac_md5((guchar *) account->password, strlen(account->password),		 (guchar *) msg_id, strlen(msg_id), response, sizeof(response));	snprintf(reply, sizeof(reply),		"%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",		account->username,		response[0], response[1], response[2], response[3],		response[4], response[5], response[6], response[7],		response[8], response[9], response[10], response[11],		response[12], response[13], response[14], response[15]);	to64frombits((guchar *) buf1, (guchar *) reply, strlen(reply));	len = strlen(buf1);	if (len + 3 > sizeof(buf1))		return FALSE;	strcpy(buf1 + len, "\r\n");	server_command(conn, mbox, buf1);	return TRUE;	}/* NTLM authentication */static intdo_ntlm(ConnInfo *conn, char *command, Mailbox *mbox)	{	gint			len;	gchar			msgbuf[2048];	tSmbNtlmAuthRequest	request;	tSmbNtlmAuthChallenge	challenge;	tSmbNtlmAuthResponse	response;	snprintf(msgbuf, sizeof(msgbuf), "%s NTLM\r\n", command);	server_command(conn, mbox, msgbuf);	if (!server_response(conn, mbox, "+ "))		return FALSE;	buildSmbNtlmAuthRequest(&request, mbox->account->username, NULL);	if (_GK.debug_level & DEBUG_MAIL)		dumpSmbNtlmAuthRequest(stdout, &request);	memset(msgbuf, 0, sizeof(msgbuf));	to64frombits((guchar *) msgbuf, (guchar *) &request, SmbLength(&request));	len = strlen(msgbuf);	if (len + 3 > sizeof(msgbuf))		return FALSE;	strcpy(msgbuf + len, "\r\n");	server_command(conn, mbox, msgbuf);	if (!server_response(conn, mbox, "+ "))		return FALSE;	len = from64tobits((char *)&challenge, mbox->tcp_in->str,			   sizeof(challenge));	if (len < 0)		{		if (_GK.debug_level & DEBUG_MAIL)			g_print(_("could not decode BASE64 challenge\n"));		return FALSE;		}	if (_GK.debug_level & DEBUG_MAIL)		dumpSmbNtlmAuthChallenge(stdout, &challenge);	buildSmbNtlmAuthResponse(&challenge, &response,				 mbox->account->username,				 mbox->account->password);	if (_GK.debug_level & DEBUG_MAIL)		dumpSmbNtlmAuthResponse(stdout, &response);	memset(msgbuf, 0, sizeof msgbuf);	to64frombits((guchar *)msgbuf, (guchar *) &response, SmbLength(&response));	len = strlen(msgbuf);	if (len + 3 > sizeof(msgbuf))		return FALSE;	strcpy(msgbuf + len, "\r\n");	server_command(conn, mbox, msgbuf);	return TRUE;	}static gbooleancheck_pop3(Mailbox *mbox)	{	MailAccount		*account = mbox->account;	ConnInfo		conn;	gchar			line[128], buf[128];	gchar			*challenge = NULL;	if (!tcp_connect(&conn, mbox))		return FALSE;	/* Is the machine we are connected to really a POP3 server?	*/	if (! server_response(&conn, mbox, "+OK"))		return tcp_shutdown(&conn, mbox, tcp_error_message[1], FALSE);	if (account->authmech == AUTH_APOP &&	    (strlen(mbox->tcp_in->str) < 3 ||	     (challenge = g_strdup(mbox->tcp_in->str + 3)) == NULL))		return tcp_shutdown(&conn, mbox, tcp_error_message[1], FALSE);#ifdef HAVE_SSL	if (account->use_ssl == SSL_STARTTLS)		{		server_command(&conn, mbox, "STLS\r\n");		if (!server_response(&conn, mbox, "+OK"))			{			if (challenge)				g_free(challenge);			return tcp_shutdown(&conn, mbox,					    N_("Bad response after STLS."),					    FALSE);			}		if (!ssl_negotiate(&conn, mbox))			{			if (challenge)				g_free(challenge);			return FALSE;			}		}#endif	if (account->authmech == AUTH_APOP)		{		static const gchar hex[] = "0123456789abcdef";		MD5_CTX ctx;		gint	i;		gchar	*key, *p;		guchar	digest[16];		gchar	ascii_digest[33];		if ((key = strchr(challenge, '<')) == NULL)			{			g_free(challenge);			return tcp_shutdown(&conn, mbox, tcp_error_message[6],					    TRUE);			}		if ((p = strchr(key, '>')) == NULL)			{			g_free(challenge);			return tcp_shutdown(&conn, mbox, tcp_error_message[6],

⌨️ 快捷键说明

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