mirror of
https://github.com/haiwen/seafile.git
synced 2025-01-07 03:17:13 +08:00
[client] Use user accetped self-signed certificates in https connection.
This commit is contained in:
parent
23f661c248
commit
3a1602a3a6
@ -10,9 +10,12 @@
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
#endif
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include <ccnet/ccnet-client.h>
|
||||
|
||||
@ -411,6 +414,99 @@ load_ca_bundle (CURL *curl)
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
static gboolean
|
||||
load_certs (sqlite3_stmt *stmt, void *vdata)
|
||||
{
|
||||
X509_STORE *store = vdata;
|
||||
X509 *saved = NULL;
|
||||
const char *pem_b64;
|
||||
char *pem = NULL;
|
||||
BIO *b = NULL;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
pem_b64 = (const char *)sqlite3_column_text (stmt, 0);
|
||||
|
||||
gsize len;
|
||||
pem = (char *)g_base64_decode (pem_b64, &len);
|
||||
if (!pem) {
|
||||
seaf_warning ("Failed to decode base64.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
b = BIO_new (BIO_s_mem());
|
||||
if (!b) {
|
||||
seaf_warning ("Failed to alloc BIO\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (BIO_write (b, pem, len) != len) {
|
||||
seaf_warning ("Failed to write pem to BIO\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
saved = PEM_read_bio_X509 (b, NULL, 0, NULL);
|
||||
if (!saved) {
|
||||
seaf_warning ("Failed to read PEM from BIO\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
X509_STORE_add_cert (store, saved);
|
||||
|
||||
out:
|
||||
g_free (pem);
|
||||
if (b)
|
||||
BIO_free (b);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
load_certs_from_db (X509_STORE *store)
|
||||
{
|
||||
char *cert_db_path = NULL;
|
||||
sqlite3 *db = NULL;
|
||||
char *sql;
|
||||
int ret = 0;
|
||||
|
||||
cert_db_path = g_build_filename (seaf->seaf_dir, "certs.db", NULL);
|
||||
if (sqlite_open_db (cert_db_path, &db) < 0) {
|
||||
seaf_warning ("Failed to open certs.db\n");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sql = "SELECT cert FROM Certs;";
|
||||
|
||||
if (sqlite_foreach_selected_row (db, sql, load_certs, store) < 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (cert_db_path);
|
||||
if (db)
|
||||
sqlite_close_db (db);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static CURLcode
|
||||
ssl_callback (CURL *curl, void *ssl_ctx, void *userptr)
|
||||
{
|
||||
SSL_CTX *ctx = ssl_ctx;
|
||||
X509_STORE *store;
|
||||
|
||||
store = SSL_CTX_get_cert_store(ctx);
|
||||
|
||||
/* Add all certs stored in db as trusted CA certs.
|
||||
* This workaround has one limitation though. The self-signed certs cannot
|
||||
* contain chain. It must be the CA itself.
|
||||
*/
|
||||
load_certs_from_db (store);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
set_proxy (CURL *curl, gboolean is_https)
|
||||
{
|
||||
@ -532,6 +628,11 @@ http_get (CURL *curl, const char *url, const char *token,
|
||||
load_ca_bundle (curl);
|
||||
#endif
|
||||
|
||||
if (!seaf->disable_verify_certificate) {
|
||||
curl_easy_setopt (curl, CURLOPT_SSL_CTX_FUNCTION, ssl_callback);
|
||||
curl_easy_setopt (curl, CURLOPT_SSL_CTX_DATA, url);
|
||||
}
|
||||
|
||||
int rc = curl_easy_perform (curl);
|
||||
if (rc != 0) {
|
||||
seaf_warning ("libcurl failed to GET %s: %s.\n",
|
||||
@ -655,6 +756,11 @@ http_put (CURL *curl, const char *url, const char *token,
|
||||
load_ca_bundle (curl);
|
||||
#endif
|
||||
|
||||
if (!seaf->disable_verify_certificate) {
|
||||
curl_easy_setopt (curl, CURLOPT_SSL_CTX_FUNCTION, ssl_callback);
|
||||
curl_easy_setopt (curl, CURLOPT_SSL_CTX_DATA, url);
|
||||
}
|
||||
|
||||
int rc = curl_easy_perform (curl);
|
||||
if (rc != 0) {
|
||||
seaf_warning ("libcurl failed to PUT %s: %s.\n",
|
||||
@ -741,6 +847,11 @@ http_post (CURL *curl, const char *url, const char *token,
|
||||
load_ca_bundle (curl);
|
||||
#endif
|
||||
|
||||
if (!seaf->disable_verify_certificate) {
|
||||
curl_easy_setopt (curl, CURLOPT_SSL_CTX_FUNCTION, ssl_callback);
|
||||
curl_easy_setopt (curl, CURLOPT_SSL_CTX_DATA, url);
|
||||
}
|
||||
|
||||
gboolean is_https = (strncasecmp(url, "https", strlen("https")) == 0);
|
||||
set_proxy (curl, is_https);
|
||||
|
||||
|
4
lib/db.c
4
lib/db.c
@ -201,6 +201,7 @@ char *sqlite_get_string (sqlite3 *db, const char *sql)
|
||||
const char *res = NULL;
|
||||
int result;
|
||||
sqlite3_stmt *stmt;
|
||||
char *ret;
|
||||
|
||||
if ( !(stmt = sqlite_query_prepare(db, sql)) )
|
||||
return NULL;
|
||||
@ -208,8 +209,9 @@ char *sqlite_get_string (sqlite3 *db, const char *sql)
|
||||
result = sqlite3_step (stmt);
|
||||
if (result == SQLITE_ROW) {
|
||||
res = (const char *)sqlite3_column_text (stmt, 0);
|
||||
ret = g_strdup(res);
|
||||
sqlite3_finalize (stmt);
|
||||
return g_strdup(res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (result == SQLITE_ERROR) {
|
||||
|
Loading…
Reference in New Issue
Block a user