View | Details | Raw Unified | Return to bug 12355
Collapse All | Expand All

(-)mod_ssl.c (+1 lines)
Lines 389-394 Link Here
389
static void ssl_register_hooks(apr_pool_t *p)
389
static void ssl_register_hooks(apr_pool_t *p)
390
{
390
{
391
    ssl_io_filter_register(p);
391
    ssl_io_filter_register(p);
392
    ssl_reneg_filter_register(p);
392
393
393
    ap_hook_pre_connection(ssl_hook_pre_connection,NULL,NULL, APR_HOOK_MIDDLE);
394
    ap_hook_pre_connection(ssl_hook_pre_connection,NULL,NULL, APR_HOOK_MIDDLE);
394
    ap_hook_post_config   (ssl_init_Module,        NULL,NULL, APR_HOOK_MIDDLE);
395
    ap_hook_post_config   (ssl_init_Module,        NULL,NULL, APR_HOOK_MIDDLE);
(-)mod_ssl.h (+1 lines)
Lines 675-680 Link Here
675
void         ssl_io_filter_init(conn_rec *, SSL *);
675
void         ssl_io_filter_init(conn_rec *, SSL *);
676
void         ssl_io_filter_register(apr_pool_t *);
676
void         ssl_io_filter_register(apr_pool_t *);
677
long         ssl_io_data_cb(BIO *, int, MODSSL_BIO_CB_ARG_TYPE *, int, long, long);
677
long         ssl_io_data_cb(BIO *, int, MODSSL_BIO_CB_ARG_TYPE *, int, long, long);
678
void         ssl_reneg_filter_register(apr_pool_t *p);
678
679
679
/*  PRNG  */
680
/*  PRNG  */
680
int          ssl_rand_seed(server_rec *, apr_pool_t *, ssl_rsctx_t, char *);
681
int          ssl_rand_seed(server_rec *, apr_pool_t *, ssl_rsctx_t, char *);
(-)ssl_engine_kernel.c (-231 / +260 lines)
Lines 29-34 Link Here
29
                                            -- Unknown                */
29
                                            -- Unknown                */
30
#include "mod_ssl.h"
30
#include "mod_ssl.h"
31
31
32
static int reneg_and_check(request_rec *r, int quick);
33
32
/*
34
/*
33
 *  Post Read Request Handler
35
 *  Post Read Request Handler
34
 */
36
 */
Lines 159-164 Link Here
159
    return DECLINED;
161
    return DECLINED;
160
}
162
}
161
163
164
static ap_filter_rec_t *reneg_filter_rec;
165
166
/* Output filter which is inserted into the filter stack to perform a
167
 * renegotiation after the HTTP filter returns EOS. */
168
static apr_status_t reneg_in_filter(ap_filter_t *f, 
169
                                    apr_bucket_brigade *bb,
170
                                    ap_input_mode_t mode,
171
                                    apr_read_type_e block,
172
                                    apr_off_t bytes)
173
{
174
    apr_bucket *bkt;
175
    apr_status_t rv;
176
177
    rv = ap_get_brigade(f->next, bb, mode, block, bytes);
178
    if (rv != APR_SUCCESS || mode != AP_MODE_READBYTES) {
179
        return rv;
180
    }
181
182
    for (bkt = APR_BRIGADE_FIRST(bb);
183
         bkt != APR_BRIGADE_SENTINEL(bb);
184
         bkt = APR_BUCKET_NEXT(bkt))
185
    {
186
        if (APR_BUCKET_IS_EOS(bkt)) {
187
            /* No more work for this filter. */
188
            ap_remove_input_filter(f);
189
190
            /* Now really do the negotiation and access control checks. */
191
            if (reneg_and_check(f->r, 0)) {
192
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
193
                              "renegotiation failed; sending 403 error");
194
                bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
195
                bkt = ap_bucket_error_create(HTTP_FORBIDDEN, NULL,
196
                                             f->r->pool, f->c->bucket_alloc);
197
                APR_BRIGADE_INSERT_TAIL(bb, bkt);
198
                bkt = apr_bucket_eos_create(f->c->bucket_alloc);
199
                APR_BRIGADE_INSERT_TAIL(bb, bkt);
200
                
201
                rv = ap_pass_brigade(f->r->output_filters, bb);
202
                if (rv)
203
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
204
                                  "failed sending 403 after renegotiation");
205
206
                return APR_EACCES;
207
            }
208
209
        }
