mirror of
https://github.com/nextcloud/desktop.git
synced 2024-12-15 10:11:36 +03:00
615 lines
22 KiB
C
615 lines
22 KiB
C
/*
|
|
* libcsync -- a library to sync a directory with another
|
|
*
|
|
* Copyright (c) 2011 by Andreas Schneider <asn@cryptomilk.org>
|
|
* Copyright (c) 2012 by Klaas Freitag <freitag@owncloud.com>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "csync_owncloud.h"
|
|
#include "csync_owncloud_private.h"
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include "csync_private.h"
|
|
|
|
|
|
/*
|
|
* helper method to build up a user text for SSL problems, called from the
|
|
* verify_sslcert callback.
|
|
*/
|
|
static void addSSLWarning( char *ptr, const char *warn, int len )
|
|
{
|
|
char *concatHere = ptr;
|
|
int remainingLen = 0;
|
|
|
|
if( ! (warn && ptr )) return;
|
|
remainingLen = len - strlen(ptr);
|
|
if( remainingLen <= 0 ) return;
|
|
concatHere = ptr + strlen(ptr); /* put the write pointer to the end. */
|
|
strncpy( concatHere, warn, remainingLen );
|
|
}
|
|
|
|
/*
|
|
* Callback to verify the SSL certificate, called from libneon.
|
|
* It analyzes the SSL problem, creates a user information text and passes
|
|
* it to the csync callback to ask the user.
|
|
*/
|
|
#define LEN 4096
|
|
static int ssl_callback_by_neon(void *userdata, int failures,
|
|
const ne_ssl_certificate *certificate)
|
|
{
|
|
char problem[LEN];
|
|
char buf[MAX(NE_SSL_DIGESTLEN, NE_ABUFSIZ)];
|
|
int ret = -1;
|
|
const ne_ssl_certificate *cert = certificate;
|
|
csync_auth_callback authcb = NULL;
|
|
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
|
|
|
|
memset( problem, 0, LEN );
|
|
|
|
while( cert ) {
|
|
|
|
addSSLWarning( problem, "There are problems with the SSL certificate:\n", LEN );
|
|
if( failures & NE_SSL_NOTYETVALID ) {
|
|
addSSLWarning( problem, " * The certificate is not yet valid.\n", LEN );
|
|
}
|
|
if( failures & NE_SSL_EXPIRED ) {
|
|
addSSLWarning( problem, " * The certificate has expired.\n", LEN );
|
|
}
|
|
|
|
if( failures & NE_SSL_UNTRUSTED ) {
|
|
addSSLWarning( problem, " * The certificate is not trusted!\n", LEN );
|
|
}
|
|
if( failures & NE_SSL_IDMISMATCH ) {
|
|
addSSLWarning( problem, " * The hostname for which the certificate was "
|
|
"issued does not match the hostname of the server\n", LEN );
|
|
}
|
|
if( failures & NE_SSL_BADCHAIN ) {
|
|
addSSLWarning( problem, " * The certificate chain contained a certificate other than the server cert\n", LEN );
|
|
}
|
|
if( failures & NE_SSL_REVOKED ) {
|
|
addSSLWarning( problem, " * The server certificate has been revoked by the issuing authority.\n", LEN );
|
|
}
|
|
|
|
if (ne_ssl_cert_digest(cert, buf) == 0) {
|
|
addSSLWarning( problem, "Certificate fingerprint: ", LEN );
|
|
addSSLWarning( problem, buf, LEN );
|
|
addSSLWarning( problem, "\n", LEN );
|
|
}
|
|
cert = ne_ssl_cert_signedby( cert );
|
|
}
|
|
addSSLWarning( problem, "Do you want to accept the certificate chain anyway?\nAnswer yes to do so and take the risk: ", LEN );
|
|
|
|
if( ctx->csync_ctx ) {
|
|
authcb = csync_get_auth_callback( ctx->csync_ctx );
|
|
}
|
|
if( authcb ){
|
|
/* call the csync callback */
|
|
DEBUG_WEBDAV("Call the csync callback for SSL problems");
|
|
memset( buf, 0, NE_ABUFSIZ );
|
|
(*authcb) ( problem, buf, NE_ABUFSIZ-1, 1, 0, csync_get_userdata(ctx->csync_ctx) );
|
|
if( buf[0] == 'y' || buf[0] == 'Y') {
|
|
ret = 0;
|
|
} else {
|
|
DEBUG_WEBDAV("Authentication callback replied %s", buf );
|
|
|
|
}
|
|
}
|
|
DEBUG_WEBDAV("## VERIFY_SSL CERT: %d", ret );
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Authentication callback. Is set by ne_set_server_auth to be called
|
|
* from the neon lib to authenticate a request.
|
|
*/
|
|
static int authentication_callback_by_neon( void *userdata, const char *realm, int attempt,
|
|
char *username, char *password)
|
|
{
|
|
char buf[NE_ABUFSIZ];
|
|
csync_auth_callback authcb = NULL;
|
|
int re = attempt;
|
|
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
|
|
|
|
(void) realm;
|
|
|
|
/* DEBUG_WEBDAV( "Authentication required %s", realm ); */
|
|
if( username && password ) {
|
|
DEBUG_WEBDAV( "Authentication required %s", username );
|
|
if( ctx->dav_session.user ) {
|
|
/* allow user without password */
|
|
if( strlen( ctx->dav_session.user ) < NE_ABUFSIZ ) {
|
|
strcpy( username, ctx->dav_session.user );
|
|
}
|
|
if( ctx->dav_session.pwd && strlen( ctx->dav_session.pwd ) < NE_ABUFSIZ ) {
|
|
strcpy( password, ctx->dav_session.pwd );
|
|
}
|
|
} else {
|
|
authcb = csync_get_auth_callback( ctx->csync_ctx );
|
|
if( authcb != NULL ){
|
|
/* call the csync callback */
|
|
DEBUG_WEBDAV("Call the csync callback for %s", realm );
|
|
memset( buf, 0, NE_ABUFSIZ );
|
|
(*authcb) ("Enter your username: ", buf, NE_ABUFSIZ-1, 1, 0, csync_get_userdata(ctx->csync_ctx) );
|
|
if( strlen(buf) < NE_ABUFSIZ ) {
|
|
strcpy( username, buf );
|
|
}
|
|
memset( buf, 0, NE_ABUFSIZ );
|
|
(*authcb) ("Enter your password: ", buf, NE_ABUFSIZ-1, 0, 0, csync_get_userdata(ctx->csync_ctx) );
|
|
if( strlen(buf) < NE_ABUFSIZ) {
|
|
strcpy( password, buf );
|
|
}
|
|
} else {
|
|
re = 1;
|
|
}
|
|
}
|
|
}
|
|
return re;
|
|
}
|
|
|
|
/*
|
|
* Authentication callback. Is set by ne_set_proxy_auth to be called
|
|
* from the neon lib to authenticate against a proxy. The data to authenticate
|
|
* against comes from mirall throught vio_module_init function.
|
|
*/
|
|
static int proxy_authentication_callback_by_neon( void *userdata, const char *realm, int attempt,
|
|
char *username, char *password)
|
|
{
|
|
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
|
|
(void) realm;
|
|
if( ctx->dav_session.proxy_user && strlen( ctx->dav_session.proxy_user ) < NE_ABUFSIZ) {
|
|
strcpy( username, ctx->dav_session.proxy_user );
|
|
if( ctx->dav_session.proxy_pwd && strlen( ctx->dav_session.proxy_pwd ) < NE_ABUFSIZ) {
|
|
strcpy( password, ctx->dav_session.proxy_pwd );
|
|
}
|
|
}
|
|
/* NTLM needs several attempts */
|
|
return (attempt < 3) ? 0 : -1;
|
|
}
|
|
|
|
/* Configure the proxy depending on the variables */
|
|
static int configureProxy( csync_owncloud_ctx_t *ctx, ne_session *session )
|
|
{
|
|
int port = 8080;
|
|
int re = -1;
|
|
|
|
if( ! session ) return -1;
|
|
if( ! ctx->dav_session.proxy_type ) return 0; /* Go by NoProxy per default */
|
|
|
|
if( ctx->dav_session.proxy_port > 0 ) {
|
|
port = ctx->dav_session.proxy_port;
|
|
}
|
|
|
|
if( c_streq(ctx->dav_session.proxy_type, "NoProxy" )) {
|
|
DEBUG_WEBDAV("No proxy configured.");
|
|
re = 0;
|
|
} else if( c_streq(ctx->dav_session.proxy_type, "DefaultProxy") ||
|
|
c_streq(ctx->dav_session.proxy_type, "HttpProxy") ||
|
|
c_streq(ctx->dav_session.proxy_type, "HttpCachingProxy") ||
|
|
c_streq(ctx->dav_session.proxy_type, "Socks5Proxy")) {
|
|
|
|
if( ctx->dav_session.proxy_host ) {
|
|
DEBUG_WEBDAV("%s at %s:%d", ctx->dav_session.proxy_type, ctx->dav_session.proxy_host, port );
|
|
if (c_streq(ctx->dav_session.proxy_type, "Socks5Proxy")) {
|
|
ne_session_socks_proxy(session, NE_SOCK_SOCKSV5, ctx->dav_session.proxy_host, port,
|
|
ctx->dav_session.proxy_user, ctx->dav_session.proxy_pwd);
|
|
} else {
|
|
ne_session_proxy(session, ctx->dav_session.proxy_host, port );
|
|
}
|
|
re = 2;
|
|
} else {
|
|
DEBUG_WEBDAV("%s requested but no proxy host defined.", ctx->dav_session.proxy_type );
|
|
/* we used to try ne_system_session_proxy here, but we should rather err out
|
|
to behave exactly like the caller. */
|
|
}
|
|
} else {
|
|
DEBUG_WEBDAV( "Unsupported Proxy: %s", ctx->dav_session.proxy_type );
|
|
}
|
|
|
|
return re;
|
|
}
|
|
|
|
/*
|
|
* This hook is called for with the response of a request. Here its checked
|
|
* if a Set-Cookie header is there for the PHPSESSID. The key is stored into
|
|
* the webdav session to be added to subsequent requests.
|
|
*/
|
|
static void post_request_hook(ne_request *req, void *userdata, const ne_status *status)
|
|
{
|
|
const char *set_cookie_header = NULL;
|
|
const char *sc = NULL;
|
|
char *key = NULL;
|
|
|
|
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
|
|
|
|
if (ctx->dav_session.session_key)
|
|
return; /* We already have a session cookie, and we should ignore other ones */
|
|
|
|
if(!(status && req)) return;
|
|
if( status->klass == 2 || status->code == 401 ) {
|
|
/* successful request */
|
|
set_cookie_header = ne_get_response_header( req, "Set-Cookie" );
|
|
if( set_cookie_header ) {
|
|
DEBUG_WEBDAV(" Set-Cookie found: %s", set_cookie_header);
|
|
/* try to find a ', ' sequence which is the separator of neon if multiple Set-Cookie
|
|
* headers are there.
|
|
* The following code parses a string like this:
|
|
* Set-Cookie: 50ace6bd8a669=p537brtt048jh8srlp2tuep7em95nh9u98mj992fbqc47d1aecp1;
|
|
*/
|
|
sc = set_cookie_header;
|
|
while(sc) {
|
|
const char *sc_val = sc;
|
|
const char *sc_end = sc_val;
|
|
int cnt = 0;
|
|
int len = strlen(sc_val); /* The length of the rest of the header string. */
|
|
|
|
while( cnt < len && *sc_end != ';' && *sc_end != ',') {
|
|
cnt++;
|
|
sc_end++;
|
|
}
|
|
if( cnt == len ) {
|
|
/* exit: We are at the end. */
|
|
sc = NULL;
|
|
} else if( *sc_end == ';' ) {
|
|
/* We are at the end of the session key. */
|
|
int keylen = sc_end-sc_val;
|
|
if( key ) {
|
|
int oldlen = strlen(key);
|
|
key = c_realloc(key, oldlen + 2 + keylen+1);
|
|
strcpy(key + oldlen, "; ");
|
|
strncpy(key + oldlen + 2, sc_val, keylen);
|
|
key[oldlen + 2 + keylen] = '\0';
|
|
} else {
|
|
key = c_malloc(keylen+1);
|
|
strncpy( key, sc_val, keylen );
|
|
key[keylen] = '\0';
|
|
}
|
|
|
|
/* now search for a ',' to find a potential other header entry */
|
|
while(cnt < len && *sc_end != ',') {
|
|
cnt++;
|
|
sc_end++;
|
|
}
|
|
if( cnt < len )
|
|
sc = sc_end+2; /* mind the space after the comma */
|
|
else
|
|
sc = NULL;
|
|
} else if( *sc_end == ',' ) {
|
|
/* A new entry is to check. */
|
|
if( *(sc_end + 1) == ' ') {
|
|
sc = sc_end+2;
|
|
} else {
|
|
/* error condition */
|
|
sc = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
DEBUG_WEBDAV("Request failed, don't take session header.");
|
|
}
|
|
if( key ) {
|
|
DEBUG_WEBDAV("----> Session-key: %s", key);
|
|
SAFE_FREE(ctx->dav_session.session_key);
|
|
ctx->dav_session.session_key = key;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* this hook is called just after a request has been created, before its sent.
|
|
* Here it is used to set the proxy connection header if available.
|
|
*/
|
|
static void request_created_hook(ne_request *req, void *userdata,
|
|
const char *method, const char *requri)
|
|
{
|
|
// FIXME Can possibly be merged with pre_send_hook
|
|
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata;
|
|
(void) method;
|
|
(void) requri;
|
|
|
|
if( !req ) return;
|
|
|
|
if(ctx->dav_session.proxy_type) {
|
|
/* required for NTLM */
|
|
ne_add_request_header(req, "Proxy-Connection", "Keep-Alive");
|
|
}
|
|
}
|
|
|
|
/*
|
|
* this hook is called just before a request has been sent.
|
|
* Here it is used to set the session cookie if available.
|
|
*/
|
|
static void pre_send_hook(ne_request *req, void *userdata,
|
|
ne_buffer *header)
|
|
{
|
|
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata;
|
|
|
|
if( !req ) return;
|
|
|
|
if(ctx->dav_session.session_key) {
|
|
ne_buffer_concat(header, "Cookie: ", ctx->dav_session.session_key, "\r\n", NULL);
|
|
} else {
|
|
DEBUG_WEBDAV("csync pre_send_hook We don't have a Auth Cookie (session_key), this is wrong!");
|
|
}
|
|
}
|
|
|
|
static int post_send_hook(ne_request *req, void *userdata,
|
|
const ne_status *status)
|
|
{
|
|
const char *location;
|
|
csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata;
|
|
(void) status;
|
|
|
|
location = ne_get_response_header(req, "Location");
|
|
|
|
if( !location ) return NE_OK;
|
|
|
|
if( ctx->dav_session.redir_callback ) {
|
|
if( ctx->dav_session.redir_callback( ctx->csync_ctx, location ) ) {
|
|
return NE_REDIRECT;
|
|
} else {
|
|
return NE_RETRY;
|
|
}
|
|
}
|
|
|
|
return NE_REDIRECT;
|
|
}
|
|
|
|
/*
|
|
* Connect to a DAV server
|
|
* This function sets the flag _connected if the connection is established
|
|
* and returns if the flag is set, so calling it frequently is save.
|
|
*/
|
|
int dav_connect(CSYNC *csyncCtx, const char *base_url) {
|
|
int useSSL = 0;
|
|
int rc;
|
|
char protocol[6] = {'\0'};
|
|
char uaBuf[256];
|
|
char *path = NULL;
|
|
char *scheme = NULL;
|
|
char *host = NULL;
|
|
unsigned int port = 0;
|
|
int proxystate = -1;
|
|
csync_owncloud_ctx_t *ctx = csyncCtx->owncloud_context;
|
|
struct csync_client_certs_s* clientCerts = csyncCtx->clientCerts;
|
|
|
|
if (ctx->_connected) {
|
|
return 0;
|
|
}
|
|
|
|
rc = c_parse_uri( base_url, &scheme,
|
|
&ctx->dav_session.user,
|
|
&ctx->dav_session.pwd,
|
|
&host, &port, &path );
|
|
if( rc < 0 ) {
|
|
DEBUG_WEBDAV("Failed to parse uri %s", base_url );
|
|
goto out;
|
|
}
|
|
|
|
DEBUG_WEBDAV("* scheme %s", scheme );
|
|
DEBUG_WEBDAV("* host %s", host );
|
|
DEBUG_WEBDAV("* port %u", port );
|
|
DEBUG_WEBDAV("* path %s", path );
|
|
|
|
if( strcmp( scheme, "owncloud" ) == 0 || strcmp( scheme, "http" ) == 0 ) {
|
|
strcpy( protocol, "http");
|
|
} else if( strcmp( scheme, "ownclouds" ) == 0 || strcmp( scheme, "https") == 0 ) {
|
|
strcpy( protocol, "https");
|
|
useSSL = 1;
|
|
} else {
|
|
DEBUG_WEBDAV("Invalid scheme %s, go out here!", scheme );
|
|
rc = -1;
|
|
goto out;
|
|
}
|
|
|
|
DEBUG_WEBDAV("* user %s", ctx->dav_session.user ? ctx->dav_session.user : "");
|
|
|
|
if (port == 0) {
|
|
port = ne_uri_defaultport(protocol);
|
|
}
|
|
|
|
ctx->dav_session.ctx = ne_session_create( protocol, host, port);
|
|
|
|
if (ctx->dav_session.ctx == NULL) {
|
|
DEBUG_WEBDAV("Session create with protocol %s failed", protocol );
|
|
rc = -1;
|
|
goto out;
|
|
}
|
|
|
|
if (ctx->dav_session.read_timeout != 0) {
|
|
ne_set_read_timeout(ctx->dav_session.ctx, ctx->dav_session.read_timeout);
|
|
DEBUG_WEBDAV("Timeout set to %u seconds", ctx->dav_session.read_timeout );
|
|
}
|
|
// Should never take more than some seconds, 30 is really a max.
|
|
ne_set_connect_timeout(ctx->dav_session.ctx, 30);
|
|
|
|
snprintf( uaBuf, sizeof(uaBuf), "Mozilla/5.0 (%s) csyncoC/%s",
|
|
csync_owncloud_get_platform(), CSYNC_STRINGIFY( LIBCSYNC_VERSION ));
|
|
ne_set_useragent( ctx->dav_session.ctx, uaBuf);
|
|
ne_set_server_auth(ctx->dav_session.ctx, authentication_callback_by_neon, ctx);
|
|
|
|
if( useSSL ) {
|
|
if (!ne_has_support(NE_FEATURE_SSL)) {
|
|
DEBUG_WEBDAV("Error: SSL is not enabled.");
|
|
rc = -1;
|
|
goto out;
|
|
}
|
|
|
|
if(clientCerts != NULL) {
|
|
ne_ssl_client_cert *clicert;
|
|
|
|
DEBUG_WEBDAV("dav_connect: certificatePath and certificatePasswd are set, so we use it" );
|
|
DEBUG_WEBDAV(" with certificatePath: %s", clientCerts->certificatePath );
|
|
DEBUG_WEBDAV(" with certificatePasswd: %s", clientCerts->certificatePasswd );
|
|
clicert = ne_ssl_clicert_read ( clientCerts->certificatePath );
|
|
if ( clicert == NULL ) {
|
|
DEBUG_WEBDAV ( "Error read certificate : %s", ne_get_error ( ctx->dav_session.ctx ) );
|
|
} else {
|
|
if ( ne_ssl_clicert_encrypted ( clicert ) ) {
|
|
int rtn = ne_ssl_clicert_decrypt ( clicert, clientCerts->certificatePasswd );
|
|
if ( !rtn ) {
|
|
DEBUG_WEBDAV ( "Certificate was deciphered successfully." );
|
|
ne_ssl_set_clicert ( ctx->dav_session.ctx, clicert );
|
|
} else {
|
|
DEBUG_WEBDAV ( "Errors while deciphering certificate: %s", ne_get_error ( ctx->dav_session.ctx ) );
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
DEBUG_WEBDAV("dav_connect: error with csync_client_certs_s* clientCerts");
|
|
}
|
|
ne_ssl_trust_default_ca( ctx->dav_session.ctx );
|
|
ne_ssl_set_verify( ctx->dav_session.ctx, ssl_callback_by_neon, ctx);
|
|
}
|
|
|
|
/* Hook called when a request is created. It sets the proxy connection header. */
|
|
ne_hook_create_request( ctx->dav_session.ctx, request_created_hook, ctx );
|
|
/* Hook called after response headers are read. It gets the Session ID. */
|
|
ne_hook_post_headers( ctx->dav_session.ctx, post_request_hook, ctx );
|
|
/* Hook called before a request is sent. It sets the cookies. */
|
|
ne_hook_pre_send( ctx->dav_session.ctx, pre_send_hook, ctx );
|
|
/* Hook called after request is dispatched. Used for handling possible redirections. */
|
|
ne_hook_post_send( ctx->dav_session.ctx, post_send_hook, ctx );
|
|
|
|
/* Proxy support */
|
|
proxystate = configureProxy( ctx, ctx->dav_session.ctx );
|
|
if( proxystate < 0 ) {
|
|
DEBUG_WEBDAV("Error: Proxy-Configuration failed.");
|
|
} else if( proxystate > 0 ) {
|
|
ne_set_proxy_auth( ctx->dav_session.ctx, proxy_authentication_callback_by_neon, ctx );
|
|
}
|
|
|
|
ctx->_connected = 1;
|
|
rc = 0;
|
|
out:
|
|
SAFE_FREE(path);
|
|
SAFE_FREE(host);
|
|
SAFE_FREE(scheme);
|
|
return rc;
|
|
}
|
|
|
|
|
|
char *owncloud_error_string(CSYNC* ctx)
|
|
{
|
|
return ctx->owncloud_context->dav_session.error_string;
|
|
}
|
|
|
|
int owncloud_commit(CSYNC* ctx) {
|
|
if (!ctx->owncloud_context) {
|
|
return 0;
|
|
}
|
|
|
|
if( ctx->owncloud_context->dav_session.ctx ) {
|
|
ne_forget_auth(ctx->owncloud_context->dav_session.ctx);
|
|
ne_session_destroy(ctx->owncloud_context->dav_session.ctx );
|
|
ctx->owncloud_context->dav_session.ctx = 0;
|
|
}
|
|
|
|
/* DEBUG_WEBDAV( "********** vio_module_shutdown" ); */
|
|
|
|
ctx->owncloud_context->dav_session.ctx = 0;
|
|
|
|
// ne_sock_exit();
|
|
ctx->owncloud_context->_connected = 0; /* triggers dav_connect to go through the whole neon setup */
|
|
|
|
SAFE_FREE( ctx->owncloud_context->dav_session.user );
|
|
SAFE_FREE( ctx->owncloud_context->dav_session.pwd );
|
|
SAFE_FREE( ctx->owncloud_context->dav_session.session_key);
|
|
SAFE_FREE( ctx->owncloud_context->dav_session.error_string );
|
|
return 0;
|
|
}
|
|
|
|
void owncloud_destroy(CSYNC* ctx)
|
|
{
|
|
owncloud_commit(ctx);
|
|
SAFE_FREE(ctx->owncloud_context);
|
|
|
|
if (ctx->clientCerts) {
|
|
SAFE_FREE(ctx->clientCerts->certificatePasswd);
|
|
SAFE_FREE(ctx->clientCerts->certificatePath);
|
|
SAFE_FREE(ctx->clientCerts);
|
|
}
|
|
ne_sock_exit();
|
|
}
|
|
|
|
int owncloud_set_property(CSYNC* ctx, const char *key, void *data) {
|
|
#define READ_STRING_PROPERTY(P) \
|
|
if (c_streq(key, #P)) { \
|
|
SAFE_FREE(ctx->owncloud_context->dav_session.P); \
|
|
ctx->owncloud_context->dav_session.P = c_strdup((const char*)data); \
|
|
return 0; \
|
|
}
|
|
READ_STRING_PROPERTY(session_key)
|
|
READ_STRING_PROPERTY(proxy_type)
|
|
READ_STRING_PROPERTY(proxy_host)
|
|
READ_STRING_PROPERTY(proxy_user)
|
|
READ_STRING_PROPERTY(proxy_pwd)
|
|
#undef READ_STRING_PROPERTY
|
|
|
|
if (c_streq(key, "proxy_port")) {
|
|
ctx->owncloud_context->dav_session.proxy_port = *(int*)(data);
|
|
return 0;
|
|
}
|
|
if (c_streq(key, "read_timeout") || c_streq(key, "timeout")) {
|
|
ctx->owncloud_context->dav_session.read_timeout = *(int*)(data);
|
|
return 0;
|
|
}
|
|
if( c_streq(key, "get_dav_session")) {
|
|
/* Give the ne_session to the caller */
|
|
*(ne_session**)data = ctx->owncloud_context->dav_session.ctx;
|
|
return 0;
|
|
}
|
|
if( c_streq(key, "redirect_callback")) {
|
|
if (data) {
|
|
csync_owncloud_redirect_callback_t* cb_wrapper = data;
|
|
ctx->owncloud_context->dav_session.redir_callback = *cb_wrapper;
|
|
} else {
|
|
ctx->owncloud_context->dav_session.redir_callback = NULL;
|
|
}
|
|
}
|
|
if( c_streq(key, "SSLClientCerts")) {
|
|
if(ctx->clientCerts != NULL) {
|
|
SAFE_FREE(ctx->clientCerts->certificatePasswd);
|
|
SAFE_FREE(ctx->clientCerts->certificatePath);
|
|
SAFE_FREE(ctx->clientCerts);
|
|
ctx->clientCerts = NULL;
|
|
}
|
|
if (data) {
|
|
struct csync_client_certs_s* clientCerts = (struct csync_client_certs_s*) data;
|
|
struct csync_client_certs_s* newCerts = c_malloc(sizeof(struct csync_client_certs_s));
|
|
newCerts->certificatePath = c_strdup(clientCerts->certificatePath);
|
|
newCerts->certificatePasswd = c_strdup(clientCerts->certificatePasswd);
|
|
ctx->clientCerts = newCerts;
|
|
} else {
|
|
DEBUG_WEBDAV("error: in owncloud_set_property for 'SSLClientCerts'" );
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void owncloud_init(CSYNC* ctx) {
|
|
|
|
ne_sock_init();
|
|
|
|
ctx->owncloud_context = c_malloc( sizeof( struct csync_owncloud_ctx_s ));
|
|
ctx->owncloud_context->csync_ctx = ctx; // back reference
|
|
|
|
}
|
|
|
|
/* vim: set ts=4 sw=4 et cindent: */
|
|
|