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