Changeset 42307a9 in mod_gnutls for src


Ignore:
Timestamp:
Apr 6, 2005, 12:52:25 AM (18 years ago)
Author:
Paul Querna <chip@…>
Branches:
asyncio, debian/master, debian/stretch-backports, jessie-backports, main, master, msva, proxy-ticket, upstream
Children:
6af4f74
Parents:
fcb122d
Message:
  • remove anno creds
  • initial attempt at Server Name Extension
  • change to adding 'mod_gnutls' to the server sig instead of GnuTLS/
  • fix for EOF/EOC/EOS buckets
  • 'general' code cleanups
Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_cache.c

    rfcb122d r42307a9  
    3333#endif
    3434
    35 #define GNUTLS_SESSION_ID_STRING_LEN \
    36     ((GNUTLS_MAX_SESSION_ID + 1) * 2)
     35
    3736#define MC_TAG "mod_gnutls:"
    3837#define MC_TAG_LEN \
     
    4140
    4241static char *gnutls_session_id2sz(unsigned char *id, int idlen,
    43                         char *str, int strsize)
     42                               char *str, int strsize)
    4443{
    4544    char *cp;
     
    4746 
    4847    cp = apr_cpystrn(str, MC_TAG, MC_TAG_LEN);
     48    for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) {
     49        apr_snprintf(cp, strsize - (cp-str), "%02X", id[n]);
     50        cp += 2;
     51    }
     52    *cp = '\0';
     53    return str;
     54}
     55
     56char *mod_gnutls_session_id2sz(unsigned char *id, int idlen,
     57                               char *str, int strsize)
     58{
     59    char *cp;
     60    int n;
     61   
     62    cp = str;
    4963    for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) {
    5064        apr_snprintf(cp, strsize - (cp-str), "%02X", id[n]);
     
    104118
    105119        rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p);
    106         if(rv != APR_SUCCESS) {
     120        if (rv != APR_SUCCESS) {
    107121            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
    108122                         "[gnutls_cache] Failed to Parse Server: '%s'", split);
     
    110124        }
    111125
    112         if(host_str == NULL) {
     126        if (host_str == NULL) {
    113127            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
    114128                         "[gnutls_cache] Failed to Parse Server, "
     
    129143                                        600,
    130144                                        &st);
    131         if(rv != APR_SUCCESS) {
     145        if (rv != APR_SUCCESS) {
    132146            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
    133147                         "[gnutls_cache] Failed to Create Server: %s:%d",
     
    137151
    138152        rv = apr_memcache_add_server(mc, st);
    139         if(rv != APR_SUCCESS) {
     153        if (rv != APR_SUCCESS) {
    140154            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
    141155                         "[gnutls_cache] Failed to Add Server: %s:%d",
     
    162176        return -1;
    163177
    164     timeout = ctxt->sc->cache_timeout;
    165 
    166     rv = apr_memcache_set(mc,  strkey, data.data, data.size, timeout, 0);
    167 
    168     if(rv != APR_SUCCESS) {
     178    timeout = apr_time_sec(ctxt->sc->cache_timeout);
     179
     180    rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, 0);
     181
     182    if (rv != APR_SUCCESS) {
    169183        ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
    170184                     ctxt->c->base_server,
     
    188202
    189203    strkey = gnutls_session_id2sz(key.data, key.size, buf, sizeof(buf));
    190     if(!strkey) {
     204    if (!strkey) {
    191205        return data;
    192206    }
     
    195209                           &value, &value_len, NULL);
    196210
    197     if(rv != APR_SUCCESS) {
     211    if (rv != APR_SUCCESS) {
    198212        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
    199213                     ctxt->c->base_server,
     
    230244    rv = apr_memcache_delete(mc, strkey, 0);
    231245
    232     if(rv != APR_SUCCESS) {
     246    if (rv != APR_SUCCESS) {
    233247        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
    234248                     ctxt->c->base_server,
     
    249263    apr_status_t rv;
    250264    apr_dbm_t *dbm;
     265    apr_datum_t *keylist;
     266    apr_datum_t dbmkey;
     267    apr_datum_t dbmval;
     268    apr_time_t ex;
     269    apr_time_t dtime;
     270    apr_pool_t* spool;
     271    int i = 0;
     272    int keyidx = 0;
     273    int should_delete = 0;
     274
     275    apr_pool_create(&spool, ctxt->c->pool);
     276    ex = apr_time_now();
     277   
     278    rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, APR_DBM_READONLY,
     279                      SSL_DBM_FILE_MODE, spool);
     280    if (rv != APR_SUCCESS) {
     281        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
     282                     ctxt->c->base_server,
     283                     "[gnutls_cache] error opening cache searcher '%s'",
     284                     ctxt->sc->cache_config);
     285        return -1;
     286    }
     287
     288#define KEYMAX 128
     289
     290    keylist = apr_palloc(spool, sizeof(dbmkey)*KEYMAX);
     291
     292    apr_dbm_firstkey(dbm, &dbmkey);
     293    while (dbmkey.dptr != NULL) {
     294        apr_dbm_fetch(dbm, dbmkey, &dbmval);
     295        if (dbmval.dptr != NULL) {
     296            if (dbmval.dsize >= sizeof(apr_time_t)) {
     297                memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t));
     298                if (dtime < ex) {
     299                    should_delete = 1;
     300                }
     301            }
     302            else {
     303                should_delete = 1;
     304            }
     305           
     306            if (should_delete == 1) {
     307                should_delete = 0;
     308                keylist[keyidx].dptr = apr_palloc(spool, dbmkey.dsize) ;
     309                memcpy(keylist[keyidx].dptr, dbmkey.dptr, dbmkey.dsize);
     310                keylist[keyidx].dsize = dbmkey.dsize;
     311                keyidx++;
     312                if (keyidx == KEYMAX) {
     313                    break;
     314                }
     315            }
     316           
     317        }
     318        apr_dbm_nextkey(dbm, &dbmkey);
     319    }
     320    apr_dbm_close(dbm);
    251321
    252322    rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
    253                       APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool);
    254     if (rv != APR_SUCCESS) {
    255         ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
    256                      ctxt->c->base_server,
    257                      "[gnutls_cache] error opening cache '%s'",
    258                      ctxt->sc->cache_config);
    259         return -1;
    260     }
     323                  APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, spool);
     324    if (rv != APR_SUCCESS) {
     325        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
     326                 ctxt->c->base_server,
     327                 "[gnutls_cache] error opening cache writer '%s'",
     328                 ctxt->sc->cache_config);
     329        return -1;
     330    }
     331
     332    for (i = 0; i < keyidx; i++) {
     333        apr_dbm_delete(dbm, keylist[i]);
     334    }
     335
    261336    apr_dbm_close(dbm);
    262 
     337    apr_pool_destroy(spool);
     338   
    263339    return 0;
    264340}
     
    276352    dbmkey.dsize = key.size;
    277353
     354    dbm_cache_expire(ctxt);
     355
    278356    rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
    279357                      APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool);
     
    287365
    288366    rv = apr_dbm_fetch(dbm, dbmkey, &dbmval);
    289 
     367   
    290368    if (rv != APR_SUCCESS) {
    291369        apr_dbm_close(dbm);
     
    297375        return data;
    298376    }
    299 
    300     data.data = gnutls_malloc(dbmval.dsize - sizeof(apr_time_t));
    301     if (data.data == NULL)
    302         return data;
     377    apr_dbm_close(dbm);
    303378
    304379    data.size = dbmval.dsize - sizeof(apr_time_t);
     380
     381    data.data = gnutls_malloc(data.size);
     382    if (data.data == NULL) {
     383        return data;
     384    }
     385   
    305386    memcpy(data.data, dbmval.dptr+sizeof(apr_time_t), data.size);
    306387
    307     apr_dbm_close(dbm);
    308388    return data;
    309389}
     
    317397    mod_gnutls_handle_t *ctxt = baton;
    318398    apr_status_t rv;
    319     apr_time_t timeout;
     399    apr_time_t expiry;
    320400   
    321401    dbmkey.dptr  = (char *)key.data;
     
    323403
    324404    /* create DBM value */
    325     dbmval.dsize = data.size;
    326     dbmval.dptr  = (char *)malloc(dbmval.dsize+sizeof(apr_time_t));
    327 
     405    dbmval.dsize = data.size + sizeof(apr_time_t);
     406    dbmval.dptr  = (char *)malloc(dbmval.dsize);
     407
     408    expiry = apr_time_now() + ctxt->sc->cache_timeout;
     409
     410    memcpy((char *)dbmval.dptr, &expiry, sizeof(apr_time_t));
    328411    memcpy((char *)dbmval.dptr+sizeof(apr_time_t),
    329412           data.data, data.size);
     413
     414    dbm_cache_expire(ctxt);
    330415
    331416    rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
     
    341426
    342427    rv = apr_dbm_store(dbm, dbmkey, dbmval);
    343 
     428   
    344429    if (rv != APR_SUCCESS) {
    345430        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
     
    369454    dbmkey.dsize = key.size;
    370455
     456    dbm_cache_expire(ctxt);
     457   
    371458    rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
    372459                      APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool);
     
    384471        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
    385472                     ctxt->c->base_server,
    386                      "[gnutls_cache] error storing in cache '%s'",
     473                     "[gnutls_cache] error deleting from cache '%s'",
    387474                     ctxt->sc->cache_config);
    388475        apr_dbm_close(dbm);
     
    395482}
    396483
    397 static int dbm_cache_child_init(apr_pool_t *p, server_rec *s,
     484static int dbm_cache_post_config(apr_pool_t *p, server_rec *s,
    398485                                mod_gnutls_srvconf_rec *sc)
    399486{
     
    435522{
    436523    if (sc->cache_type == mod_gnutls_cache_dbm) {
    437         return dbm_cache_child_init(p, s, sc);
     524        return dbm_cache_post_config(p, s, sc);
    438525    }
    439526    return 0;
     
    458545int mod_gnutls_cache_session_init(mod_gnutls_handle_t *ctxt)
    459546{
    460     printf("Type: %d Params: %s\n",ctxt->sc->cache_type, ctxt->sc->cache_config);
    461547    if (ctxt->sc->cache_type == mod_gnutls_cache_dbm) {
    462548        gnutls_db_set_retrieve_function(ctxt->session, dbm_cache_fetch);
     
    473559    }
    474560#endif
    475     else {
    476         assert(1);
    477         /* No Session Cache is Available. Opps. */
    478     }
    479     return 0;
    480 }
     561
     562    return 0;
     563}
  • src/gnutls_io.c

    rfcb122d r42307a9  
    272272                             " (%d) '%s'", rc, gnutls_strerror(rc));
    273273            }
     274            else if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
     275                rc = gnutls_alert_get(ctxt->session);
     276                ap_log_error(APLOG_MARK, APLOG_INFO, ctxt->input_rc,
     277                             ctxt->c->base_server,
     278                             "GnuTLS: Warning Alert From Client: "
     279                             " (%d) '%s'", rc, gnutls_alert_get_name(rc));
     280            }
     281            else if (rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
     282                rc = gnutls_alert_get(ctxt->session);
     283                ap_log_error(APLOG_MARK, APLOG_INFO, ctxt->input_rc,
     284                             ctxt->c->base_server,
     285                             "GnuTLS: Fatal Alert From Client: "
     286                             "(%d) '%s'", rc, gnutls_alert_get_name(rc));
     287                ctxt->input_rc = APR_EGENERAL;
     288                break;
     289            }
    274290            else {
    275291                /* Some Other Error. Report it. Die. */
     
    342358{
    343359    int ret;
    344 
     360    int errcode;
    345361    if (ctxt->status != 0) {
    346362        return;
     
    353369        if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED
    354370            || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
    355             ret = gnutls_alert_get(ctxt->session);
     371            errcode = gnutls_alert_get(ctxt->session);
    356372            ap_log_error(APLOG_MARK, APLOG_ERR, 0, ctxt->c->base_server,
    357                          "GnuTLS: Hanshake Alert (%d) '%s'.\n", ret,
    358                          gnutls_alert_get_name(ret));
     373                         "GnuTLS: Hanshake Alert (%d) '%s'.", errcode,
     374                         gnutls_alert_get_name(errcode));
    359375        }
    360376   
     
    399415
    400416    if (ctxt->status == 0) {
     417        char* server_name;
     418        int server_type;
     419        int data_len = 256;
     420       
    401421        gnutls_do_handshake(ctxt);
     422       
     423        /**
     424         * Due to issues inside the GnuTLS API, we cannot currently do TLS 1.1
     425         * Server Name Indication.
     426         */
     427        server_name = apr_palloc(ctxt->c->pool, data_len);
     428        if (gnutls_server_name_get(ctxt->session, server_name, &data_len, &server_type, 0) == 0) {
     429            if (server_type == GNUTLS_NAME_DNS) {
     430                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
     431                             ctxt->c->base_server,
     432                             "GnuTLS: TLS 1.1 Server Name: "
     433                             "%s", server_name);
     434               
     435            }
     436        }
    402437    }
    403438
     
    450485{
    451486    apr_size_t ret;
     487    apr_bucket* e;
    452488    mod_gnutls_handle_t *ctxt = (mod_gnutls_handle_t *) f->ctx;
    453489    apr_status_t status = APR_SUCCESS;
     
    470506        apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
    471507        if (AP_BUCKET_IS_EOC(bucket)) {
    472 
     508            do {
     509                ret = gnutls_alert_send(ctxt->session, GNUTLS_AL_FATAL,
     510                                        GNUTLS_A_CLOSE_NOTIFY);
     511            } while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
     512
     513            apr_bucket_copy(bucket, &e);
     514            APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e);
     515           
     516            if ((status = ap_pass_brigade(f->next, ctxt->output_bb)) != APR_SUCCESS) {
     517                apr_brigade_cleanup(ctxt->output_bb);
     518                return status;
     519            }
     520
     521            apr_brigade_cleanup(ctxt->output_bb);
    473522            gnutls_bye(ctxt->session, GNUTLS_SHUT_WR);
    474523            gnutls_deinit(ctxt->session);
    475 
     524            continue;
     525
     526        } else if (APR_BUCKET_IS_FLUSH(bucket) || APR_BUCKET_IS_EOS(bucket)) {
     527
     528            apr_bucket_copy(bucket, &e);
     529            APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e);
    476530            if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
     531                apr_brigade_cleanup(ctxt->output_bb);
    477532                return status;
    478533            }
    479             break;
    480 
    481         } else if (APR_BUCKET_IS_FLUSH(bucket) || APR_BUCKET_IS_EOS(bucket)) {
    482 
    483             if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
    484                 return status;
    485             }
    486             break;
     534            apr_brigade_cleanup(ctxt->output_bb);
     535            continue;
    487536        }
    488537        else {
     
    629678    ctxt->output_rc = ap_pass_brigade(ctxt->output_filter->next,
    630679                                      ctxt->output_bb);
    631     /* create new brigade ready for next time through */
    632     ctxt->output_bb =
    633         apr_brigade_create(ctxt->c->pool, ctxt->c->bucket_alloc);
     680    /* clear the brigade to be ready for next time */
     681    apr_brigade_cleanup(ctxt->output_bb);
     682
    634683    return (ctxt->output_rc == APR_SUCCESS) ? 1 : -1;
    635684}
     
    640689    mod_gnutls_handle_t *ctxt = ptr;
    641690
    642         /* pass along the encrypted data
    643          * need to flush since we're using SSL's malloc-ed buffer
    644          * which will be overwritten once we leave here
    645          */
    646         apr_bucket *bucket = apr_bucket_transient_create(buffer, len,
    647                                                          ctxt->output_bb->
    648                                                          bucket_alloc);
    649 
    650         ctxt->output_length += len;
    651         APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, bucket);
    652 
    653         if (write_flush(ctxt) < 0) {
    654             return -1;
    655         }
     691    /* pass along the encrypted data
     692     * need to flush since we're using SSL's malloc-ed buffer
     693     * which will be overwritten once we leave here
     694     */
     695    apr_bucket *bucket = apr_bucket_transient_create(buffer, len,
     696                                                    ctxt->output_bb->bucket_alloc);
     697    ctxt->output_length += len;
     698    APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, bucket);
     699
     700    if (write_flush(ctxt) < 0) {
     701        return -1;
     702    }
    656703    return len;
    657704}
  • src/mod_gnutls.c

    rfcb122d r42307a9  
    190190
    191191            if (sc->cert_file != NULL && sc->key_file != NULL) {
     192
    192193                rv = gnutls_certificate_set_x509_key_file(sc->certs, sc->cert_file,
    193194                                                 sc->key_file,
     
    215216    } /* first_run */
    216217
    217     ap_add_version_component(p, "GnuTLS/" LIBGNUTLS_VERSION);
     218    ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION);
    218219
    219220    return OK;
     
    265266
    266267    return 443;
     268}
     269
     270/* TODO: Complete support for Server Name Indication */
     271static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret)
     272{
     273    char* server_name;
     274    int server_type;
     275    int data_len = 256;
     276    mod_gnutls_handle_t *ctxt;   
     277    ctxt = gnutls_transport_get_ptr(session);
     278
     279    ret->type = GNUTLS_CRT_X509;
     280    ret->ncerts = 1;
     281    server_name = apr_palloc(ctxt->c->pool, data_len);
     282    if (gnutls_server_name_get(ctxt->session, server_name, &data_len, &server_type, 0) == 0) {
     283        if (server_type == GNUTLS_NAME_DNS) {
     284            ap_log_error(APLOG_MARK, APLOG_INFO, 0,
     285                         ctxt->c->base_server,
     286                         "GnuTLS: Virtual Host: "
     287                         "%s", server_name);
     288        }
     289    }
     290
     291    return 0;
    267292}
    268293
     
    300325    gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, sc->certs);
    301326
    302 //  if(anon) {
    303 //    gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON, sc->anoncred);
    304 //  }
    305 
    306327    gnutls_certificate_server_set_request(ctxt->session, GNUTLS_CERT_IGNORE);
    307328
    308329    mod_gnutls_cache_session_init(ctxt);
     330
     331    /* TODO: Finish Support for Server Name Indication */
     332    /* gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn); */
    309333    return ctxt;
    310334}
     
    342366static int mod_gnutls_hook_fixups(request_rec *r)
    343367{
     368    unsigned char sbuf[GNUTLS_MAX_SESSION_ID];
     369    char buf[GNUTLS_SESSION_ID_STRING_LEN];
    344370    const char* tmp;
     371    int len;
    345372    mod_gnutls_handle_t *ctxt;
    346373    apr_table_t *env = r->subprocess_env;
     
    353380
    354381    apr_table_setn(env, "HTTPS", "on");
     382
     383    apr_table_setn(env, "GNUTLS_VERSION_INTERFACE", MOD_GNUTLS_VERSION);
     384    apr_table_setn(env, "GNUTLS_VERSION_LIBRARY", LIBGNUTLS_VERSION);
     385
    355386    apr_table_setn(env, "SSL_PROTOCOL",
    356387                   gnutls_protocol_get_name(gnutls_protocol_get_version(ctxt->session)));
     388
    357389    apr_table_setn(env, "SSL_CIPHER",
    358390                   gnutls_cipher_get_name(gnutls_cipher_get(ctxt->session)));
    359391
     392    apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE");
     393
    360394    tmp = apr_psprintf(r->pool, "%d",
    361395              8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session)));
    362396
    363397    apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp);
     398
    364399    apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp);
    365400
     401    len = sizeof(sbuf);
     402    gnutls_session_get_id(ctxt->session, sbuf, &len);
     403    tmp = mod_gnutls_session_id2sz(sbuf, len, buf, sizeof(buf));
     404    apr_table_setn(env, "SSL_SESSION_ID", tmp);
     405   
    366406    return OK;
    367407}
     
    385425                                                        module_config,
    386426                                                        &gnutls_module);
     427   
    387428    sc->key_file = ap_server_root_relative(parms->pool, arg);
    388429    return NULL;
     
    509550
    510551    gnutls_certificate_allocate_credentials(&sc->certs);
    511     gnutls_anon_allocate_server_credentials(&sc->anoncred);
    512552    sc->key_file = NULL;
    513553    sc->cert_file = NULL;
Note: See TracChangeset for help on using the changeset viewer.