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