~ubuntu-branches/ubuntu/raring/nss/raring-security

« back to all changes in this revision

Viewing changes to mozilla/security/nss/cmd/selfserv/selfserv.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2010-03-25 13:46:06 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20100325134606-bl6liuok2w9l7snv
Tags: 3.12.6-0ubuntu1
* New upstream release 3.12.6 RTM (NSS_3_12_6_RTM)
  - fixes CVE-2009-3555 aka US-CERT VU#120541
* Adjust patches to changed upstream code base
  - update debian/patches/38_kbsd.patch
  - update debian/patches/38_mips64_build.patch
  - update debian/patches/85_security_load.patch
* Remove patches that are merged upstream
  - delete debian/patches/91_nonexec_stack.patch
  - update debian/patches/series
* Bump nspr dependency to 4.8
  - update debian/control
* Add new symbols for 3.12.6
  - update debian/libnss3-1d.symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
176
176
"Usage: %s -n rsa_nickname -p port [-3BDENRSTbjlmrsuvx] [-w password]\n"
177
177
"         [-t threads] [-i pid_file] [-c ciphers] [-d dbdir] [-g numblocks]\n"
178
178
"         [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n"
 
179
"         [-a sni_name]\n"
179
180
#ifdef NSS_ENABLE_ECC
180
181
"         [-C SSLCacheEntries] [-e ec_nickname]\n"
181
182
#else
189
190
"-D means disable Nagle delays in TCP\n"
190
191
"-E means disable export ciphersuites and SSL step down key gen\n"
191
192
"-R means disable detection of rollback from TLS to SSL3\n"
 
193
"-a configure server for SNI.\n"
 
194
"-k expected name negotiated on server sockets"
192
195
"-b means try binding to the port and exit\n"
193
196
"-m means test the model-socket feature of SSL_ImportFD.\n"
194
197
"-r flag is interepreted as follows:\n"
200
203
"-u means enable Session Ticket extension for TLS.\n"
201
204
"-v means verbose output\n"
202
205
"-x means use export policy.\n"
 
206
"-z means enable compression.\n"
203
207
"-L seconds means log statistics every 'seconds' seconds (default=30).\n"
204
208
"-M maxProcs tells how many processes to run in a multi-process server\n"
205
209
"-N means do NOT use the server session cache.  Incompatible with -M.\n"
387
391
               suite.effectiveKeyBits, suite.symCipherName, 
388
392
               suite.macBits, suite.macAlgorithmName);
389
393
            FPRINTF(stderr, 
390
 
            "selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n",
 
394
            "selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n"
 
395
            "          Compression: %s\n",
391
396
               channel.authKeyBits, suite.authAlgorithmName,
392
 
               channel.keaKeyBits,  suite.keaTypeName);
 
397
               channel.keaKeyBits,  suite.keaTypeName,
 
398
               channel.compressionMethodName);
393
399
        }
394
400
    }
 
401
    if (verbose) {
 
402
        SECItem *hostInfo  = SSL_GetNegotiatedHostInfo(fd);
 
403
        if (hostInfo) {
 
404
            char namePref[] = "selfserv: Negotiated server name: ";
 
405
 
 
406
            fprintf(stderr, "%s", namePref);
 
407
            fwrite(hostInfo->data, hostInfo->len, 1, stderr);
 
408
            SECITEM_FreeItem(hostInfo, PR_TRUE);
 
409
            hostInfo = NULL;
 
410
            fprintf(stderr, "\n");
 
411
        }
 
412
    }
395
413
    if (requestCert)
396
414
        cert = SSL_PeerCertificate(fd);
397
415
    else
426
444
    return (MakeCertOK ? SECSuccess : SECFailure);
427
445
}
428
446
 
 
447
#define MAX_VIRT_SERVER_NAME_ARRAY_INDEX  10
 
448
 
 
449
/* Simple SNI socket config function that does not use SSL_ReconfigFD.
 
450
 * Only uses one server name but verifies that the names match. */
 
451
PRInt32 
 
452
mySSLSNISocketConfig(PRFileDesc *fd, const SECItem *sniNameArr,
 
453
                     PRUint32 sniNameArrSize, void *arg)
 