210
    }
211
212
    return APR_SUCCESS;
213
}
214
215
void ssl_reneg_filter_register(apr_pool_t *p)
216
{
217
    /* only requirement is that this input filter comes before the
218
     * ap_http_filter. */
219
    reneg_filter_rec =
220
        ap_register_input_filter("SSL_RENEG", reneg_in_filter, NULL,
221
                                 AP_FTYPE_PROTOCOL - 1);
222
}
223
162
/*
224
/*
163
 *  Access Handler
225
 *  Access Handler
164
 */
226
 */
Lines 169-186 Link Here
169
    SSLConnRec *sslconn = myConnConfig(r->connection);
231
    SSLConnRec *sslconn = myConnConfig(r->connection);
170
    SSL *ssl            = sslconn ? sslconn->ssl : NULL;
232
    SSL *ssl            = sslconn ? sslconn->ssl : NULL;
171
    SSL_CTX *ctx = NULL;
233
    SSL_CTX *ctx = NULL;
172
    apr_array_header_t *requires;
173
    ssl_require_t *ssl_requires;
174
    char *cp;
234
    char *cp;
175
    int ok, i;
176
    BOOL renegotiate = FALSE, renegotiate_quick = FALSE;
235
    BOOL renegotiate = FALSE, renegotiate_quick = FALSE;
177
    X509 *cert;
178
    X509 *peercert;
236
    X509 *peercert;
179
    X509_STORE *cert_store = NULL;
180
    X509_STORE_CTX cert_store_ctx;
181
    STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL;
237
    STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL;
182
    SSL_CIPHER *cipher = NULL;
238
    SSL_CIPHER *cipher = NULL;
183
    int depth, verify_old, verify, n;
239
    int verify_old, verify, n;
184
240
185
    if (ssl) {
241
    if (ssl) {
186
        ctx = SSL_get_SSL_CTX(ssl);
242
        ctx = SSL_get_SSL_CTX(ssl);
Lines 489-723 Link Here
489
    }
545
    }
490
#endif /* HAVE_SSL_SET_CERT_STORE */
546
#endif /* HAVE_SSL_SET_CERT_STORE */
491
547
492
    /* 
548
    if (!renegotiate) {
493
     * SSL renegotiations in conjunction with HTTP
549
        /* Nothing more to do here. */
494
     * requests using the POST method are not supported.
550
        return DECLINED;
495
     *
496
     * Background:
497
     *
498
     * 1. When the client sends a HTTP/HTTPS request, Apache's core code
499
     * reads only the request line ("METHOD /path HTTP/x.y") and the
500
     * attached MIME headers ("Foo: bar") up to the terminating line ("CR
501
     * LF"). An attached request body (for instance the data of a POST
502
     * method) is _NOT_ read. Instead it is read by mod_cgi's content
503
     * handler and directly passed to the CGI script.
504
     *
505
     * 2. mod_ssl supports per-directory re-configuration of SSL parameters.
506
     * This is implemented by performing an SSL renegotiation of the
507
     * re-configured parameters after the request is read, but before the
508
     * response is sent. In more detail: the renegotiation happens after the
509
     * request line and MIME headers were read, but _before_ the attached
510
     * request body is read. The reason simply is that in the HTTP protocol
511
     * usually there is no acknowledgment step between the headers and the
512
     * body (there is the 100-continue feature and the chunking facility
513
     * only), so Apache has no API hook for this step.
514
     *
515
     * 3. the problem now occurs when the client sends a POST request for
516
     * URL /foo via HTTPS the server and the server has SSL parameters
517
     * re-configured on a per-URL basis for /foo. Then mod_ssl has to
518
     * perform an SSL renegotiation after the request was read and before
519
     * the response is sent. But the problem is the pending POST body data
