ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

libcurl CURLOPT_SSH_PUBLIC_KEYFILE 详解:SFTP/SCP 公钥认证文件配置指南

libcurl CURLOPT_SSH_PUBLIC_KEYFILE 详解:SFTP/SCP 公钥认证文件配置指南 libcurl CURLOPT_SSH_PUBLIC_KEYFILE 详解SFTP/SCP 公钥认证文件配置指南【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl导读CURLOPT_SSH_PUBLIC_KEYFILE是 libcurl 中用于指定 SSH 公钥文件的选项作用于 SFTP 与 SCP 两种协议的公钥认证流程。本文基于该选项的官方文档结合 libcurl 源码实现lib/setopt.c、lib/vssh/vssh.c与测试用例tests/libtest/lib583.c完整讲解其默认行为、传参规则、空字符串语义、与私钥选项的配合方式以及连接一旦建立即被 vetted 复用这一关键生命周期特性帮助你写出可正确落地的 SSH 公钥认证代码。选项原型与所属协议CURLOPT_SSH_PUBLIC_KEYFILE自 libcurl 7.16.1 起加入仅适用于SFTP与SCP协议。其函数原型如下#include curl/curl.h CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSH_PUBLIC_KEYFILE, char *filename);从源码角度看它在 include/curl/curl.h 中被声明为CURLOPTTYPE_STRINGPOINT类型内部枚举 ID 为 152即向 libcurl 传递一个指向字符串的指针在 lib/easyoptions.c 的选项表中则登记为CURLOT_STRING类型。这两处定义决定了它接受的参数必须是char *形式的文件路径字符串。参数说明与默认行为传入公钥文件路径向该选项传入一个指向公钥文件名的char *指针libcurl 会在建立 SFTP/SCP 连接时使用该公钥文件进行认证curl_easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, /home/clarkkent/.ssh/id_rsa.pub);未设置时的默认值若HOME环境变量已设置libcurl 默认使用$HOME/.ssh/id_dsa.pub若HOME未设置则在当前目录下查找id_dsa.pub。需要注意的是文档给出的默认查找逻辑以id_dsa.pub为基准而当前仓库中 SSH 连接建立时的实际密钥探测逻辑更为宽泛。在 lib/vssh/vssh.c 中可以看到libcurl 会依次尝试$HOME/.ssh/id_rsa、$HOME/.ssh/id_dsa再回退到当前目录下的id_rsa、id_dsa最终才会放弃探测。这意味着实际运行时对密钥文件的搜索比文档描述的默认值更宽容但显式传入本选项仍是控制公钥文件最可靠的方式。字符串生命周期调用方不需要在设置该选项后继续持有字符串libcurl 会在curl_easy_setopt内部通过Curl_setstropt拷贝该字符串见 lib/setopt.c。这一点在编写长期运行的应用程序时非常重要——设置后即可安全释放或复用传入的缓冲区。传 NULL 与空字符串的语义文档中有一个容易被忽视但非常实用的行为传入NULL或空字符串时libcurl 不向 SSH 库传递任何公钥而是由 SSH 库从私钥推导公钥若 SSH 库无法从私钥推导出公钥且又未提供公钥文件则传输失败。这一行为在 lib/vssh/vssh.c 的实现中得到印证/* * Unless the user explicitly specifies a public key file, let the SSH * library extract the public key from the private key file. This is done * by passing sshc-pub_key NULL. */ str CURL_EASY_STR(data, STRING_SSH_PUBLIC_KEY); if(str *str) { /* treat empty string the same way as NULL */ sshc-pub_key curlx_strdup(str); ... }源码注释明确写道将空字符串与 NULL 等同对待。也就是说如果你希望完全依赖从私钥推导公钥的机制只需不设置该选项或将值置为空字符串即可。相应地lib/vssh/vssh.c 会在开启 verbose 模式时打印所采用的文件SSH: public key file /path/to/key.pub SSH: private key file /path/to/key SSH: public key auth without private key set!其中最后一条日志意味着公钥已设置但私钥未提供此时认证大概率无法成功可作为排错时的线索。空字符串技巧的版本历史空字符串等价于 NULL这一技巧是在7.26.0版本中加入的。在此之前空字符串不会被特殊处理。如果你的代码需要兼容 7.26.0 之前的旧版本 libcurl应显式传 NULL 而不是空字符串。与私钥选项配合使用公钥认证几乎总是需要私钥配合两者成对出现。相关选项是CURLOPT_SSH_PRIVATE_KEYFILE见 CURLOPT_SSH_PRIVATE_KEYFILE 文档其底层实现同样位于 lib/setopt.c映射到STRING_SSH_PRIVATE_KEY字符串槽位。此外CURLOPT_SSH_AUTH_TYPES 用于指定允许的认证方式位掩码如CURLSSH_AUTH_PUBLICKEY、CURLSSH_AUTH_PASSWORD、CURLSSH_AUTH_AGENT等默认值为CURLSSH_AUTH_ANY即允许所有可用方式。仓库中的测试用例是公私钥配对使用的典型示范。tests/libtest/lib583.c 中同时设置公钥与私钥文件easy_setopt(curl, CURLOPT_USERPWD, libtest_arg2); easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, test_argv[3]); easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, test_argv[4]);若你的私钥带有口令保护可通过 CURLOPT_KEYPASSWD 提供口令从 lib/vssh/vssh.c 可以看到该口令会作为sshc-passphrase传入 SSH 库。完整示例以下是一个可直接编译运行的完整示例源自官方文档结合上述要点补充了返回值检查演示如何通过 SFTP 协议配合公钥认证下载文件#include stdio.h #include curl/curl.h int main(void) { CURL *curl curl_easy_init(); if(curl) { CURLcode result; curl_easy_setopt(curl, CURLOPT_URL, sftp://example.com/file); curl_easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, /home/clarkkent/.ssh/id_rsa.pub); curl_easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, /home/clarkkent/.ssh/id_rsa); result curl_easy_perform(curl); if(result ! CURLE_OK) fprintf(stderr, curl_easy_perform() failed: %s\n, curl_easy_strerror(result)); curl_easy_cleanup(curl); } return 0; }如需使用 SCP 协议仅需将 URL 前缀改为scp://即可其余选项完全一致。多接口multi场景下的使用该选项同样适用于 multi 接口。仓库测试 tests/libtest/lib582.c 展示了在 multi 事件驱动模型中设置公钥/私钥文件并执行 SFTP 上传的完整流程easy_setopt(curl, CURLOPT_USERPWD, libtest_arg3); easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, test_argv[4]); easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, test_argv[5]);这组测试用例本身也是学习SFTP 上传 multi 接口组合的绝佳参考。连接复用语义仅用于建立新连接这是本选项最容易被误用的特性务必注意该选项仅用于建立新连接。公钥在 libcurl 建立新的 SSH 连接时使用一旦连接成功建立并通过验证该连接即被视为vetted已审查可信即使之后修改此选项libcurl 也可能复用这条旧连接。实际影响是对同一个 easy handle 反复执行curl_easy_perform第二次及后续请求可能直接复用第一次建立的已验证连接不会重新读取新的公钥文件若公钥文件被轮换或更改而连接仍然存活新公钥不会立即生效若要强制应用新的公钥配置需要让旧连接关闭例如等待其空闲超时、或在 multi 接口中移除并重新加入 handle再发起新的连接。这一设计是出于安全与性能的双重考量已通过验证的连接无需重复认证从而避免握手开销。返回值与错误处理curl_easy_setopt总是返回CURLcode类型的错误码CURLE_OK (0)设置成功非零值发生错误具体含义参见 libcurl-errors 文档。对于本选项而言传入非法的参数类型例如 NULL 之外的错误类型指针可能触发类型检查错误。当使用 GCC 且启用了 typecheck-gcc.h 提供的编译期类型检查时传入错误类型的参数会在编译期直接报错这有助于提前发现笔误。关于curl_easy_setopt的通用用法可参考 curl_easy_setopt 文档。使用要点总结场景推荐做法显式指定公钥文件传入绝对路径字符串如/home/user/.ssh/id_rsa.pub让 SSH 库从私钥推导公钥不设置本选项或传入 NULL / 空字符串7.26.0私钥有口令保护配合 CURLOPT_KEYPASSWD 提供口令控制认证方式配合 CURLOPT_SSH_AUTH_TYPES 设置CURLSSH_AUTH_PUBLICKEY等位掩码修改公钥后立即生效确保旧连接已关闭使 libcurl 建立新连接字符串生命周期设置后即可释放libcurl 内部会拷贝排错开启CURLOPT_VERBOSE观察 SSH: public key file ... 日志版本前提本选项自 7.16.1 起可用空字符串技巧自 7.26.0 起生效文章中的源码行为以当前仓库lib/vssh/vssh.c、lib/setopt.c为准且仅在使用 SFTP/SCP 协议并启用 SSH 支持USE_SSH的构建中生效。【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表