使用流上下文可以在PHP下使用FTPS吗? [英] Is it possible to work with FTPS under PHP using stream context?

查看:111
本文介绍了使用流上下文可以在PHP下使用FTPS吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解到,在PHP for Windows下使用 ftps ('ftp_ssl_connect()')非常困难。您被要求进入构建自己的二进制文件的漫长旅程,以包含Open SSL ...我在 phpseclib 一个>作为替代品(但获得openssl.cnf的权利,以支持同行验证听起来很难,我也...)。

然后我打了这篇文章及其令人愉快的简单示例,包括工作同行验证(以避免Man-in-中级攻击)将我的注意力吸引到了流:

  $ uri ='https://www.bankofamerica.com/ ; 
$ ctx = stream_context_create(['ssl'=> [
'verify_peer'=> true,// important
'cafile'=>'/ hard / path / to / cacert.pem',
'CN_match'=>'www.bankofamerica.com'
]]);
$ html = file_get_contents($ uri,FALSE,$ ctx); //我们很好

但是,这对于ftp连接有用吗? 我也可以使用经过同行验证的流上下文来打开ftps流吗? PHP手册提示,ssl上下文选项也适用于sftp,但缺乏进一步的指导。



所以我疯狂地猜测:

  $ ctx = stream_context_create(['ftps'=> [
'verify_peer'=> true,
'cafile'=>'d:/sandbox/mycerts.pem',
'CN_match'=>'ftp-12345678.mywebhoster.com'
]]);

对吗?错误?用户+密码作为选项了吗?然后什么?用户/密码了吗?或以后?我无能为力......




  • 如何扫描远程ftp目录内容以开始使用?

  • 如何从ftp服务器上传或下载文件?



有甚么可能吗? (几行代码会非常有用....)或者流只适用于单一文件访问?



更新
Curl可以做我想做的事(包括同行验证和目录定位)如此答案所示。将在本周晚些时候进行检查......

解决方案

这项工作会如何?



< blockquote>

我也可以使用经过同行验证的流上下文来打开ftps流吗?


是的。 ftps 流包装器使用与 https 包装器相同的SSL上下文选项,并且只要您在PHP构建中启用了openssl扩展,就可以使用它。您可以通过检查 的输出来验证 ftps 包装器是否可用。 stream_get_wrappers() 就像这样:

 <?php 
print_r (stream_get_wrappers());

如果您在PHP构建中启用了ext / openssl,您会看到 ftps 和其他可用的流包装一起列在输出中。



如何分配SSL上下文选项?



< blockquote>

所以我疯狂猜测


你真的很接近!您需要在代码中进行更改的唯一方法是用ssl替换ftps,如下所示:

 <?php 
$ ctx = stream_context_create(['ssl'=> [
' verify_peer'=> true,
'cafile'=>'d:/sandbox/mycerts.pem',
'CN_match'=>'ftp-12345678.mywebhoster.com'
]]);

无论您使用的是 https ftps 或任何其他流封装,控制SSL / TLS加密的上下文选项总是存储在ssl键中。



我在哪里放置用户名/密码?




对吗?错误?用户+密码作为选项了吗?然后什么?用户/密码了吗?或以后?我无能为力......


ftps 流封装期望URI中的用户名和密码如下所示:

 <?php 
$ ftpPath ='ftps: //username:password@example.com';

不要被我们在这里指定的用户/传入明文中抛出。流包装将仅在加密连接建立后发送用户名和密码



整合在一起



opendir() 系列函数支持 ftp 包装器(自PHP 5.0起)。您可以像使用本地文件系统路径一样使用这些函数:

 <?php 
$ ctx = stream_context_create (['ssl'=> [
'verify_peer'=> true,
'cafile'=>'d:/sandbox/mycerts.pem',
'CN_match'= >'ftp-12345678.mywebhoster.com'
]]);
$ dirHandle = opendir('ftps:// username:password@example.com/',$ ctx); ($ file = readdir($ dirHandle))!== == false){
echofilename:$ file\\\
;
}
closedir($ dirHandle);



有关SSL / TLS名称匹配的注意事项