520
     * in the receive buffer of SSL (which Apache still has not read - it's
521
     * pending until mod_cgi sucks it in). When mod_ssl now tries to perform
522
     * the renegotiation the pending data leads to an I/O error.
523
     *
524
     * Solution Idea:
525
     *
526
     * There are only two solutions: Either to simply state that POST
527
     * requests to URLs with SSL re-configurations are not allowed, or to
528
     * renegotiate really after the _complete_ request (i.e. including
529
     * the POST body) was read. Obviously the latter would be preferred,
530
     * but it cannot be done easily inside Apache, because as already
531
     * mentioned, there is no API step between the body reading and the body
532
     * processing. And even when we mod_ssl would hook directly into the
533
     * loop of mod_cgi, we wouldn't solve the problem for other handlers, of
534
     * course. So the only general solution is to suck in the pending data
535
     * of the request body from the OpenSSL BIO into the Apache BUFF. Then
536
     * the renegotiation can be done and after this step Apache can proceed
537
     * processing the request as before.
538
     *
539
     * Solution Implementation:
540
     *
541
     * We cannot simply suck in the data via an SSL_read-based loop because of
542
     * HTTP chunking. Instead we _have_ to use the Apache API for this step which
543
     * is aware of HTTP chunking. So the trick is to suck in the pending request
544
     * data via the Apache API (which uses Apache's BUFF code and in the
545
     * background mod_ssl's I/O glue code) and re-inject it later into the Apache
546
     * BUFF code again. This way the data flows twice through the Apache BUFF, of
547
     * course. But this way the solution doesn't depend on any Apache specifics
548
     * and is fully transparent to Apache modules.
549
     *
550
     * !! BUT ALL THIS IS STILL NOT RE-IMPLEMENTED FOR APACHE 2.0 !!
551
     */
552
    if (renegotiate && !renegotiate_quick && (r->method_number == M_POST)) {
553
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
554
                     "SSL Re-negotiation in conjunction "
555
                     "with POST method not supported!\n"
556
                     "hint: try SSLOptions +OptRenegotiate");
557
558
        return HTTP_METHOD_NOT_ALLOWED;
559
    }
551
    }
560
552
561
    /*
553
    /* This function is called after reading the request-header.  If
562
     * now do the renegotiation if anything was actually reconfigured
554
     * the HTTP request includes a message body, then the client may
563
     */
555
     * already have sent all the SSL records containing that body.
564
    if (renegotiate) {
556
     * It's not possible to do a renegotiation until all those SSL
565
        /*
557
     * records have been read and processed, so the renegotiation has
566
         * Now we force the SSL renegotation by sending the Hello Request
558
     * to be delayed until that point (when an EOS is returned by the
567
         * message to the client. Here we have to do a workaround: Actually
559
     * HTTP input filter). */
568
         * OpenSSL returns immediately after sending the Hello Request (the
560
569
         * intent AFAIK is because the SSL/TLS protocol says it's not a must
561
    if (!renegotiate_quick &&
570
         * that the client replies to a Hello Request). But because we insist
562
        (apr_table_get(r->headers_in, "Transfer-Encoding") ||
571
         * on a reply (anything else is an error for us) we have to go to the
563
         ((cp = (char *)apr_table_get(r->headers_in, "Content-Length")) != NULL
572
         * ACCEPT state manually. Using SSL_set_accept_state() doesn't work
564
          && strcmp(cp, "0")))) {
573
         * here because it resets too much of the connection.  So we set the
574
         * state explicitly and continue the handshake manually.
575
         */
576
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
565
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
577
                     "Requesting connection re-negotiation");
566
                     "SSL re-negotiation needed for request with body: "
578
567
                     "delaying until after body has been read");
579
        if (renegotiate_quick) {
568
        ap_add_input_filter_handle(reneg_filter_rec, NULL, r, r->connection);
580
            STACK_OF(X509) *cert_stack;
581
582
            /* perform just a manual re-verification of the peer */
583
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
584
                         "Performing quick renegotiation: "
585
                         "just re-verifying the peer");
586
569
587
            cert_stack = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl);
