Symfony-Finder cant open dir - php

I try to read the dir and wanna get the last files from the current date.
When I put the url in the browser I got a result of all the files, which are in the ftp-directory.
So I have the proof, that the ftp-connectionparameter still works.
When I try to start the following function, then I get the error
RecursiveDirectoryIterator::__construct(ftp://...#example.com:4242): failed to open dir: operation failed
Here is the Exception from symfony:
/**
* #Route("/download", name="getfile")
*/
public function getFileWithFtp()
{
$host = "example.com";
$username = "username";
$userpass = "userpass";
$port = 4242;
$url = 'ftp://' . $username . ':' . $userpass . '#' . $host . ':' . $port .'/';
$datum = date('Y-m-d');
$finder = new Finder();
$iterator = $finder
->files()
->in($url)
->name('*BEHWN.TXT')
->date($datum);
$anzahl = count($iterator);
return $this->render('ftp/index.html.twig', [
'controller_name' => 'FtpController',
'url' => $url,
'anzahl' => $anzahl
]);
}
WHen i open the url with the file with file_gets_content($url."filename.txt"), then i get the content without error.
Only it seems that I dont use the Finder from Symfony not correct.
My current Symfony is 4.1.4 and I had cleared the caches and also i deleted the cache-files manually.
Thanks for every tipp
Here is the link to the symfony-finder-component:
https://symfony.com/doc/current/components/finder.html
As the Finder uses PHP iterators, you can pass any URL with a supported protocol:
Here is the part of the FTP code from the documentation:
// always add a trailing slash when looking for in the FTP root dir
$finder->in('ftp://example.com/');
// you can also look for in a FTP directory
$finder->in('ftp://example.com/pub/');

As stated in the docs, what you have in $iterator is a PHP iterator,
so you need to use iterator_count:
$anzahl = iterator_count($iterator);

This WILL not work anymore IF you are using symfony v3.4.7 and above..
There is the issue:
https://github.com/symfony/symfony/issues/27423
I did a fix but it will take a while till it gets merged i think
https://github.com/symfony/symfony/pull/28604
Summary:
"In Finder[...]was released which should remove duplicate slashes from path names.
However, this results in an error when used to find files in an FTP root dir."
"As a result, a working code before v3.4.7 result in breaking code after v3.4.7"
This is the method messing things up, including my fix
https://github.com/symfony/symfony/blob/0670c48477b3d88787b6fe0dec168c5c8ae49c66/src/Symfony/Component/Finder/Finder.php#L741

Related

SSRS SDK For PHP : Not working from PHP 5.5

I'm using the SSRS SDK For PHP which has not been updated since years surprisingly (08.04.2010) .
It works fine under PHP 5.4 (5.4.44) but not under 5.5+ (5.5.37, 5.6.28, 7.x)
The error is :
array ( )Failed to connect to Reporting Service Make sure that the url
(https://myHost:60004/ReportServer/) and credentials are
correct!
The exception is thrown in line 207 because the var $content is equals to FALSE (so can't load the content).
It's perfectly fine with PHP 5.4.44.
I can't find the "SSRS SDK For PHP" documentation regarding the PHP version supported...
I'm not using any framework such as Symfony2, CakePHP, Zend Framework,... except Bootstrap.
Does anyone know or have figured out this issue?
EDIT
As asked in a comment, here is my code :
function buildSSRSReport($companyId)
{
require_once '../tools/SSRSReport/SSRSReport.php';
try {
// Create a connection to the SSRS Server
$rs = new SSRSReport(new Credentials(SSRS_USER_ID, SSRS_PASSWORD), SSRS_REPORT_SERVER_URL);
$sqlConnection = self::getSqlConnection();
// Load the report and specify the params required for its execution
$executionInfo = $rs->LoadReport2(self::getSSRSEnvironment(), NULL);
$parameters = array();
$parameters[0] = new ParameterValue();
$parameters[0]->Name = "CompanyId";
$parameters[0]->Value = $companyId;
$rs->SetExecutionParameters2($parameters);
// Require the Report to be rendered in HTML format
$renderAsHTML = new RenderAsPDF();
// Set the links in the reports to point to the php app
//$renderAsHTML->ReplacementRoot = getPageURL();
// Set the root path on the server for any image included in the report
//$renderAsHTML->StreamRoot = './images/';
// Execute the Report
$result_html = $rs->Render2($renderAsHTML,
PageCountModeEnum::$Actual,
$Extension,
$MimeType,
$Encoding,
$Warnings,
$StreamIds);
$pdfFileName = self::getCompanyAlias($sqlConnection, $companyId) . ".pdf";
header('Content-Type: application/x-download');
header('Content-Disposition: attachment; filename="' . $pdfFileName . '"');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
return $result_html;
} catch (SSRSReportException $serviceException) {
echo $serviceException->GetErrorMessage();
}
}
function getSSRSEnvironment()
{
return "/DEV/CompanyESGReportingServices-DEV/Main";
}
private function getSqlConnection()
{
require_once("../inc/eth_connexion.php");
/* These 4 variables are contained within the eth_connexion.php file */
$serverName = SQL_SERVERNAME;
$userName = SQL_USERNAME;
$dbName = SQL_DATABASENAME;
$password = SQL_PASSWORD;
// SQLSRV : Connection array used when calling SQL via sqlsrv_query
$connectionInfo = array("Database"=> SQL_DATABASENAME,
"UID"=> SQL_USERNAME,
"PWD"=> SQL_PASSWORD,
"ReturnDatesAsStrings" => true);
$sqlConnection = sqlsrv_connect($serverName, $connectionInfo);
if (!$sqlConnection) {
die('Can't log to the database');
}
return $sqlConnection;
}
And here is the source code of the SSRSReport constructor (original from the SSRS SDK For PHP) :
public function SSRSReport($credentials, $url, $proxy = null)
{
$this->_BaseUrl = ($url[strlen($url) - 1] == '/')? $url : $url . '/';
$executionServiceUrl = $this->_BaseUrl . self::ExecutionService;
$managementServiceUrl = $this->_BaseUrl . self::ManagementService;
$options = $credentials->getCredentails();
$stream_conext_params = array( 'http' =>
array('header' =>
array($credentials->getBase64Auth())));
if(isset($proxy))
{
$options = array_merge($options, $proxy->getProxy());
$stream_conext_params['http']['proxy'] = 'tcp://' .
$proxy->getHost() .
':' .
$proxy->getPort();
if($proxy->getLogin() != null)
{
$stream_conext_params['http']['header'][1] = $proxy->getBase64Auth();
}
}
/**
* If the SoapClient call fails, we cannot catch exception or supress warning
* since it throws php fatal exception.
* http://bugs.php.net/bug.php?id=34657
* So try to load the wsdl by
* calling file_get_contents (with warning supressed i.e. using # symbol
* infront of the function call)
* http://stackoverflow.com/questions/272361/how-can-i-handle-the-warning-of-filegetcontents-function-in-php
*/
$context = stream_context_create($stream_conext_params);
$content = #file_get_contents($executionServiceUrl, false, $context);
if ($content === FALSE) // I'M GOING HERE WITH PHP 5.5+
{
throw new SSRSReportException("",
"Failed to connect to Reporting Service <br/> Make sure " .
"that the url ($this->_BaseUrl) and credentials are correct!");
}
$this->_soapHandle_Exe = new SoapClient ($executionServiceUrl, $options);
$this->_soapHandle_Mgt = new SoapClient ($managementServiceUrl, $options);
$this->ClearRequest();
}
The exact error message is :
https://myPublicHostProvider:60004/ReportServer/ReportExecution2005.asmx?wsdl
Authorization: Basic = array(1) {
["http"]=> array(1) { ["header"]=> array(1) { [0]=> string(57)
"Authorization: Basic =" } } }
Failed to connect to Reporting Service
Make sure that the url (https://myPublicHostProvider:60004/ReportServer/) and credentials are correct!
SSRS SDK for PHP Configuration Pointers
Make sure your Report Server instance is accessible. Test it by going to the Web Portal or the Service URL.
Provide your credentials. If you are authenticated, then the credentials that you used are valid.
After that, go to the directory \Program Files\Microsoft SQL Server\<INSTANCE_NAME>\Reporting Services\ReportServer and look for the file named rsreportserver.config
Find this snippet
<Authentication>
<AuthenticationTypes>
<RSWindowsNTLM/>
</AuthenticationTypes>
<Authentication>
Add <RSWindowsBasic/> below the <RSWindowsNTLM/> entry.
For your reference, this was the snippet I used to test my instance during configuration.
require_once( 'SSRSReport\bin\SSRSReport.php' );
define( 'UID', 'DOMAIN\Username' );
define( 'PASWD', 'Password' );
define( 'SERVICE_URL', 'http://127.0.0.1/SERVICE_URL/' );
try {
$ssrs_report = new SSRSReport( new Credentials( UID, PASWD ), SERVICE_URL );
$ssrs_report->LoadReport2( '/test', NULL );
$renderAsHTML = new RenderAsHTML();
$result_html = $ssrs_report->Render2(
$renderAsHTML,
PageCountModeEnum::$Estimate,
$Extension,
$MimeType,
$Encoding,
$Warnings,
$StreamIds
);
echo $result_html;
} catch ( SSRSReportException $serviceException ) {
echo $serviceException->GetErrorMessage();
}
It can successfully load the RDL that is located on the load path.
Thanks for your help MiSAKACHi. It pointed me on the right direction. Actually, I'm using a remote dedicated server on a hosting provider on which I don't have access. But the <RSWindowsBasic/> is there as it can load the report with PHP 5.4. Everything is fine under this version.
Thanks to you, I found the issue : I'm using HTTPS and with HTTPS it doesn't work whereas it works when I'm using HTTP !
I'm check with my hosting provider if they can do something.
EDIT - Solution
My hosting provider fixed the issue last year (forgot to post it here). During the time it wasn't fixed, I was still under PHP 5.4.
I paste their original message :
These issues that you describe is because the installed Certificate is a self signed Certificate. New Web Browsers and PHP Version don't accept these Certificates because of Security Risks.
We have changed the Certificate with a official issued Certificate
I just want to add that I was facing issue using the codeplex ssrsphp, therefore I googled and found another sdk, which works perfectly. I'm using php 7+. Here is the link and I'm available if there're any questions related to this.

Connect to azure-blob through azure-website with php

I have set up an windows azure website (php), and I want to connect to the azure storage (blob) environment. I walked through the How to use the Blob service from PHP tutorial, but that only mentions the case when the website is stored localy.
I tried to set up a few cases, but i'm constantly getting a http 500 error.
<?php
require_once 'WindowsAzure/WindowsAzure.php';
use WindowsAzure\Common\ServicesBuilder;
use WindowsAzure\Common\ServiceException;
//$connectionString = "\WindowsAzure\Blob\Internal\IBlob";
// Create blob REST proxy.
$blobRestProxy = ServicesBuilder::getInstance()->createBlobService($connectionString); // the code gets stuck at this line, result is a HTTP 500 error
$content = fopen("C:\Users\Public\Pictures\Sample%20Pictures\Woestijn.jpg", "r");
$blob_name = "newBlob";
try {
//Upload blob
$blobRestProxy->createBlockBlob("default", $blob_name, $content);
}
catch(ServiceException $e){
// Handle exception based on error codes and messages.
// Error codes and messages are here:
// http://msdn.microsoft.com/en-us/library/windowsazure/dd179439.aspx
$code = $e->getCode();
$error_message = $e->getMessage();
echo $code.": ".$error_message."<br />";
}?>
Is there anyone who had a similar problem and managed to figure it out?
EDIT:
I now narrowed down the error search. I went into the ServicesBuilder.php file, and commented out line by line, until the page stopped to work. The line it went wrong at is $httpClient, as shown below:
public function createBlobService($connectionString)
{
$settings = StorageServiceSettings::createFromConnectionString(
$connectionString
);
$httpClient = $this->httpClient();
$serializer = $this->serializer();
$uri = Utilities::tryAddUrlScheme(
$settings->getBlobEndpointUri()
);
From what I'm seeing you're filling up the $connectionString variable with this value: "\WindowsAzure\Blob\Internal\IBlob" (even though it's commented - so probably you're passing it from somewhere else). If that's the case you'll need to change it.
The connection string should be a reference to your storage account containing the protocol, the name of the account and the key (you can find the name and the key in the portal):
$connectionString = "DefaultEndpointsProtocol=https;AccountName=jeroensaccount;AccountKey=fjmezfjmIOFJEZIOPAFJAZOPIFJAIMO"

Unable to create directory in php

I was trying out this tutorial for reading rss feeds with a php file and caching it.
I copied and pasted the source into my own project. I am using XAMPP on Mac OS X installation.
Here is the source:
First of all, I cannot create a directory with mkdir. It says permission denied.
Second, $feed = file_get_contents($path, true); is not returning a php object. I mean when i check it with if ( is_object($feed) && $feed->query->count ), I cannot get through.
Last, I cannot $cachefile = fopen($cache, 'wb');
<?php
$cache = dirname(__FILE__) . "/cache/feed";
echo filemtime($cache);
if(filemtime($cache))
{
// Get from server
if ( !file_exists(dirname(__FILE__) . '/cache') ) {
mkdir(dirname(__FILE__) . '/cache', 0777);
}
// YQL query (SELECT * from feed ... ) // Split for readability
$path = "http://query.yahooapis.com/v1/public/yql?q=";
$path .= urlencode("SELECT * FROM feed WHERE url='http://feeds.hindustantimes.com/HT-HomePage-TopStories'");
$path .= "&format=json";
// Call YQL, and if the query didn't fail, cache the returned data
$feed = file_get_contents($path, true);
print_r($feed);
// If something was returned, cache
if ( is_object($feed) && $feed->query->count ) {
$cachefile = fopen($cache, 'wb');
fwrite($cachefile, $feed);
fclose($cachefile);
echo 'writing to disk';
}
}
else
{
// We already have local cache. Use that instead.
$feed = file_get_contents($cache);
}
// Decode that shizzle
$feed = json_decode($feed);
print_r($feed);
// Include the view
//include('views/site.tmpl.php');
?>
Pretty sure XAMPP runs as the "nobody" user so you're going to have to give "nobody" permissions to the directories you want to be writable:
chown nobody:nobody dir_in_question
Keep in mind that XAMPP is a great dev server, but is not secure out of the box so be careful about using this in production. See this article for relevant issues.

php directory traversal issue

Hi
We have some php code using the file_get_contents() function, and I understand this is vulnerable to direcoty traversel attacks. Given the following code:
$mydata=$_GET['thefile'];
$data = file_get_contents ('/var/html'.$file);
echo $data
How can I do some simple input filtering so I can block the posibility that someone might do directory traversel by playing around with my input?
/MR
You want basename:
$mydata = basename(realpath($_GET['thefile']));
Appended to (slight modifications of) your example:
$file=$_GET['thefile'];
$mypath='/var/www/';
$location= basename(realpath($mypath.$file));
$data = file_get_contents($location);
echo $data;
Note... although this does some level of error checking, it does no error handling. I'll leave that up to you.
If the $_GET['thefile'] won't use folders like "images/fileX.jpg" you can use basename()
$filename = basename($_GET['thefile']);
readfile('/var/html/'.$filename);
When '../../passwords.txt' is given as $_GET['thefile'] it will be converted by basename to 'passwords.txt'.
Adding realpath() inside a basename doesn't add any security.
If your script does need to support subdirectories then use realpath() to determine if it's inside the '/var/html' directory.
$baseDir = realpath('/var/html/'); // (mayby /var/html is a symlink)
$baseDirLength = strlen($baseDir);
$filepath = realpath('/var/html/'.$_GET['thefile']);
if (substr($filepath, 0, $baseDirLength) == $baseDir) {
// Even when all the '../' in the thefile are resolved
// the path is within the $baseDir
} else {
// invalid $_GET['thefile']
}

Getting the URL path to the directory of a file (PHP)

Hi
I have a php file at, say, localhost/foo/foo/bar.php
which includes a file at localhost/foo/included.php
I need to be able to get "localhost/foo/" as a string inside included.php
If, instead of localhost/foo/foo/bar.php, it's localhost/big/burpy/lolz/here.php (still including included.php) I still need to get "localhost/foo/"
So, I need the path of the included file and not the one that the client requested.
I know when I see the solution I'm going to feel like a doofus, but it just escapes me at the moment. Help please? thanks :)
This how it got working for me :)
<?php
$path = (#$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
$path .=$_SERVER["SERVER_NAME"]. dirname($_SERVER["PHP_SELF"]);
echo $path;
?>
I figured it out myself:
$realpath = str_replace('\\', '/', dirname(__FILE__));
$whatIwanted = substr_replace(str_replace($_SERVER['DOCUMENT_ROOT'], '', $realpath), "", -6);
There we go :) Thanks for the help guys.
Inside your included file:
$yourdir = dirname(__FILE__);
or if you're using PHP 5.3.x:
$yourdir = __DIR__;
Get the document root from
// contains the document root, e.g. C:\xampp\htdocs
$docRoot = realpath($_SERVER['DOCUMENT_ROOT']);
// strip drive letter if found
if(strpos($docRoot, ':') === 1) $docRoot = substr($docRoot, 2);
// directory of included file, e.g. C:\xampp\htdocs\include
$dirInclude = realpath(dirname(__FILE__));
// strip drive letter if found
if(strpos($dirInclude, ':') === 1) $dirInclude = substr($dirInclude, 2);
// find the document root
$rootPos = strpos($dirInclude, $docRoot);
// if the path really starts with the document root
if($rootPos === 0){
// example: \xampp\htdocs\include
$visibleDir = substr($rootPos, $);
// convert backslashes to slashes and strip drive letter
$webPath = str_replace('\\', '/', $visibleDir);
// yields: http://localhost/include
echo 'http://localhost' . $webPath;
}
else{
// included file was outside the webroot, nothing to do...
}
The steps for this are:
Use dirname(__FILE__) to get the folder of the include file.
Get the server root using $_SERVER['DOCUMENT_ROOT']
Remove the document root from the include folder to get the relative include folder
Obtain the server url
Append the relative include folder to the server url

Categories