Posted
about 13 years
ago
When installing horde to a custom pear location, you need to run the pear of your custom location, not the system pear with the custom location’s config.
So the steps would be:
1 mkdir /srv/horde
2 pear config-create /srv/horde/
... [More]
/srv/horde/pear.conf
3 pear -c /srv/horde/pear.conf install PEAR
as the install docs say but then:
4 /srv/horde/pear/pear -c /srv/horde/pear.conf channel-discover pear.horde.org
5 /srv/horde/pear/pear -c /srv/horde/pear.conf run-scripts horde/Horde_Role
6 /srv/horde/pear/pear -c /srv/horde/pear.conf install --alldeps horde/groupware
Otherwise running the Horde_Role script will fail saying
config-set (horde_dir, /srv/horde/, user) failed, channel pear.php.net
This was experienced on SLES11SP1, SLES11SP2 and openSUSE Factory.
I did not test this for any debian based products yet. [Less]
|
Posted
about 13 years
ago
When installing horde to a custom pear location, you need to run the pear of your custom location, not the system pear with the custom location’s config.
So the steps would be:
1 mkdir /srv/horde
2 pear config-create /srv/horde/
... [More]
/srv/horde/pear.conf
3 pear -c /srv/horde/pear.conf install PEAR
as the install docs say but then:
4 /srv/horde/pear/pear -c /srv/horde/pear.conf channel-discover pear.horde.org
5 /srv/horde/pear/pear -c /srv/horde/pear.conf run-scripts horde/Horde_Role
6 /srv/horde/pear/pear -c /srv/horde/pear.conf install --alldeps horde/groupware
Otherwise running the Horde_Role script will fail saying
config-set (horde_dir, /srv/horde/, user) failed, channel pear.php.net
This was experienced on SLES11SP1, SLES11SP2 and openSUSE Factory.
I did not test this for any debian based products yet.
[Less]
|
Posted
over 13 years
ago
When we discovered the successful attack on ftp.horde.org two weeks ago we were of course frantic to determine which packages had been affected in addition to the one Horde 3 archive Jan identified as modified initially.For the Horde 4 packages we
... [More]
had no hashes to verify the file integrity though. While PEAR supports signing of packages via GPG that seems to be a feature which is virtually unused. For one thing not that many PHP based projects use PEAR packaging and in addition there is no way to automatically verify package integrity on the user side when installing via PEAR. So we also didn't consider signing our packages when switching to installing Horde via PEAR.Obviously you gain a different perspective on that issue once a hacker implanted a backdoor in some of your packages. Of course we invested a lot of time into securing our infrastructure now to ensure that such an event never happens again. On our side the file integrity is constantly monitored now. But we will also have to investigate how we can improve the PEAR based installation procedure so that it also allows for the required amount of security on the user side.But if we had no hashes how did we ensure the Horde 4 packages were indeed unmodified? Git to the rescue! As we tag all our releases it was a matter of creating a short script to automatically compare the current state of the packages on our PEAR server against the state we had within git.Without further ado - here is the script I used:#!/bin/bash
git reset --hard HEAD
git clean -f -d
STAMP=`date +%y%m%d-%H%M`
mkdir ../diffs-$STAMP
mkdir -p ../validate-$STAMP/pear.horde.org
mkdir -p ../validate-$STAMP/rebuild
for package in `cat ../pear-recovery-packages.txt | grep -v ".tar$"`
do
TAG=${package/.tgz/}
TAG=${TAG,,}
PPATH=${package/-*/}
if [ "x${PPATH/Horde_*/}" == "x" ]; then
PPATH=framework/${PPATH/Horde_};
fi
if [ "x${PPATH/groupware*/}" == "x" ]; then
PPATH=bundles/$PPATH;
fi
if [ "x${PPATH/webmail*/}" == "x" ]; then
PPATH=bundles/$PPATH;
fi
PRESENT=`git tag -l $TAG`
if [ "x$PRESENT" == "x" ]; then
echo
echo "======================================================================"
echo "Tag $TAG for package $package is missing!"
echo "======================================================================"
echo
echo "$package: TAG MISSING" >> ../status-$STAMP
else
rm *.tgz
rm -rf ../validate-$STAMP/pear.horde.org/*
rm -rf ../validate-$STAMP/rebuild/*
GIT=`git checkout $TAG`
horde-components -z $PPATH --keep-version
if [ -e $package ]; then
cp *.tgz ../validate-$STAMP/pear.horde.org/
cp ../pear.horde.org/get/$package ../validate-$STAMP/rebuild/
tar -C ../validate-$STAMP/pear.horde.org/ -x -z -f ../validate-$STAMP/pear.horde.org/*.tgz
tar -C ../validate-$STAMP/rebuild/ -x -z -f ../validate-$STAMP/rebuild/*.tgz
DIFF=`diff -Naur ../validate-$STAMP/pear.horde.org/${package/.tgz/} ../validate-$STAMP/rebuild/${package/.tgz/}`
if [ "x$DIFF" != "x" ]; then
echo
echo "======================================================================"
echo "Diff for package $package detected!"
diff -Naur ../validate-$STAMP/pear.horde.org/${package/.tgz/} ../validate-$STAMP/rebuild/${package/.tgz/} > ..$
echo "======================================================================"
echo
echo "$package: DIFF" >> ../status-$STAMP
else
echo
echo "======================================================================"
echo "$package CLEAN!!!"
echo "======================================================================"
echo
echo "$package: CLEAN" >> ../status-$STAMP
fi
else
echo
echo "======================================================================"
echo "Failed rebuilding package $package!"
echo "======================================================================"
echo
echo "$package: FAILED REBUILDING" >> ../status-$STAMP
fi
fi
done
The script walks through the list of packages we had on the PEAR
server, moves back in time within ouTruncated by Planet Horde, read more at the original (another 1668 bytes) [Less]
|
Posted
over 13 years
ago
When we discovered the successful attack on ftp.horde.org two weeks ago we were of course frantic to determine which packages had been affected in addition to the one Horde 3 archive Jan identified as modified initially.For the Horde 4 packages we
... [More]
had no hashes to verify the file integrity though. While PEAR supports signing of packages via GPG that seems to be a feature which is virtually unused. For one thing not that many PHP based projects use PEAR packaging and in addition there is no way to automatically verify package integrity on the user side when installing via PEAR. So we also didn't consider signing our packages when switching to installing Horde via PEAR.Obviously you gain a different perspective on that issue once a hacker implanted a backdoor in some of your packages. Of course we invested a lot of time into securing our infrastructure now to ensure that such an event never happens again. On our side the file integrity is constantly monitored now. But we will also have to investigate how we can improve the PEAR based installation procedure so that it also allows for the required amount of security on the user side.But if we had no hashes how did we ensure the Horde 4 packages were indeed unmodified? Git to the rescue! As we tag all our releases it was a matter of creating a short script to automatically compare the current state of the packages on our PEAR server against the state we had within git.Without further ado - here is the script I used:#!/bin/bash
git reset --hard HEAD
git clean -f -d
STAMP=`date +%y%m%d-%H%M`
mkdir ../diffs-$STAMP
mkdir -p ../validate-$STAMP/pear.horde.org
mkdir -p ../validate-$STAMP/rebuild
for package in `cat ../pear-recovery-packages.txt | grep -v ".tar$"`
do
TAG=${package/.tgz/}
TAG=${TAG,,}
PPATH=${package/-*/}
if [ "x${PPATH/Horde_*/}" == "x" ]; then
PPATH=framework/${PPATH/Horde_};
fi
if [ "x${PPATH/groupware*/}" == "x" ]; then
PPATH=bundles/$PPATH;
fi
if [ "x${PPATH/webmail*/}" == "x" ]; then
PPATH=bundles/$PPATH;
fi
PRESENT=`git tag -l $TAG`
if [ "x$PRESENT" == "x" ]; then
echo
echo "======================================================================"
echo "Tag $TAG for package $package is missing!"
echo "======================================================================"
echo
echo "$package: TAG MISSING" >> ../status-$STAMP
else
rm *.tgz
rm -rf ../validate-$STAMP/pear.horde.org/*
rm -rf ../validate-$STAMP/rebuild/*
GIT=`git checkout $TAG`
horde-components -z $PPATH --keep-version
if [ -e $package ]; then
cp *.tgz ../validate-$STAMP/pear.horde.org/
cp ../pear.horde.org/get/$package ../validate-$STAMP/rebuild/
tar -C ../validate-$STAMP/pear.horde.org/ -x -z -f ../validate-$STAMP/pear.horde.org/*.tgz
tar -C ../validate-$STAMP/rebuild/ -x -z -f ../validate-$STAMP/rebuild/*.tgz
DIFF=`diff -Naur ../validate-$STAMP/pear.horde.org/${package/.tgz/} ../validate-$STAMP/rebuild/${package/.tgz/}`
if [ "x$DIFF" != "x" ]; then
echo
echo "======================================================================"
echo "Diff for package $package detected!"
diff -Naur ../validate-$STAMP/pear.horde.org/${package/.tgz/} ../validate-$STAMP/rebuild/${package/.tgz/} > ..$
echo "======================================================================"
echo
echo "$package: DIFF" >> ../status-$STAMP
else
echo
echo "======================================================================"
echo "$package CLEAN!!!"
echo "======================================================================"
echo
echo "$package: CLEAN" >> ../status-$STAMP
fi
else
echo
echo "======================================================================"
echo "Failed rebuilding package $package!"
echo "======================================================================"
echo
echo "$package: FAILED REBUILDING" >> ../status-$STAMP
fi
fi
done
The script walks through the list of packages we had on the PEAR
server, moves back in time within ouTruncated by Planet Horde, read more at the original (another 1487 bytes) [Less]
|
Posted
over 13 years
ago
The spring 2012 release of the Horde Application Suite and Framework will probably be called Horde 5. In a recent discussion the majority of developers agreed on a new major revision for some changes that some view as minor backward compatibility
... [More]
break. Currently planned features include:
New standard UI for “traditional view”
Move of Ajax code from specific apps to a common framework
Release of a small inventory management app (sesha)
complete configuration via UI (likely)
Webmail: Write support for smartphone view
Calendar: Resource calendar support for ajax view
At the same time, Horde 3 will no longer receive any support. Horde 3 has been around since 2005 and really has reached its end of life.
Since the Horde 4 release, The Horde 3 family of applications has only received critical bugfixes and security updates, the last being released this february. You should really consider updating to Horde 4 – the transition from Horde 3 to Horde 4 has been tested and done by numerous people and the transition from Horde 4 to Horde 5 should run smoothly as both releases are PEAR based.
I have already removed all things horde3 from OpenSUSE-Factory. OpenSUSE 12.2 will not ship Horde 3 any longer. Depending on packaging progress, openSUSE 12.2 will very likely ship Horde 5 or the most recent Horde 4 release. Horde 4 maintainence will continue.
Horde 3 Packages in the server:php:applications repository (see here) will be available at least until openSUSE 12.1 runs out of maintainence. I won’t give these much attention though. Please also note Eleusis Password Manager will be dropped with currently no planned replacement. [Less]
|
Posted
over 13 years
ago
The spring 2012 release of the Horde Application Suite and Framework will probably be called Horde 5. In a recent discussion the majority of developers agreed on a new major revision for some changes that some view as minor backward compatibility
... [More]
break. Currently planned features include:
New standard UI for “traditional view”
Move of Ajax code from specific apps to a common framework
Release of a small inventory management app (sesha)
complete configuration via UI (likely)
Webmail: Write support for smartphone view
Calendar: Resource calendar support for ajax view
At the same time, Horde 3 will no longer receive any support. Horde 3 has been around since 2005 and really has reached its end of life.
Since the Horde 4 release, The Horde 3 family of applications has only received critical bugfixes and security updates, the last being released this february. You should really consider updating to Horde 4 – the transition from Horde 3 to Horde 4 has been tested and done by numerous people and the transition from Horde 4 to Horde 5 should run smoothly as both releases are PEAR based.
I have already removed all things horde3 from OpenSUSE-Factory. OpenSUSE 12.2 will not ship Horde 3 any longer. Depending on packaging progress, openSUSE 12.2 will very likely ship Horde 5 or the most recent Horde 4 release. Horde 4 maintainence will continue.
Horde 3 Packages in the server:php:applications repository (see here) will be available at least until openSUSE 12.1 runs out of maintainence. I won’t give these much attention though. Please also note Eleusis Password Manager will be dropped with currently no planned replacement.
[Less]
|
Posted
over 13 years
ago
Horde provides system wide customisation and configuration of applications through php configuration files. These files can be edited by hand or written from an administrator config UI. This ui is automatically generated from a file called conf.xml
... [More]
located in your $application/config/ directory.
The config xml allows dropdowns, multiselect fields, tick boxes, radio buttons and even conditionally adding or removing a field or inserting a valid php expression.
For example a dropdown box in the horde base application’s config is generated by this snippet:
2
0
1
2
3
This is all nice but what if you need to provide application data rather than static values? The answer is configspecial
How does that work?
calls the horde api. the “application” part tells you which application’s api to call. You can either reference an application by its registry name (horde, imp, kronolith, turba…) or by its api name (horde,mail, calendar, addressbook)
What’s the difference? When you call turba, you get turba. When you call addressbook, you can hook into whatever application provides addressbook. For example, spam handling and ticket queues have been implemented by multiple applications. You can even implement your own handlers for any existing api.
The called application must have a method configSpecialValues() in its lib/Application.php class file. This method gets called and its only parameter is the “name” property from the xml. In our example it’s “sources”. This method will return an array of source names to use in your config screen.
/**
* Returns values for configuration settings.
*
* @param string $what The configuration setting to return.
*
* @return array The values for the requested configuration setting.
*/
public function configSpecialValues($what)
{
switch ($what) {
case sources:
try {
$addressbooks = Turba::getAddressBooks(Horde_Perms::READ);
} catch (Horde_Exception $e) {
return array();
}
foreach ($addressbooks as &$addressbook) {
$addressbook = $addressbook['title'];
}
$addressbooks[''] = _("None");
return $addressbooks;
}
}
Et voila – you have a list of addressbooks to choose from. [Less]
|
Posted
over 13 years
ago
Synopsis
Horde’s powerful RPC API has been used numerous times to allow integration of horde-based data into external applications or remote sites. It also provides an easy to set up basis for distributed applications with headless workers. In this
... [More]
article I will give you a brief introduction on how to build a scalable distributed architecture based on Horde 4.
Distributed Architecture
Assumptions:
You want your application to be scalable over several hosts. We call the controlling instance the master and the reacting instances the workers.
You don’t want to keep a lot of state on the worker. Adding or removing a worker instance should not require complicated setup. Most cloud layers like OpenStack assume worker instances to be virtually stateless. The master is the single source of truth and should be able to rebuild any broken or lost worker setup from stored information.
You are working in a hostile environment, e.g. the internet. Firewall only allows select ports and data has to travel over lines you cannot trust. You want to resort to https transport with real certificates.
The master:
I won’t go into too many details on the master setup this time. Create a basic app from the skeleton as the horde wiki describes. Separate a communication driver for worker Api calls from the driving logic in your app and don’t couple them too tightly. Usually you want small commits of changes to both the master’s idea and the worker’s reality and you want to check back if everything worked out. This doesn’t scale well on large-scale changes though.
Sometimes you want to make complex changes to the “truth” or “theory” in the master’s db before you commit them to the worker world out there.
Accessing the worker from the master:
The core piece of your communication with the worker are just a few lines of code
protected function callWorker(WorkerInstance $worker, $callMethod, array $parameters = array()) {
try {
$http = new Horde_Http_Client(array('request.username' => $worker->rpcuser, 'request.password' => $worker->rpcuserpass, 'request.timeout' => 20 ));
$response = Horde_Rpc::request(
'xmlrpc',
'https://' . $worker->worker_hostname . '/' . $worker->worker_subdir .'/rpc.php',
$callMethod,
$http,
array($parameters)
);
}
catch (Exception $e) {
throw new Insysgui_Exception($e);
}
return $response;
}
This is a dumbed down version for demonstration purposes. You might want to model WorkerInstance based on Horde_Rdo, the horde ORM layer. It is desirable to evaluate lazy relations and lazy attributes. This has important performance implications but more on this in another post. We’re also selling consulting
Worker setup:
We want a stateless worker instance. Obviously, this is theory. Truth is: You need a unique IP and you probably want a unique hostname. Nowadays cloud layers can provide that level of configuration. How about a horde instance without db?
horde/config/registry.local.php
You want the worker to talk under a specific api name. Add a block to your registry.local.php
'myvpnworkerworker' => array (
'name' => _("someworkerfooname"), /* we can even drop the _() as nobody will localize this */
'provides' => 'myvpnworkerapp',
)
horde/config/conf.php
This is stripped down to just the important lines
$conf['auth']['params']['htpasswd_file'] = '/not/in/webroot/passwords.secret';
$conf['auth']['params']['encryption'] = 'plain'; /* In real world, you want to use some encryption instead */
$conf['auth']['driver'] = 'http'; /* We want authentication by http layer after all */
We want the server to be stateless and not to rely on external data. We don’t want a local mysqld running and we don’t want a remote ldap either. We will store the credentials in a .htpasswd style file. For demonstration purposes, we use plain authentication.
The file would look like this:
passwd.passwd would look like this:
rpcuser:totallTruncated by Planet Horde, read more at the original (another 4911 bytes) [Less]
|
Posted
over 13 years
ago
Synopsis
Horde’s powerful RPC API has been used numerous times to allow integration of horde-based data into external applications or remote sites. It also provides an easy to set up basis for distributed applications with headless workers. In this
... [More]
article I will give you a brief introduction on how to build a scalable distributed architecture based on Horde 4.
Distributed Architecture
Assumptions:
You want your application to be scalable over several hosts. We call the controlling instance the master and the reacting instances the workers.
You don’t want to keep a lot of state on the worker. Adding or removing a worker instance should not require complicated setup. Most cloud layers like OpenStack assume worker instances to be virtually stateless. The master is the single source of truth and should be able to rebuild any broken or lost worker setup from stored information.
You are working in a hostile environment, e.g. the internet. Firewall only allows select ports and data has to travel over lines you cannot trust. You want to resort to https transport with real certificates.
The master:
I won’t go into too many details on the master setup this time. Create a basic app from the skeleton as the horde wiki describes. Separate a communication driver for worker Api calls from the driving logic in your app and don’t couple them too tightly. Usually you want small commits of changes to both the master’s idea and the worker’s reality and you want to check back if everything worked out. This doesn’t scale well on large-scale changes though.
Sometimes you want to make complex changes to the “truth” or “theory” in the master’s db before you commit them to the worker world out there.
Accessing the worker from the master:
The core piece of your communication with the worker are just a few lines of code
protected function callWorker(WorkerInstance $worker, $callMethod, array $parameters = array()) {
try {
$http = new Horde_Http_Client(array('request.username' => $worker->rpcuser, 'request.password' => $worker->rpcuserpass, 'request.timeout' => 20 ));
$response = Horde_Rpc::request(
'xmlrpc',
'https://' . $worker->worker_hostname . '/' . $worker->worker_subdir .'/rpc.php',
$callMethod,
$http,
array($parameters)
);
}
catch (Exception $e) {
throw new Insysgui_Exception($e);
}
return $response;
}
This is a dumbed down version for demonstration purposes. You might want to model WorkerInstance based on Horde_Rdo, the horde ORM layer. It is desirable to evaluate lazy relations and lazy attributes. This has important performance implications but more on this in another post. We’re also selling consulting
Worker setup:
We want a stateless worker instance. Obviously, this is theory. Truth is: You need a unique IP and you probably want a unique hostname. Nowadays cloud layers can provide that level of configuration. How about a horde instance without db?
horde/config/registry.local.php
You want the worker to talk under a specific api name. Add a block to your registry.local.php
'myvpnworkerworker' => array (
'name' => _("someworkerfooname"), /* we can even drop the _() as nobody will localize this */
'provides' => 'myvpnworkerapp',
)
horde/config/conf.php
This is stripped down to just the important lines
$conf['auth']['params']['htpasswd_file'] = '/not/in/webroot/passwords.secret';
$conf['auth']['params']['encryption'] = 'plain'; /* In real world, you want to use some encryption instead */
$conf['auth']['driver'] = 'http'; /* We want authentication by http layer after all */
We want the server to be stateless and not to rely on external data. We don’t want a local mysqld running and we don’t want a remote ldap either. We will store the credentials in a .htpasswd style file. For demonstration purposes, we use plain authentication.
The file would look like this:
passwd.passwd would look like thiTruncated by Planet Horde, read more at the original (another 4946 bytes) [Less]
|
Posted
over 13 years
ago
It is official now: Horde gets a booth on CeBIT 2012! Sponsored by Linux New Media the company behind the Linux Magazine. Thanks! Simply awesome!
Hope to see you there!
|