Exemplo n.º 1
0
static int acpt_state(BIO *b, BIO_ACCEPT *c)
{
    BIO *bio = NULL, *dbio;
    int s = -1;
    int i;

 again:
    switch (c->state) {
    case ACPT_S_BEFORE:
        if (c->param_addr == NULL) {
            BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_PORT_SPECIFIED);
            return (-1);
        }
        s = BIO_get_accept_socket(c->param_addr, c->bind_mode);
        if (s == INVALID_SOCKET)
            return (-1);

        if (c->accept_nbio) {
            if (!BIO_socket_nbio(s, 1)) {
                closesocket(s);
                BIOerr(BIO_F_ACPT_STATE,
                       BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET);
                return (-1);
            }
        }
        c->accept_sock = s;
        b->num = s;
        c->state = ACPT_S_GET_ACCEPT_SOCKET;
        return (1);
        /* break; */
    case ACPT_S_GET_ACCEPT_SOCKET:
        if (b->next_bio != NULL) {
            c->state = ACPT_S_OK;
            goto again;
        }
        BIO_clear_retry_flags(b);
        b->retry_reason = 0;
        i = BIO_accept(c->accept_sock, &(c->addr));

        /* -2 return means we should retry */
        if (i == -2) {
            BIO_set_retry_special(b);
            b->retry_reason = BIO_RR_ACCEPT;
            return -1;
        }

        if (i < 0)
            return (i);

        bio = BIO_new_socket(i, BIO_CLOSE);
        if (bio == NULL)
            goto err;

        BIO_set_callback(bio, BIO_get_callback(b));
        BIO_set_callback_arg(bio, BIO_get_callback_arg(b));

        if (c->nbio) {
            if (!BIO_socket_nbio(i, 1)) {
                BIOerr(BIO_F_ACPT_STATE,
                       BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET);
                goto err;
            }
        }

        /*
         * If the accept BIO has an bio_chain, we dup it and put the new
         * socket at the end.
         */
        if (c->bio_chain != NULL) {
            if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
                goto err;
            if (!BIO_push(dbio, bio))
                goto err;
            bio = dbio;
        }
        if (BIO_push(b, bio) == NULL)
            goto err;

        c->state = ACPT_S_OK;
        return (1);
 err:
        if (bio != NULL)
            BIO_free(bio);
        else if (s >= 0)
            closesocket(s);
        return (0);
        /* break; */
    case ACPT_S_OK:
        if (b->next_bio == NULL) {
            c->state = ACPT_S_GET_ACCEPT_SOCKET;
            goto again;
        }
        return (1);
        /* break; */
    default:
        return (0);
        /* break; */
    }

}
Exemplo n.º 2
0
Arquivo: main.c Projeto: ep69/petera
static int
decryptd(int argc, char *argv[])
{
    const char *hp = DEO_SOCKET;
    const char *tlsfile = NULL;
    const char *encfile = NULL;
    const char *decdir = NULL;
    int ret = EXIT_FAILURE;
    AUTO(ctx, ctx);
    int lfds = 0;
    int sock = 0;

    signal(SIGINT, on_signal);
    signal(SIGQUIT, on_signal);
    signal(SIGTERM, on_signal);
    signal(SIGUSR1, on_signal);
    signal(SIGUSR2, on_signal);

    if (!deo_getopt(argc, argv, "ht:e:d:l:", "", NULL, NULL,
                       option, &tlsfile, option, &encfile,
                       option, &decdir, option, &hp)
        || tlsfile == NULL || encfile == NULL || decdir == NULL
        || (ctx = ctx_init(tlsfile, encfile, decdir)) == NULL) {
        ERR_print_errors_fp(stderr);
        fprintf(stderr, "Usage: deo decryptd "
                        "[-l <[host:]port>] -t <tlsfile> "
                        "-e <encfile> -d <decdir>\n");
        return EXIT_FAILURE;
    }

    lfds = sd_listen_fds(0);
    if (lfds <= 0) {
        sock = BIO_get_accept_socket((char *) hp, 0);
        if (sock < 0) {
            ERR_print_errors_fp(stderr);
            goto error;
        }

        if (listen(sock, 64) != 0)
            goto error;
    }

    while (true) {
        DEO_ERR err = DEO_ERR_NONE;
        AUTO(ASN1_OCTET_STRING, pt);
        AUTO(DEO_MSG, in);
        AUTO(BIO, sio);
        AUTO_FD(cfd);
        int lfd;

        if (!have_conn(lfds, sock, &lfd))
            break;

        if (!do_accept(ctx->ctx, lfd, &cfd, &sio))
            continue;

        in = d2i_bio_max(&DEO_MSG_it, sio, NULL, DEO_MAX_INPUT);
        if (in == NULL)
            continue;

        switch (in->type) {
        case DEO_MSG_TYPE_CRT_REQ:
            ASN1_item_i2d_bio(&DEO_MSG_it, sio, &(DEO_MSG) {
                .type = DEO_MSG_TYPE_CRT_REP,
                .value.crt_rep = ctx->crt
            });
            break;

        case DEO_MSG_TYPE_DEC_REQ:
            err = decrypt(ctx, in->value.dec_req, &pt);
            if (err != DEO_ERR_NONE) {
                SEND_ERR(sio, err);
                break;
            }

            ASN1_item_i2d_bio(&DEO_MSG_it, sio, &(DEO_MSG) {
                .type = DEO_MSG_TYPE_DEC_REP,
                .value.dec_rep = pt
            });
            break;

        default:
            break;
        }