570
        return DECLINED;
588
571
    }
589
            cert = SSL_get_peer_certificate(ssl);
590
591
            if (!cert_stack && cert) {
592
                /* client cert is in the session cache, but there is
593
                 * no chain, since ssl3_get_client_certificate()
594
                 * sk_X509_shift-ed the peer cert out of the chain.
595
                 * we put it back here for the purpose of quick_renegotiation.
596
                 */
597
                cert_stack = sk_new_null();
598
                sk_X509_push(cert_stack, MODSSL_PCHAR_CAST cert);
599
            }
600
601
            if (!cert_stack || (sk_X509_num(cert_stack) == 0)) {
602
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
603
                             "Cannot find peer certificate chain");
604
605
                return HTTP_FORBIDDEN;
606
            }
607
608
            if (!(cert_store ||
609
                  (cert_store = SSL_CTX_get_cert_store(ctx))))
610
            {
611
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
612
                             "Cannot find certificate storage");
613
614
                return HTTP_FORBIDDEN;
615
            }
616
617
            if (!cert) {
618
                cert = sk_X509_value(cert_stack, 0);
619
            }
620
621
            X509_STORE_CTX_init(&cert_store_ctx, cert_store, cert, cert_stack);
622
            depth = SSL_get_verify_depth(ssl);
623
624
            if (depth >= 0) {
625
                X509_STORE_CTX_set_depth(&cert_store_ctx, depth);
626
            }
627
628
            X509_STORE_CTX_set_ex_data(&cert_store_ctx,
629
                                       SSL_get_ex_data_X509_STORE_CTX_idx(),
630
                                       (char *)ssl);
631
572
632
            if (!modssl_X509_verify_cert(&cert_store_ctx)) {
573
    /* Now actually perform the SSL renegotiation; return DECLINED
633
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
574
     * here instead of OK, to allow mod_auth and other to deny
634
                             "Re-negotiation verification step failed");
575
     * access. */
635
                ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server);
576
    return (reneg_and_check(r, renegotiate_quick) 
636
            }
577
            ? HTTP_FORBIDDEN : DECLINED);
578
}
637
579
638
            SSL_set_verify_result(ssl, cert_store_ctx.error);
580
/* Do the SSL renegotiation and perform access control checks.
639
            X509_STORE_CTX_cleanup(&cert_store_ctx);
581
 * Returns non-zero if access control checks failed. */
582
static int reneg_and_check(request_rec *r, int quick)
583
{
584
    SSLDirConfigRec *dc = myDirConfig(r);
585
    SSLConnRec *sslconn = myConnConfig(r->connection);
586
    SSL *ssl            = sslconn ? sslconn->ssl : NULL;
587
    apr_array_header_t *requires;
588
    ssl_require_t *ssl_requires;
589
    X509_STORE *cert_store = NULL;
590
    X509_STORE_CTX cert_store_ctx;
591
    X509 *cert;
592
    SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
593
    int depth, i, ok;
594
    char *cp;
640
595
641
            if (cert_stack != SSL_get_peer_cert_chain(ssl)) {
596
    /*
642
                /* we created this ourselves, so free it */
597
     * Now we force the SSL renegotation by sending the Hello Request
643
                sk_X509_pop_free(cert_stack, X509_free);
598
     * message to the client. Here we have to do a workaround: Actually
644
            }
599
     * OpenSSL returns immediately after sending the Hello Request (the
600
     * intent AFAIK is because the SSL/TLS protocol says it's not a must
601
     * that the client replies to a Hello Request). But because we insist
602
     * on a reply (anything else is an error for us) we have to go to the
603
     * ACCEPT state manually. Using SSL_set_accept_state() doesn't work
604
     * here because it resets too much of the connection.  So we set the
605
     * state explicitly and continue the handshake manually.
606
     */
607
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
608
                 "Requesting connection re-negotiation");
609
    
610
    if (quick) {
611
        STACK_OF(X509) *cert_stack;
612
        
613
        /* perform just a manual re-verification of the peer */
614
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
615
                     "Performing quick renegotiation: "
616
                     "just re-verifying the peer");
