Показаны сообщения с ярлыком PHP. Показать все сообщения
Показаны сообщения с ярлыком PHP. Показать все сообщения

пятница, 4 апреля 2008 г.

Дополнительная защита веб-сервера

По наводке от моего товарища Lice пришлось ковырять как закрыть от PHP-скриптов доступ в другие каталоги. дело в том, что если не установлен PHP как CGI модуль, то варианта два. Либо SafeMode + doc_root, что совсем не приятно и мне не нравится. Причины расписывать тут не буду, т.к. не хочется устраивать холивар. В общем, я пошел по другому пути. В каждый виртуальный хост Апача я добавил такую конструкцию:

php_admin_value open_basedir /var/www/user/

Таки образом я избавился от неприятной вещи по типу fileread(’/etc/passwd’);.

Дальше больше. Lice по FTP залил какой-то ПХП-шный shell и стали тестировать. Как я и ожидал, каталоги то он увидел, а вот скачать что-либо, кроме как из своего каталога - никак.

Вот теперь надо отрубить system и exec с кучей всего еще. В php.ini мы правим:

disable_functions = “apache_get_modules,apache_get_version,apache_getenv,apache_note, apache_setenv,disk_free_space,diskfreespace,dl,highlight_file,ini_alter,ini_restore,openlog, passthru,phpinfo,proc_nice,shell_exec,show_source,symlink,system,exec”

Отдельное огромное спасибо Lice за помощь.

взял отсюда...

суббота, 9 февраля 2008 г.

PHP XML-RPC server, Python XML-RPC client

Стоит задача, поднять web-сервис на защищенном (HTTPS) канале.

Технологий web-сервисов в принципе две: SOAP и XML-RPC. SOAP - тяжелая и замороченная, предназначена для крупных проектов, пока еще не окончательно стандартизована. XML-RPC легкая и полностью стандартизована, построена на использовании XML формата передачи данных между клиентом и сервером по HTTP протоколу. PHP5 поддерживает обе технологии. В дерево исходников PHP5 входит одна из реализаций библиотеки XML-RPC, написанной на С. Правда документация крайне скудная, но разобраться можно.

XML-RPC server:

1. Определяем функции, которые будут доступны клиенту. Для примера напишем функцию сложения двух чисел:
function srvAdd($MethodName, $Params, $AppData)
{
return $Params[0]+$Params[1];
}
Любая функция, регистрируемая на xml-rpc сервере, должна принимать 3 параметра:

$MethodName - внешнее имя функции;
$Params - массив параметров, передаваемых клиентом;
$AppData - дополнительные параметры, передаваемые при вызове функции xmlrpc_server_call_method().

2. Создаем XML-RPC сервер вызовом функции

srv=xmlrpc_server_create();

3. Регистрируем на сервере, определенные ранее функции

xmlrpc_server_register_method($srv, "Add", "srvAdd");

Здесь:
Add - внешнее имя функции srvAdd,
srv - handler сервера.

4. Получаем "сырой" запрос от клиента

$xmlRequest = $HTTP_RAW_POST_DATA;

5. Передаем запрос в диспетчер функций, который автоматически определит какую функцию вызвать.

$response = xmlrpc_server_call_method($srv, $xmlRequest, Null);

Здесь:
$srv - handler xml-rpc сервера;
$xmlRequest - данные от клиента в xml-формате;
Третий параметр, в данном случае пустой, передает дополнительные данные для определенных ранее функций (параметр $AppData).

6. Отдаем клиенту результаты работы функции

print $response;

7. Закрываем сервер.

xmlrpc_server_destroy($srv);

Приведу весь код xml-rpc сервера в котором клиенту доступны несколько функций:


function About($MethodName, $Params, $AppData)
{
$sAbout="ekXMLRPCServer Class v0.9.5\n (c) 2008 Klek\n Author: Eugene Klepikov\n Email: ";
return $sAbout;;
}
//-----------------------------------------------------------------------------
class ekXMLRPCServer
{
private $srvh=null;
private $xmlRequest="";
private $response="";
private $about="";
private $help="";
private $userData=null;
private $arOutOptions=array(
"output_type" => "xml",
"verbosity" => "pretty",
"escaping" => array("markup", "non-ascii", "non-print"),
"version" => "xmlrpc",
"encoding" => "iso-8859-1"
//"encoding" => "utf-8"
);
//-----------------------------------------------------------------------------

function __construct()
{
$this->srvh=xmlrpc_server_create();
$this->registerMethod("system.about", "About");
$this->registerMethod("help", "help");
}
//-----------------------------------------------------------------------------

function __destruct()
{
xmlrpc_server_destroy($this->srvh);
}
//-----------------------------------------------------------------------------

function registerMethod($methodName, $functionName)
{
xmlrpc_server_register_method($this->srvh, $methodName, $functionName);
}
//-----------------------------------------------------------------------------

function request($Request)
{
$this->xmlRequest=$Request;
}
//-----------------------------------------------------------------------------

function run()
{
$this->response=xmlrpc_server_call_method($this->srvh, $this->xmlRequest, $this->userData, $this->arOutOptions);
print $this->response;
}
//-----------------------------------------------------------------------------
}

Поместим файл с кодом xml-rpc сервера в защищенный каталог apache, чтобы к нему можно было коннесктится через SSL https://www.mydomain.ru/xmlrpcserver.php

XML-RPC Client

Клиента проще всего написать на Python, т.к. все нужные библиотеки уже есть в стандартной поставке.

>>> import xmlrpclib
>>> server = xmlrpclib.Server("https://www.mydomain.ru/xmlrpcserver.php")

Теперь можно вызывать функции сервера.

>>> server.Add('10', '15')
>>> 25
>>>

Функции Array() и Dict() различаются типом возвращаемого массива.

>>> server.Array("Peter")
>>>['Peter', 'Hello, Peter. How are you today?']

Array() возвращает список.

>>> server.Dict("Peter")
>>>{'name': 'Peter', 'greeting': 'Hello, Peter. How are you today?'}

Dict() возвращает словарь, т.к. в реализации функции мы использовали именованный массив.

XML-RPC сервер имеет и несколько встроенных функций, одна из которых
>>>server.system.listMethods()
>>>['system.listMethods', 'system.methodHelp', 'system.methodSignature', 'system.describeMethods', 'system.multiCall', 'system.getCapabilities', 'Uptime', 'Array', 'Dict', 'Add']

возвращает список всех доступных на сервере функций.

Замечания:

1. В питоновских библиотеках xmlrpclib, urllib, httplib не предусмотрена проверка сертификата сервера.

2. Для работы с библиотекой XML-RPC в PHP5 нужно поставить модуль php5-xmlrpc из репозитария дистрибутива или, при самостоятельной сборке, добавить к команде configure параметр --with-xmlrpc[=DIR].

воскресенье, 23 декабря 2007 г.

PHP и MySQL на смартфонах с Symbian уже в 2008 году

Интересная новость...
По данным symbianone.com на конференции CCNC в Лас-Вегасе в январе 2008 года будет представлено решение PAMP (Personal Apache, MySQL, PHP) для S60 смартфонов. В дополнение к самому PHP будут так же представлены расширения для доступа к функциональному ядру телефона!

Изначально, новость появилась в форуме компании NOKIA. Некоторые обозреватели полагают, что приход локальных веб-приложений на аппаратную платформу мобильных телефонов несёт за собой новую эру веба даже не смотря на то, что сейчас лидером в области ОС для мобильных устройств является Microsoft.

Источник...

четверг, 6 декабря 2007 г.

Сделайте свой код совместимым с PHP6

С выходом PHP6 некоторые скрипты, разработчики которых используют устаревшие конструкции PHP, перестанут работать. Чтобы избежать такой ситуации нужно придерживаться некоторых новых правил.
  1. register_globals. В PHP6 больше не будет поддержки register_globals. Уже в 5-ой версии разработчики PHP рекомендовали отключать эту переменную в php.ini, да и по умолчанию она была в off. Так вот, в 6-й версии от register_globals полностью отказались. Пользуйтесь суперглобальными массивами: $_GET, $_POST, $_SERVER, $_REQUEST и т.д.
  2. magic_quotes. При включенной данной переменной, PHP автоматом экранировал символы: одинарной кавычки, двойной кавычки, обратного слэша и NULL. Часто имела место быть ситуация повторной экранировки, когда у разработчика скрипта и пользователя magic_quotes в php.ini принимала разные значения (on/off). Разработчики PHP в 6-й версии наконец решили совсем избавиться от этой переменной.
  3. register_long_arrays. Вместо длинных массивов типа $HTTP_POST_VARS (их больше не будет), пользуйтесь суперглобальными $_GET, $_POST, $_SERVER, $_REQUEST и т.д.
  4. preg вместо ereg. Для работы с регулярными выражениями вместо функции ereg нужно использовать preg. ereg уходит из языка.
  5. Классы. Не создавайте экземпляр класса при помощи оператора ссылки (&).
    $a = & new object(); // Не будет работать в PHP6
    $a = new object(); // Будет работать в PHP 6
