Пример #1
0
Файл: vtpm.c Проект: 0day-ci/xen
static void main_loop(void) {
   tpmcmd_t* tpmcmd = NULL;
   int res = -1;

   info("VTPM Initializing\n");

   /* Set required tpm config args */
   opt_args.tpmconf |= TPM_CONF_STRONG_PERSISTENCE;
   opt_args.tpmconf &= ~TPM_CONF_USE_INTERNAL_PRNG;
   opt_args.tpmconf |= TPM_CONF_GENERATE_EK;
   opt_args.tpmconf |= TPM_CONF_GENERATE_SEED_DAA;

   /* Initialize the emulator */
   tpm_emulator_init(opt_args.startup, opt_args.tpmconf);

   /* Initialize any requested PCRs with hardware TPM values */
   if(vtpm_initialize_hw_pcrs(tpmfront_dev, opt_args.hwinitpcrs) != TPM_SUCCESS) {
      error("Failed to initialize PCRs with hardware TPM values");
      goto abort_postpcrs;
   }

   tpmcmd = tpmback_req_any();
   while(tpmcmd) {
      /* Handle the request */
      if(tpmcmd->req_len) {
	 uint8_t* locality_mask = tpmcmd->opaque;
	 uint8_t locality_bit = (1 << (tpmcmd->locality & 7));
	 int locality_byte = tpmcmd->locality >> 3;
	 tpmcmd->resp = NULL;
	 tpmcmd->resp_len = 0;

	 if (nr_client_localities && !locality_mask)
	    locality_mask = generate_locality_mask(tpmcmd->domid, tpmcmd->handle);
	 if (nr_client_localities && !locality_mask) {
            error("Unknown client label in tpm_handle_command");
            create_error_response(tpmcmd, TPM_FAIL);
	 }
	 else if (nr_client_localities && !(locality_mask[locality_byte] & locality_bit)) {
            error("Invalid locality (%d) for client in tpm_handle_command", tpmcmd->locality);
            create_error_response(tpmcmd, TPM_FAIL);
	 }
         /* Check for TPM Manager passthrough command */
         else if(check_passthru(tpmcmd)) {
	 }
         /* Check for disabled ordinals */
         else if(!check_ordinal(tpmcmd)) {
            create_error_response(tpmcmd, TPM_BAD_ORDINAL);
         }
         /* If not disabled, do the command */
         else {
            if((res = tpm_handle_command(tpmcmd->req, tpmcmd->req_len, &tpmcmd->resp, &tpmcmd->resp_len, tpmcmd->locality)) != 0) {
               error("tpm_handle_command() failed");
               create_error_response(tpmcmd, TPM_FAIL);
            }
         }
      }

      /* Send the response */
      tpmback_resp(tpmcmd);

      /* Wait for the next request */
      tpmcmd = tpmback_req_any();

   }
Пример #2
0
static void main_loop(void)
{
    int sock = -1, devfd = -1, fh, res, npoll;
    int32_t in_len;
    uint32_t out_len;
    uint8_t in[TPM_CMD_BUF_SIZE], *out;
    struct sockaddr_un addr;
    socklen_t addr_len;
    struct pollfd poll_table[2];

    info("staring main loop");
    /* open UNIX socket */
    if (opt_socket_name) {
	sock = init_socket(opt_socket_name);
	if (sock < 0) exit(EXIT_FAILURE);
    }

    if (opt_dev_name) {
	devfd = init_device(opt_dev_name);
	if (devfd < 0)
	    exit(EXIT_FAILURE);
    }

    /* init tpm emulator */
    debug("initializing TPM emulator");
    if (tpm_emulator_init(tpm_startup, tpm_config) != 0) {
        error("tpm_emulator_init() failed");
        close(sock);
        unlink(opt_socket_name);
        exit(EXIT_FAILURE);
    }

    /* start command processing */
    while (!stopflag) {
        /* wait for incomming connections */
        debug("waiting for connections...");
	npoll = 0;
	if (sock != -1) {
	    poll_table[npoll].fd = sock;
	    poll_table[npoll].events = POLLIN;
	    poll_table[npoll++].revents = 0;
	}
	if (devfd != -1) {
	    poll_table[npoll].fd = devfd;
	    poll_table[npoll].events = POLLIN | POLLERR;
	    poll_table[npoll++].revents = 0;
	}
	res = poll(poll_table, npoll, -1);
        if (res < 0) {
            error("poll(sock,dev) failed: %s", strerror(errno));
            break;
        }

	if (devfd != -1 && poll_table[npoll - 1].revents) {
	    /* if POLLERR was set, let read() handle it */
	    if (handle_emuldev_command(devfd) < 0)
		break;
	}
	if (sock == -1 || !poll_table[0].revents)
	    continue;

	/* Beyond this point, npoll will always be 1 if the emulator device is
	 * not open and 2 if it is, so we can just fill in the second slot of
	 * the poll table unconditionally and rely on passing npoll to poll().
	 */

        addr_len = sizeof(addr);
        fh = accept(sock, (struct sockaddr*)&addr, &addr_len);
        if (fh < 0) {
            error("accept() failed: %s", strerror(errno));
            continue;
        }
        /* receive and handle commands */
        in_len = 0;
        do {
            debug("waiting for commands...");
	    poll_table[0].fd = fh;
	    poll_table[0].events = POLLIN;
	    poll_table[0].revents = 0;
	    poll_table[1].fd = devfd;
	    poll_table[1].events = POLLIN | POLLERR;
	    poll_table[1].revents = 0;

	    res = poll(poll_table, npoll, TPM_COMMAND_TIMEOUT);
            if (res < 0) {
                error("poll(fh) failed: %s", strerror(errno));
                close(fh);
                break;
            } else if (res == 0) {
#ifdef TPMD_DISCONNECT_IDLE_CLIENTS	    
                info("connection closed due to inactivity");
                close(fh);
                break;
#else		
                continue;
#endif		
            }

	    if (poll_table[1].revents) {
		/* if POLLERR was set, let read() handle it */
		if (handle_emuldev_command(devfd) < 0)
		    break;
	    }
	    if (!poll_table[0].revents)
		continue;

            in_len = read(fh, in, sizeof(in));
            if (in_len > 0) {
                debug("received %d bytes", in_len);
                out = NULL;
                res = tpm_handle_command(in, in_len, &out, &out_len);
                if (res < 0) {
                    error("tpm_handle_command() failed");
                } else {
                    debug("sending %d bytes", out_len);
                    uint32_t len = 0;
                    while (len < out_len) {
                        res = write(fh, &out[len], out_len - len);
                        if (res < 0) {
                            error("write(%d) failed: %s", 
                                  out_len - len, strerror(errno));
                            break;
                        }
                        len += res;
                    }
                    tpm_free(out);
                }
            }
        } while (in_len > 0);
        close(fh);
    }
    /* shutdown tpm emulator */
    tpm_emulator_shutdown();
    /* close socket */
    close(sock);
    unlink(opt_socket_name);
    info("main loop stopped");
}