2 * QEMU migration TLS support
4 * Copyright (c) 2015 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
23 #include "migration.h"
26 #include "crypto/tlscreds.h"
27 #include "qemu/error-report.h"
28 #include "qapi/error.h"
31 static QCryptoTLSCreds
*
32 migration_tls_get_creds(QCryptoTLSCredsEndpoint endpoint
, Error
**errp
)
35 const char *tls_creds
= migrate_tls_creds();
38 creds
= object_resolve_path_component(object_get_objects_root(), tls_creds
);
40 error_setg(errp
, "No TLS credentials with id '%s'", tls_creds
);
43 ret
= (QCryptoTLSCreds
*)object_dynamic_cast(
44 creds
, TYPE_QCRYPTO_TLS_CREDS
);
46 error_setg(errp
, "Object with id '%s' is not TLS credentials",
50 if (!qcrypto_tls_creds_check_endpoint(ret
, endpoint
, errp
)) {
58 static void migration_tls_incoming_handshake(QIOTask
*task
,
61 QIOChannel
*ioc
= QIO_CHANNEL(qio_task_get_source(task
));
64 if (qio_task_propagate_error(task
, &err
)) {
65 trace_migration_tls_incoming_handshake_error(error_get_pretty(err
));
66 error_report_err(err
);
68 trace_migration_tls_incoming_handshake_complete();
69 migration_channel_process_incoming(ioc
);
71 object_unref(OBJECT(ioc
));
74 void migration_tls_channel_process_incoming(MigrationState
*s
,
78 QCryptoTLSCreds
*creds
;
81 creds
= migration_tls_get_creds(QCRYPTO_TLS_CREDS_ENDPOINT_SERVER
, errp
);
86 tioc
= qio_channel_tls_new_server(ioc
, creds
, migrate_tls_authz(), errp
);
91 trace_migration_tls_incoming_handshake_start();
92 qio_channel_set_name(QIO_CHANNEL(tioc
), "migration-tls-incoming");
93 qio_channel_tls_handshake(tioc
,
94 migration_tls_incoming_handshake
,
101 static void migration_tls_outgoing_handshake(QIOTask
*task
,
104 MigrationState
*s
= opaque
;
105 QIOChannel
*ioc
= QIO_CHANNEL(qio_task_get_source(task
));
108 if (qio_task_propagate_error(task
, &err
)) {
109 trace_migration_tls_outgoing_handshake_error(error_get_pretty(err
));
111 trace_migration_tls_outgoing_handshake_complete();
113 migration_channel_connect(s
, ioc
, NULL
, err
);
114 object_unref(OBJECT(ioc
));
117 QIOChannelTLS
*migration_tls_client_create(QIOChannel
*ioc
,
118 const char *hostname
,
121 QCryptoTLSCreds
*creds
;
123 creds
= migration_tls_get_creds(QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT
, errp
);
128 const char *tls_hostname
= migrate_tls_hostname();
129 if (tls_hostname
&& *tls_hostname
) {
130 hostname
= tls_hostname
;
133 return qio_channel_tls_new_client(ioc
, creds
, hostname
, errp
);
136 void migration_tls_channel_connect(MigrationState
*s
,
138 const char *hostname
,
143 tioc
= migration_tls_client_create(ioc
, hostname
, errp
);
148 /* Save hostname into MigrationState for handshake */
149 s
->hostname
= g_strdup(hostname
);
150 trace_migration_tls_outgoing_handshake_start(hostname
);
151 qio_channel_set_name(QIO_CHANNEL(tioc
), "migration-tls-outgoing");
152 qio_channel_tls_handshake(tioc
,
153 migration_tls_outgoing_handshake
,
159 bool migrate_channel_requires_tls_upgrade(QIOChannel
*ioc
)
161 if (!migrate_tls()) {
165 return !object_dynamic_cast(OBJECT(ioc
), TYPE_QIO_CHANNEL_TLS
);