diff options
author | Nourredine <n.octeau@agim.idshost.fr> | 2014-11-18 18:44:14 +0300 |
---|---|---|
committer | Joachim Schiele <js@lastlog.de> | 2015-01-22 02:55:11 +0300 |
commit | ba8b1bbe06aacb02b00737968503dc9ca95ba23a (patch) | |
tree | e12066961d820d0b27bceb80b6d714366584ba64 /csync | |
parent | 82e5e36c57d2451de27c151afd85f296a12da5f2 (diff) |
adds 'SSL client certificate' support from n.octeau with qknight changes as:
* removed broken QSsl::SslV3 default
* rewrote slotHandleErrors(): no longer claim errors which are none.
* hack reverted: lib64 was not the cause for NixOS issues related to libraries.
* refactored csync/src/csync_owncloud.c and discovered+fixed why the dav_connect was never getting the certPath+certPassoword
* cleanup of code but seems this crushed the ssl client certificate support
* fixes the https://github.com/owncloud/client/issues/69#issuecomment-69358377 issue
* lots of cleanup
* From TODO list : translate all french comments into english
* changed _pemCertificate type from QString to QByteArray
Diffstat (limited to 'csync')
-rw-r--r-- | csync/src/CMakeLists.txt | 4 | ||||
-rw-r--r-- | csync/src/csync.h | 5 | ||||
-rw-r--r-- | csync/src/csync_owncloud.c | 53 | ||||
-rw-r--r-- | csync/src/csync_owncloud_private.h | 1 | ||||
-rw-r--r-- | csync/src/csync_private.h | 4 |
5 files changed, 64 insertions, 3 deletions
diff --git a/csync/src/CMakeLists.txt b/csync/src/CMakeLists.txt index 415fdd565..3b2f5f058 100644 --- a/csync/src/CMakeLists.txt +++ b/csync/src/CMakeLists.txt @@ -30,6 +30,7 @@ set(CSYNC_LINK_LIBRARIES ${SQLITE3_LIBRARIES} ${NEON_LIBRARIES} ${HTTPBF_LIBRARY} + ${CRYPTO_LIBRARY} ) if(HAVE_ICONV AND WITH_ICONV) @@ -88,6 +89,9 @@ include_directories( ${CSYNC_PRIVATE_INCLUDE_DIRS} ) +find_package(OpenSSL) +FIND_LIBRARY(CRYPTO_LIBRARY NAMES crypto) + add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS}) #add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS}) diff --git a/csync/src/csync.h b/csync/src/csync.h index 78a092ff7..001b5f224 100644 --- a/csync/src/csync.h +++ b/csync/src/csync.h @@ -44,6 +44,11 @@ extern "C" { #endif +struct csync_client_certs_s { + char *certificatePath; + char *certificatePasswd; +}; + /** * Instruction enum. In the file traversal structure, it describes * the csync state of a file. diff --git a/csync/src/csync_owncloud.c b/csync/src/csync_owncloud.c index 5cf08c43f..a5e0644de 100644 --- a/csync/src/csync_owncloud.c +++ b/csync/src/csync_owncloud.c @@ -374,7 +374,7 @@ static int post_send_hook(ne_request *req, void *userdata, * This function sets the flag _connected if the connection is established * and returns if the flag is set, so calling it frequently is save. */ -static int dav_connect(csync_owncloud_ctx_t *ctx, const char *base_url) { +static int dav_connect(csync_owncloud_ctx_t *ctx, struct csync_client_certs_s* clientCerts, const char *base_url) { int useSSL = 0; int rc; char protocol[6] = {'\0'}; @@ -447,6 +447,29 @@ static int dav_connect(csync_owncloud_ctx_t *ctx, const char *base_url) { 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); } @@ -654,7 +677,7 @@ csync_vio_handle_t *owncloud_opendir(CSYNC *ctx, const char *uri) { DEBUG_WEBDAV("opendir method called on %s", uri ); - if (dav_connect( ctx->owncloud_context, uri ) < 0) { + if (dav_connect( ctx->owncloud_context, ctx->clientCerts, uri ) < 0) { DEBUG_WEBDAV("connection failed"); return NULL; } @@ -691,6 +714,7 @@ csync_vio_handle_t *owncloud_opendir(CSYNC *ctx, const char *uri) { int owncloud_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle) { struct listdir_context *fetchCtx = dhandle; + free_fetchCtx(fetchCtx); (void)ctx; return 0; @@ -789,6 +813,12 @@ void owncloud_destroy(CSYNC* ctx) { owncloud_commit(ctx); SAFE_FREE(ctx->owncloud_context); + + SAFE_FREE(ctx->clientCerts->certificatePasswd); + SAFE_FREE(ctx->clientCerts->certificatePath); + SAFE_FREE(ctx->clientCerts); + ctx->clientCerts = NULL; + ctx->owncloud_context = 0; } @@ -826,12 +856,28 @@ int owncloud_set_property(CSYNC* ctx, const char *key, void *data) { 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; } @@ -847,3 +893,4 @@ void owncloud_init(CSYNC* ctx) { } /* vim: set ts=4 sw=4 et cindent: */ + diff --git a/csync/src/csync_owncloud_private.h b/csync/src/csync_owncloud_private.h index 6da641961..fc75006e1 100644 --- a/csync/src/csync_owncloud_private.h +++ b/csync/src/csync_owncloud_private.h @@ -108,6 +108,7 @@ struct csync_owncloud_ctx_s { int _connected; /* flag to indicate if a connection exists, ie. the dav_session is valid */ }; + typedef struct csync_owncloud_ctx_s csync_owncloud_ctx_t; //typedef csync_owncloud_ctx_t* csync_owncloud_ctx_p; diff --git a/csync/src/csync_private.h b/csync/src/csync_private.h index 764491647..2938ee6d3 100644 --- a/csync/src/csync_private.h +++ b/csync/src/csync_private.h @@ -80,6 +80,7 @@ typedef struct csync_file_stat_s csync_file_stat_t; struct csync_owncloud_ctx_s; // csync_owncloud.c + /** * @brief csync public structure */ @@ -92,6 +93,9 @@ struct csync_s { } callbacks; c_strlist_t *excludes; + // needed for SSL client certificate support + struct csync_client_certs_s *clientCerts; + struct { char *file; sqlite3 *db; |