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 qio_channel_add_watch_full(ioc->master, 202 condition, 203 qio_channel_tls_handshake_io, 204 data, 205 NULL, 206 context); 207 } 208 } 209 210 211 static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc, 212 GIOCondition condition, 213 gpointer user_data) 214 { 215 QIOChannelTLSData *data = user_data; 216 QIOTask *task = data->task; 217 GMainContext *context = data->context; 218 QIOChannelTLS *tioc = QIO_CHANNEL_TLS( 219 qio_task_get_source(task)); 220 221 g_free(data); 222 qio_channel_tls_handshake_task(tioc, task, context); 223 224 if (context) { 225 g_main_context_unref(context); 226 } 227 228 return FALSE; 229 } 230 231 void qio_channel_tls_handshake(QIOChannelTLS *ioc, 232 QIOTaskFunc func, 233 gpointer opaque, 234 GDestroyNotify destroy, 235 GMainContext *context) 236 { 237 QIOTask *task; 238 239 task = qio_task_new(OBJECT(ioc), 240 func, opaque, destroy); 241 242 trace_qio_channel_tls_handshake_start(ioc); 243 qio_channel_tls_handshake_task(ioc, task, context); 244 } 245 246 247 static void qio_channel_tls_init(Object *obj G_GNUC_UNUSED) 248 { 249 } 250 251 252 static void qio_channel_tls_finalize(Object *obj) 253 { 254 QIOChannelTLS *ioc = QIO_CHANNEL_TLS(obj); 255 256 object_unref(OBJECT(ioc->master)); 257 qcrypto_tls_session_free(ioc->session); 258 } 259 260 261 static ssize_t qio_channel_tls_readv(QIOChannel *ioc, 262 const struct iovec *iov, 263 size_t niov, 264 int **fds, 265 size_t *nfds, 266 int flags, 267 Error **errp) 268 { 269 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 270 size_t i; 271 ssize_t got = 0; 272 273 for (i = 0 ; i < niov ; i++) { 274 ssize_t ret = qcrypto_tls_session_read(tioc->session, 275 iov[i].iov_base, 276 iov[i].iov_len); 277 if (ret < 0) { 278 if (errno == EAGAIN) { 279 if (got) { 280 return got; 281 } else { 282 return QIO_CHANNEL_ERR_BLOCK; 283 } 284 } else if (errno == ECONNABORTED && 285 (qatomic_load_acquire(&tioc->shutdown) & 286 QIO_CHANNEL_SHUTDOWN_READ)) { 287 return 0; 288 } 289 290 error_setg_errno(errp, errno, 291 "Cannot read from TLS channel"); 292 return -1; 293 } 294 got += ret; 295 if (ret < iov[i].iov_len) { 296 break; 297 } 298 } 299 return got; 300 } 301 302 303 static ssize_t qio_channel_tls_writev(QIOChannel *ioc, 304 const struct iovec *iov, 305 size_t niov, 306 int *fds, 307 size_t nfds, 308 int flags, 309 Error **errp) 310 { 311 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 312 size_t i; 313 ssize_t done = 0; 314 315 for (i = 0 ; i < niov ; i++) { 316 ssize_t ret = qcrypto_tls_session_write(tioc->session, 317 iov[i].iov_base, 318 iov[i].iov_len); 319 if (ret <= 0) { 320 if (errno == EAGAIN) { 321 if (done) { 322 return done; 323 } else { 324 return QIO_CHANNEL_ERR_BLOCK; 325 } 326 } 327 328 error_setg_errno(errp, errno, 329 "Cannot write to TLS channel"); 330 return -1; 331 } 332 done += ret; 333 if (ret < iov[i].iov_len) { 334 break; 335 } 336 } 337 return done; 338 } 339 340 static int qio_channel_tls_set_blocking(QIOChannel *ioc, 341 bool enabled, 342 Error **errp) 343 { 344 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 345 346 return qio_channel_set_blocking(tioc->master, enabled, errp); 347 } 348 349 static void qio_channel_tls_set_delay(QIOChannel *ioc, 350 bool enabled) 351 { 352 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 353 354 qio_channel_set_delay(tioc->master, enabled); 355 } 356 357 static void qio_channel_tls_set_cork(QIOChannel *ioc, 358 bool enabled) 359 { 360 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 361 362 qio_channel_set_cork(tioc->master, enabled); 363 } 364 365 static int qio_channel_tls_shutdown(QIOChannel *ioc, 366 QIOChannelShutdown how, 367 Error **errp) 368 { 369 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 370 371 qatomic_or(&tioc->shutdown, how); 372 373 return qio_channel_shutdown(tioc->master, how, errp); 374 } 375 376 static int qio_channel_tls_close(QIOChannel *ioc, 377 Error **errp) 378 { 379 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 380 381 return qio_channel_close(tioc->master, errp); 382 } 383 384 static void qio_channel_tls_set_aio_fd_handler(QIOChannel *ioc, 385 AioContext *ctx, 386 IOHandler *io_read, 387 IOHandler *io_write, 388 void *opaque) 389 { 390 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 391 392 qio_channel_set_aio_fd_handler(tioc->master, ctx, io_read, io_write, opaque); 393 } 394 395 typedef struct QIOChannelTLSSource QIOChannelTLSSource; 396 struct QIOChannelTLSSource { 397 GSource parent; 398 QIOChannelTLS *tioc; 399 }; 400 401 static gboolean 402 qio_channel_tls_source_check(GSource *source) 403 { 404 QIOChannelTLSSource *tsource = (QIOChannelTLSSource *)source; 405 406 return qcrypto_tls_session_check_pending(tsource->tioc->session) > 0; 407 } 408 409 static gboolean 410 qio_channel_tls_source_prepare(GSource *source, gint *timeout) 411 { 412 *timeout = -1; 413 return qio_channel_tls_source_check(source); 414 } 415 416 static gboolean 417 qio_channel_tls_source_dispatch(GSource *source, GSourceFunc callback, 418 gpointer user_data) 419 { 420 return G_SOURCE_CONTINUE; 421 } 422 423 static void 424 qio_channel_tls_source_finalize(GSource *source) 425 { 426 QIOChannelTLSSource *tsource = (QIOChannelTLSSource *)source; 427 428 object_unref(OBJECT(tsource->tioc)); 429 } 430 431 static GSourceFuncs qio_channel_tls_source_funcs = { 432 qio_channel_tls_source_prepare, 433 qio_channel_tls_source_check, 434 qio_channel_tls_source_dispatch, 435 qio_channel_tls_source_finalize 436 }; 437 438 static void 439 qio_channel_tls_read_watch(QIOChannelTLS *tioc, GSource *source) 440 { 441 GSource *child; 442 QIOChannelTLSSource *tlssource; 443 444 child = g_source_new(&qio_channel_tls_source_funcs, 445 sizeof(QIOChannelTLSSource)); 446 tlssource = (QIOChannelTLSSource *)child; 447 448 tlssource->tioc = tioc; 449 object_ref(OBJECT(tioc)); 450 451 g_source_add_child_source(source, child); 452 g_source_unref(child); 453 } 454 455 static GSource *qio_channel_tls_create_watch(QIOChannel *ioc, 456 GIOCondition condition) 457 { 458 QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc); 459 GSource *source = qio_channel_create_watch(tioc->master, condition); 460 461 if (condition & G_IO_IN) { 462 qio_channel_tls_read_watch(tioc, source); 463 } 464 465 return source; 466 } 467 468 QCryptoTLSSession * 469 qio_channel_tls_get_session(QIOChannelTLS *ioc) 470 { 471 return ioc->session; 472 } 473 474 static void qio_channel_tls_class_init(ObjectClass *klass, 475 void *class_data G_GNUC_UNUSED) 476 { 477 QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass); 478 479 ioc_klass->io_writev = qio_channel_tls_writev; 480 ioc_klass->io_readv = qio_channel_tls_readv; 481 ioc_klass->io_set_blocking = qio_channel_tls_set_blocking; 482 ioc_klass->io_set_delay = qio_channel_tls_set_delay; 483 ioc_klass->io_set_cork = qio_channel_tls_set_cork; 484 ioc_klass->io_close = qio_channel_tls_close; 485 ioc_klass->io_shutdown = qio_channel_tls_shutdown; 486 ioc_klass->io_create_watch = qio_channel_tls_create_watch; 487 ioc_klass->io_set_aio_fd_handler = qio_channel_tls_set_aio_fd_handler; 488 } 489 490 static const TypeInfo qio_channel_tls_info = { 491 .parent = TYPE_QIO_CHANNEL, 492 .name = TYPE_QIO_CHANNEL_TLS, 493 .instance_size = sizeof(QIOChannelTLS), 494 .instance_init = qio_channel_tls_init, 495 .instance_finalize = qio_channel_tls_finalize, 496 .class_init = qio_channel_tls_class_init, 497 }; 498 499 static void qio_channel_tls_register_types(void) 500 { 501 type_register_static(&qio_channel_tls_info); 502 } 503 504 type_init(qio_channel_tls_register_types); 505