Ubuntu 下 nginx-1.24.0 源码分析 - ngx_ssl_version 函数

定义

event\ngx_event_openssl.h 中:

#if (OPENSSL_VERSION_NUMBER >= 0x10100001L)

#define ngx_ssl_version()       OpenSSL_version(OPENSSL_VERSION)

#else

#define ngx_ssl_version()       SSLeay_version(SSLEAY_VERSION)

#endif
#if (OPENSSL_VERSION_NUMBER >= 0x10100001L)

预处理指令,用于条件编译 ,

检查 OPENSSL_VERSION_NUMBER 是否大于或等于 0x10100001L(OpenSSL 1.1.0 版本对应的十六进制常量)

根据 OpenSSL 的版本号,决定使用不同的版本获取函数。这是为了确保代码与不同版本的 OpenSSL 兼容

OpenSSL 的版本号是通过一个宏 OPENSSL_VERSION_NUMBER 来表示的,这个宏的值是一个十六进制常量,它编码了 OpenSSL 的版本信息。
OpenSSL_version() 是 OpenSSL 1.1.0 新增的 API,用于获取版本信息。

OPENSSL_VERSION 是参数,表示需要获取完整的版本字符串

OPENSSL_VERSION_NUMBER

定义在 event\ngx_event_openssl.h

#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)
#undef OPENSSL_VERSION_NUMBER
#if (LIBRESSL_VERSION_NUMBER >= 0x2080000fL)
#define OPENSSL_VERSION_NUMBER  0x1010000fL
#else
#define OPENSSL_VERSION_NUMBER  0x1000107fL
#endif
#endif

这段代码是 Nginx 源码中用于处理 LibreSSL 和 OpenSSL 版本兼容性问题的部分。

#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)

defined LIBRESSL_VERSION_NUMBER

检查是否定义了 LIBRESSL_VERSION_NUMBER 宏。

这个宏通常在使用 LibreSSL 的时候会被定义,表明当前环境使用的是 LibreSSL 而非 OpenSSL。

OPENSSL_VERSION_NUMBER == 0x20000000L

检查 OPENSSL_VERSION_NUMBER 是否等于 0x20000000L

这个常量可能是一个特殊的占位值或标识符,通常用于区分 LibreSSL 和 OpenSSL 的版本

第三方库 openssl/opensslv.h 中定义了 OPENSSL_VERSION_NUMBER

用以下代码去输出它的值:

#include <stdio.h>
#include <openssl/opensslv.h>

int main() {
    printf("OPENSSL_VERSION_NUMBER: 0x%lx\n", OPENSSL_VERSION_NUMBER);
    return 0;
}

没有 LIBRESSL_VERSION_NUMBER 的定义

#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)

条件不成立

OPENSSL_VERSION_NUMBER 的值还是 0x30000020

#if (OPENSSL_VERSION_NUMBER >= 0x10100001L)

这个条件就成立

于是 ngx_ssl_version 的定义是这个

#define ngx_ssl_version()       OpenSSL_version(OPENSSL_VERSION)

可用以下代码查看 OPENSSL_VERSION 的值:

#include <stdio.h>
#include <openssl/crypto.h>

int main() {
    printf("OPENSSL_VERSION: %d\n", OPENSSL_VERSION);
    return 0;
}

用以下代码去使用以下 OpenSSL_version(OPENSSL_VERSION) 看一下效果

在编译时,需要使用 -lcrypto-lssl 选项来链接 OpenSSL 的库

#include <stdio.h>
#include <openssl/crypto.h>
#include <openssl/opensslv.h>

int main() {
    printf("OPENSSL_VERSION: %s\n", OpenSSL_version(OPENSSL_VERSION));
    return 0;
}
#undef OPENSSL_VERSION_NUMBER

取消定义 OPENSSL_VERSION_NUMBER

如果满足前面的条件(即当前环境是 LibreSSL 并且 OPENSSL_VERSION_NUMBER 被设置为 0x20000000L),则取消它的定义。这是因为需要重新定义 OPENSSL_VERSION_NUMBER 为一个更合理的值,以适应 Nginx 的版本检查逻辑

#if (LIBRESSL_VERSION_NUMBER >= 0x2080000fL)

LIBRESSL_VERSION_NUMBER >= 0x2080000fL

检查 LibreSSL 的版本号是否大于或等于 0x2080000fL

如果 LibreSSL 的版本号足够新,则执行接下来的代码块。这个版本号的编码格式通常与 LibreSSL 的内部版本表示有关,0x2080000fL 对应的是一个特定的 LibreSSL 版本。

#define OPENSSL_VERSION_NUMBER  0x1010000fL

定义 OPENSSL_VERSION_NUMBER0x1010000fL

如果 LibreSSL 的版本号 >= 0x2080000fL,则将 OPENSSL_VERSION_NUMBER 设置为 0x1010000fL。这个值对应的是 OpenSSL 1.1.0 的版本号(或者类似的功能集合),目的是让 Nginx 在处理 LibertySSL 的时候,能够伪造成 OpenSSL 1.1.0 的版本,从而兼容某些依赖于 OpenSSL 版本号的逻辑。

#else

预处理指令,表示如果第 3 行的条件不成立(即 LibreSSL 的版本号 < 0x2080000fL),则执行接下来的代码块

#define OPENSSL_VERSION_NUMBER  0x1000107fL
相关推荐
Мартин.13 小时前
[Meachines] [Easy] Broker Apache MQ RCE+Nginx ngx_http_dav_module权限提升
nginx·http·apache
Dragon水魅15 小时前
Ubuntu22.04 配置deepseek知识库
linux·服务器·深度学习·ubuntu
阿昊真人20 小时前
mobaxterm 无法ssh连接ubuntu
ubuntu
蓝创精英团队1 天前
基于Ubuntu Ollama 部署 DeepSeek-R132B 聊天大模型(附带流式接口调用示例)
linux·运维·ubuntu·deepseek
罗伯特祥1 天前
ubuntu安装VMware报错/dev/vmmon加载失败
ubuntu·appimage·libfuse
Coding Happily1 天前
拯救者Y9000P双系统ubuntu22.04安装4070显卡驱动
ubuntu·显卡驱动·双系统
踩踩芽1 天前
【苍穹外卖】修改前端代码解决修改Nginx端口后websocket连接失败的问题
websocket·nginx·苍穹外卖
狂笑韦恩1 天前
Ubuntu 作为 FTP 服务器,Windows 作为 FTP 客户端
linux·服务器·ubuntu
晴空万里Linux1 天前
VMware 虚拟机 ubuntu 20.04 扩容工作硬盘
linux·运维·ubuntu