Пример #1
0
void
logerr(const char *ctl, ...)
{
    int saved_errno;
    va_list va;

    saved_errno = errno;
    va_start(va, ctl);
    vlogline(0, 0, ctl, va);
    logerrstr(": %s", strerror(saved_errno));
    va_end(va);

}
Пример #2
0
void myprintf (const char *format, ...)
{
    va_list args;
    char buf[4 * PBC_DES_KEY_BUF];
    pool *p = NULL;

    assert (ssl != NULL);

    va_start (args, format);
    vsnprintf (buf, sizeof (buf), format, args);
    va_end (args);

    if (debug) {
        pbc_log_activity (p, PBC_LOG_DEBUG_VERBOSE, "Sending: \"%s\"",
                          buf);
    }

    if (SSL_write (ssl, buf, strlen (buf)) < 0) {
        logerrstr ("SSL_write");
        exit (1);
    }
}
Пример #3
0
/* run as if invoked by inetd */
int main (int argc, char *argv[])
{
    int c;
    int filetype = SSL_FILETYPE_PEM;
    char *peer = NULL;
    char *ptr;
    char buf[4096];
    enum optype op = NOOP;
    char *setkey = NULL;
    SSL_CTX *ctx;
    X509 *client_cert;
    int r;
    pool *p = NULL;
    security_context *context = NULL;
    int max_wait = 0;

    while ((c = getopt (argc, argv, "apc:k:C:D:f:")) != -1) {
        switch (c) {
        case 'a':
            filetype = SSL_FILETYPE_ASN1;
            break;

        case 'p':
            filetype = SSL_FILETYPE_PEM;
            break;

        case 'c':
            /* 'optarg' is the certificate file */
            certfile = strdup (optarg);
            break;

        case 'k':
            /* 'optarg' is the key file */
            keyfile = strdup (optarg);
            break;

        case 'C':
            /* 'optarg' is the CA we accept */
            cafile = strdup (optarg);
            break;

        case 'D':
            /* 'optarg' is a directory of CAs */
            cadir = strdup (optarg);
            break;

        case 'f':
            configfile = strdup (optarg);
            break;

        case '?':
        default:
            usage ();
            break;
        }
    }

    libpbc_config_init (p, configfile, "keyserver");
    pbc_log_init_syslog (p, "keyserver");
    libpbc_pubcookie_init (p, &context);

    debug = libpbc_config_getint (p, "logging_level", 0);
    if (!keyfile)
        keyfile =
            libpbc_config_getstring (p, "ssl_key_file", "server.pem");
    if (!certfile)
        certfile =
            libpbc_config_getstring (p, "ssl_cert_file", "server.pem");
    if (!cafile)
        cafile = libpbc_config_getstring (p, "ssl_ca_file", NULL);
    if (!cadir)
        cadir = libpbc_config_getstring (p, "ssl_ca_path", NULL);

    gcfile = libpbc_config_getstring (p, "granting_cert_file", NULL);
    max_wait = libpbc_config_getint (p, "keyserver_max_wait_time", 0);
    if (max_wait < 0)
        max_wait = 0;

    /* xxx log connection information */

    /* initalize the PRNG as best we can if we have to */
    if (RAND_status () == 0) {
        pbc_time_t t = pbc_time (NULL);
        pid_t pid = getpid ();
        char buf[1024];
        char *cmd[3] = { "/bin/ps", "-ef", NULL };

        RAND_seed ((unsigned char *) &t, sizeof (t));
        RAND_seed ((unsigned char *) &pid, sizeof (pid));

        capture_cmd_output (p, cmd, buf, sizeof (buf));
        RAND_seed ((unsigned char *) buf, sizeof (buf));
    }

    /* Load SSL Error Strings */
    SSL_load_error_strings ();

    /* initialize the OpenSSL connection */
    SSL_library_init ();

    ctx = SSL_CTX_new (TLSv1_server_method ());

    /* setup the correct certificate */
    if (!SSL_CTX_use_certificate_file (ctx, certfile, filetype)) {
        logerrstr ("SSL_CTX_use_certificate_file");
        exit (1);
    }
    if (!SSL_CTX_use_PrivateKey_file (ctx, keyfile, filetype)) {
        logerrstr ("SSL_CTX_use_PrivateKey_file");
        exit (1);
    }
    if (!SSL_CTX_load_verify_locations (ctx, cafile, cadir)) {
        logerrstr ("SSL_CTX_load_verify_locations");
        exit (1);
    }

    SSL_CTX_set_verify (ctx,
                        SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
                        | SSL_VERIFY_CLIENT_ONCE, verify_callback);

    ssl = SSL_new (ctx);

    /* negotiate SSL */
    SSL_set_rfd (ssl, 0);
    SSL_set_wfd (ssl, 1);
    SSL_set_accept_state (ssl);

    /* If no data in max_wait seconds, give up */
    if (max_wait) {
        signal (SIGALRM, sig_alarm);
        alarm (max_wait);
    }

    if (SSL_accept (ssl) <= 0) {
        logerrstr ("SSL_accept");
        ERR_print_errors_fp (stderr);
        exit (1);
    }
    if (max_wait)
        alarm (0);

    /* check certificate */
    client_cert = SSL_get_peer_certificate (ssl);
    if (client_cert == NULL) {
        pbc_log_activity (p, PBC_LOG_ERROR, "client_cert == NULL???");
        exit (1);
    }

    peer = get_cn_from_crt (client_cert);
    if (peer == NULL) {
        pbc_log_activity (p, PBC_LOG_ERROR, "peer == NULL???");
        exit (1);
    }

    pbc_log_activity (p, PBC_LOG_DEBUG_VERBOSE, "peer cn: %s\n", peer);

    /* read HTTP query */
    if ((c=SSL_read (ssl, buf, sizeof(buf)-1)) <= 0) {
        pbc_log_activity (p, PBC_LOG_ERROR, "SSL_read() failed");
        ERR_print_errors_fp (stderr);
        exit (1);
    }
    buf[c] = '\0';

    pbc_log_activity (p, PBC_LOG_DEBUG_VERBOSE, "REQ=%s", buf);
    for (ptr = buf; *ptr != '\0'; ptr++) {
        if (*ptr == '?' || *ptr == '&') {       /* next arg */
            /* look for 'genkey' */
            if (!strncmp (ptr + 1, "genkey=yes", 10)) {
                op = GENKEY;
            }

            else if (!strncmp (ptr + 1, "genkey=no", 9)) {
                op = FETCHKEY;
            }

            else if (!strncmp (ptr + 1, "genkey=put", 10)) {
                op = SETKEY;
            }

            else if (!strncmp (ptr + 1, "genkey=permit", 13)) {
                op = PERMIT;
            }

            else if (!strncmp (ptr + 1, "genkey=getgc", 12)) {
                op = FETCHGC;
            }

            else if (!strncmp (ptr + 1, "genkey=setpkey", 12)) {
                op = SETPKEY;
            }

            /* look for 'setkey' */
            else if (!strncmp (ptr + 1, "setkey=", 7)) {
                char *q;

                ptr++;          /* ? or & */
                ptr += 7;       /* setkey= */

                setkey = strdup (ptr);
                /* terminated by ? - this is a bit dubious, but i think it's 
                   compensated for later - ssw */
                q = strchr (setkey, '?');
                if (q)
                    *q = '\0';
            }
        }
    }

    if (op == NOOP) {
        pbc_log_activity (p, PBC_LOG_ERROR,
                          "peer didn't specify an operation");
        exit (1);
    }

    /* call doit */

    r = doit (peer, context, op, setkey, client_cert);
    SSL_shutdown (ssl);

    return r;
}