617
        
618
        cert_stack = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl);
619
        
620
        cert = SSL_get_peer_certificate(ssl);
621
        
622
        if (!cert_stack && cert) {
623
            /* client cert is in the session cache, but there is
624
             * no chain, since ssl3_get_client_certificate()
625
             * sk_X509_shift-ed the peer cert out of the chain.
626
             * we put it back here for the purpose of quick_renegotiation.
627
             */
628
            cert_stack = sk_new_null();
629
            sk_X509_push(cert_stack, MODSSL_PCHAR_CAST cert);
645
        }
630
        }
646
        else {
631
        
647
            request_rec *id = r->main ? r->main : r;
632
        if (!cert_stack || (sk_X509_num(cert_stack) == 0)) {
648
633
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
649
            /* do a full renegotiation */
634
                         "Cannot find peer certificate chain");
650
            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
635
            
651
                         "Performing full renegotiation: "
636
            return 1;
652
                         "complete handshake protocol");
653
654
            SSL_set_session_id_context(ssl,
655
                                       (unsigned char *)&id,
656
                                       sizeof(id));
657
658
            SSL_renegotiate(ssl);
659
            SSL_do_handshake(ssl);
660
661
            if (SSL_get_state(ssl) != SSL_ST_OK) {
662
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
663
                             "Re-negotiation request failed");
664
665
                r->connection->aborted = 1;
666
                return HTTP_FORBIDDEN;
667
            }
668
669
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
670
                         "Awaiting re-negotiation handshake");
671
672
            SSL_set_state(ssl, SSL_ST_ACCEPT);
673
            SSL_do_handshake(ssl);
674
675
            if (SSL_get_state(ssl) != SSL_ST_OK) {
676
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
677
                             "Re-negotiation handshake failed: "
678
                        "Not accepted by client!?");
679
680
                r->connection->aborted = 1;
681
                return HTTP_FORBIDDEN;
682
            }
683
        }
637
        }
684
638
        
685
        /*
639
        if (!(cert_store ||
686
         * Remember the peer certificate's DN
640
              (cert_store = SSL_CTX_get_cert_store(ctx))))
687
         */
641
        {
688
        if ((cert = SSL_get_peer_certificate(ssl))) {
642
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
689
            if (sslconn->client_cert) {
643
                         "Cannot find certificate storage");
690
                X509_free(sslconn->client_cert);
644
            
691
            }
645
            return 1;
692
            sslconn->client_cert = cert;
693
            sslconn->client_dn = NULL;
694
        }
646
        }
695
647
        
696
        /*
648
        if (!cert) {
697
         * Finally check for acceptable renegotiation results
649
            cert = sk_X509_value(cert_stack, 0);
650
        }
651
        
652
        X509_STORE_CTX_init(&cert_store_ctx, cert_store, cert, cert_stack);
653
        depth = SSL_get_verify_depth(ssl);
654
        
655
        if (depth >= 0) {
656
            X509_STORE_CTX_set_depth(&cert_store_ctx, depth);
657
        }
658
        
659
        X509_STORE_CTX_set_ex_data(&cert_store_ctx,
660
                                   SSL_get_ex_data_X509_STORE_CTX_idx(),
661
                                   (char *)ssl);
662
        
663
        if (!modssl_X509_verify_cert(&cert_store_ctx)) {
664
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
665
                         "Re-negotiation verification step failed");
666
            ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server);
667
        }
668
        
669
        SSL_set_verify_result(ssl, cert_store_ctx.error);
670
        X509_STORE_CTX_cleanup(&cert_store_ctx);
671
        
672
        if (cert_stack != SSL_get_peer_cert_chain(ssl)) {
673
            /* we created this ourselves, so free it */
674
            sk_X509_pop_free(cert_stack, X509_free);
675
        }
676
    }
677
    else {
678
        request_rec *id = r->main ? r->main : r;
679
        
680
        /* do a full renegotiation */
681
        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
682
                     "Performing full renegotiation: "
683
                     "complete handshake protocol");
684
        
685
        SSL_set_session_id_context(ssl,
686
                                   (unsigned char *)&id,
687
                                   sizeof(id));
