summaryrefslogtreecommitdiffstats
path: root/lib/private/installer.php
diff options
context:
space:
mode:
authorLukas Reschke <lukas@owncloud.com>2016-01-09 22:15:50 +0100
committerLukas Reschke <lukas@owncloud.com>2016-01-10 19:40:28 +0100
commitc009d5dcc1be69d280a71e01c5302f7fc3e5edc7 (patch)
tree41cf627cb0c3a11b2450e3f0737bd360060b2a8f /lib/private/installer.php
parent656b5418996744b5ba095afac59b4fdb4db37337 (diff)
downloadnextcloud-server-c009d5dcc1be69d280a71e01c5302f7fc3e5edc7.tar.gz
nextcloud-server-c009d5dcc1be69d280a71e01c5302f7fc3e5edc7.zip
Verify signature of apps with level "Official" coming from the appstore
This change will verify the signature of all apps with the level "Official" coming from the appstore or if they have been signed before.
Diffstat (limited to 'lib/private/installer.php')
-rw-r--r--lib/private/installer.php45
1 files changed, 39 insertions, 6 deletions
diff --git a/lib/private/installer.php b/lib/private/installer.php
index ed50503b3dc..3072cfd3b28 100644
--- a/lib/private/installer.php
+++ b/lib/private/installer.php
@@ -82,9 +82,10 @@ class OC_Installer{
$l = \OC::$server->getL10N('lib');
list($extractDir, $path) = self::downloadApp($data);
- $info = self::checkAppsIntegrity($data, $extractDir, $path);
- $basedir=OC_App::getInstallPath().'/'.$info['id'];
+ $info = self::checkAppsIntegrity($data, $extractDir, $path);
+ $appId = OC_App::cleanAppId($info['id']);
+ $basedir = OC_App::getInstallPath().'/'.$appId;
//check if the destination directory already exists
if(is_dir($basedir)) {
OC_Helper::rmdirr($extractDir);
@@ -163,6 +164,8 @@ class OC_Installer{
* @brief Update an application
* @param array $info
* @param bool $isShipped
+ * @throws Exception
+ * @return bool
*
* This function could work like described below, but currently it disables and then
* enables the app again. This does result in an updated app.
@@ -191,7 +194,7 @@ class OC_Installer{
* upgrade.php can determine the current installed version of the app using
* "\OC::$server->getAppConfig()->getValue($appid, 'installed_version')"
*/
- public static function updateApp( $info=array(), $isShipped=false) {
+ public static function updateApp($info=array(), $isShipped=false) {
list($extractDir, $path) = self::downloadApp($info);
$info = self::checkAppsIntegrity($info, $extractDir, $path, $isShipped);
@@ -307,11 +310,12 @@ class OC_Installer{
* check an app's integrity
* @param array $data
* @param string $extractDir
+ * @param string $path
* @param bool $isShipped
* @return array
* @throws \Exception
*/
- public static function checkAppsIntegrity($data, $extractDir, $path, $isShipped=false) {
+ public static function checkAppsIntegrity($data, $extractDir, $path, $isShipped = false) {
$l = \OC::$server->getL10N('lib');
//load the info.xml file of the app
if(!is_file($extractDir.'/appinfo/info.xml')) {
@@ -329,12 +333,41 @@ class OC_Installer{
}
if(!is_file($extractDir.'/appinfo/info.xml')) {
OC_Helper::rmdirr($extractDir);
- if($data['source']=='http') {
+ if($data['source'] === 'http') {
unlink($path);
}
throw new \Exception($l->t("App does not provide an info.xml file"));
}
- $info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml', true);
+
+ $info = OC_App::getAppInfo($extractDir.'/appinfo/info.xml', true);
+
+ // We can't trust the parsed info.xml file as it may have been tampered
+ // with by an attacker and thus we need to use the local data to check
+ // whether the application needs to be signed.
+ $appId = OC_App::cleanAppId($data['appdata']['id']);
+ $appBelongingToId = OC_App::getInternalAppIdByOcs($appId);
+ if(is_string($appBelongingToId)) {
+ $previouslySigned = \OC::$server->getConfig()->getAppValue($appBelongingToId, 'signed', 'false');
+ } else {
+ $appBelongingToId = $info['id'];
+ $previouslySigned = 'false';
+ }
+ if($data['appdata']['level'] === OC_App::officialApp || $previouslySigned === 'true') {
+ \OC::$server->getConfig()->setAppValue($appBelongingToId, 'signed', 'true');
+ $integrityResult = \OC::$server->getIntegrityCodeChecker()->verifyAppSignature(
+ $appBelongingToId,
+ $extractDir
+ );
+ if($integrityResult !== []) {
+ $e = new \Exception(
+ $l->t(
+ 'Signature could not get checked. Please contact the app developer and check your admin screen.'
+ )
+ );
+ throw $e;
+ }
+ }
+
// check the code for not allowed calls
if(!$isShipped && !OC_Installer::checkCode($extractDir)) {
OC_Helper::rmdirr($extractDir);