1 /* 2 * QEMU I/O channels TLS driver 3 * 4 * Copyright (c) 2015 Red Hat, Inc. 5 * 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. 10 * 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. 15 * 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/>. 18 * 19 */ 20 21 #include "qemu/osdep.h" 22 #include "qapi/error.h" 23 #include "qemu/module.h" 24 #include "io/channel-tls.h" 25 #include "trace.h" 26 #include "qemu/atomic.h" 27 28 29 static ssize_t qio_channel_tls_write_handler(const char *buf, 30 size_t len, 31 void *opaque) 32 { 33 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(opaque); 34 ssize_t ret; 35 36 ret = qio_channel_write(tioc->master, buf, len, NULL); 37 if (ret == QIO_CHANNEL_ERR_BLOCK) { 38 errno = EAGAIN; 39 return -1; 40 } else if (ret < 0) { 41 errno = EIO; 42 return -1; 43 } 44 return ret; 45 } 46 47 static ssize_t qio_channel_tls_read_handler(char *buf, 48 size_t len, 49 void *opaque) 50 { 51 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(opaque); 52 ssize_t ret; 53 54 ret = qio_channel_read(tioc->master, buf, len, NULL); 55 if (ret == QIO_CHANNEL_ERR_BLOCK) { 56 errno = EAGAIN; 57 return -1; 58 } else if (ret < 0) { 59 errno = EIO; 60 return -1; 61 } 62 return ret; 63 } 64 65 66 QIOChannelTLS * 67 qio_channel_tls_new_server(QIOChannel *master, 68 QCryptoTLSCreds *creds, 69 const char *aclname, 70 Error **errp) 71 { 72 QIOChannelTLS *tioc; 73 QIOChannel *ioc; 74 75 tioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS)); 76 ioc = QIO_CHANNEL(tioc); 77 78 tioc->master = master; 79 ioc->follow_coroutine_ctx = master->follow_coroutine_ctx; 80 if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { 81 qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); 82 } 83 object_ref(OBJECT(master)); 84 85 tioc->session = qcrypto_tls_session_new( 86 creds, 87 NULL, 88 aclname, 89 QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, 90 errp); 91 if (!tioc->session) { 92 goto error; 93 } 94 95 qcrypto_tls_session_set_callbacks( 96 tioc->session, 97 qio_channel_tls_write_handler, 98 qio_channel_tls_read_handler, 99 tioc); 100 101 trace_qio_channel_tls_new_server(tioc, master, creds, aclname); 102 return tioc; 103 104 error: 105 object_unref(OBJECT(tioc)); 106 return NULL; 107 } 108 109 QIOChannelTLS * 110 qio_channel_tls_new_client(QIOChannel *master, 111 QCryptoTLSCreds *creds, 112 const char *hostname, 113 Error **errp) 114 { 115 QIOChannelTLS *tioc; 116 QIOChannel *ioc; 117 118 tioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS)); 119 ioc = QIO_CHANNEL(tioc); 120 121 tioc->master = master; 122 ioc->follow_coroutine_ctx = master->follow_coroutine_ctx; 123 if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { 124 qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); 125 } 126 object_ref(OBJECT(master)); 127 128 tioc->session = qcrypto_tls_session_new( 129 creds, 130 hostname, 131 NULL, 132 QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT, 133 errp); 134 if (!tioc->session) { 135 goto error; 136 } 137 138 qcrypto_tls_session_set_callbacks( 139 tioc->session, 140 qio_channel_tls_write_handler, 141 qio_channel_tls_read_handler, 142 tioc); 143 144 trace_qio_channel_tls_new_client(tioc, master, creds, hostname); 145 return tioc; 146 147 error: 148 object_unref(OBJECT(tioc)); 149 return NULL; 150 } 151 152 struct QIOChannelTLSData { 153 QIOTask *task; 154 GMainContext *context; 155 }; 156 typedef struct QIOChannelTLSData QIOChannelTLSData; 157 158 static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc, 159 GIOCondition condition, 160 gpointer user_data); 161 162 static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc, 163 QIOTask *task, 164 GMainContext *context) 165 { 166 Error *err = NULL; 167 QCryptoTLSSessionHandshakeStatus status; 168 169 if (qcrypto_tls_session_handshake(ioc->session, &err) < 0) { 170 trace_qio_channel_tls_handshake_fail(ioc); 171 qio_task_set_error(task, err); 172 qio_task_complete(task); 173 return; 174 } 175 176 status = qcrypto_tls_session_get_handshake_status(ioc->session); 177 if (status == QCRYPTO_TLS_HANDSHAKE_COMPLETE) { 178 trace_qio_channel_tls_handshake_complete(ioc); 179 if (qcrypto_tls_session_check_credentials(ioc->session, 180 &err) < 0) { 181 trace_qio_channel_tls_credentials_deny(ioc); 182 qio_task_set_error(task, err); 183 } else { 184 trace_qio_channel_tls_credentials_allow(ioc); 185 } 186 qio_task_complete(task); 187 } else { 188 GIOCondition condition; 189 QIOChannelTLSData *data = g_new0(typeof(*data), 1); 190 191 data->task = task; 192 data->context = context; 193 194 if (context) { 195 g_main_context_ref(context); 196 } 197 198 if (status == QCRYPTO_TLS_HANDSHAKE_SENDING) { 199 condition = G_IO_OUT; 200 } else { 201 condition = G_IO_IN; 202 } 203 204 trace_qio_channel_tls_handshake_pending(ioc, status); 205 ioc->hs_ioc_tag = 206 qio_channel_add_watch_full(ioc->master, 207 condition, 208 qio_channel_tls_handshake_io, 209 data, 210 NULL, 211 context); 212 } 213 } 214 215 216 static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc, 217 GIOCondition condition, 218 gpointer user_data) 219 { 220 QIOChannelTLSData *data = user_data; 221 QIOTask *task = data->task; 222 GMainContext *context = data->context; 223 QIOChannelTLS *tioc = QIO_CHANNEL_TLS( 224 qio_task_get_source(task)); 225 226 tioc->hs_ioc_tag = 0; 227 g_free(data); 228 qio_channel_tls_handshake_task(tioc, task, context); 229 230 if (context) { 231 g_main_context_unref(context); 232 } 233 234 return FALSE; 235 } 236 237 void qio_channel_tls_handshake(QIOChannelTLS *ioc, 238 QIOTaskFunc func, 239 gpointer opaque, 240 GDestroyNotify destroy, 241 GMainContext *context) 242 { 243 QIOTask *task; 244 245 task = qio_task_new(OBJECT(ioc), 246 func, opaque, destroy); 247 248 trace_qio_channel_tls_handshake_start(ioc); 249 qio_channel_tls_handshake_task(ioc, task, context); 250 } 251 252 253 static void qio_channel_tls_init(Object *obj G_GNUC_UNUSED) 254 { 255 } 256 257 258 static void qio_channel_tls_finalize(Object *obj) 259 { 260 QIOChannelTLS *ioc = QIO_CHANNEL_TLS(obj); 261 262 object_unref(OBJECT(ioc->master)); 263 qcrypto_tls_session_free(ioc->session); 264 } 265 266 267 static ssize_t qio_channel_tls_readv(QIOChannel *ioc, 268 const struct iovec *iov, 269 size_t niov, 270 int **fds, 271 size_t *nfds, 272 int flags, 273 Error **errp) 274 { 275 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 276 size_t i; 277 ssize_t got = 0; 278 279 for (i = 0 ; i < niov ; i++) { 280 ssize_t ret = qcrypto_tls_session_read(tioc->session, 281 iov[i].iov_base, 282 iov[i].iov_len); 283 if (ret < 0) { 284 if (errno == EAGAIN) { 285 if (got) { 286 return got; 287 } else { 288 return QIO_CHANNEL_ERR_BLOCK; 289 } 290 } else if (errno == ECONNABORTED && 291 (qatomic_load_acquire(&tioc->shutdown) & 292 QIO_CHANNEL_SHUTDOWN_READ)) { 293 return 0; 294 } 295 296 error_setg_errno(errp, errno, 297 "Cannot read from TLS channel"); 298 return -1; 299 } 300 got += ret; 301 if (ret < iov[i].iov_len) { 302 break; 303 } 304 } 305 return got; 306 } 307 308 309 static ssize_t qio_channel_tls_writev(QIOChannel *ioc, 310 const struct iovec *iov, 311 size_t niov, 312 int *fds, 313 size_t nfds, 314 int flags, 315 Error **errp) 316 { 317 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 318 size_t i; 319 ssize_t done = 0; 320 321 for (i = 0 ; i < niov ; i++) { 322 ssize_t ret = qcrypto_tls_session_write(tioc->session, 323 iov[i].iov_base, 324 iov[i].iov_len); 325 if (ret <= 0) { 326 if (errno == EAGAIN) { 327 if (done) { 328 return done; 329 } else { 330 return QIO_CHANNEL_ERR_BLOCK; 331 } 332 } 333 334 error_setg_errno(errp, errno, 335 "Cannot write to TLS channel"); 336 return -1; 337 } 338 done += ret; 339 if (ret < iov[i].iov_len) { 340 break; 341 } 342 } 343 return done; 344 } 345 346 static int qio_channel_tls_set_blocking(QIOChannel *ioc, 347 bool enabled, 348 Error **errp) 349 { 350 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 351 352 return qio_channel_set_blocking(tioc->master, enabled, errp); 353 } 354 355 static void qio_channel_tls_set_delay(QIOChannel *ioc, 356 bool enabled) 357 { 358 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 359 360 qio_channel_set_delay(tioc->master, enabled); 361 } 362 363 static void qio_channel_tls_set_cork(QIOChannel *ioc, 364 bool enabled) 365 { 366 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 367 368 qio_channel_set_cork(tioc->master, enabled); 369 } 370 371 static int qio_channel_tls_shutdown(QIOChannel *ioc, 372 QIOChannelShutdown how, 373 Error **errp) 374 { 375 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 376 377 qatomic_or(&tioc->shutdown, how); 378 379 return qio_channel_shutdown(tioc->master, how, errp); 380 } 381 382 static int qio_channel_tls_close(QIOChannel *ioc, 383 Error **errp) 384 { 385 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 386 387 if (tioc->hs_ioc_tag) { 388 trace_qio_channel_tls_handshake_cancel(ioc); 389 g_clear_handle_id(&tioc->hs_ioc_tag, g_source_remove); 390 } 391 392 return qio_channel_close(tioc->master, errp); 393 } 394 395 static void qio_channel_tls_set_aio_fd_handler(QIOChannel *ioc, 396 AioContext *read_ctx, 397 IOHandler *io_read, 398 AioContext *write_ctx, 399 IOHandler *io_write, 400 void *opaque) 401 { 402 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 403 404 qio_channel_set_aio_fd_handler(tioc->master, read_ctx, io_read, 405 write_ctx, io_write, opaque); 406 } 407 408 typedef struct QIOChannelTLSSource QIOChannelTLSSource; 409 struct QIOChannelTLSSource { 410 GSource parent; 411 QIOChannelTLS *tioc; 412 }; 413 414 static gboolean 415 qio_channel_tls_source_check(GSource *source) 416 { 417 QIOChannelTLSSource *tsource = (QIOChannelTLSSource *)source; 418 419 return qcrypto_tls_session_check_pending(tsource->tioc->session) > 0; 420 } 421 422 static gboolean 423 qio_channel_tls_source_prepare(GSource *source, gint *timeout) 424 { 425 *timeout = -1; 426 return qio_channel_tls_source_check(source); 427 } 428 429 static gboolean 430 qio_channel_tls_source_dispatch(GSource *source, GSourceFunc callback, 431 gpointer user_data) 432 { 433 return G_SOURCE_CONTINUE; 434 } 435 436 static void 437 qio_channel_tls_source_finalize(GSource *source) 438 { 439 QIOChannelTLSSource *tsource = (QIOChannelTLSSource *)source; 440 441 object_unref(OBJECT(tsource->tioc)); 442 } 443 444 static GSourceFuncs qio_channel_tls_source_funcs = { 445 qio_channel_tls_source_prepare, 446 qio_channel_tls_source_check, 447 qio_channel_tls_source_dispatch, 448 qio_channel_tls_source_finalize 449 }; 450 451 static void 452 qio_channel_tls_read_watch(QIOChannelTLS *tioc, GSource *source) 453 { 454 GSource *child; 455 QIOChannelTLSSource *tlssource; 456 457 child = g_source_new(&qio_channel_tls_source_funcs, 458 sizeof(QIOChannelTLSSource)); 459 tlssource = (QIOChannelTLSSource *)child; 460 461 tlssource->tioc = tioc; 462 object_ref(OBJECT(tioc)); 463 464 g_source_add_child_source(source, child); 465 g_source_unref(child); 466 } 467 468 static GSource *qio_channel_tls_create_watch(QIOChannel *ioc, 469 GIOCondition condition) 470 { 471 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 472 GSource *source = qio_channel_create_watch(tioc->master, condition); 473 474 if (condition & G_IO_IN) { 475 qio_channel_tls_read_watch(tioc, source); 476 } 477 478 return source; 479 } 480 481 QCryptoTLSSession * 482 qio_channel_tls_get_session(QIOChannelTLS *ioc) 483 { 484 return ioc->session; 485 } 486 487 static void qio_channel_tls_class_init(ObjectClass *klass, 488 void *class_data G_GNUC_UNUSED) 489 { 490 QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass); 491 492 ioc_klass->io_writev = qio_channel_tls_writev; 493 ioc_klass->io_readv = qio_channel_tls_readv; 494 ioc_klass->io_set_blocking = qio_channel_tls_set_blocking; 495 ioc_klass->io_set_delay = qio_channel_tls_set_delay; 496 ioc_klass->io_set_cork = qio_channel_tls_set_cork; 497 ioc_klass->io_close = qio_channel_tls_close; 498 ioc_klass->io_shutdown = qio_channel_tls_shutdown; 499 ioc_klass->io_create_watch = qio_channel_tls_create_watch; 500 ioc_klass->io_set_aio_fd_handler = qio_channel_tls_set_aio_fd_handler; 501 } 502 503 static const TypeInfo qio_channel_tls_info = { 504 .parent = TYPE_QIO_CHANNEL, 505 .name = TYPE_QIO_CHANNEL_TLS, 506 .instance_size = sizeof(QIOChannelTLS), 507 .instance_init = qio_channel_tls_init, 508 .instance_finalize = qio_channel_tls_finalize, 509 .class_init = qio_channel_tls_class_init, 510 }; 511 512 static void qio_channel_tls_register_types(void) 513 { 514 type_register_static(&qio_channel_tls_info); 515 } 516 517 type_init(qio_channel_tls_register_types); 518