688
        
689
        SSL_renegotiate(ssl);
690
        SSL_do_handshake(ssl);
691
        
692
        if (SSL_get_state(ssl) != SSL_ST_OK) {
693
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
694
                         "Re-negotiation request failed");
695
            
696
            r->connection->aborted = 1;
697
            return 1;
698
        }
699
        
700
        ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
701
                     "Awaiting re-negotiation handshake");
702
        
703
        /* XXX: Should replace SSL_set_state with SSL_renegotiate(ssl);
704
         * However, this causes failures in perl-framework currently, 
705
         * perhaps pre-test if we have already negotiated?
698
         */
706
         */
699
        if (dc->nVerifyClient != SSL_CVERIFY_NONE) {
707
        SSL_set_state(ssl, SSL_ST_ACCEPT);
700
            BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE);
708
        SSL_do_handshake(ssl);
709
        
710
        if (SSL_get_state(ssl) != SSL_ST_OK) {
711
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
712
                         "Re-negotiation handshake failed: "
713
                         "Not accepted by client!?");
714
            
715
            r->connection->aborted = 1;
716
            return 1;
717
        }
718
    }
719
    
720
    /*
721
     * Remember the peer certificate's DN
722
     */
723
    if ((cert = SSL_get_peer_certificate(ssl))) {
724
        if (sslconn->client_cert) {
725
            X509_free(sslconn->client_cert);
726
        }
727
        sslconn->client_cert = cert;
728
        sslconn->client_dn = NULL;
729
    }
730
    
731
    /*
732
     * Finally check for acceptable renegotiation results
733
     */
734
    if (dc->nVerifyClient != SSL_CVERIFY_NONE) {
735
        BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE);
736
        
737
        if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
738
            ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
739
                         "Re-negotiation handshake failed: "
740
                         "Client verification failed");
741
            
742
            return 1;
743
        }
744
        
745
        if (do_verify) {
746
            X509 *peercert;
701
747
702
            if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
748
            if ((peercert = SSL_get_peer_certificate(ssl)) == NULL) {
703
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
749
                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
704
                             "Re-negotiation handshake failed: "
750
                             "Re-negotiation handshake failed: "
705
                             "Client verification failed");
751
                             "Client certificate missing");
706
752
                
707
                return HTTP_FORBIDDEN;
753
                return 1;
708
            }
709
710
            if (do_verify) {
711
                if ((peercert = SSL_get_peer_certificate(ssl)) == NULL) {
712
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
713
                                 "Re-negotiation handshake failed: "
714
                                 "Client certificate missing");
715
716
                    return HTTP_FORBIDDEN;
717
                }
718
719
                X509_free(peercert);
720
            }
754
            }
755
            
756
            X509_free(peercert);
721
        }
757
        }
722
    }
758
    }
723
759
Lines 744-750 Link Here
744
            /* remember forbidden access for strict require option */
780
            /* remember forbidden access for strict require option */
745
            apr_table_setn(r->notes, "ssl-access-forbidden", "1");
781
            apr_table_setn(r->notes, "ssl-access-forbidden", "1");
746
782
747
            return HTTP_FORBIDDEN;
783
            return 1;
748
        }
784
        }
749
785
750
        if (ok != 1) {
786
        if (ok != 1) {
Lines 765-782 Link Here
765
            /* remember forbidden access for strict require option */
801
            /* remember forbidden access for strict require option */
766
            apr_table_setn(r->notes, "ssl-access-forbidden", "1");
802
            apr_table_setn(r->notes, "ssl-access-forbidden", "1");
767
803
768
            return HTTP_FORBIDDEN;
804
            return 1;
769
        }
805
        }
770
    }
806
    }
771
807
772
    /*
808
    return 0;
773
     * Else access is granted from our point of view (except vendor
774
     * handlers override). But we have to return DECLINED here instead
775
     * of OK, because mod_auth and other modules still might want to
776
     * deny access.
777
     */
778
779
    return DECLINED;
780
}
809
}
781
810
782
/*
811
/*

Return to bug 12355