Источник...

Вышел новый номер PHP Inside - #20

После огромного промежутка, почти в год (прошлый номер выходил в январе 2007) состоялся релиз нового номера PHP Inside. На этот раз двадцатый! Прекращать выпуски мы не будем и далее.
Как я и обещал на майской конференции PHPConf, до конца года мы обязательно выпустим новый номер. И вот выпустили!
Скачать!
В номере:
  • Новости, обзоры, работа
  • Интервью: Athlon Sports об использовании PHP и Flash
  • Интервью: UMI.CMS обещает производительность и красивый код
  • Вся правда о поисковых системах, написанных на PHP
  • Реализация загрузки по требованию
  • Ассамблея программистов. Ведение проектов он-лайн
  • Грамотная конфигурация проекта
  • Командная строка в PHP? Это возможно!
  • Секреты предметной области. Автоматизация преобразования состояния объектов предметной области в XML
  • 10 с лишним способов обвалить работу MySQL

среда, 3 октября 2007 г.

Материалы PHPCONF 2007.

Видео материалы конференции для разработчиков на PHP PHPConf 2007.
смотреть

четверг, 3 мая 2007 г.

Класс на PHP для создания новостной ленты в формате RSS 2.0

На сайте RUSSLAVBANK есть ссылка для получения новостей в формате RSS 2.0.
Для формирования RSS-ленты я написал класс. Так как все мои сайты написаны на PHP, соответственно и данный класс написан на нем же :)
Файл с описанием класса называется ekrss.phpc.
Пример скрипта новостной ленты, с использованием этого класса, выложу позже.



