mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-08-01 23:33:42 +00:00
Add ca_path and skip_verify option for mysql (#610)
* Add ca_path and skip_verify option for mysql * Add comment --------- Co-authored-by: 杨赫然 <heran.yang@seafile.com>
This commit is contained in:
parent
b5993456e3
commit
b558426da8
@ -68,6 +68,8 @@ mysql_db_new (const char *host,
|
|||||||
const char *db_name,
|
const char *db_name,
|
||||||
const char *unix_socket,
|
const char *unix_socket,
|
||||||
gboolean use_ssl,
|
gboolean use_ssl,
|
||||||
|
gboolean skip_verify,
|
||||||
|
const char *ca_path,
|
||||||
const char *charset);
|
const char *charset);
|
||||||
static DBConnection *
|
static DBConnection *
|
||||||
mysql_db_get_connection (SeafDB *db);
|
mysql_db_get_connection (SeafDB *db);
|
||||||
@ -234,12 +236,14 @@ seaf_db_new_mysql (const char *host,
|
|||||||
const char *db_name,
|
const char *db_name,
|
||||||
const char *unix_socket,
|
const char *unix_socket,
|
||||||
gboolean use_ssl,
|
gboolean use_ssl,
|
||||||
|
gboolean skip_verify,
|
||||||
|
const char *ca_path,
|
||||||
const char *charset,
|
const char *charset,
|
||||||
int max_connections)
|
int max_connections)
|
||||||
{
|
{
|
||||||
SeafDB *db;
|
SeafDB *db;
|
||||||
|
|
||||||
db = mysql_db_new (host, port, user, passwd, db_name, unix_socket, use_ssl, charset);
|
db = mysql_db_new (host, port, user, passwd, db_name, unix_socket, use_ssl, skip_verify, ca_path, charset);
|
||||||
if (!db)
|
if (!db)
|
||||||
return NULL;
|
return NULL;
|
||||||
db->type = SEAF_DB_TYPE_MYSQL;
|
db->type = SEAF_DB_TYPE_MYSQL;
|
||||||
@ -751,6 +755,8 @@ typedef struct MySQLDB {
|
|||||||
char *db_name;
|
char *db_name;
|
||||||
char *unix_socket;
|
char *unix_socket;
|
||||||
gboolean use_ssl;
|
gboolean use_ssl;
|
||||||
|
gboolean skip_verify;
|
||||||
|
char *ca_path;
|
||||||
char *charset;
|
char *charset;
|
||||||
} MySQLDB;
|
} MySQLDB;
|
||||||
|
|
||||||
@ -775,6 +781,8 @@ mysql_db_new (const char *host,
|
|||||||
const char *db_name,
|
const char *db_name,
|
||||||
const char *unix_socket,
|
const char *unix_socket,
|
||||||
gboolean use_ssl,
|
gboolean use_ssl,
|
||||||
|
gboolean skip_verify,
|
||||||
|
const char *ca_path,
|
||||||
const char *charset)
|
const char *charset)
|
||||||
{
|
{
|
||||||
MySQLDB *db = g_new0 (MySQLDB, 1);
|
MySQLDB *db = g_new0 (MySQLDB, 1);
|
||||||
@ -786,6 +794,8 @@ mysql_db_new (const char *host,
|
|||||||
db->db_name = g_strdup(db_name);
|
db->db_name = g_strdup(db_name);
|
||||||
db->unix_socket = g_strdup(unix_socket);
|
db->unix_socket = g_strdup(unix_socket);
|
||||||
db->use_ssl = use_ssl;
|
db->use_ssl = use_ssl;
|
||||||
|
db->skip_verify = skip_verify;
|
||||||
|
db->ca_path = g_strdup(ca_path);
|
||||||
db->charset = g_strdup(charset);
|
db->charset = g_strdup(charset);
|
||||||
|
|
||||||
mysql_library_init (0, NULL, NULL);
|
mysql_library_init (0, NULL, NULL);
|
||||||
@ -803,6 +813,7 @@ mysql_db_get_connection (SeafDB *vdb)
|
|||||||
int read_write_timeout = 5;
|
int read_write_timeout = 5;
|
||||||
MYSQL *db_conn;
|
MYSQL *db_conn;
|
||||||
MySQLDBConnection *conn = NULL;
|
MySQLDBConnection *conn = NULL;
|
||||||
|
int ssl_mode;
|
||||||
|
|
||||||
db_conn = mysql_init (NULL);
|
db_conn = mysql_init (NULL);
|
||||||
if (!db_conn) {
|
if (!db_conn) {
|
||||||
@ -810,8 +821,18 @@ mysql_db_get_connection (SeafDB *vdb)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (db->use_ssl)
|
if (db->use_ssl && !db->skip_verify) {
|
||||||
mysql_ssl_set(db_conn, 0,0,0,0,0);
|
// Set ssl_mode to SSL_MODE_VERIFY_IDENTITY to verify server cert.
|
||||||
|
// When ssl_mode is set to SSL_MODE_VERIFY_IDENTITY, MYSQL_OPT_SSL_CA is required to verify server cert.
|
||||||
|
// Refer to: https://dev.mysql.com/doc/c-api/5.7/en/mysql-options.html
|
||||||
|
ssl_mode = SSL_MODE_VERIFY_IDENTITY;
|
||||||
|
mysql_options(db_conn, MYSQL_OPT_SSL_MODE, &ssl_mode);
|
||||||
|
mysql_options(db_conn, MYSQL_OPT_SSL_CA, db->ca_path);
|
||||||
|
} else if (db->use_ssl && db->skip_verify) {
|
||||||
|
// Set ssl_mode to SSL_MODE_PREFERRED to skip verify server cert.
|
||||||
|
ssl_mode = SSL_MODE_PREFERRED;
|
||||||
|
mysql_options(db_conn, MYSQL_OPT_SSL_MODE, &ssl_mode);
|
||||||
|
}
|
||||||
|
|
||||||
if (db->charset)
|
if (db->charset)
|
||||||
mysql_options(db_conn, MYSQL_SET_CHARSET_NAME, db->charset);
|
mysql_options(db_conn, MYSQL_SET_CHARSET_NAME, db->charset);
|
||||||
|
@ -25,6 +25,8 @@ seaf_db_new_mysql (const char *host,
|
|||||||
const char *db,
|
const char *db,
|
||||||
const char *unix_socket,
|
const char *unix_socket,
|
||||||
gboolean use_ssl,
|
gboolean use_ssl,
|
||||||
|
gboolean skip_verify,
|
||||||
|
const char *ca_path,
|
||||||
const char *charset,
|
const char *charset,
|
||||||
int max_connections);
|
int max_connections);
|
||||||
|
|
||||||
|
@ -62,6 +62,8 @@ mysql_db_start (SeafileSession *session)
|
|||||||
char *host, *user, *passwd, *db, *unix_socket, *charset;
|
char *host, *user, *passwd, *db, *unix_socket, *charset;
|
||||||
int port;
|
int port;
|
||||||
gboolean use_ssl = FALSE;
|
gboolean use_ssl = FALSE;
|
||||||
|
gboolean skip_verify = FALSE;
|
||||||
|
char *ca_path = NULL;
|
||||||
int max_connections = 0;
|
int max_connections = 0;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
@ -100,6 +102,18 @@ mysql_db_start (SeafileSession *session)
|
|||||||
use_ssl = g_key_file_get_boolean (session->config,
|
use_ssl = g_key_file_get_boolean (session->config,
|
||||||
"database", "use_ssl", NULL);
|
"database", "use_ssl", NULL);
|
||||||
|
|
||||||
|
skip_verify = g_key_file_get_boolean (session->config,
|
||||||
|
"database", "skip_verify", NULL);
|
||||||
|
|
||||||
|
if (use_ssl && !skip_verify) {
|
||||||
|
ca_path = seaf_key_file_get_string (session->config,
|
||||||
|
"database", "ca_path", NULL);
|
||||||
|
if (!ca_path) {
|
||||||
|
seaf_warning ("ca_path is required if use ssl and don't skip verify.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
charset = seaf_key_file_get_string (session->config,
|
charset = seaf_key_file_get_string (session->config,
|
||||||
"database", "connection_charset", NULL);
|
"database", "connection_charset", NULL);
|
||||||
|
|
||||||
@ -113,7 +127,7 @@ mysql_db_start (SeafileSession *session)
|
|||||||
max_connections = DEFAULT_MAX_CONNECTIONS;
|
max_connections = DEFAULT_MAX_CONNECTIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, charset, max_connections);
|
session->db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, skip_verify, ca_path, charset, max_connections);
|
||||||
if (!session->db) {
|
if (!session->db) {
|
||||||
seaf_warning ("Failed to start mysql db.\n");
|
seaf_warning ("Failed to start mysql db.\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -252,6 +266,8 @@ ccnet_init_mysql_database (SeafileSession *session)
|
|||||||
char *host, *user, *passwd, *db, *unix_socket, *charset;
|
char *host, *user, *passwd, *db, *unix_socket, *charset;
|
||||||
int port;
|
int port;
|
||||||
gboolean use_ssl = FALSE;
|
gboolean use_ssl = FALSE;
|
||||||
|
gboolean skip_verify = FALSE;
|
||||||
|
char *ca_path = NULL;
|
||||||
int max_connections = 0;
|
int max_connections = 0;
|
||||||
|
|
||||||
host = ccnet_key_file_get_string (session->ccnet_config, "Database", "HOST");
|
host = ccnet_key_file_get_string (session->ccnet_config, "Database", "HOST");
|
||||||
@ -286,6 +302,15 @@ ccnet_init_mysql_database (SeafileSession *session)
|
|||||||
unix_socket = ccnet_key_file_get_string (session->ccnet_config,
|
unix_socket = ccnet_key_file_get_string (session->ccnet_config,
|
||||||
"Database", "UNIX_SOCKET");
|
"Database", "UNIX_SOCKET");
|
||||||
use_ssl = g_key_file_get_boolean (session->ccnet_config, "Database", "USE_SSL", NULL);
|
use_ssl = g_key_file_get_boolean (session->ccnet_config, "Database", "USE_SSL", NULL);
|
||||||
|
skip_verify = g_key_file_get_boolean (session->ccnet_config, "Database", "SKIP_VERIFY", NULL);
|
||||||
|
if (use_ssl && !skip_verify) {
|
||||||
|
ca_path = seaf_key_file_get_string (session->ccnet_config,
|
||||||
|
"Database", "CA_PATH", NULL);
|
||||||
|
if (!ca_path) {
|
||||||
|
seaf_warning ("ca_path is required if use ssl and don't skip verify.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
charset = ccnet_key_file_get_string (session->ccnet_config,
|
charset = ccnet_key_file_get_string (session->ccnet_config,
|
||||||
"Database", "CONNECTION_CHARSET");
|
"Database", "CONNECTION_CHARSET");
|
||||||
@ -298,7 +323,7 @@ ccnet_init_mysql_database (SeafileSession *session)
|
|||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
session->ccnet_db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, charset, max_connections);
|
session->ccnet_db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, skip_verify, ca_path, charset, max_connections);
|
||||||
if (!session->ccnet_db) {
|
if (!session->ccnet_db) {
|
||||||
seaf_warning ("Failed to open ccnet database.\n");
|
seaf_warning ("Failed to open ccnet database.\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2,10 +2,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@ -14,7 +17,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
"github.com/go-sql-driver/mysql"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/haiwen/seafile-server/fileserver/blockmgr"
|
"github.com/haiwen/seafile-server/fileserver/blockmgr"
|
||||||
"github.com/haiwen/seafile-server/fileserver/commitmgr"
|
"github.com/haiwen/seafile-server/fileserver/commitmgr"
|
||||||
@ -120,8 +123,15 @@ func loadCcnetDB() {
|
|||||||
}
|
}
|
||||||
var dsn string
|
var dsn string
|
||||||
if unixSocket == "" {
|
if unixSocket == "" {
|
||||||
if skipVerify {
|
if useTLS && skipVerify {
|
||||||
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify", user, password, host, port, dbName)
|
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify", user, password, host, port, dbName)
|
||||||
|
} else if useTLS && !skipVerify {
|
||||||
|
capath := ""
|
||||||
|
if key, err = section.GetKey("CA_PATH"); err == nil {
|
||||||
|
capath = key.String()
|
||||||
|
}
|
||||||
|
registerCA(capath)
|
||||||
|
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=custom", user, password, host, port, dbName)
|
||||||
} else {
|
} else {
|
||||||
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t", user, password, host, port, dbName, useTLS)
|
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t", user, password, host, port, dbName, useTLS)
|
||||||
}
|
}
|
||||||
@ -143,6 +153,21 @@ func loadCcnetDB() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// registerCA registers CA to verify server cert.
|
||||||
|
func registerCA(capath string) {
|
||||||
|
rootCertPool := x509.NewCertPool()
|
||||||
|
pem, err := ioutil.ReadFile(capath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
|
||||||
|
log.Fatal("Failed to append PEM.")
|
||||||
|
}
|
||||||
|
mysql.RegisterTLSConfig("custom", &tls.Config{
|
||||||
|
RootCAs: rootCertPool,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func loadSeafileDB() {
|
func loadSeafileDB() {
|
||||||
seafileConfPath := filepath.Join(centralDir, "seafile.conf")
|
seafileConfPath := filepath.Join(centralDir, "seafile.conf")
|
||||||
|
|
||||||
@ -197,8 +222,15 @@ func loadSeafileDB() {
|
|||||||
|
|
||||||
var dsn string
|
var dsn string
|
||||||
if unixSocket == "" {
|
if unixSocket == "" {
|
||||||
if skipVerify {
|
if useTLS && skipVerify {
|
||||||
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify", user, password, host, port, dbName)
|
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify", user, password, host, port, dbName)
|
||||||
|
} else if useTLS && !skipVerify {
|
||||||
|
capath := ""
|
||||||
|
if key, err = section.GetKey("ca_path"); err == nil {
|
||||||
|
capath = key.String()
|
||||||
|
}
|
||||||
|
registerCA(capath)
|
||||||
|
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=custom", user, password, host, port, dbName)
|
||||||
} else {
|
} else {
|
||||||
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t", user, password, host, port, dbName, useTLS)
|
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t", user, password, host, port, dbName, useTLS)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user