~ubuntu-branches/ubuntu/breezy/aolserver4-nsopenssl/breezy

« back to all changes in this revision

Viewing changes to nsopenssl.c

  • Committer: Bazaar Package Importer
  • Author(s): Francesco Paolo Lovergine
  • Date: 2004-10-20 17:04:01 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041020170401-mwubft23zl4g5hhf
Tags: 3.0beta22-3
Added x509.o linking, it was missed due to oversight in the new Makefile :-/
Thanks Luke Pond.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
 */
34
34
 
35
35
static const char *RCSID =
36
 
    "@(#) $Header: /cvsroot/aolserver/nsopenssl/nsopenssl.c,v 1.66 2004/01/19 23:03:11 scottg Exp $, compiled: "
 
36
    "@(#) $Header: /cvsroot/aolserver/nsopenssl/nsopenssl.c,v 1.75 2004/08/25 21:36:53 dossy Exp $, compiled: "
37
37
    __DATE__ " " __TIME__;
38
38
 
39
39
#include "nsopenssl.h"
234
234
    char          *lockName   = NULL;
235
235
 
236
236
    Ns_DStringInit(&ds);
237
 
 
238
237
    thisServer = ns_malloc(sizeof(Server));
239
 
    if (thisServer == NULL)
 
238
    if (thisServer == NULL) {
240
239
        Ns_Log(Fatal, "%s (%s): memory allocation failed");
241
 
 
 
240
    }
242
241
    thisServer->server = server;
243
242
    thisServer->defaultservercontext = NULL;
244
243
    thisServer->defaultclientcontext = NULL;
245
244
    thisServer->nextSessionCacheId = 1;
246
 
 
247
245
    Ns_MutexInit(&thisServer->lock);
248
246
    Ns_DStringPrintf(&ds, "server:%s", server);
249
247
    lockName = Ns_DStringExport(&ds);
251
249
    Ns_DStringTrunc(&ds, 0);
252
250
    ns_free(lockName);
253
251
    lockName = NULL;
254
 
 
255
252
    hPtr = Tcl_CreateHashEntry(&NsOpenSSLServers, server, &new);
256
253
    Tcl_SetHashValue(hPtr, thisServer);
257
254
    Tcl_InitHashTable(&thisServer->sslcontexts, TCL_STRING_KEYS);
305
302
                server, MODULE);
306
303
        return;
307
304
    }
