【问题标题】:openssl accept connection use my bufferopenssl 接受连接使用我的缓冲区
【发布时间】:2017-05-13 05:43:18
【问题描述】:

正常:浏览器发送到我的代理:“CONNECT...\r\n\r\n”,代理发送“200 OK\r\n\r\n”,浏览器发送加密请求,代理调用 SSL_accept (插座)。好的。

问题:浏览器发送到我的代理服务器:“CONNECT...\r\n\r\n”+ 下一个加密请求。代理发送“200 OK\r\n\r\n”,调用 SSL_accept(socket) 返回 SSL_ERROR_SSL 或 SSL_ERROR_SYSCALL,因为代理读取了加密请求的缓冲区部分。

解决方案:

  1. 使用 recv(sock, buf, buffer_size, MSG_PEEK) 和 recv(sock, buf, used_size, 0)。问题:将读取所有数据,或者 pool() 中的无限信号。

  2. 如何调用 SSL_accept() 将我的缓冲区与部分加密数据一起使用?

  3. 有什么解决办法吗?

【问题讨论】:

  • 解决方案是修复有问题的客户端。在尝试协商 TLS 之前,客户端必须等待代理建立连接并发送“200 ok...”。客户端的代码坏了。
  • 不要在空行之后读取任何内容,即使这意味着您必须一次读取一个字节:性能在这里并不重要。并确保在建立上游连接之前不发送 200 OK。
  • @SamVarshavchik 错误在代理端。允许客户端在收到200 回复之前发送数据。这在CONNECT specSection 3.3 "Data Pipelining" 中有说明。代理不应首先调用 SSL_accept(),因为它不是 TLS 握手的目标。它应该将原始数据按原样传递到下一个服务器。

标签: c++ openssl


【解决方案1】:

问题在于您的代理,而不是客户端。

根据CONNECT specification 的第 3.3 节:

3.3。数据流水线

客户端在收到“200 连接建立”(或任何其他成功或错误代码)之前发送一些用于服务器的数据是合法的。这可以减少延迟并增加当任何用于远程服务器的握手数据可以在与代理请求相同的 TCP 数据包中发送时,效率。这允许代理在与远程服务器建立连接后立即转发数据,而无需等待到客户端的两次往返时间(向客户端发送 200;等待来自客户端的下一个数据包)。

这意味着代理服务器不能假定从 客户端套接字描述符只会返回代理请求。)相反,代理请求之后可能有任何数量的不透明数据,一旦建立连接,必须将其转发到服务器。但是,如果与远程服务器的连接失败,或者代理服务器不允许连接,则打算发送给远程服务器的数据将被代理丢弃。

真正的错误是您的 HTTP 代理不应该首先调用 SSL_accept(),因为它不是客户端 TLS 握手的目标。请求的服务器是目标,因此只有它才能正确响应握手。您的代理不得响应握手。这可能会导致客户端失败(尤其是在客户端正确地完成其工作以验证响应不是来自中间人的情况下)。

您的代理必须与请求的服务器建立正常的未加密连接,然后来回传递任何原始数据。您的代理不是客户端/服务器加密会话的参与者,它只是促进客户端和服务器之间数据交换的传递,仅此而已。

不要试图以任何方式解释客户端或服务器的数据,这不是您要处理的数据。初始 CONNECT 请求之后的所有内容对于代理都是不透明的,必须按原样转发。您不知道客户端和服务器如何相互通信,也无法做出任何假设。

【讨论】:

  • 全部正确,但代理中间人。
猜你喜欢
  • 2018-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-19
  • 1970-01-01
  • 2013-08-19
  • 2010-09-14
  • 2021-07-24
相关资源
最近更新 更多