如果它最初不起作用,则应该测试而不传递包含SSL选项的附加上下文 $ ctx 。服务器证书的CN(通用名称)字段必须与您指定的CN_match值匹配(对子域名进行有限的通配符匹配)。另外,在即将发布的PHP-5.6版本之前,不支持将名称与远程方证书中的使用者备用名称字段进行匹配。除非您正在使用5.6的开发预览,否则您将不具备此功能(SAN匹配),并且如果服务器依赖于SAN,则对等验证例程将失败。


I learned that using ftps (´ftp_ssl_connect()´) under PHP for Windows is tough. You are asked to enter a long journey of building your own binaries to include Open SSL... I found advice on phpseclib as a replacement (but getting openssl.cnf right to support peer validation sounds pretty hard to me, too...).

Then I hit this article and its pleasingly simple example including working peer validation (to avoid Man-in-the-middle-Attacks) drew my attention to streams:

$uri = 'https://www.bankofamerica.com/';
$ctx = stream_context_create(['ssl' => [
    'verify_peer' => true, // important
    'cafile' => '/hard/path/to/cacert.pem',
    'CN_match' => 'www.bankofamerica.com'
]]);
$html = file_get_contents($uri, FALSE, $ctx); // we are good

However, is this useful for ftp connections? Can I also use peer-validated stream contexts to open ftps streams? The php manual hints, ssl context options also apply to sftp, but lacks further guidance.

So I am wildly guessing:

$ctx = stream_context_create(['ftps' => [
    'verify_peer' => true,
    'cafile' => 'd:/sandbox/mycerts.pem',
    'CN_match' => 'ftp-12345678.mywebhoster.com'
]]);

Right? Wrong? User+Password as options now? And then what? User/Password now? Or later? I am clueless...

  • How do I scan the remote ftp directory contents to start with?
  • How to I upload or download a file from an ftp server?

Is any of that even possible? (A few lines of code would be very helpful....) Or are streams only good for singular file access?

Update: Curl might do what I want (including peer validation and directory lsiting) as shown in this SO answer. Will examine later this week...

解决方案

Will this work?

Can I also use peer-validated stream contexts to open ftps streams?

Yes. The ftps stream wrapper utilizes the same SSL context options as the https wrapper and will be available as long as you have the openssl extension enabled in your PHP build. You can verify if the ftps wrapper is available by checking the output from stream_get_wrappers() like so:

<?php
print_r(stream_get_wrappers());

If you have ext/openssl enabled in your php build you'll see ftps listed in the output alongside the other available stream wrappers.

How do I assign the SSL context options?

So I am wildly guessing

You're really close! The only thing you need to change in your code is to replace "ftps" with "ssl" as shown here:

<?php
$ctx = stream_context_create(['ssl' => [
    'verify_peer' => true,
    'cafile' => 'd:/sandbox/mycerts.pem',
    'CN_match' => 'ftp-12345678.mywebhoster.com'
]]);

Regardless of whether you're using https, ftps or any other stream wrapper the context options governing SSL/TLS encryption are always stored in the "ssl" key.

Where do I put the user/password?

Right? Wrong? User+Password as options now? And then what? User/Password now? Or later? I am clueless...

The ftp and ftps stream wrappers both expect the username and password in the URI as shown here:

<?php
$ftpPath = 'ftps://username:password@example.com';

Don't be thrown off by our specification of the user/pass in cleartext here. The stream wrapper will only send the username and password after an encrypted connection is established.

Putting it all together

The opendir() family of functions supports the ftp wrapper (since PHP 5.0). You use these functions the same way you would with local filesystem paths:

<?php
$ctx = stream_context_create(['ssl' => [
    'verify_peer' => true,
    'cafile' => 'd:/sandbox/mycerts.pem',
    'CN_match' => 'ftp-12345678.mywebhoster.com'
]]);
$dirHandle = opendir('ftps://username:password@example.com/', $ctx);
while (($file = readdir($dirHandle)) !== false) {
    echo "filename: $file\n";
}
closedir($dirHandle);

Note on SSL/TLS name matching

If it doesn't work initially you should test without passing the additional context $ctx containing the SSL options. The CN (common name) field of the server's certificate must match the "CN_match" value you specify (with limited wildcard matching for subdomains). Also, prior to the forthcoming PHP-5.6 release there is no support for matching names against the Subject Alternative Name field in the remote party's certificate. Unless you're working with a development preview for 5.6 you won't have this capability (SAN matching) and the peer verification routine will fail if the server relies on SAN.

这篇关于使用流上下文可以在PHP下使用FTPS吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