<?
//____________________________________________________________________________
// ekrss.phpc
// RSS Class v1.0.9
// Author: Eugene Klepikov
// E-mail: klek@comtv.ru
// Created: 03.04.2006
// Updated: 29.05.2006
// Copyright: (c) 2006 Klek
// Licence: GPL
//_____________________________________________________________________________
class ekMakeRSS
{
private $xml;
private $rss;
private $Title;
private $Link;
private $Description;
private $Lang;
private $Encoding;
private $pubDate;
private $lastBuildDate;
private $Copyright;
private $Generator;
private $Docs;
private $managingEditor;
private $webMaster;

private $imageTitle;
private $imageURL;
private $imageLink;
private $imageDescription;
private $imageWidth;
private $imageHeight;

private $itemTitle;
private $itemLink;
private $itemDescription;
private $itemAuthor;
private $itemCategory;
private $itemGuid;
private $itemPubDate;
private $itemComments;
private $itemEnclosure;
private $itemSource;

private $Items;
//-----------------------------------------------------------------------------

function __construct()
{
$this->Encoding="windows-1251";
$this->xml="<?xml version=\"1.0\" encoding=\"{$this->Encoding}\" ?>\n";
$this->rss="<rss version=\"2.0\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n";
$this->Title="My RSS Channel";
$this->Link="http://";
$this->Description="My RSS Channel";
$this->Lang="ru";
$this->pubDate="";
$this->lastBuildDate=gmdate("D, d M Y H:i:s")." +0300";
$this->Copyright="Copyright";
$this->Generator="ekRSS v1.0.9 (c)Klek, 2006";
$this->Docs="http://blogs.law.harvard.edu/tech/rss";
$this->managingEditor="";
$this->webMaster="";

$this->imageTitle="";
$this->imageURL="";
$this->imageLink="";
$this->imageDescription="";
$this->imageWidth="";
$this->imageHeight="";

$this->Items=array();
$this->itemTitle="";
$this->itemLink="";
$this->itemDescription="";
$this->itemAuthor="";
$this->itemCategory="";
$this->itemGuid="";
$this->itemPubDate="";
$this->itemComments="";
$this->itemEnclosure="";
$this->itemSource="";
}
//-----------------------------------------------------------------------------

function __set($varName,$varValue)
{
if(isset($this->$varName))
{
$this->$varName=$varValue;
if($varName=="Encoding")
{
$this->xml="<?xml version=\"1.0\" encoding=\"{$this->Encoding}\" ?>\n";
}
}
}
//-----------------------------------------------------------------------------

function __get($varName)
{
return (isset($this->$varName)) ? $this->$varName : $this->$varName="";
}
//-----------------------------------------------------------------------------

function AddItem()
{
$arItem=array();
$arItem['title']=$this->itemTitle;
$arItem['link']=$this->itemLink;
$arItem['description']=$this->itemDescription;
$arItem['author']=$this->itemAuthor;
$arItem['comments']=$this->itemComments;
$arItem['enclosure']=$this->itemEnclosure;
$arItem['guid']=$this->itemGuid;
$arItem['pubDate']=$this->itemPubDate;
$arItem['source']=$this->itemSource;

$this->Items[]=$arItem;
}
//-----------------------------------------------------------------------------

private function __SendItem()
{
foreach($this->Items as $Item)
{
echo "<item>\n";
echo "<title><![CDATA[{$Item['title']}]]></title>\n";
echo "<link>{$Item['link']}</link>\n";
echo "<description><![CDATA[{$Item['description']}]]></description>\n";
if(trim($Item['author']) != "") echo "<dc:creator>{$Item['author']}</dc:creator>\n";
if(trim($Item['category']) != "") echo "<dc:subject>{$Item['category']}</dc:subject>\n";
if(trim($Item['comments']) != "") echo "<comments>{$Item['comments']}</comments>\n";
if(trim($Item['pubDate']) != "") echo "<pubDate>{$Item['pubDate']}</pubDate>\n";
if(trim($Item['guid']) != "") echo "<guid isPermaLink=\"true\">{$Item['guid']}</guid>\n";
if(trim($Item['source']) != "") echo "<source>{$Item['source']}</source>\n";
echo "</item>\n";
}
}
//-----------------------------------------------------------------------------

private function __SendImage()
{
if($this->imageTitle != "" and $this->imageURL != "" and $this->imageLink != "")
{
echo "<image>\n";
echo "<title>{$this->imageTitle}</title>\n";
echo "<url>{$this->imageURL}</url>\n";
echo "<link>{$this->imageLink}</link>\n";
if(trim($this->imageDescription) != "") echo "<description>{$this->imageDescription}</description>\n";
if(trim($this->imageWidth != "")) echo "<width>{$this->imageWidth}</width>\n";
if(trim($this->imageHeight != "")) echo "<height>{$this->imageHeight}</height>\n";
echo "</image>\n";
}
}
//-----------------------------------------------------------------------------
function Send()
{
header("Content-Type: text/xml");
echo $this->xml;
echo $this->rss;
echo "<channel>\n";
echo "<title>{$this->Title}</title>\n";
echo "<link>{$this->Link}</link>\n";
echo "<description>{$this->Description}</description>\n";
echo "<language>{$this->Lang}</language>\n";
echo "<copyright>{$this->Copyright}</copyright>\n";
if(trim($this->pubDate) != "")
echo "<pubDate>{$this->pubDate}</pubDate>\n";
if(trim($this->lastBuildDate) != "")
echo "<lastBuildDate>{$this->lastBuildDate}</lastBuildDate>\n";
echo "<docs>{$this->Docs}</docs>\n";
echo "<generator>{$this->Generator}</generator>\n";
if(trim($this->managingEditor) != "")
echo "<managingEditor>{$this->managingEditor}</managingEditor>\n";
if(trim($this->webMaster) != "")
echo "<webMaster>{$this->webMaster}</webMaster>\n";
$this->__SendImage();
$this->__SendItem();
echo "</channel>\n";
echo "</rss>\n";
}
//-----------------------------------------------------------------------------
}
?>