Changeset aa99b13 in mod_gnutls


Ignore:
Timestamp:
Sep 27, 2004, 3:21:52 PM (15 years ago)
Author:
Paul Querna <chip@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, master, msva, upstream
Children:
7e2b223
Parents:
6a8a839
Message:

commit before i move everything around

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/mod_gnutls.c

    r6a8a839 raa99b13  
    5050    char *cert_file;
    5151    int enabled;
    52     int non_https;
    5352    int ciphers[16];
    5453    int key_exchange[16];
     
    6362    gnutls_srvconf_rec *sc;
    6463    gnutls_session_t session;
    65 #ifdef GNUTLS_AS_FILTER
    6664    ap_filter_t *input_filter;
    6765    apr_bucket_brigade *input_bb;
    6866    apr_read_type_e input_block;
    69 #endif
     67    int status;
     68    int non_https;
    7069};
    7170
    72 #ifdef GNUTLS_AS_FILTER
    7371static apr_status_t gnutls_filter_input(ap_filter_t * f,
    7472                                        apr_bucket_brigade * bb,
     
    8684    }
    8785
     86
     87    for (b = APR_BRIGADE_FIRST(bb);
     88         b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) {
     89        if (APR_BUCKET_IS_EOS(b)) {
     90            /* end of connection */
     91        }
     92        else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)
     93                 == APR_SUCCESS) {
     94            /* more data */
     95        }
     96    }
     97
    8898    return status;
    8999}
     100
     101#define HANDSHAKE_ATTEMPTS 10
    90102
    91103static apr_status_t gnutls_filter_output(ap_filter_t * f,
    92104                                         apr_bucket_brigade * bb)
    93105{
    94     apr_bucket *b;
     106    int ret, i;
    95107    const char *buf = 0;
    96108    apr_size_t bytes = 0;
    97109    gnutls_handle_t *ctxt = (gnutls_handle_t *) f->ctx;
    98110    apr_status_t status = APR_SUCCESS;
    99 
    100     if (!ctxt) {
    101         /* first run. */
    102     }
    103 
    104     for (b = APR_BRIGADE_FIRST(bb);
    105          b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) {
    106         if (APR_BUCKET_IS_EOS(b)) {
    107             /* end of connection */
    108         }
    109         else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)
    110                  == APR_SUCCESS) {
    111             /* more data */
     111    apr_read_type_e rblock = APR_NONBLOCK_READ;
     112
     113    if (f->c->aborted) {
     114        apr_brigade_cleanup(bb);
     115        return APR_ECONNABORTED;
     116    }
     117
     118    if(ctxt->status == 0) {
     119        for (i=HANDSHAKE_ATTEMPTS; i>0; i--){
     120            ret = gnutls_handshake(ctxt->session);
     121
     122            if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN){
     123                continue;
     124            }
     125
     126            if (ret < 0) {
     127                if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
     128                    ret = gnutls_alert_get(ctxt->session);
     129                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, f->c->base_server,
     130                        "GnuTLS: Hanshake Alert (%d) '%s'.\n", ret, gnutls_alert_get_name(ret));
     131                }
     132
     133                if (gnutls_error_is_fatal(ret) != 0) {
     134                    gnutls_deinit(ctxt->session);
     135                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, f->c->base_server,
     136                         "GnuTLS: Handshake Failed (%d) '%s'",ret, gnutls_strerror(ret));
     137                    ctxt->status = -1;
     138                    break;
     139                }
     140            }
     141            else {
     142                ctxt->status = 1;
     143                break; /* all done with the handshake */
     144            }
     145        }
     146    }
     147
     148    if (ctxt->status < 0) {
     149        return ap_pass_brigade(f->next, bb);
     150    }
     151
     152    while (!APR_BRIGADE_EMPTY(bb)) {
     153        apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
     154        if (APR_BUCKET_IS_EOS(bucket) || APR_BUCKET_IS_FLUSH(bucket)) {
     155            /** TODO: GnuTLS doesn't have a special flush method? **/
     156            if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
     157                return status;
     158            }
     159            break;
     160        }
     161        else if(AP_BUCKET_IS_EOC(bucket)) {
     162            gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
     163
     164            if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
     165                return status;
     166            }
     167            break;
     168        }
     169        else {
     170            /* filter output */
     171            const char *data;
     172            apr_size_t len;
     173
     174            status = apr_bucket_read(bucket, &data, &len, rblock);
     175
     176            if (APR_STATUS_IS_EAGAIN(status)) {
     177                 rblock = APR_BLOCK_READ;
     178                 continue; /* and try again with a blocking read. */
     179            }
     180
     181            rblock = APR_NONBLOCK_READ;
     182
     183            if (!APR_STATUS_IS_EOF(status) && (status != APR_SUCCESS)) {
     184                break;
     185            }
     186
     187            ret = gnutls_record_send(ctxt->session, data, len);
     188            status = ssl_filter_write(f, data, len);
     189            if(ret < 0) {
     190                /* error sending output */
     191            }
     192            else if ((apr_size_t)res != len) {
     193                /* not all of the data was sent. */
     194                /* mod_ssl basicly errors out here.. this doesn't seem right? */
     195            }
     196            else {
     197                /* send complete */
     198               
     199            }
     200
     201            apr_bucket_delete(bucket);
     202
     203            if (status != APR_SUCCESS) {
     204                break;
     205            }
     206
    112207        }
    113208    }
     
    115210    return status;
    116211}
    117 
    118 #endif /* GNUTLS_AS_FILTER */
    119212
    120213static apr_status_t gnutls_cleanup_pre_config(void *data)
     
    207300}
    208301
    209 #ifdef GNUTLS_AS_FILTER
    210302/**
    211303 * From mod_ssl / ssl_engine_io.c
     
    346438    return 0;
    347439}
    348 #endif /* GNUTLS_AS_FILTER */
    349440
    350441static int gnutls_hook_pre_connection(conn_rec * c, void *csd)
    351442{
    352 #ifndef GNUTLS_AS_FILTER
    353     int cfd;
    354     int ret;
    355 #endif
    356443    gnutls_handle_t *ctxt;
    357444    gnutls_srvconf_rec *sc =
     
    367454
    368455    ctxt->sc = sc;
     456    ctxt->status = 0;
    369457    gnutls_init(&ctxt->session, GNUTLS_SERVER);
    370458
     
    376464
    377465    gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, sc->certs);
     466//  if(anon) {
     467//    gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON, sc->anoncred);
     468//  }
     469
    378470    gnutls_certificate_server_set_request(ctxt->session, GNUTLS_CERT_IGNORE);
    379471
     
    383475    ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
    384476
    385 #ifdef GNUTLS_AS_FILTER
    386477    gnutls_transport_set_pull_function(ctxt->session, gnutls_transport_read);
    387478    gnutls_transport_set_push_function(ctxt->session, gnutls_transport_write);
    388479    gnutls_transport_set_ptr(ctxt->session, ctxt);
    389 
    390480    ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c);
    391481    ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c);
    392 #else
    393     apr_os_sock_get(&cfd, csd);
    394     gnutls_transport_set_ptr(ctxt->session, (gnutls_transport_ptr)cfd);
    395     gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON, sc->anoncred);
    396 
    397     do{
    398         ret = gnutls_handshake(ctxt->session);
    399 
    400         if(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN){
    401             continue;
    402         }
    403 
    404         if (ret < 0) {
    405             if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
    406                 ret = gnutls_alert_get(ctxt->session);
    407                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server,
    408                     "GnuTLS: Hanshake Alert (%d) '%s'.\n", ret, gnutls_alert_get_name(ret));
    409             }
    410 
    411             if (gnutls_error_is_fatal(ret) != 0) {
    412                 gnutls_deinit(ctxt->session);
    413                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server,
    414                      "GnuTLS: Handshake Failed (%d) '%s'",ret, gnutls_strerror(ret));
    415                 sc->non_https = 1;
    416                 break;
    417             }
    418         }
    419         break; /* all done with the handshake */
    420     } while(1);
    421 #endif
     482
    422483    return OK;
    423484}
     
    502563     *          ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5);
    503564     */
    504 #ifdef GNUTLS_AS_FILTER
    505565    ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, gnutls_filter_input,
    506566                             NULL, AP_FTYPE_CONNECTION + 5);
    507567    ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME, gnutls_filter_output,
    508568                              NULL, AP_FTYPE_CONNECTION + 5);
    509 #endif
    510569}
    511570
Note: See TracChangeset for help on using the changeset viewer.