/** * Authenticates the user - NOT EFFECTIVELY IMPLEMENTED * Normally some kind of password check would be done here. * Alternatively, the password could be ignored and an Apache * authentication via mod_auth_* could be done * * @param string $username * @param string $domain * @param string $password * * @access public * @return boolean */ public function Logon($username, $domain, $password) { $this->url = CARDDAV_PROTOCOL . '://' . CARDDAV_SERVER . ':' . CARDDAV_PORT . str_replace("%d", $domain, str_replace("%u", $username, CARDDAV_PATH)); $this->default_url = CARDDAV_PROTOCOL . '://' . CARDDAV_SERVER . ':' . CARDDAV_PORT . str_replace("%d", $domain, str_replace("%u", $username, CARDDAV_DEFAULT_PATH)); if (defined('CARDDAV_GAL_PATH')) { $this->gal_url = CARDDAV_PROTOCOL . '://' . CARDDAV_SERVER . ':' . CARDDAV_PORT . str_replace("%d", $domain, str_replace("%u", $username, CARDDAV_GAL_PATH)); } else { $this->gal_url = false; } $this->server = new carddav_backend($this->url, CARDDAV_URL_VCARD_EXTENSION); $this->server->set_auth($username, $password); if ($connected = $this->server->check_connection()) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendCardDAV->Logon(): User '%s' is authenticated on '%s'", $username, $this->url)); $this->username = $username; $this->domain = $domain; // Autodiscover all the addressbooks $this->discoverAddressbooks(); } else { //TODO: get error message $error = ''; ZLog::Write(LOGLEVEL_ERROR, sprintf("BackendCardDAV->Logon(): User '%s' failed to authenticate on '%s': %s", $username, $this->url, $error)); $this->server = null; } return $connected; }
/** * Returns a valid and unused vCard id * * @return string $vcard_id Valid vCard id */ private function generate_vcard_id() { $vcard_id = null; for ($number = 0; $number <= 25; $number++) { if ($number == 8 || $number == 17) { $vcard_id .= '-'; } else { $vcard_id .= $this->vcard_id_chars[mt_rand(0, count($this->vcard_id_chars) - 1)]; } } try { $carddav = new carddav_backend($this->url); $carddav->set_auth($this->username, $this->password); $result = $carddav->query($this->url . $vcard_id . $this->url_vcard_extension, 'GET'); if ($result['http_code'] !== 404) { $vcard_id = $this->generate_vcard_id(); } return $vcard_id; } catch (Exception $e) { throw new Exception($e->getMessage(), self::EXCEPTION_COULD_NOT_GENERATE_NEW_VCARD_ID); } }
/** * Deletes the CardDAV server contact * * @param array $carddav_contact_ids CardDAV contact ids * @return mixed affected CardDAV contacts or false */ private function carddav_delete($carddav_contact_ids) { $server = current(carddav::get_carddav_server($this->carddav_server_id)); $carddav_backend = new carddav_backend($server['url']); if ($this->rc->decrypt($server['password']) == '%p') { $server['password'] = $this->rcpassword; } $carddav_backend->set_auth($server['username'], $this->rc->decrypt($server['password']), $server['authtype']); if ($carddav_backend->check_connection()) { foreach ($carddav_contact_ids as $carddav_contact_id) { $contact = $this->get_carddav_addressbook_contact($carddav_contact_id); $carddav_backend->delete($contact['vcard_id']); $this->counter++; if ($this->counter < count($carddav_contact_ids)) { continue; } if ($this->counter > 1) { $contact['vcard_id'] = false; } $this->carddav_addressbook_sync($server, $carddav_contact_id, $contact['vcard_id']); } return count($carddav_contact_ids); } return false; }
Considering we are running as a long running process, we should definetely run as a non-privileged user to protect in case of a worst-case exploit. Note that this doesn't apply unless the process is launched by the root user, such as when started by init */ if ($config["SMStoXMPP"]["app_user"] && $config["SMStoXMPP"]["app_group"]) { $user = posix_getpwnam($config["SMStoXMPP"]["app_user"]); @posix_setuid($user['uid']); $group = posix_getgrnam($config["SMStoXMPP"]["app_group"]); @posix_setgid($group['gid']); } // connect to CardDAV $carddav = new carddav_backend($config["SMStoXMPP"]["contacts_url"]); $carddav->set_auth($config["SMStoXMPP"]["contacts_username"], $config["SMStoXMPP"]["contacts_password"]); // handle posix signals in a sane way pcntl_signal(SIGTERM, "sig_handler_child", false); pcntl_signal(SIGHUP, "sig_handler_child", false); pcntl_signal(SIGINT, "sig_handler_child", false); pcntl_signal(SIGUSR1, "sig_handler_child", false); // we set the rescan option here, and do the actual CardDAV download // and sync inside the loop - this allows us to schedule automatic // rechecks $address_rescan = true; // store address to contact mapping in memory $address_map = array(); // background worker loop while (true) { // garbage collect - needed with long running scripts gc_collect_cycles();
/** * Returns a valid and unused vCard id * * @return string Valid vCard id */ private function generate_vcard_id() { $id = null; for ($number = 0; $number <= 25; $number++) { if ($number == 8 || $number == 17) { $id .= '-'; } else { $id .= $this->vcard_id_chars[mt_rand(0, count($this->vcard_id_chars) - 1)]; } } $this->current_id = $id; $carddav = new carddav_backend($this->url); $carddav->set_auth($this->username, $this->password); if ($carddav->query($this->url . $id . $this->ext, 'GET', null, null, true)) { return $this->generate_vcard_id(); } else { return $id; } }
define('CARDDAV_DEFAULT_PATH', CARDDAV_PATH . 'personal/'); $username = "******"; $password = "******"; $domain = ""; $url = CARDDAV_PROTOCOL . '://' . CARDDAV_SERVER . ':' . CARDDAV_PORT . str_replace("%d", $domain, str_replace("%u", $username, CARDDAV_PATH)); $default_url = CARDDAV_PROTOCOL . '://' . CARDDAV_SERVER . ':' . CARDDAV_PORT . str_replace("%d", $domain, str_replace("%u", $username, CARDDAV_DEFAULT_PATH)); if (defined('CARDDAV_GAL_PATH')) { $gal_url = CARDDAV_PROTOCOL . '://' . CARDDAV_SERVER . ':' . CARDDAV_PORT . str_replace("%d", $domain, str_replace("%u", $username, CARDDAV_GAL_PATH)); } else { $gal_url = false; } echo "{$url}\n"; echo "{$default_url}\n"; echo "{$gal_url}\n"; $server = new carddav_backend($url); $server->set_auth($username, $password); //$server->enable_debug(); $raw = $server->get(false, false, true); echo "{$raw}\n"; //var_dump($server->get_debug()); if ($raw !== false) { $xml = new SimpleXMLElement($raw); foreach ($xml->addressbook_element as $response) { if ($gal_url !== false) { if (strcmp(urldecode($response->url), $gal_url) == 0) { echo sprintf("BackendCardDAV::discoverAddressbooks() Ignoring GAL addressbook '%s'\n", $this->gal_url); continue; } } echo sprintf("BackendCardDAV::discoverAddressbooks() Found addressbook '%s'\n", urldecode($response->url)); }