308
 
 
309
305
    for (i = 0; i < Ns_SetSize(sslcontexts); ++i) {
310
306
        name = Ns_SetKey(sslcontexts, i);
311
307
        Ns_Log(Notice, "%s (%s): loading SSL context '%s'", MODULE, server, name);
325
321
 
326
322
    path = Ns_ConfigGetPath(server, MODULE, "defaults", NULL);
327
323
    defaults = Ns_ConfigGetSection(path);
328
 
 
329
324
    if (defaults == NULL) {
330
325
        Ns_Log(Notice, "%s (%s): no default SSL contexts defined for this server", 
331
326
                MODULE, server);
332
327
        return;
333
328
    }
334
 
 
335
329
    for (i = 0; i < Ns_SetSize(defaults); ++i) {
336
330
        name = Ns_SetKey(defaults, i);
337
331
        value = Ns_ConfigGetValue(path, name);
338
 
 
339
 
        //Ns_Log(Debug, "LoadSSLContexts: default context name = (%s), value = (%s)", name, value); 
340
 
 
341
332
        sslcontext = Ns_OpenSSLServerSSLContextGet(server, value);
342
333
        if (sslcontext != NULL) {
343
334
            Ns_Log(Notice, "%s (%s): default SSL context for %s is %s", MODULE, server, name, value);
344
 
            if (STREQ(name, "server")) {
 
335
            if (STRIEQ(name, "server")) {
345
336
                thisServer->defaultservercontext = value;
346
337
                Ns_Log(Notice, "default server SSL context: %s", thisServer->defaultservercontext);
347
 
            } else if (STREQ(name, "client")) {
 
338
            } else if (STRIEQ(name, "client")) {
348
339
                thisServer->defaultclientcontext = value;
349
340
                Ns_Log(Notice, "default client SSL context: %s", thisServer->defaultclientcontext);
350
341
            } else {
401
392
                MODULE, server, name);
402
393
        return NULL;
403
394
    }
404
 
 
405
395
    sslcontext = NsOpenSSLContextCreate(server, name);
406
396
 
407
397
    /*
433
423
    if (certFile != NULL) {
434
424
        NsOpenSSLContextCertFileSet(server, sslcontext, certFile);
435
425
    }
436
 
 
437
426
    keyFile = Ns_ConfigGetValue(path, "keyfile");
438
427
    if (keyFile != NULL) {
439
428
        NsOpenSSLContextKeyFileSet(server, sslcontext, keyFile);
447
436
    if (protocols != NULL) {
448
437
        NsOpenSSLContextProtocolsSet(server, sslcontext, protocols);
449
438
    }
450
 
 
451
439
    cipherSuite = Ns_ConfigGetValue(path, "ciphersuite");
452
440
    if (cipherSuite != NULL) {
453
441
        NsOpenSSLContextCipherSuiteSet(server, sslcontext, cipherSuite);
463
451
    if (caFile != NULL) {
464
452
        NsOpenSSLContextCAFileSet(server, sslcontext, caFile);
465
453
    }
466
 
 
467
454
    caDir = Ns_ConfigGetValue(path, "cadir");
468
455
    if (caDir != NULL) {
469
456
        NsOpenSSLContextCADirSet(server, sslcontext, caDir);
497
484
    if (sessionCache == NS_TRUE) {
498
485
        NsOpenSSLContextSessionCacheSet(server, sslcontext, sessionCache);
499
486
    }
500
 
 
501
487
    if (Ns_ConfigGetInt(path, "sessioncachesize", &sessionCacheSize) == NS_TRUE) {
502
488
        NsOpenSSLContextSessionCacheSizeSet(server, sslcontext, sessionCacheSize);
503
489
    }
504
 
 
505
490
    if (Ns_ConfigGetInt(path, "sessioncachetimeout", &sessionCacheTimeout) == NS_TRUE) {
506
491
        NsOpenSSLContextSessionCacheTimeoutSet(server, sslcontext, sessionCacheTimeout);
507
492
    }
542
527
{
543
528
    char *server = (char *) arg;
544
529
 
545
 
    /* XXX Ns_RegisterAtShutdown isn't calling this function at shutdown time */
546
 
    /* XXX in AOLserver 4.0. */
547
 
 
548
530
    Ns_Log(Notice, "Shutdown called for server %s", server);
549
531
 
550
532
    /*
557
539
     *   free vserver
558
540
     */
559
541
 
560
 
 
561
542
    return;
562
543
}
563
544
 
597
578
    if (CRYPTO_set_mem_functions(ns_malloc, ns_realloc, ns_free) == 0)
598
579
        Ns_Log(Warning, "%s: OpenSSL memory callbacks failed in InitOpenSSL",
599
580
                MODULE);
600
 
 
601
581
    num_locks = CRYPTO_num_locks();
602
582
    locks = ns_calloc(num_locks, sizeof(*locks));
603
 
 
604
583
    for (i = 0; i < num_locks; i++) {
605
584
        Ns_DStringPrintf(&ds, "crypto:%d", i);
606
585
        lockName = Ns_DStringExport(&ds);
609
588
        ns_free(lockName);
610
589
        lockName = NULL;
611
590
    }
612
 
 
613
591
    Ns_DStringFree(&ds);
614
 
 
615
592
    CRYPTO_set_locking_callback(ThreadLockCallback);
616
593
    CRYPTO_set_id_callback(ThreadIdCallback);
617
594
 
633
610
        Ns_Log(Notice, "%s: Seeding OpenSSL's PRNG", MODULE);
634
611
        SeedPRNG();
635
612
    }
636
 
 
637
613
    if (! RAND_status()) {
638
614
        Ns_Log(Warning, "%s: PRNG fails to have enough entropy after %d tries", 
639
615
                MODULE, seedcnt);
680
656
    if (RAND_status()) {
681
657
        return NS_TRUE;
682
658
    } 
683
 
 
684
659
    path = Ns_ConfigGetPath(MODULE, NULL);
685
 
 
686
660
    if (Ns_ConfigGetInt(path, "seedbytes", &seedBytes) == NS_FALSE) {
687
661
        seedBytes = DEFAULT_SEEDBYTES;
688
662
    }
689
 
 
690
663
    if (Ns_ConfigGetInt(path, "maxbytes", &maxBytes) == NS_FALSE) {
691
664
        maxBytes = DEFAULT_MAXBYTES;
692
665
    }
708
681
    } else {
709
682
        Ns_Log(Warning, "%s: No randomFile set and/or found", MODULE);
710
683
    }
711
 
 
712
684
    if (RAND_status()) {
713
685
        return NS_TRUE;
714
686
    }
720
692
    size = sizeof(double) * seedBytes;
721
693
    buf_ptr = Ns_Malloc(size);
722
694
    bufoffset_ptr = buf_ptr;
723
 
 
724
695
    for (i = 0; i < seedBytes; i++) {
725
696
        *bufoffset_ptr = Ns_DRand();
726
697
        bufoffset_ptr++;
727
698
    }
728
 
 
729
699
    RAND_add(buf_ptr, seedBytes, (double) seedBytes);
730
700
    ns_free(buf_ptr);
731
 
 
732
701
    if (!RAND_status()) {
733
702
        Ns_Log(Warning, "%s: failed to seed PRNG", MODULE);
734
703
        return NS_FALSE;
811
780
    Ns_DString  ds;
812
781
 
813
782
    Ns_DStringInit(&ds);
814
 
 
815
783
    lock = ns_calloc(1, sizeof(*lock));
816
784
    Ns_DStringVarAppend(&ds, "openssl: ", file, ": ");
817
785
    Ns_DStringPrintf(&ds, "%d", line);
818
786
    Ns_MutexSetName2(lock, MODULE, Ns_DStringValue(&ds));
 
787
 
819
788
    return (struct CRYPTO_dynlock_value *) lock;
820
789
}
821
790
 
901
870
 
902
871
    path = Ns_ConfigGetPath(server, MODULE, "ssldrivers", NULL);
903
872
    ssldrivers = Ns_ConfigGetSection(path);
904
 
 
905
873
    if (ssldrivers == NULL) {
906
874
        Ns_Log(Notice, "%s (%s): no SSL drivers defined for this server", 
907
875
                MODULE, server);
908
876
        return;
909
877
    }
910
 
 
911
878
    for (i = 0; i < Ns_SetSize(ssldrivers); ++i) {
912
879
        name = Ns_SetKey(ssldrivers, i);
913
880
        Ns_Log(Notice, "%s (%s): loading '%s' SSL driver", MODULE, server, name);
914
 
 
915
881
        path = Ns_ConfigGetPath(server, MODULE, "ssldriver", name, NULL);
916
882
        if (path == NULL) {
917
883
            Ns_Log(Error, "%s (%s): SSL driver '%s' not defined in configuration file",
918
884
                    MODULE, server, name);
919
885
            continue;
920
886
        }
921
 
 
922
887
        sslcontextname = Ns_ConfigGetValue(path, "sslcontext");
923
888
        if (sslcontextname == NULL) {
924
889
            Ns_Log(Error, "%s (%s): 'sslcontext' parameter not defined for driver '%s'",
937
902
         */
938
903
 
939
904
        ssldriver = ns_calloc(1, sizeof(NsOpenSSLDriver));
940
 
 
941
 
        //Ns_Log(Debug, "LoadSSLDrivers: ssldriver = (%p)", ssldriver);
942
 
 
943
905
        ssldriver->server     = server;
944
906
        ssldriver->sslcontext = sslcontext;
945
907
        ssldriver->name       = name;
946
908
        ssldriver->path       = path;
947
909
        ssldriver->refcnt     = 0;
948
 
 
949
910
        if (!Ns_ConfigGetInt(path, "port", &ssldriver->port)) {
950
911
            ssldriver->port = 443;
951
912
        }
980
941
static int
981
942
InitSSLDriver(char *server, NsOpenSSLDriver *ssldriver)
982
943
{
983
 
    /* XXX uninitialized here */
984
944
    Ns_DriverInitData  init;
985
945
    Server            *thisServer = NULL;
986
946
    Tcl_HashEntry     *hPtr       = NULL;
1104
1064
static int
1105
1065
OpenSSLProc(Ns_DriverCmd cmd, Ns_Sock *sock, struct iovec *bufs, int nbufs)
1106
1066
{
1107
 
    NsOpenSSLDriver *ssldriver = (NsOpenSSLDriver *) sock->driver->arg;
1108
 
    NsOpenSSLConn   *sslconn   = (NsOpenSSLConn *) sock->arg;
1109
 
    int              n         = 0;
1110
 
    int              total     = 0;
 
1067
    NsOpenSSLDriver *driver = (NsOpenSSLDriver *) sock->driver->arg;
 
1068
    NsOpenSSLConn   *conn   = (NsOpenSSLConn *)   sock->arg;
 
1069
    int n = -1, total, op;
1111
1070
 
1112
1071
    switch (cmd) {
1113
1072
        case DriverRecv:
1114
1073
        case DriverSend:
1115
 
 
1116
 
            /* 
1117
 
             * Create the SSL layer on first I/O and run SSL handshake.
1118
 
             */
1119
 
 
1120
 
            if (sslconn == NULL) {
1121
 
#if 0
1122
 
                /* XXX core driver socket handles this, no? */
1123
 
                /* XXX look at interaction issues - when driver sock dies, how do I handle it? */
1124
 
                n = sock->driver->recvwait;
1125
 
                if (n > sock->driver->sendwait) 
1126
 
                    n = sock->driver->sendwait;
1127
 
#endif
1128
 
 
1129
 
                sslconn = NsOpenSSLConnCreate(sock->sock, ssldriver->sslcontext);
1130
 
                if (sslconn == NULL) {
1131
 
                    return NS_ERROR;
1132
 
                }
1133
 
                sslconn->refcnt++;
1134
 
 
1135
 
                // XXX Ns_Log(Debug, "OpenSSLProc: ssldriver = (%p), sslcontext = (%p), sslconn = (%p)", 
1136
 
                // XXX        ssldriver, ssldriver->sslcontext, sslconn);
1137
 
 
1138
 
                /* XXX find way to ditch this part -- set later or on-demand */
1139
 
                sslconn->peerport = ssldriver->port;
1140
 
                sock->arg = (void *) sslconn;
 
1074
            if (conn == NULL) {
 
1075
                /* 
 
1076
                 * If first connection, wrap SSL around the socket.
 
1077
                 */
 
1078
 
 
1079
                conn = NsOpenSSLConnCreate(sock->sock, driver->sslcontext);
 
1080
                conn->refcnt++;
 
1081
                conn->peerport  = driver->port;
 
1082
                conn->recvwait  = sock->driver->recvwait;
 
1083
                conn->sendwait  = sock->driver->sendwait;
 
1084
                sock->arg       = (void *) conn;
1141
1085
            }
1142
1086
 
1143
1087
            /* 
1144
 
             * Process each buffer one at a time 
 
1088
             * Process each buffer one at a time.
1145
1089
             */
1146
1090
 
 
1091
            op = (cmd == DriverSend) ? NSOPENSSL_SEND : NSOPENSSL_RECV;
1147
1092
            total = 0;
1148
1093
            do {
1149
 
                if (cmd == DriverSend) {
1150
 
                    // XXX Ns_Log(Debug, "OpenSSLProc: DriverSend: towrite = %d", (int) bufs->iov_len);
1151
 
                    n = NsOpenSSLConnSend(sslconn->ssl, bufs->iov_base, (int) bufs->iov_len);
1152
 
                } else {
1153
 
                    // XXX Ns_Log(Debug, "OpenSSLProc: DriverRecv: toread = %d", (int) bufs->iov_len);
1154
 
                    n = NsOpenSSLConnRecv(sslconn->ssl, bufs->iov_base, (int) bufs->iov_len);
1155
 
                }
1156
 
                if (n < 0 && total > 0) {
1157
 
                    /* NB: Mask error if some bytes were read. */
1158
 
                    n = 0;
 
1094
                n = NsOpenSSLConnOp(conn->ssl, bufs->iov_base,
 
1095
                        (int) bufs->iov_len, op);
 
1096
                if (n > 0) {
 
1097
                    total += n;
1159
1098
                }
1160
1099
                ++bufs;
1161
 
                total += n;
1162
1100
            } while (n > 0 && --nbufs > 0);
1163
 
            n = total;
 
1101
            if (n > 0) {
 
1102
                n = total;
 
1103
            }
1164
1104
            break;
1165
1105
 
1166
1106
        case DriverKeep:
1167
 
            if (sslconn != NULL && NsOpenSSLConnFlush(sslconn) == NS_OK) {
 
1107
            if (conn != NULL && NsOpenSSLConnFlush(conn) == NS_OK) {
1168
1108
                n = 0;
1169
1109
            } else {
1170
1110
                n = -1;
1172
1112
            break;
1173
1113
 
1174
1114
        case DriverClose:
1175
 
            if (sslconn != NULL) {
1176
 
                (void) NsOpenSSLConnFlush(sslconn);
1177
 
                NsOpenSSLConnDestroy(sslconn);
 
1115
            if (conn != NULL) {
 
1116
                (void) NsOpenSSLConnFlush(conn);
 
1117
                NsOpenSSLConnDestroy(conn);
1178
1118
                sock->arg = NULL;
1179
1119
            }
1180
1120
            n = 0;
1181
1121
            break;
1182
1122
 
1183
1123
        default:
1184
 
            Ns_Log(Error, "%s (%s): Unsupported driver command encountered", 
1185
 
                    MODULE, ssldriver->server);
 
1124
            Ns_Log(Error, "%s (%s): Unsupported driver command '%d'", 
 
1125
                    MODULE, driver->server, cmd);
1186
1126
            n = -1;
1187
1127
            break;
1188
1128
    }
1189
 
 
1190
1129
    return n;
1191
1130
}
1192
1131