454
{
 
455
    PRInt32        i = 0;
 
456
    const SECItem *current = sniNameArr;
 
457
    const char    **nameArr = (const char**)arg;
 
458
    const secuPWData *pwdata;
 
459
    CERTCertificate *    cert = NULL;
 
460
    SECKEYPrivateKey *   privKey = NULL;
 
461
 
 
462
    PORT_Assert(fd && sniNameArr);
 
463
    if (!fd || !sniNameArr) {
 
464
        return SSL_SNI_SEND_ALERT;
 
465
    }
 
466
 
 
467
    pwdata = SSL_RevealPinArg(fd);
 
468
 
 
469
    for (;current && i < sniNameArrSize;i++) {
 
470
        int j = 0;
 
471
        for (;j < MAX_VIRT_SERVER_NAME_ARRAY_INDEX && nameArr[j];j++) {
 
472
            if (!PORT_Strncmp(nameArr[j],
 
473
                              (const char *)current[i].data,
 
474
                              current[i].len) &&
 
475
                PORT_Strlen(nameArr[j]) == current[i].len) {
 
476
                const char *nickName = nameArr[j];
 
477
                if (j == 0) {
 
478
                    /* default cert */
 
479
                    return 0;
 
480
                }
 
481
                /* if pwdata is NULL, then we would not get the key and
 
482
                 * return an error status. */
 
483
                cert = PK11_FindCertFromNickname(nickName, &pwdata);
 
484
                if (cert == NULL) {
 
485
                    goto loser; /* Send alert */
 
486
                }
 
487
                privKey = PK11_FindKeyByAnyCert(cert, &pwdata);
 
488
                if (privKey == NULL) {
 
489
                    goto loser; /* Send alert */
 
490
                }
 
491
                if (SSL_ConfigSecureServer(fd, cert, privKey,
 
492
                                           kt_rsa) != SECSuccess) {
 
493
                    goto loser; /* Send alert */
 
494
                }
 
495
                SECKEY_DestroyPrivateKey(privKey);
 
496
                CERT_DestroyCertificate(cert);
 
497
                return i;
 
498
            }
 
499
        }
 
500
    }
 
501
loser:
 
502
    if (privKey) {
 
503
        SECKEY_DestroyPrivateKey(privKey);
 
504
    }
 
505
    if (cert) {
 
506
        CERT_DestroyCertificate(cert);
 
507
    }
 
508
    return SSL_SNI_SEND_ALERT;
 
509
}
 
510
 
 
511
 
429
512
/**************************************************************************
430
513
** Begin thread management routines and data.
431
514
**************************************************************************/
717
800
PRBool disableLocking  = PR_FALSE;
718
801
PRBool testbypass      = PR_FALSE;
719
802
PRBool enableSessionTickets = PR_FALSE;
 
803
PRBool enableCompression    = PR_FALSE;
 
804
PRBool failedToNegotiateName  = PR_FALSE;
 
805
static char  *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX];
720
806
 
721
807
static const char stopCmd[] = { "GET /stop " };
722
808
static const char getCmd[]  = { "GET " };
1521
1607
}
1522
1608
 
1523
1609
void
 
1610
handshakeCallback(PRFileDesc *fd, void *client_data)
 
1611
{
 
1612
    const char *handshakeName = (const char *)client_data;
 
1613
    if (handshakeName && !failedToNegotiateName) {
 
1614
        SECItem *hostInfo  = SSL_GetNegotiatedHostInfo(fd);
 
1615
        if (!hostInfo || PORT_Strncmp(handshakeName, (char*)hostInfo->data,
 
1616
                                      hostInfo->len)) {
 
1617
            failedToNegotiateName = PR_TRUE;
 
1618
        }
 
1619
    }
 
1620
}
 
1621
 
 
1622
void
1524
1623
server_main(
1525
1624
    PRFileDesc *        listen_sock,
1526
1625
    int                 requestCert, 
1527
1626
    SECKEYPrivateKey ** privKey,
1528
 
    CERTCertificate **  cert)
 
1627
    CERTCertificate **  cert,
 
1628
    const char *expectedHostNameVal)
1529
1629
{
1530
1630
    PRFileDesc *model_sock      = NULL;
1531
1631
    int         rv;
1599
1699
        }
1600
1700
    }
1601
1701
 
 
1702
    if (enableCompression) {
 
1703
        rv = SSL_OptionSet(model_sock, SSL_ENABLE_DEFLATE, PR_TRUE);
 
1704
        if (rv != SECSuccess) {
 
1705
            errExit("error enabling compression ");
 
1706
        }
 
1707
    }
 
1708
 
 
1709
    rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig,
 
1710
                                 (void*)&virtServerNameArray);
 
1711
    if (rv != SECSuccess) {
 
1712
        errExit("error enabling SNI extension ");
 
1713
    }
 
1714
 
