Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F1842491
kolab_sync.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
kolab_sync.php
View Options
<?php
/**
* Main application class (based on Roundcube Framework)
*/
class
kolab_sync
extends
rcube
{
public
$app_name
=
'ActiveSync for Kolab'
;
// no double quotes inside
private
$data
=
array
();
const
CHARSET
=
'UTF-8'
;
/**
* This implements the 'singleton' design pattern
*
* @return kolab_sync The one and only instance
*/
static
function
get_instance
()
{
if
(!
self
::
$instance
||
!
is_a
(
self
::
$instance
,
'kolab_sync'
))
{
self
::
$instance
=
new
kolab_sync
();
self
::
$instance
->
startup
();
// init AFTER object was linked with self::$instance
}
return
self
::
$instance
;
}
public
function
startup
()
{
// Initialize Syncroton Logger
$this
->
logger
=
new
Zend_Log
();
$priority
=
Zend_Log
::
DEBUG
;
$writer
=
new
Zend_Log_Writer_Stream
(
'logs/console'
);
$filter
=
new
Zend_Log_Filter_Priority
(
$priority
);
$this
->
logger
->
addWriter
(
$writer
);
$this
->
logger
->
addFilter
(
$filter
);
}
/**
* Application execution (authentication and ActiveSync)
*/
public
function
run
()
{
// when used with (f)cgi no PHP_AUTH* variables are available without defining a special rewrite rule
if
(!
isset
(
$_SERVER
[
'PHP_AUTH_USER'
]))
{
// "Basic didhfiefdhfu4fjfjdsa34drsdfterrde..."
if
(
isset
(
$_SERVER
[
"REMOTE_USER"
]))
{
$basicAuthData
=
base64_decode
(
substr
(
$_SERVER
[
"REMOTE_USER"
],
6
));
}
elseif
(
isset
(
$_SERVER
[
"REDIRECT_REMOTE_USER"
]))
{
$basicAuthData
=
base64_decode
(
substr
(
$_SERVER
[
"REDIRECT_REMOTE_USER"
],
6
));
}
elseif
(
isset
(
$_SERVER
[
"Authorization"
]))
{
$basicAuthData
=
base64_decode
(
substr
(
$_SERVER
[
"Authorization"
],
6
));
}
elseif
(
isset
(
$_SERVER
[
"HTTP_AUTHORIZATION"
]))
{
$basicAuthData
=
base64_decode
(
substr
(
$_SERVER
[
"HTTP_AUTHORIZATION"
],
6
));
}
if
(
isset
(
$basicAuthData
)
&&
!
empty
(
$basicAuthData
))
{
list
(
$_SERVER
[
'PHP_AUTH_USER'
],
$_SERVER
[
'PHP_AUTH_PW'
])
=
explode
(
":"
,
$basicAuthData
);
}
}
if
(!
empty
(
$_SERVER
[
'PHP_AUTH_USER'
])
&&
!
empty
(
$_SERVER
[
'PHP_AUTH_PW'
]))
{
// Nokia N9 sends username in form domain.tld\username
$username
=
explode
(
"
\\
"
,
$_SERVER
[
'PHP_AUTH_USER'
]);
if
(
count
(
$username
)
==
2
)
{
$_SERVER
[
'PHP_AUTH_USER'
]
=
$username
[
1
];
}
$userid
=
$this
->
authenticate
(
$_SERVER
[
'PHP_AUTH_USER'
],
$_SERVER
[
'PHP_AUTH_PW'
]);
}
if
(
empty
(
$userid
))
{
header
(
'WWW-Authenticate: Basic realm="'
.
$this
->
app_name
.
'"'
);
header
(
'HTTP/1.1 401 Unauthorized'
);
exit
;
}
// Register Syncroton backends
Syncroton_Registry
::
set
(
'loggerBackend'
,
$this
->
logger
);
Syncroton_Registry
::
set
(
Syncroton_Registry
::
DATABASE
,
new
kolab_sync_db
);
Syncroton_Registry
::
set
(
Syncroton_Registry
::
TRANSACTIONMANAGER
,
kolab_sync_transaction_manager
::
getInstance
());
Syncroton_Registry
::
set
(
Syncroton_Registry
::
DEVICEBACKEND
,
new
kolab_sync_backend_device
);
Syncroton_Registry
::
set
(
Syncroton_Registry
::
FOLDERBACKEND
,
new
kolab_sync_backend_folder
);
Syncroton_Registry
::
set
(
Syncroton_Registry
::
SYNCSTATEBACKEND
,
new
kolab_sync_backend_state
);
Syncroton_Registry
::
set
(
Syncroton_Registry
::
CONTENTSTATEBACKEND
,
new
kolab_sync_backend_content
);
Syncroton_Registry
::
setContactsDataClass
(
'kolab_sync_data_contacts'
);
Syncroton_Registry
::
setCalendarDataClass
(
'kolab_sync_data_calendar'
);
// Syncroton_Registry::setEmailDataClass('kolab_sync_data_email');
// Syncroton_Registry::setTasksDataClass('kolab_sync_data_tasks');
// Run Syncroton
$syncroton
=
new
Syncroton_Server
(
$userid
);
$syncroton
->
handle
();
}
/**
* Authenticates a user in LDAP and Roundcube
*/
public
function
authenticate
(
$username
,
$password
)
{
// Get IMAP host
$host
=
$this
->
config
->
get
(
'default_host'
);
$host
=
rcube_utils
::
parse_host
(
$host
);
// Get user
$user
=
$this
->
get_ldap_user
(
$username
,
$host
);
// Get Roundcube user ID
$userid
=
$this
->
get_rcube_user
(
$user
,
$password
,
$host
);
return
$userid
;
}
/**
* Returns user login attribute from LDAP server
*/
private
function
get_ldap_user
(
$username
,
$host
)
{
$login_attr
=
$this
->
config
->
get
(
'kolab_auth_login'
);
$addressbook
=
$this
->
config
->
get
(
'kolab_auth_addressbook'
);
$filter
=
$this
->
config
->
get
(
'kolab_auth_filter'
);
$filter
=
$this
->
parse_vars
(
$filter
,
$username
,
$host
);
if
(!
is_array
(
$addressbook
))
{
$ldap_config
=
(
array
)
$this
->
config
->
get
(
'ldap_public'
);
$addressbook
=
$ldap_config
[
$addressbook
];
}
if
(
empty
(
$addressbook
))
{
return
null
;
}
if
(
empty
(
$login_attr
))
{
return
null
;
}
$addressbook
[
'filter'
]
=
$filter
;
$addressbook
[
'sizelimit'
]
=
2
;
$this
->
ldap
=
new
rcube_ldap
(
$addressbook
,
$this
->
config
->
get
(
'ldap_debug'
),
$this
->
config
->
mail_domain
(
$host
)
);
if
(!
$this
->
ldap
->
ready
)
{
return
null
;
}
// get record
$results
=
$this
->
ldap
->
list_records
();
if
(
count
(
$results
->
records
)
!=
1
)
{
return
null
;
}
if
(
$record
=
$results
->
records
[
0
])
{
return
is_array
(
$record
[
$login_attr
])
?
$record
[
$login_attr
][
0
]
:
$record
[
$login_attr
];
}
}
/**
* Prepares filter query for LDAP search
*/
private
function
parse_vars
(
$str
,
$user
,
$host
)
{
$domain
=
$this
->
config
->
get
(
'username_domain'
);
if
(!
empty
(
$domain
)
&&
strpos
(
$user
,
'@'
)
===
false
)
{
if
(
is_array
(
$domain
)
&&
isset
(
$domain
[
$host
]))
$user
.=
'@'
.
rcube_utils
::
parse_host
(
$domain
[
$host
],
$host
);
else
if
(
is_string
(
$domain
))
$user
.=
'@'
.
rcube_utils
::
parse_host
(
$domain
,
$host
);
}
// replace variables in filter
list
(
$u
,
$d
)
=
explode
(
'@'
,
$user
);
$dc
=
'dc='
.
strtr
(
$d
,
array
(
'.'
=>
',dc='
));
// hierarchal domain string
$replaces
=
array
(
'%dc'
=>
$dc
,
'%d'
=>
$d
,
'%fu'
=>
$user
,
'%u'
=>
$u
);
return
strtr
(
$str
,
$replaces
);
}
/**
* Returns Roundcube user ID for specified username and host.
* Also sets IMAP connection credentials.
*/
private
function
get_rcube_user
(
$username
,
$password
,
$host
)
{
if
(
empty
(
$username
))
{
return
null
;
}
$login_lc
=
$this
->
config
->
get
(
'login_lc'
);
// parse $host
$a_host
=
parse_url
(
$host
);
if
(
$a_host
[
'host'
])
{
$host
=
$a_host
[
'host'
];
$ssl
=
(
isset
(
$a_host
[
'scheme'
])
&&
in_array
(
$a_host
[
'scheme'
],
array
(
'ssl'
,
'imaps'
,
'tls'
)))
?
$a_host
[
'scheme'
]
:
null
;
if
(!
empty
(
$a_host
[
'port'
]))
{
$port
=
$a_host
[
'port'
];
}
else
if
(
$ssl
&&
$ssl
!=
'tls'
&&
(!
$config
[
'default_port'
]
||
$config
[
'default_port'
]
==
143
))
{
$port
=
993
;
}
}
if
(!
$port
)
{
$port
=
$this
->
config
->
get
(
'default_port'
);
}
// Convert username to lowercase. If storage backend
// is case-insensitive we need to store always the same username
if
(
$login_lc
)
{
$username
=
mb_strtolower
(
$username
);
}
// Here we need IDNA ASCII
// Only rcube_contacts class is using domain names in Unicode
$host
=
rcube_utils
::
idn_to_ascii
(
$host
);
if
(
strpos
(
$username
,
'@'
))
{
// lowercase domain name
list
(
$local
,
$domain
)
=
explode
(
'@'
,
$username
);
$username
=
$local
.
'@'
.
mb_strtolower
(
$domain
);
$username
=
rcube_utils
::
idn_to_ascii
(
$username
);
}
// user already registered?
$user
=
rcube_user
::
query
(
$username
,
$host
);
if
(!
is_object
(
$user
))
{
// @TODO: log error
return
null
;
}
// Configure environment
$this
->
user
=
$user
;
// rcube::get_storage() uses session, kolab-sync doesn't
// @TODO: modify framework to support private class variables
// or other method to provide storage credentials
global
$_SESSION
;
$_SESSION
[
'storage_host'
]
=
$host
;
$_SESSION
[
'username'
]
=
$username
;
$_SESSION
[
'storage_port'
]
=
$port
;
$_SESSION
[
'storage_ssl'
]
=
$ssl
;
$_SESSION
[
'password'
]
=
$this
->
encrypt
(
$password
);
// $this->set_storage_prop();
// force reloading complete list of subscribed mailboxes
// $storage->clear_cache('mailboxes', true);
// overwrite config with user preferences
$this
->
config
->
set_user_prefs
((
array
)
$this
->
user
->
get_prefs
());
return
$user
->
ID
;
}
/**
* Function to be executed in script shutdown
*/
public
function
shutdown
()
{
parent
::
shutdown
();
if
(
$this
->
ldap
)
{
$this
->
ldap
->
close
();
}
// write performance stats to logs/console
if
(
$this
->
config
->
get
(
'devel_mode'
))
{
if
(
function_exists
(
'memory_get_usage'
))
$mem
=
sprintf
(
'%.1f'
,
memory_get_usage
()
/
1048576
);
if
(
function_exists
(
'memory_get_peak_usage'
))
$mem
.=
'/'
.
sprintf
(
'%.1f'
,
memory_get_peak_usage
()
/
1048576
);
$log
=
$_SERVER
[
'REQUEST_URI'
]
.
(
$mem
?
" [$mem]"
:
''
);
if
(
defined
(
'RCMAIL_START'
))
self
::
print_timer
(
RCMAIL_START
,
$log
);
else
self
::
console
(
$log
);
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Mon, Aug 25, 10:14 PM (3 m, 2 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
257090
Default Alt Text
kolab_sync.php (9 KB)
Attached To
Mode
R4 syncroton
Attached
Detach File
Event Timeline
Log In to Comment