- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 Vala 和 GLib + GIO 实现一个简单的 SMTP 服务器。
到目前为止,纯文本通信没有问题,但当涉及使用 STARTTLS 的 TLS 时,事情会变得更加困难。
这是我到目前为止的代码:
const string appname = "vsmtpd";
const string hostname = "myserver";
const uint16 listenport = 10025;
const string keyfile = "vsmtpd.key";
const string certfile = "vsmtpd.crt";
// TODO: Parse EHLO instead of constant string
const string username = "myclient";
void process_request_plain (InputStream input, OutputStream output) throws Error {
output.write (@"220 $hostname ESMTP $appname\n".data);
var data_in = new DataInputStream (input);
string line;
while ((line = data_in.read_line (null)) != null) {
stdout.printf ("%s\n", line);
line = line.chomp ();
if (line.substring (0, 5) == "EHLO ") {
output.write (@"250-$hostname Hello $username\n".data);
output.write ("250 STARTTLS\n".data);
}
else if (line == "STARTTLS") {
output.write ("220 Go ahead\n".data);
break;
}
else {
output.write ("502 Command not implemented\n".data);
}
}
}
int main () {
try {
TlsCertificate cert = new TlsCertificate.from_files
(certfile, keyfile);
var service = new SocketService ();
service.add_inet_port (listenport, null);
service.start ();
while (true) {
SocketConnection conn = service.accept (null);
process_request_plain (conn.input_stream, conn.output_stream);
TlsServerConnection tlsconn = TlsServerConnection.@new (conn, cert);
assert_nonnull (tlsconn);
// TODO: Is this neccessary?
tlsconn.accept_certificate.connect ((peer_cert, errors) => {
stdout.printf ("TLS accepting peer cert\n");
return true;
});
try {
tlsconn.handshake ();
stdout.printf ("TLS handshake ok\n");
} catch (Error e) {
stdout.printf ("TLS handshake failed\n");
stderr.printf ("%s\n", e.message);
}
}
} catch (Error e) {
stderr.printf ("%s\n", e.message);
}
return 0;
}
在 vsmtpd.key
和 vsmtpd.crt
中提供有效的 SSL 证书(我使用 openssl req -x509 -newkey rsa:2048 -keyout vsmtpd 生成) .key -out vsmtpd.pem -days 365 -nodes
)我启动程序并运行此 OpenSSL 命令来测试 STARTTLS:
openssl s_client -connect localhost:10025 -starttls smtp -debug
我的程序的输出是:
EHLO openssl.client.net
STARTTLS
TLS handshake failed
Stream is already closed
OpenSSL 的输出是:
CONNECTED(00000003)
read from 0x6ae470 [0x6af050] (4096 bytes => 26 (0x1A))
0000 - 32 32 30 20 6d 79 73 65-72 76 65 72 20 45 53 4d 220 myserver ESM
0010 - 54 50 20 76 73 6d 74 70-64 0a TP vsmtpd.
write to 0x6ae470 [0x6b0060] (25 bytes => 25 (0x19))
0000 - 45 48 4c 4f 20 6f 70 65-6e 73 73 6c 2e 63 6c 69 EHLO openssl.cli
0010 - 65 6e 74 2e 6e 65 74 0d-0a ent.net..
read from 0x6ae470 [0x6af050] (4096 bytes => 28 (0x1C))
0000 - 32 35 30 2d 6d 79 73 65-72 76 65 72 20 48 65 6c 250-myserver Hel
0010 - 6c 6f 20 6d 79 63 6c 69-65 6e 74 0a lo myclient.
read from 0x6ae470 [0x6af050] (4096 bytes => 13 (0xD))
0000 - 32 35 30 20 53 54 41 52-54 54 4c 53 0a 250 STARTTLS.
write to 0x6ae470 [0x7ffdb4aea9e0] (10 bytes => 10 (0xA))
0000 - 53 54 41 52 54 54 4c 53-0d 0a STARTTLS..
read from 0x6ae470 [0x6a13a0] (8192 bytes => 13 (0xD))
0000 - 32 32 30 20 47 6f 20 61-68 65 61 64 0a 220 Go ahead.
write to 0x6ae470 [0x6aefa0] (204 bytes => 204 (0xCC))
0000 - 16 03 01 00 c7 01 00 00-c3 03 03 0e ac 05 35 45 ..............5E
0010 - db 95 f6 a7 37 55 d8 ca-14 d7 5f 8e 6a 62 08 50 ....7U...._.jb.P
0020 - c9 81 b7 55 75 a8 4c 17-c0 a1 53 00 00 76 00 a5 ...Uu.L...S..v..
0030 - 00 a3 00 a1 00 9f 00 6b-00 6a 00 69 00 68 00 39 .......k.j.i.h.9
0040 - 00 38 00 37 00 36 00 88-00 87 00 86 00 85 00 9d .8.7.6..........
0050 - 00 3d 00 35 00 84 00 a4-00 a2 00 a0 00 9e 00 67 .=.5...........g
0060 - 00 40 00 3f 00 3e 00 33-00 32 00 31 00 30 00 9a .@.?.>.3.2.1.0..
0070 - 00 99 00 98 00 97 00 45-00 44 00 43 00 42 00 9c .......E.D.C.B..
0080 - 00 3c 00 2f 00 96 00 41-00 07 00 05 00 04 00 16 .<./...A........
0090 - 00 13 00 10 00 0d 00 0a-00 15 00 12 00 0f 00 0c ................
00a0 - 00 09 00 ff 02 01 00 00-23 00 23 00 00 00 0d 00 ........#.#.....
00b0 - 16 00 14 06 01 06 02 05-01 05 02 04 01 04 02 03 ................
00c0 - 01 03 02 02 01 02 02 00-0f 00 01 01 ............
read from 0x6ae470 [0x6b4500] (7 bytes => -1 (0xFFFFFFFFFFFFFFFF))
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 80 bytes and written 239 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
---
据我从输出中了解到,我的程序会在 TLS 握手完成之前关闭连接。 (我也尝试过使用 Thunderbird 和 Claws Mail)
我在这里做错了什么?
PS:我找不到任何有关如何在 STARTTLS 情况下使用 GTLsServerConnection
的示例。
更新:
我尝试了 OpenSSL 的 -ssl2、-ssl3、-tls1、-tls1_1、-tls1_2 选项,但也不起作用。
openssl s_client -connect localhost:10025 -starttls smtp -state
产量:
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:error in SSLv2/v3 read server hello A
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 100 bytes and written 239 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
---
所以客户端发送了“client hello A”,但是服务器没有发送正确的“server hello A”。
作为替代方案,您也可以尝试 gnutls-cli --crlf --starttls-proto=smtp --port 10025 localhost
。
GNUTLS_DEBUG_LEVEL=11 ./vsmtpd
的输出为:
gnutls[2]: Enabled GnuTLS logging...
gnutls[2]: Intel SSSE3 was detected
gnutls[2]: Intel AES accelerator was detected
gnutls[2]: Intel GCM accelerator was detected
gnutls[2]: Enabled GnuTLS logging...
gnutls[2]: Intel SSSE3 was detected
gnutls[2]: Intel AES accelerator was detected
gnutls[2]: Intel GCM accelerator was detected
gnutls[3]: ASSERT: x509_b64.c:299
gnutls[9]: Could not find '-----BEGIN RSA PRIVATE KEY'
gnutls[3]: ASSERT: x509_b64.c:299
gnutls[9]: Could not find '-----BEGIN DSA PRIVATE KEY'
gnutls[3]: ASSERT: x509_b64.c:299
gnutls[9]: Could not find '-----BEGIN EC PRIVATE KEY'
gnutls[3]: ASSERT: privkey.c:503
gnutls[2]: Falling back to PKCS #8 key decoding
EHLO openssl.client.net
STARTTLS
gnutls[5]: REC[0xfa67e0]: Allocating epoch #0
gnutls[3]: ASSERT: gnutls_constate.c:586
gnutls[5]: REC[0xfa67e0]: Allocating epoch #1
gnutls[3]: ASSERT: gnutls_buffers.c:1138
gnutls[10]: READ: -1 returned from 0xfa4120, errno=0 gerrno=5
gnutls[3]: ASSERT: gnutls_buffers.c:364
gnutls[3]: ASSERT: gnutls_buffers.c:572
gnutls[3]: ASSERT: gnutls_record.c:1058
gnutls[3]: ASSERT: gnutls_record.c:1179
gnutls[3]: ASSERT: gnutls_buffers.c:1392
gnutls[3]: ASSERT: gnutls_handshake.c:1428
gnutls[3]: ASSERT: gnutls_handshake.c:3098
gnutls[3]: ASSERT: gnutls_db.c:334
TLS handshake failed
Stream is already closed
gnutls[5]: REC[0xfa67e0]: Start of epoch cleanup
gnutls[5]: REC[0xfa67e0]: End of epoch cleanup
gnutls[5]: REC[0xfa67e0]: Epoch #0 freed
gnutls[5]: REC[0xfa67e0]: Epoch #1 freed
最佳答案
问题隐藏在 DataInputStream
实现中的某个地方。
一旦我删除它并使用以下替换 read_line ()
,它就可以正常工作。
string? read_line (InputStream input) throws Error {
var buffer = new uint8[1];
var sb = new StringBuilder ();
buffer[0] = '\0';
while (buffer[0] != '\n') {
input.read (buffer);
sb.append_c ((char) buffer[0]);
}
return (string) sb.data;
}
void process_request_plain (InputStream input, OutputStream output) throws Error {
output.write (@"220 $hostname ESMTP $appname\n".data);
string line;
while ((line = read_line (input)) != null) {
stdout.printf ("%s\n", line);
line = line.chomp ();
if (line.substring (0, 5) == "EHLO ") {
output.write (@"250-$hostname Hello $username\n".data);
output.write ("250 STARTTLS\n".data);
}
else if (line == "STARTTLS") {
output.write ("220 Go ahead\n".data);
break;
}
else {
output.write ("502 Command not implemented\n".data);
}
}
}
关于smtp - 如何实现服务器端 SMTP STARTTLS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32967750/
我有以下代码: import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException
我正在尝试使用 Vala 和 GLib + GIO 实现一个简单的 SMTP 服务器。 到目前为止,纯文本通信没有问题,但当涉及使用 STARTTLS 的 TLS 时,事情会变得更加困难。 这是我到目
每次有人运行 apacheant 来更新我们的实时服务器时,我都会尝试向我的团队发送电子邮件,我尝试通过 GMAIL 发送电子邮件,但是当我运行 ant upload_live -d 时,我收到以下错
我能够通过 IP 和端口连接到所需的套接字。 - (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host por
我正在尝试为我在办公室网络上运行的小型监控脚本设置一些基本的电子邮件功能。在我的 Ubuntu 10.10 服务器上运行脚本(见下文)工作正常,但是当我在 Windows 桌面计算机上运行它时,它会在
我是 python 的新手。我已经对 python 的鸭子类型进行了一些研究,但我遇到了如下情况。 当我查看 Python 标准库时,我发现 API 仅指定参数名称,这些名称似乎提示要传递的内容但类型
最近似乎支持 SSL/TLS added通过 SecureSocket 到 Dart类,这很棒。 所以,例如这个 SecureSocket.connect(_host, _port).then(
我正在尝试使用 TLS 连接到 apacheds,但我得到了一个 LdapOperationException: PROTOCOL_ERROR:服务器将断开连接! 这是我的代码: LdapNetwor
我正在尝试使用 STARTTLS 命令发送电子邮件。我在 Gmail 中设置了一个测试帐户,并将其设置为仅接受具有 TLS 连接的入站电子邮件。 由于我不想深入的原因,我无法使用 JavaMail 或
所以我有一个简单的(仍然需要工作!)python/twisted 邮件服务器,它支持纯文本/TLS 邮件。我还刚刚使用 smtplib 编写了一个简单的客户端程序。 如果我使用 telnet 连接到我
我正在用 C++ 编写电子邮件客户端,使用 Winsock2 API 从 Gmail 帐户通过 SMTP 发送电子邮件。我没有使用任何其他第三方库。 我已经通过端口587(用于TLS)连接到Gmail
我正在尝试通过 log4j 发送错误电子邮件。通过使用以下附加程序:
这可能是一个重复的问题,但我仍然面临着这方面的问题,希望有解决方案。提前致谢。 我正在尝试通过公司的服务器发送邮件 我目前使用的是 Python 2.6 版和 Ubuntu 10.04 这是我得到的错
我正在使用我的 Gmail 帐户运行这个简单的示例,但它不起作用并出现以下错误: send failed, exception: com.sun.mail.smtp.SMTPSendFai
我正在尝试使用以下代码使用 sendmailR 包从 R 发送电子邮件,不幸的是失败了: ## Set mail contents from ', Sys.info()[4]) to ' subjec
在设置我的 session 时,我正在设置 starttls.enable 和 .required 属性,但是当连接发生时,它应该会根据文档失败: mail.smtp.starttls.enable
我正在尝试在sendmail中启动tls,但我不知道如何使用证书。请给我建议方法 > telnet localhost 25 Trying 127.0.0.1... Connected to loca
我尝试使用 STARTTLS 通过 php 和 swiftmailer 发送电子邮件,但收到证书错误。我拥有 SMTP 服务器的 root 访问权限,并且使用的证书是自签名的。我在两台机器上都使用 D
我尝试通过 postfix 通过 gmail 发送电子邮件,但它显示以下错误: 必须首先发出 STARTTLS 命令。 Sep 6 01:11:34 NovusTec postfix/smtp[10
我想实现 STARTTLS在 iOS 应用程序中,但我无法从文档中弄清楚如何去做。 到目前为止我有: 我使用 CFStreamCreatePairWithSocketToHost 创建套接字并打开流:
我是一名优秀的程序员,十分优秀!