1602
1715
    for (kea = kt_rsa; kea < kt_kea_size; kea++) {
1603
1716
        if (cert[kea] != NULL) {
1604
1717
            secStatus = SSL_ConfigSecureServer(model_sock, 
1631
1744
        errExit("SSL_CipherPrefSetDefault:SSL_RSA_WITH_NULL_MD5");
1632
1745
    }
1633
1746
 
 
1747
    if (expectedHostNameVal) {
 
1748
        SSL_HandshakeCallback(model_sock, handshakeCallback,
 
1749
                              (void*)expectedHostNameVal);
 
1750
    }
1634
1751
 
1635
1752
    if (requestCert) {
1636
1753
        SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate, 
1818
1935
    SSL3Statistics      *ssl3stats;
1819
1936
    PRUint32             i;
1820
1937
    secuPWData  pwdata = { PW_NONE, 0 };
1821
 
 
 
1938
    int                  virtServerNameIndex = 1;
 
1939
    char                *expectedHostNameVal = NULL;
 
1940
 
1822
1941
    tmp = strrchr(argv[0], '/');
1823
1942
    tmp = tmp ? tmp + 1 : argv[0];
1824
1943
    progName = strrchr(tmp, '\\');
1830
1949
    ** numbers, then capital letters, then lower case, alphabetical. 
1831
1950
    */
1832
1951
    optstate = PL_CreateOptState(argc, argv, 
1833
 
        "2:3BC:DEL:M:NP:RSTbc:d:e:f:g:hi:jlmn:op:qrst:uvw:xy");
 
1952
        "2:3BC:DEL:M:NP:RSTa:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz");
1834
1953
    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
1835
1954
        ++optionsFound;
1836
1955
        switch(optstate->option) {
1869
1988
 
1870
1989
        case 'T': disableTLS = PR_TRUE; break;
1871
1990
 
 
1991
        case 'a': if (virtServerNameIndex >= MAX_VIRT_SERVER_NAME_ARRAY_INDEX) {
 
1992
                      Usage(progName);
 
1993
                  }
 
1994
                  virtServerNameArray[virtServerNameIndex++] =
 
1995
                      PORT_Strdup(optstate->value); break;
 
1996
 
1872
1997
        case 'b': bindOnly = PR_TRUE; break;
1873
1998
 
1874
1999
        case 'c': cipherString = PORT_Strdup(optstate->value); break;
1898
2023
            loggingLayer = PR_TRUE;
1899
2024
            break;
1900
2025
 
 
2026
        case 'k': expectedHostNameVal = PORT_Strdup(optstate->value);
 
2027
                  break;
 
2028
 
1901
2029
        case 'l': useLocalThreads = PR_TRUE; break;
1902
2030
 
1903
2031
        case 'm': useModelSocket = PR_TRUE; break;
1904
2032
 
1905
 
        case 'n': nickName = PORT_Strdup(optstate->value); break;
 
2033
        case 'n': nickName = PORT_Strdup(optstate->value);
 
2034
                  virtServerNameArray[0] = PORT_Strdup(optstate->value);
 
2035
                  break;
1906
2036
 
1907
2037
        case 'P': certPrefix = PORT_Strdup(optstate->value); break;
1908
2038
 
1935
2065
 
1936
2066
        case 'y': debugCache = PR_TRUE; break;
1937
2067
 
 
2068
        case 'z': enableCompression = PR_TRUE; break;
 
2069
 
1938
2070
        default:
1939
2071
        case '?':
1940
2072
            fprintf(stderr, "Unrecognized or bad option specified.\n");
2228
2360
    }
2229
2361
 
2230
2362
    if (rv == SECSuccess) {
2231
 
        server_main(listen_sock, requestCert, privKey, cert);
 
2363
        server_main(listen_sock, requestCert, privKey, cert,
 
2364
                    expectedHostNameVal);
2232
2365
    }
2233
2366
 
2234
2367
    VLOG(("selfserv: server_thread: exiting"));
2240
2373
        fprintf(stderr, "selfserv: Experienced ticket parse failure(s)\n");
2241
2374
        exit(1);
2242
2375
    }
 
2376
    if (failedToNegotiateName) {
 
2377
        fprintf(stderr, "selfserv: Failed properly negotiate server name\n");
 
2378
        exit(1);
 
2379
    }
2243
2380
 
2244
2381
    {
2245
2382
        int i;
2251
2388
                SECKEY_DestroyPrivateKey(privKey[i]);
2252
2389
            }
2253
2390
        }
 
2391
        for (i = 0;virtServerNameArray[i];i++) {
 
2392
            PORT_Free(virtServerNameArray[i]);
 
2393
        }
2254
2394
    }
2255
2395
 
2256
2396
    if (debugCache) {
2257
2397
        nss_DumpCertificateCacheInfo();
2258
2398
    }
2259
 
 
2260
2399
    if (nickName) {
2261
2400
        PORT_Free(nickName);
2262
2401
    }
 
2402
    if (expectedHostNameVal) {
 
2403
        PORT_Free(expectedHostNameVal);
 
2404
    }
2263
2405
    if (passwd) {
2264
2406
        PORT_Free(passwd);
2265
2407
    }