00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 const char *XrdSecProtocolsslCVSID = "$Id: XrdSecProtocolssl.cc 38011 2011-02-08 18:35:57Z ganis $";
00015
00016 #include "XrdSecProtocolssl.hh"
00017
00018 char* XrdSecProtocolssl::sslcadir=0;
00019 char* XrdSecProtocolssl::sslvomsdir=0;
00020 char* XrdSecProtocolssl::procdir=(char*)"";
00021 XrdSecProtocolsslProc* XrdSecProtocolssl::proc=(XrdSecProtocolsslProc*)0;
00022 int XrdSecProtocolssl::verifydepth=10;
00023 int XrdSecProtocolssl::verifyindex=0;
00024 int XrdSecProtocolssl::sslselecttimeout=10;
00025 int XrdSecProtocolssl::sslsessioncachesize=2000;
00026 char* XrdSecProtocolssl::sslkeyfile=0;
00027 char* XrdSecProtocolssl::sslserverkeyfile=0;
00028 char XrdSecProtocolssl::sslserverexportpassword[EXPORTKEYSTRENGTH+1];
00029 char* XrdSecProtocolssl::sslcertfile=0;
00030 char* XrdSecProtocolssl::sslproxyexportdir=(char*)0;
00031 bool XrdSecProtocolssl::sslproxyexportplain=1;
00032 int XrdSecProtocolssl::debug=0;
00033 time_t XrdSecProtocolssl::sslsessionlifetime=86400;
00034 bool XrdSecProtocolssl::isServer=0;
00035 bool XrdSecProtocolssl::forwardProxy=0;
00036 bool XrdSecProtocolssl::allowSessions=0;
00037 char* XrdSecProtocolssl::SessionIdContext = (char*)"xrootdssl";
00038 char* XrdSecProtocolssl::gridmapfile = (char*) "/etc/grid-security/grid-mapfile";
00039 bool XrdSecProtocolssl::mapuser = false;
00040 bool XrdSecProtocolssl::mapnobody = false;
00041 char* XrdSecProtocolssl::vomsmapfile = (char*) "/etc/grid-security/voms-mapfile";
00042 bool XrdSecProtocolssl::mapgroup = false;
00043 bool XrdSecProtocolssl::mapcerncertificates = false;
00044 int XrdSecProtocolssl::threadsinuse=0;
00045 int XrdSecProtocolssl::errortimeout=0;
00046 int XrdSecProtocolssl::errorverify=0;
00047 int XrdSecProtocolssl::errorqueue=0;
00048 int XrdSecProtocolssl::erroraccept=0;
00049 int XrdSecProtocolssl::errorread=0;
00050 int XrdSecProtocolssl::errorabort=0;
00051 int XrdSecProtocolssl::forwardedproxies=0;
00052 X509_STORE* XrdSecProtocolssl::store=0;
00053 X509_LOOKUP* XrdSecProtocolssl::lookup=0;
00054 SSL_CTX* XrdSecProtocolssl::ctx=0;
00055 XrdSysError XrdSecProtocolssl::ssleDest(0, "secssl_");
00056 XrdSysLogger XrdSecProtocolssl::Logger;
00057 time_t XrdSecProtocolssl::storeLoadTime;
00058
00059 XrdSysMutex XrdSecsslSessionLock::sessionmutex;
00060 XrdOucHash<XrdOucString> XrdSecProtocolssl::gridmapstore;
00061 XrdOucHash<XrdOucString> XrdSecProtocolssl::vomsmapstore;
00062 XrdOucHash<XrdOucString> XrdSecProtocolssl::stringstore;
00063 XrdSysMutex XrdSecProtocolssl::StoreMutex;
00064 XrdSysMutex XrdSecProtocolssl::GridMapMutex;
00065 XrdSysMutex XrdSecProtocolssl::VomsMapMutex;
00066 XrdSysMutex* XrdSecProtocolssl::CryptoMutexPool[PROTOCOLSSL_MAX_CRYPTO_MUTEX];
00067 XrdSysMutex XrdSecProtocolssl::ThreadsInUseMutex;
00068 XrdSysMutex XrdSecProtocolssl::ErrorMutex;
00069
00070 XrdSysMutex SSLTRACEMUTEX;
00071
00072
00073
00074
00075 static unsigned long protocolssl_id_callback(void) {
00076 return (unsigned long)XrdSysThread::ID();
00077 }
00078
00079 void protocolssl_lock(int mode, int n, const char *file, int line)
00080 {
00081 if (mode & CRYPTO_LOCK) {
00082 if (XrdSecProtocolssl::CryptoMutexPool[n]) {
00083 XrdSecProtocolssl::CryptoMutexPool[n]->Lock();
00084 }
00085 } else {
00086 if (XrdSecProtocolssl::CryptoMutexPool[n]) {
00087 XrdSecProtocolssl::CryptoMutexPool[n]->UnLock();
00088 }
00089 }
00090 }
00091
00092
00093
00094
00095
00096
00097 int secprotocolssl_pem_cb(char *buf, int size, int rwflag, void *password)
00098 {
00099 memset(buf,0,size);
00100 memcpy(buf,XrdSecProtocolssl::sslserverexportpassword,EXPORTKEYSTRENGTH+1);
00101 return EXPORTKEYSTRENGTH;
00102 }
00103
00104 void XrdSecProtocolssl::GetEnvironment() {
00105 EPNAME("GetEnvironment");
00106
00107 char proxyfile[1024];
00108 sprintf(proxyfile,"/tmp/x509up_u%d",(int)geteuid());
00109
00110 if (sslproxyexportdir) {
00111 sprintf(proxyfile,"%s/x509up_u%d",sslproxyexportdir,(int)geteuid());
00112 }
00113
00114 if (XrdSecProtocolssl::sslcertfile) { free (XrdSecProtocolssl::sslcertfile); }
00115 if (XrdSecProtocolssl::sslkeyfile) { free (XrdSecProtocolssl::sslkeyfile); }
00116
00117 XrdSecProtocolssl::sslcertfile = strdup(proxyfile);
00118 XrdSecProtocolssl::sslkeyfile = strdup(proxyfile);
00119
00120 char *cenv = getenv("XrdSecDEBUG");
00121
00122 if (cenv)
00123 if (cenv[0] >= 49 && cenv[0] <= 57) XrdSecProtocolssl::debug = atoi(cenv);
00124
00125
00126 cenv = getenv("XrdSecSSLCADIR");
00127 if (cenv) {
00128 if (XrdSecProtocolssl::sslcadir) { free (XrdSecProtocolssl::sslcadir); }
00129 XrdSecProtocolssl::sslcadir = strdup(cenv);
00130 }
00131 else {
00132
00133 cenv = getenv("X509_CERT_DIR");
00134 if (cenv) {
00135 if (XrdSecProtocolssl::sslcadir) { free (XrdSecProtocolssl::sslcadir); }
00136 XrdSecProtocolssl::sslcadir = strdup(cenv);
00137 }
00138 }
00139
00140 cenv = getenv("XrdSecSSLVOMSDIR");
00141 if (cenv) {
00142 if (XrdSecProtocolssl::sslvomsdir) { free (XrdSecProtocolssl::sslvomsdir); }
00143 XrdSecProtocolssl::sslvomsdir = strdup(cenv);
00144 }
00145
00146
00147
00148 cenv = getenv("XrdSecSSLUSERCERT");
00149 if (cenv) {
00150 if (XrdSecProtocolssl::sslcertfile) { free (XrdSecProtocolssl::sslcertfile); }
00151 XrdSecProtocolssl::sslcertfile = strdup(cenv);
00152 } else {
00153
00154 cenv = getenv("X509_USER_CERT");
00155 if (cenv) {
00156 if (XrdSecProtocolssl::sslcertfile) { free (XrdSecProtocolssl::sslcertfile); }
00157 XrdSecProtocolssl::sslcertfile = strdup(cenv);
00158 } else {
00159
00160 cenv = getenv("X509_USER_PROXY");
00161 if (cenv) {
00162 if (XrdSecProtocolssl::sslcertfile) { free (XrdSecProtocolssl::sslcertfile); }
00163 XrdSecProtocolssl::sslcertfile = strdup(cenv);
00164 }
00165 }
00166 }
00167
00168 cenv = getenv("XrdSecSSLSELECTTIMEOUT");
00169 if (cenv) {
00170 XrdSecProtocolssl::sslselecttimeout = atoi(cenv);
00171 if ( XrdSecProtocolssl::sslselecttimeout < 5) {
00172 XrdSecProtocolssl::sslselecttimeout = 5;
00173 }
00174 }
00175
00176
00177 cenv = getenv("XrdSecSSLUSERKEY");
00178 if (cenv) {
00179 if (XrdSecProtocolssl::sslkeyfile) { free (XrdSecProtocolssl::sslkeyfile); }
00180 XrdSecProtocolssl::sslkeyfile = strdup(cenv);
00181 } else {
00182
00183 cenv = getenv("X509_USER_KEY");
00184 if (cenv) {
00185 if (XrdSecProtocolssl::sslkeyfile) { free (XrdSecProtocolssl::sslkeyfile); }
00186 XrdSecProtocolssl::sslkeyfile = strdup(cenv);
00187 } else {
00188
00189 cenv = getenv("X509_USER_PROXY");
00190 if (cenv) {
00191 if (XrdSecProtocolssl::sslkeyfile) { free (XrdSecProtocolssl::sslkeyfile); }
00192 XrdSecProtocolssl::sslkeyfile = strdup(cenv);
00193 }
00194 }
00195 }
00196
00197 cenv = getenv("XrdSecSSLVERIFYDEPTH");
00198 if (cenv)
00199 XrdSecProtocolssl::verifydepth = atoi(cenv);
00200
00201
00202 cenv = getenv("XrdSecSSLPROXYFORWARD");
00203 if (cenv)
00204 XrdSecProtocolssl::forwardProxy = atoi(cenv);
00205
00206
00207 cenv = getenv("XrdSecSSLSESSION");
00208 if (cenv)
00209 XrdSecProtocolssl::allowSessions = atoi(cenv);
00210
00211 TRACE(Authen,"====> debug = " << XrdSecProtocolssl::debug);
00212 TRACE(Authen,"====> cadir = " << XrdSecProtocolssl::sslcadir);
00213 TRACE(Authen,"====> keyfile = " << XrdSecProtocolssl::sslkeyfile);
00214 TRACE(Authen,"====> certfile = " << XrdSecProtocolssl::sslcertfile);
00215 TRACE(Authen,"====> verify depth = " << XrdSecProtocolssl::verifydepth);
00216 TRACE(Authen,"====> timeout = " << XrdSecProtocolssl::sslselecttimeout);
00217 }
00218
00219 int XrdSecProtocolssl::Fatal(XrdOucErrInfo *erp, const char *msg, int rc)
00220 {
00221 const char *msgv[8];
00222 int k, i = 0;
00223
00224 msgv[i++] = "Secssl: ";
00225 msgv[i++] = msg;
00226
00227 if (erp) erp->setErrInfo(rc, msgv, i);
00228 else {for (k = 0; k < i; k++) cerr <<msgv[k];
00229 cerr <<endl;
00230 }
00231
00232 if (XrdSecProtocolssl::proc) {
00233 XrdSecProtocolsslProcFile* pf;
00234 char ErrorInfo[16384];
00235 sprintf(ErrorInfo,"errortimeout = %d\nerrorverify = %d\nerrorqueue = %d\nerroraccept = %d\nerrorread = %d\nerrorabort = %d", errortimeout, errorverify, errorqueue, erroraccept, errorread, errorabort);
00236 pf= XrdSecProtocolssl::proc->Handle("error"); pf && pf->Write(ErrorInfo);
00237 }
00238
00239 return -1;
00240 }
00241
00242
00243 int ssl_select(int fd) {
00244
00245 if (fd<0)
00246 return -1;
00247
00248 fd_set read_mask;
00249
00250 struct timeval timeout;
00251
00252 timeout.tv_sec = 0;
00253 timeout.tv_usec = 100000;
00254
00255 FD_ZERO(&read_mask);
00256 FD_SET(fd, &read_mask);
00257
00258 int result = select(fd + 1, &read_mask, 0, 0, &timeout);
00259
00260 if ( (result < 0 ) && (errno == EINTR || errno == EAGAIN))
00261 return 0;
00262
00263 if (result < 0)
00264 return -1;
00265
00266 return 1;
00267 }
00268
00269
00270 int ssl_continue(SSL* ssl, int err) {
00271 switch (SSL_get_error(ssl,err)) {
00272 case SSL_ERROR_NONE:
00273 return 0;
00274 case SSL_ERROR_WANT_WRITE:
00275 return 1;
00276 case SSL_ERROR_WANT_READ:
00277 return 1;
00278 case SSL_ERROR_WANT_X509_LOOKUP:
00279 return 1;
00280 case SSL_ERROR_SYSCALL:
00281 case SSL_ERROR_SSL:
00282 if (errno == EAGAIN)
00283 return 1;
00284 case SSL_ERROR_ZERO_RETURN:
00285 return -1;
00286 }
00287 return -1;
00288 }
00289
00290
00291
00292
00293
00294
00295 void
00296 XrdSecProtocolssl::secClient(int theFD, XrdOucErrInfo *error) {
00297
00298 EPNAME("secClient");
00299
00300 XrdSecsslThreadInUse ThreadInUse();
00301
00302 char *nossl = getenv("XrdSecNoSSL");
00303 if (nossl) {
00304 error->setErrInfo(ENOENT,"SSL is disabled by force");
00305 return ;
00306 }
00307
00308 XrdSecProtocolssl::GetEnvironment();
00309
00310 error->setErrInfo(0,"");
00311 SSLMutex.Lock();
00312
00313 int err=0;
00314 char* str;
00315 SSL_METHOD *meth;
00316 SSL_SESSION *session=0;
00317
00318 SSL_load_error_strings();
00319 SSLeay_add_ssl_algorithms();
00320 meth = (SSL_METHOD*) TLSv1_client_method();
00321
00322 ERR_load_crypto_strings();
00323
00324 XrdOucString sslsessionfile="";
00325 XrdOucString sslsessionid="";
00326
00327 sslsessionfile = "/tmp/xssl_";
00328 sslsessionid += (int)geteuid();
00329 sslsessionid += ":";
00330 sslsessionid += host.c_str();
00331 sslsessionfile += sslsessionid;
00332
00333 XrdSecsslSessionLock sessionlock;
00334 sessionlock.SoftLock();
00335
00336 if (allowSessions) {
00337 struct stat sessionstat;
00338
00339 if (!stat(sslsessionfile.c_str(),&sessionstat)) {
00340
00341 FILE* fp = fopen(sslsessionfile.c_str(), "r");
00342 if (fp) {
00343 if (sessionlock.HardLock(sslsessionfile.c_str())) {
00344 session = PEM_read_SSL_SESSION(fp, NULL, NULL, NULL);
00345 fclose(fp);
00346 sessionlock.HardUnLock();
00347 }
00348 }
00349
00350 if (session) {
00351
00352 DEBUG("Info: ("<<__FUNCTION__<<") Session loaded from " << sslsessionfile.c_str());
00353 char session_id[1024];
00354 for (int i=0; i< (int)session->session_id_length; i++) {
00355 sprintf(session_id+(i*2),"%02x",session->session_id[i]);
00356 }
00357
00358 unsigned char buf[5],*p;
00359 unsigned long l;
00360
00361 p=buf;
00362 l=session->cipher_id;
00363 l2n(l,p);
00364
00365 DEBUG("Info: ("<<__FUNCTION__<<") Session Id: "<< session_id << " Verify: " << session->verify_result << " (" << X509_verify_cert_error_string(session->verify_result) << ")");
00366 } else {
00367 DEBUG("Info: ("<<__FUNCTION__<<") Session load failed from " << sslsessionfile.c_str());
00368 ERR_print_errors_fp(stderr);
00369 }
00370 }
00371 }
00372
00373 clientctx = SSL_CTX_new (meth);
00374
00375
00376 SSL_CTX_set_options(clientctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
00377
00378 if (!clientctx) {
00379 Fatal(error,"Cannot do SSL_CTX_new",-1);
00380 exit(2);
00381 }
00382
00383 if (!XrdSecProtocolssl::sslproxyexportplain) {
00384
00385 SSL_CTX_set_default_passwd_cb(clientctx, secprotocolssl_pem_cb);
00386 SSL_CTX_set_default_passwd_cb_userdata(clientctx, XrdSecProtocolssl::sslserverexportpassword);
00387 }
00388
00389 if (SSL_CTX_use_certificate_chain_file(clientctx, sslcertfile) <= 0) {
00390 ERR_print_errors_fp(stderr);
00391 Fatal(error,"Cannot use certificate file",-1);
00392 if (clientctx) SSL_CTX_free (clientctx);
00393 SSLMutex.UnLock();
00394 return;
00395 }
00396
00397 if (SSL_CTX_use_PrivateKey_file(clientctx, sslkeyfile, SSL_FILETYPE_PEM) <= 0) {
00398 ERR_print_errors_fp(stderr);
00399 Fatal(error,"Cannot use private key file",-1);
00400 if (clientctx) SSL_CTX_free (clientctx);
00401 SSLMutex.UnLock();
00402 return;
00403 }
00404
00405
00406 if (!SSL_CTX_check_private_key(clientctx)) {
00407 fprintf(stderr,"Error: (%s) Private key does not match the certificate public key\n",__FUNCTION__);
00408 Fatal(error,"Private key does not match the certificate public key",-1);
00409 if (clientctx) SSL_CTX_free (clientctx);
00410 SSLMutex.UnLock();
00411 return;
00412 } else {
00413 DEBUG("Private key check passed ...");
00414 }
00415 SSL_CTX_load_verify_locations(clientctx, NULL,sslcadir);
00416 SSL_CTX_set_verify(clientctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, GRST_callback_SSLVerify_wrapper);
00417
00418 SSL_CTX_set_cert_verify_callback(clientctx, GRST_verify_cert_wrapper, (void *) NULL);
00419
00420 grst_cadir = sslcadir;
00421 grst_vomsdir = sslvomsdir;
00422
00423 grst_depth=verifydepth;
00424 SSL_CTX_set_verify_depth(clientctx, verifydepth);
00425
00426 if (session) {
00427 SSL_CTX_add_session(clientctx,session);
00428 }
00429
00430
00431 ssl = SSL_new (clientctx);
00432 SSL_set_purpose(ssl,X509_PURPOSE_ANY);
00433 if (session) {
00434 SSL_set_session(ssl, session);
00435 }
00436
00437 sessionlock.SoftUnLock();
00438 sessionlock.HardUnLock();
00439
00440 if (!ssl) {
00441 Fatal(error,"Cannot do SSL_new",-1);
00442 exit(6);
00443 }
00444
00445 SSL_set_fd (ssl, theFD);
00446
00447
00448 int flags;
00449
00450
00451 if ((flags = fcntl(theFD, F_GETFL, 0)) < 0) {
00452
00453 fprintf(stderr,"Error: (%s) failed to make socket non-blocking\n",__FUNCTION__);
00454 } else {
00455 if (fcntl(theFD, F_SETFL, flags | O_NONBLOCK) < 0) {
00456
00457 fprintf(stderr,"Error: (%s) failed to make socket non-blocking\n",__FUNCTION__);
00458 }
00459 }
00460
00461 time_t now= time(NULL);
00462
00463 do {
00464 if ( (time(NULL)-now) > XrdSecProtocolssl::sslselecttimeout ) {
00465 ErrorMutex.Lock();erroraccept++;errortimeout++; ErrorMutex.UnLock();
00466
00467 Fatal(error,"authenticate - handshake time out",-ETIMEDOUT);
00468 TRACE(Authen,"Error: ("<<__FUNCTION__<<") handshake timedout in SSL_connect");
00469 SSLMutex.UnLock();
00470 return;
00471 }
00472
00473 int set = ssl_select(theFD);
00474 if (set < 1)
00475 continue;
00476 err = SSL_connect (ssl);
00477 if (err>0)
00478 break;
00479 } while ( (ssl_continue(ssl,err))==1);
00480
00481
00482
00483 if (err!=1) {
00484
00485 ERR_print_errors_fp(stderr);
00486 if (clientctx) SSL_CTX_free (clientctx);
00487 SSLMutex.UnLock();
00488 return;
00489 }
00490
00491
00492 if (!session)
00493 session = SSL_get1_session(ssl);
00494
00495
00496
00497 TRACE(Authen,"SSL connection uses cipher: "<<SSL_get_cipher (ssl));
00498
00499
00500
00501 server_cert = SSL_get_peer_certificate (ssl);
00502
00503 if (!server_cert) {
00504 TRACE(Authen,"Server didn't provide certificate");
00505 }
00506
00507 XrdOucString rdn;
00508
00509 str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
00510 rdn = str;
00511 TRACE(Authen,"Server certificate subject:\t" << str);
00512 OPENSSL_free (str);
00513
00514 str = X509_NAME_oneline (X509_get_issuer_name (server_cert),0,0);
00515 TRACE(Authen,"Server certificate issuer: \t" << str);
00516 OPENSSL_free (str);
00517
00518 X509_free (server_cert);
00519 server_cert=0;
00520
00521
00522
00523
00524
00525
00526
00527 GRSTx509Chain *grst_chain = (GRSTx509Chain*) SSL_get_app_data(ssl);
00528 SSL_set_app_data(ssl,0);
00529
00530 if (grst_chain) {
00531 GRST_print_ssl_creds((void*) grst_chain);
00532 char* vr = GRST_get_voms_roles_and_free((void*) grst_chain);
00533 if (vr) {
00534 free(vr);
00535 }
00536 }
00537
00538
00539 if (forwardProxy) {
00540 if (!strcmp(sslkeyfile,sslcertfile)) {
00541
00542 int fd = open(sslkeyfile,O_RDONLY);
00543 if (fd>=0) {
00544 int nread = read(fd,proxyBuff, sizeof(proxyBuff));
00545 if (nread>=0) {
00546 TRACE(Authen,"Uploading my Proxy ...\n");
00547
00548
00549 do {
00550 if ( (time(NULL)-now) > XrdSecProtocolssl::sslselecttimeout ) {
00551 ErrorMutex.Lock();errorread++;errortimeout++; ErrorMutex.UnLock();
00552
00553 Fatal(error,"authenticate - handshake time out",-ETIMEDOUT);
00554 TRACE(Authen,"Error: ("<<__FUNCTION__<<") handshake timedout in SSL_read");
00555 ERR_remove_state(0);
00556 SSLMutex.UnLock();
00557 return;
00558 }
00559
00560 int set = ssl_select(theFD);
00561 if (set < 1)
00562 continue;
00563 err = SSL_write(ssl, proxyBuff,nread);
00564 } while ( (ssl_continue(ssl,err)) == 1);
00565
00566
00567 if (err!= nread) {
00568 Fatal(error,"Cannot forward proxy",-1);
00569 if (clientctx) SSL_CTX_free (clientctx);
00570 if (session) SSL_SESSION_free(session);
00571 SSLMutex.UnLock();
00572 return;
00573 }
00574
00575 char ok[16];
00576
00577 do {
00578 if ( (time(NULL)-now) > XrdSecProtocolssl::sslselecttimeout ) {
00579 ErrorMutex.Lock();errorread++;errortimeout++; ErrorMutex.UnLock();
00580
00581 Fatal(error,"authenticate - handshake time out",-ETIMEDOUT);
00582 TRACE(Authen,"Error: ("<<__FUNCTION__<<") handshake timedout in SSL_read");
00583 ERR_remove_state(0);
00584 SSLMutex.UnLock();
00585 return;
00586 }
00587
00588 int set = ssl_select(theFD);
00589 if (set < 1)
00590 continue;
00591 err = SSL_read(ssl,ok, 3);
00592 } while ( (ssl_continue(ssl,err)) == 1);
00593
00594 if (err != 3) {
00595 Fatal(error,"Didn't receive OK",-1);
00596 if (clientctx) SSL_CTX_free (clientctx);
00597 if (session) SSL_SESSION_free(session);
00598 SSLMutex.UnLock();
00599 return;
00600 }
00601 } else {
00602 close(fd);
00603 Fatal(error,"Cannot read proxy file to forward",-1);
00604 if (clientctx) SSL_CTX_free (clientctx);
00605 if (session) SSL_SESSION_free(session);
00606 SSLMutex.UnLock();
00607 return;
00608 }
00609 } else {
00610 Fatal(error,"Cannot read proxy file to forward",-1);
00611 if (clientctx) SSL_CTX_free (clientctx);
00612 if (session) SSL_SESSION_free(session);
00613 SSLMutex.UnLock();
00614 return;
00615 }
00616 close(fd);
00617 }
00618 }
00619
00620 if (allowSessions && session) {
00621 char session_id[1024];
00622 for (int i=0; i< (int)session->session_id_length; i++) {
00623 sprintf(session_id+(i*2),"%02x",session->session_id[i]);
00624 }
00625
00626 if (session->cipher) {
00627 DEBUG("Info: ("<<__FUNCTION__<<") Session Id: "<< session_id << " Cipher: " << session->cipher->name << " Verify: " << session->verify_result << " (" << X509_verify_cert_error_string(session->verify_result) << ")");
00628 } else {
00629 DEBUG("Info: ("<<__FUNCTION__<<") Session Id: "<< session_id << " Verify: " << session->verify_result << " (" << X509_verify_cert_error_string(session->verify_result) << ")");
00630 }
00631
00632 FILE* fp = fopen((const char*)(sslsessionfile.c_str()),"w+");
00633 if (fp) {
00634 if (sessionlock.HardLock(sslsessionfile.c_str())) {
00635 PEM_write_SSL_SESSION(fp, session);
00636 }
00637 fclose(fp);
00638 sessionlock.HardUnLock();
00639 DEBUG("Info: ("<<__FUNCTION__<<") Session stored to " << sslsessionfile.c_str());
00640 if (chmod(sslsessionfile.c_str(),S_IRUSR| S_IWUSR)) {
00641 Fatal(error,"secure session file (chmod 600 failed) ",-errno);
00642 }
00643 }
00644 }
00645
00646 do {
00647 err = SSL_shutdown(ssl);
00648 } while (ssl_continue(ssl,err) || (!err));
00649
00650 if (ssl) {
00651 SSL_free(ssl);ssl = 0;
00652 }
00653
00654 if (clientctx) SSL_CTX_free (clientctx);
00655
00656 if (session) {
00657 SSL_SESSION_free(session);
00658 }
00659
00660 SSLMutex.UnLock();
00661 return;
00662 }
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 char*
00675 STRINGSTORE(const char* __charptr__) {
00676 XrdOucString* yourstring;
00677 if (!__charptr__ ) return (char*)"";
00678
00679 XrdSecProtocolssl::StoreMutex.Lock();
00680 yourstring = XrdSecProtocolssl::stringstore.Find(__charptr__);
00681 XrdSecProtocolssl::StoreMutex.UnLock();
00682
00683 if (yourstring) {
00684 return (char*)yourstring->c_str();
00685 } else {
00686 XrdOucString* newstring = new XrdOucString(__charptr__);
00687 XrdSecProtocolssl::StoreMutex.Lock();
00688 XrdSecProtocolssl::stringstore.Add(__charptr__,newstring);
00689 XrdSecProtocolssl::StoreMutex.UnLock();
00690 return (char*)newstring->c_str();
00691 }
00692 }
00693
00694
00695 void MyGRSTerrorLogFunc (char *lfile, int lline, int llevel, char *fmt, ...) {
00696 EPNAME("grst");
00697 va_list args;
00698 char fullmessage[4096];
00699 fullmessage[0] = 0;
00700
00701 va_start(args, fmt);
00702 vsprintf(fullmessage,fmt,args);
00703 va_end(args);
00704
00705
00706 XrdOucString sfullmessage = fullmessage;
00707 sfullmessage.replace("\n","");
00708
00709 if (llevel <= GRST_LOG_WARNING) {
00710 TRACE(Authen," ("<< lfile << ":" << lline <<"): " << sfullmessage);
00711 } else if (llevel <= GRST_LOG_INFO) {
00712 TRACE(Authen, " ("<< lfile << ":" << lline <<"): " << sfullmessage);
00713 } else {
00714 DEBUG(" ("<< lfile << ":" << lline <<"): " << sfullmessage);
00715 }
00716 }
00717
00718
00719 void
00720 XrdSecProtocolssl::secServer(int theFD, XrdOucErrInfo *error) {
00721 int err=0;
00722
00723 char* str;
00724
00725 SSLMutex.Lock();
00726
00727
00728 EPNAME("secServer");
00729
00730 XrdSecsslThreadInUse ThreadInUse;
00731
00732 if ((debug>=4)) {
00733 TRACE(Identity,"Info: having " << threadsinuse << " threads running SSL authentication");
00734 }
00735
00736 XrdSecsslSessionLock sessionlock;
00737
00738
00739 GridMapMutex.Lock();
00740 if ((time(NULL)-storeLoadTime) > 3600) {
00741 if (store) {
00742 TRACE(Authen,"Reloading X509 Store from " << sslcadir);
00743 X509_STORE_free(store);
00744 store = SSL_X509_STORE_create(NULL, sslcadir);
00745 X509_STORE_set_flags(XrdSecProtocolssl::store,0);
00746 storeLoadTime = time(NULL);
00747 }
00748 }
00749 GridMapMutex.UnLock();
00750
00751 if (XrdSecProtocolssl::sslsessioncachesize) {
00752 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
00753 } else {
00754 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
00755 }
00756
00757 ssl = SSL_new (ctx);
00758 SSL_set_purpose(ssl,X509_PURPOSE_ANY);
00759
00760
00761 TRACE(Authen,"Info: ("<<__FUNCTION__<<") Session Cache has size: " <<SSL_CTX_sess_get_cache_size(ctx));
00762
00763 if (!ssl) {
00764 fprintf(stderr,"Error: (%s) failed to create context\n",__FUNCTION__);
00765 TRACE(Authen,"Error: ("<<__FUNCTION__<<") failed to create context");
00766 exit(5);
00767 }
00768
00769 SSL_set_app_data(ssl,0);
00770
00771 SSL_set_fd (ssl, theFD);
00772
00773
00774 int flags;
00775
00776
00777 if ((flags = fcntl(theFD, F_GETFL, 0)) < 0) {
00778
00779 fprintf(stderr,"Error: (%s) failed to make socket non-blocking\n",__FUNCTION__);
00780 } else {
00781 if (fcntl(theFD, F_SETFL, flags | O_NONBLOCK) < 0) {
00782
00783 fprintf(stderr,"Error: (%s) failed to make socket non-blocking\n",__FUNCTION__);
00784 }
00785 }
00786
00787 TRACE(Authen,"Before:: SSL accept loop");
00788 time_t now= time(NULL);
00789 do {
00790 if (terminate) {
00791 ErrorMutex.Lock();erroraccept++;errorabort++; ErrorMutex.UnLock();
00792
00793 Fatal(error,"authenticate - handshake abort from client",-ETIMEDOUT);
00794 TRACE(Authen,"Error: ("<<__FUNCTION__<<") aborted SSL_accept");
00795 ERR_remove_state(0);
00796 SSLMutex.UnLock();
00797 return;
00798 }
00799
00800 if ( (time(NULL)-now) > XrdSecProtocolssl::sslselecttimeout ) {
00801 ErrorMutex.Lock();erroraccept++;errortimeout++; ErrorMutex.UnLock();
00802
00803 Fatal(error,"authenticate - handshake time out",-ETIMEDOUT);
00804 TRACE(Authen,"Error: ("<<__FUNCTION__<<") handshake timedout in SSL_accept");
00805 SSLMutex.UnLock();
00806 return;
00807 }
00808
00809 int set = ssl_select(theFD);
00810 if (set < 1)
00811 continue;
00812 TRACE(Authen,"Before:: SSL accept");
00813 err = SSL_accept (ssl);
00814 TRACE(Authen,"After :: SSL accept");
00815 if (err>0)
00816 break;
00817 } while ( (ssl_continue(ssl,err))==1);
00818
00819 TRACE(Authen,"After :: SSL accept loop");
00820
00821 if (err!=1) {
00822 long verifyresult = SSL_get_verify_result(ssl);
00823 if (verifyresult != X509_V_OK) {
00824 ErrorMutex.Lock();erroraccept++;errorverify++; ErrorMutex.UnLock();
00825 Fatal(error,X509_verify_cert_error_string(verifyresult),verifyresult);
00826 TRACE(Authen,"Error: ("<<__FUNCTION__<<") failed SSL_accept ");
00827 } else {
00828 ErrorMutex.Lock();erroraccept++;errorqueue++; ErrorMutex.UnLock();
00829 Fatal(error,"do SSL_accept",-1);
00830 unsigned long lerr;
00831 while ((lerr=ERR_get_error())) {TRACE(Authen,"SSL Queue error: err=" << lerr << " msg=" <<
00832 ERR_error_string(lerr, NULL));Fatal(error,ERR_error_string(lerr,NULL),-1);}
00833 }
00834
00835 GRSTx509Chain *grst_chain = (GRSTx509Chain*) SSL_get_app_data(ssl);
00836 SSL_set_app_data(ssl,0);
00837
00838 if (grst_chain) {
00839 GRST_free_chain((void*)grst_chain);
00840 }
00841 ERR_remove_state(0);
00842 SSLMutex.UnLock();
00843 return;
00844 }
00845
00846 TRACE(Authen,"Before:: SSL get session");
00847
00848 SSL_SESSION* session = SSL_get1_session(ssl);
00849
00850 TRACE(Authen,"After :: SSL get session");
00851 if (session) {
00852 char session_id[1024];
00853 TRACE(Authen,"Doing :: SSL Print session");
00854 for (int i=0; i< (int)session->session_id_length; i++) {
00855 sprintf(session_id+(i*2),"%02x",session->session_id[i]);
00856 }
00857
00858 DEBUG("Info: ("<<__FUNCTION__<<") Session Id: "<< session_id << " Verify: " << session->verify_result << " (" << X509_verify_cert_error_string(session->verify_result) << ")");
00859 DEBUG("Info: ("<<__FUNCTION__<<") cache items : " << SSL_CTX_sess_number(ctx));
00860 DEBUG("Info: ("<<__FUNCTION__<<") client connects : " << SSL_CTX_sess_connect(ctx));
00861 DEBUG("Info: ("<<__FUNCTION__<<") client renegotiates : " << SSL_CTX_sess_connect_renegotiate(ctx));
00862 DEBUG("Info: ("<<__FUNCTION__<<") client connect finished : " << SSL_CTX_sess_connect_good(ctx));
00863 DEBUG("Info: ("<<__FUNCTION__<<") server accepts : " << SSL_CTX_sess_accept(ctx));
00864 DEBUG("Info: ("<<__FUNCTION__<<") server renegotiates : " << SSL_CTX_sess_accept_renegotiate(ctx));
00865 DEBUG("Info: ("<<__FUNCTION__<<") server accepts finished : " << SSL_CTX_sess_accept_good(ctx));
00866 DEBUG("Info: ("<<__FUNCTION__<<") session cache hits : " << SSL_CTX_sess_hits(ctx));
00867 DEBUG("Info: ("<<__FUNCTION__<<") session cache misses : " << SSL_CTX_sess_misses(ctx));
00868 DEBUG("Info: ("<<__FUNCTION__<<") session cache timeouts : " << SSL_CTX_sess_timeouts(ctx));
00869 DEBUG("Info: ("<<__FUNCTION__<<") callback cache hits : " << SSL_CTX_sess_cb_hits(ctx));
00870 DEBUG("Info: ("<<__FUNCTION__<<") cache full overflows : " << SSL_CTX_sess_cache_full(ctx) << " allowed: " << SSL_CTX_sess_get_cache_size(ctx));
00871
00872 if (XrdSecProtocolssl::proc) {
00873 XrdSecProtocolsslProcFile* pf;
00874 char CacheInfo[16384];
00875 sprintf(CacheInfo,"items = %ld\nclientconnects = %ld\nclientrenegotiates = %ld\nclientconnectfinished = %ld\nserveraccept = %ld\nserverrenegotiates = %ld\nserveracceptfinished = %ld\nsessioncachehits = %ld\nsessioncachemisses = %ld\nsessioncachetimeouts = %ld\ncallbackcachehits = %ld\ncachefulloverflows = %ld\ncachesize = %ld\nhandshakethreads = %d\nforwardedproxies = %d\n", SSL_CTX_sess_number(ctx), SSL_CTX_sess_connect(ctx),SSL_CTX_sess_connect_renegotiate(ctx),SSL_CTX_sess_connect_good(ctx), SSL_CTX_sess_accept(ctx), SSL_CTX_sess_accept_renegotiate(ctx), SSL_CTX_sess_accept_good(ctx), SSL_CTX_sess_hits(ctx), SSL_CTX_sess_misses(ctx), SSL_CTX_sess_timeouts(ctx),SSL_CTX_sess_cb_hits(ctx), SSL_CTX_sess_cache_full(ctx), SSL_CTX_sess_get_cache_size(ctx), XrdSecProtocolssl::threadsinuse, XrdSecProtocolssl::forwardedproxies);
00876
00877 pf= XrdSecProtocolssl::proc->Handle("cache"); pf && pf->Write(CacheInfo);
00878
00879 char ErrorInfo[16384];
00880 sprintf(ErrorInfo,"errortimeout = %d\nerrorverify = %d\nerrorqueue = %d\nerroraccept = %d\nerrorread = %d\nerrorabort = %d", errortimeout, errorverify, errorqueue, erroraccept, errorread, errorabort);
00881 pf= XrdSecProtocolssl::proc->Handle("error"); pf && pf->Write(ErrorInfo);
00882 }
00883 }
00884
00885
00886 SSL_SESSION_free(session);
00887
00888
00889 GRSTx509Chain *grst_chain = (GRSTx509Chain*) SSL_get_app_data(ssl);
00890 SSL_set_app_data(ssl,0);
00891
00892 XrdOucString vomsroles="";
00893 XrdOucString clientdn="";
00894
00895 if (grst_chain) {
00896 GRST_print_ssl_creds((void*) grst_chain);
00897 char* vr = GRST_get_voms_roles_and_free((void*) grst_chain);
00898 if (vr) {
00899 vomsroles = vr;
00900 free(vr);
00901 }
00902 }
00903
00904 TRACE(Authen,"Authenticated with VOMS roles: "<<vomsroles);
00905
00906 long verifyresult = SSL_get_verify_result(ssl);
00907
00908 TRACE(Authen,"Verify result is = "<<verifyresult);
00909
00910
00911
00912 DEBUG("SSL connection uses cipher " << SSL_get_cipher(ssl));
00913
00914
00915
00916 client_cert = SSL_get_peer_certificate (ssl);
00917
00918
00919 if (client_cert != NULL) {
00920 str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
00921 if (str) {
00922 TRACE(Authen,"client certificate subject: "<< str);
00923 clientdn = str;
00924 OPENSSL_free (str);
00925 } else {
00926 TRACE(Authen,"client certificate subject: none");
00927 }
00928
00929 str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0);
00930
00931 if (str) {
00932 TRACE(Authen,"client certificate issuer : "<<str);
00933 TRACE(Authen,"Setting dn="<<clientdn<<" roles="<<vomsroles);
00934 OPENSSL_free (str);
00935 } else {
00936 TRACE(Authen,"client certificate issuer : none");
00937 Fatal(error,"no client issuer",-1);
00938 ERR_remove_state(0);
00939 SSLMutex.UnLock();
00940 return;
00941 }
00942 } else {
00943 TRACE(Authen,"Client does not have certificate.");
00944 Fatal(error,"no client certificate",-1);
00945 ERR_remove_state(0);
00946 SSLMutex.UnLock();
00947 return;
00948 }
00949
00950
00951
00952 do {
00953 if (terminate) {
00954 ErrorMutex.Lock();errorabort++; ErrorMutex.UnLock();
00955
00956 Fatal(error,"authenticate - handshake abort from client",-ECONNABORTED);
00957 TRACE(Authen,"Error: ("<<__FUNCTION__<<") aborted SSL_read client proxy");
00958 ERR_remove_state(0);
00959 SSLMutex.UnLock();
00960 return;
00961 }
00962
00963 if ( (time(NULL)-now) > XrdSecProtocolssl::sslselecttimeout ) {
00964 ErrorMutex.Lock();errorread++;errortimeout++; ErrorMutex.UnLock();
00965
00966 Fatal(error,"authenticate - handshake time out",-ETIMEDOUT);
00967 TRACE(Authen,"Error: ("<<__FUNCTION__<<") handshake timedout in SSL_read");
00968 ERR_remove_state(0);
00969 SSLMutex.UnLock();
00970 return;
00971 }
00972
00973 int set = ssl_select(theFD);
00974 if (set < 1)
00975 continue;
00976 err = SSL_read(ssl,proxyBuff, sizeof(proxyBuff));
00977 } while ( (ssl_continue(ssl,err)) == 1);
00978
00979 if (err>0) {
00980 ErrorMutex.Lock();forwardedproxies++; ErrorMutex.UnLock();
00981 TRACE(Authen,"Received proxy buffer with " << err << " bytes");
00982 proxyBuff[err] = 0;
00983 Entity.endorsements = proxyBuff;
00984 err = SSL_write(ssl,"OK\n",3);
00985 if (err!=3) {
00986 ErrorMutex.Lock();errorread++; ErrorMutex.UnLock();
00987 Fatal(error,"could not send end of handshake OK",-1);
00988 ERR_remove_state(0);
00989 SSLMutex.UnLock();
00990 return;
00991 }
00992
00993
00994 } else {
00995 TRACE(Authen,"Received no proxy");
00996 }
00997
00998 struct timeval tv1, tv2;
00999 struct timezone tz;
01000
01001 gettimeofday(&tv1,&tz);
01002
01003 do {
01004 if (terminate) {
01005 break;
01006 }
01007 gettimeofday(&tv2,&tz);
01008 if ( ((((tv2.tv_sec-tv1.tv_sec)*1000)) + (((tv2.tv_usec-tv1.tv_usec))/1000)) > 500) {
01009
01010 TRACE(Authen,"Warning: ("<<__FUNCTION__<<") shutdown timed out");
01011 SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
01012 break;
01013 }
01014 err = SSL_shutdown(ssl);
01015 } while (ssl_continue(ssl,err) || (!err));
01016
01017 strncpy(Entity.prot,"ssl", sizeof(Entity.prot));
01018
01019
01020
01021
01022
01023 if (!mapuser && !mapcerncertificates) {
01024
01025 Entity.name = strdup(clientdn.c_str());
01026 } else {
01027 bool mapped=false;
01028
01029 if (mapcerncertificates) {
01030
01031 if ( (mapcerncertificates) && (clientdn.beginswith("/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN="))) {
01032 XrdOucString certsubject = clientdn;
01033 certsubject.erasefromstart(strlen("/DC=ch/DC=cern/OU=Organic Units/OU=Users/CN="));
01034 int pos=certsubject.find('/');
01035 if (pos != STR_NPOS)
01036 certsubject.erase(pos);
01037 Entity.name = strdup(certsubject.c_str());
01038 mapped=true;
01039 TRACE(Authen,"Found CERN certificate - mapping to AFS account " << certsubject);
01040 }
01041 }
01042 if (!mapped) {
01043 if (mapuser) {
01044
01045 XrdOucString certsubject = clientdn;
01046 certsubject.replace("/CN=proxy","");
01047
01048 int pos = certsubject.find("CN=");
01049 int pos2 = certsubject.find("/",pos);
01050 if (pos2>0) certsubject.erase(pos2);
01051 XrdOucString* gridmaprole;
01052 ReloadGridMapFile();
01053 GridMapMutex.Lock();
01054
01055 if ((gridmaprole = gridmapstore.Find(certsubject.c_str()))) {
01056 Entity.name = strdup(gridmaprole->c_str());
01057 Entity.role = 0;
01058 } else {
01059 Entity.name = strdup((char*)"nobody");
01060 Entity.role = 0;
01061 if (!XrdSecProtocolssl::mapnobody) {
01062 Fatal(error,"user cannot be mapped",-1);
01063 }
01064 }
01065 GridMapMutex.UnLock();
01066 } else {
01067 Entity.name = strdup((char*)"nobody");
01068 Entity.role = 0;
01069 if (!XrdSecProtocolssl::mapnobody) {
01070 Fatal(error,"user cannot be mapped",-1);
01071 }
01072 }
01073 }
01074 }
01075
01076
01077 if (!mapgroup) {
01078 if (vomsroles.length()) {
01079
01080 Entity.grps = strdup(vomsroles.c_str());
01081
01082 XrdOucString vomsrole = vomsroles.c_str();
01083
01084 if (vomsroles.length()) {
01085 int dp = vomsrole.find(":");
01086 if (dp != STR_NPOS) {
01087 vomsrole.assign(vomsroles,0,dp-1);
01088 }
01089 Entity.role = strdup(vomsrole.c_str());
01090 } else {
01091 Entity.role = strdup("");
01092 }
01093 } else {
01094
01095 struct passwd* pwd;
01096 struct group* grp;
01097 StoreMutex.Lock();
01098 if ( (pwd = getpwnam(Entity.name)) && (grp = getgrgid(pwd->pw_gid))) {
01099 Entity.grps = strdup(grp->gr_name);
01100 Entity.role = strdup(grp->gr_name);
01101 }
01102 StoreMutex.UnLock();
01103 }
01104 } else {
01105
01106 XrdOucString defaultgroup="";
01107 XrdOucString allgroups="";
01108
01109
01110 struct passwd* pwd;
01111 struct group* grp;
01112 StoreMutex.Lock();
01113 if ( (pwd = getpwnam(Entity.name)) && (grp = getgrgid(pwd->pw_gid))) {
01114 Entity.grps = strdup(grp->gr_name);
01115 Entity.role = strdup(grp->gr_name);
01116 }
01117 StoreMutex.UnLock();
01118
01119 if (vomsroles.length()) {
01120 if (VomsMapGroups(vomsroles.c_str(), allgroups,defaultgroup)) {
01121
01122 if (defaultgroup.beginswith("uid:")) {
01123 defaultgroup.erase(0,4);
01124 if (Entity.name) {
01125 free(Entity.name);
01126 }
01127 Entity.name = strdup(defaultgroup.c_str());
01128 allgroups=":";
01129 }
01130 if (!strcmp(allgroups.c_str(),":")) {
01131
01132 struct passwd* pwd;
01133 struct group* grp;
01134 StoreMutex.Lock();
01135 if ( (pwd = getpwnam(Entity.name)) && (grp = getgrgid(pwd->pw_gid))) {
01136 allgroups = grp->gr_name;
01137 defaultgroup = grp->gr_name;
01138 }
01139 StoreMutex.UnLock();
01140 }
01141 Entity.grps = strdup(allgroups.c_str());
01142 Entity.role = strdup(defaultgroup.c_str());
01143 }
01144 }
01145 }
01146
01147
01148
01149
01150
01151
01152 if (sslproxyexportdir && Entity.endorsements) {
01153 StoreMutex.Lock();
01154
01155 struct passwd* pwd;
01156 XrdOucString outputproxy = sslproxyexportdir; outputproxy+="/x509up_u";
01157 if ( (pwd = getpwnam(Entity.name)) ) {
01158 outputproxy += (int)pwd->pw_uid;
01159 } else {
01160 outputproxy += Entity.name;
01161 }
01162 XrdOucString outputproxytmp = outputproxy;
01163 outputproxytmp += (int) rand();
01164
01165 if (XrdSecProtocolssl::sslproxyexportplain) {
01166 int fd = open (outputproxytmp.c_str(),O_CREAT| O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
01167 if (fd>0) {
01168 if ( ((int)write(fd,Entity.endorsements,strlen(Entity.endorsements))) != (int)strlen(Entity.endorsements)) {
01169 unlink(outputproxytmp.c_str());
01170 Fatal(error,"cannot export(write) user proxy",-1);
01171 } else {
01172 TRACE(Identity,"Exported proxy buffer of " << Entity.name << " to file " << outputproxy.c_str());
01173 }
01174 if ( rename(outputproxytmp.c_str(),outputproxy.c_str()) ) {
01175 unlink(outputproxytmp.c_str());
01176 Fatal(error,"cannot rename temporary export proxy",-1);
01177 }
01178 close(fd);
01179 } else {
01180 Fatal(error,"cannot export(open) user proxy",-1);
01181 }
01182 } else {
01183 EVP_PKEY* pkey=NULL;
01184 X509* x509=NULL;
01185
01186 BIO* bp = BIO_new_mem_buf( (void *)Entity.endorsements, strlen(Entity.endorsements)+1);
01187 FILE* fout = fopen (outputproxytmp.c_str(),"w+");
01188 if (!fout) {
01189 Fatal(error,"cannot export user proxy - unable to open proxy file",-1);
01190 } else {
01191 if (bp) {
01192 pkey = PEM_read_bio_PrivateKey(bp, &pkey,0,0);
01193 BIO_free(bp);
01194 if (!pkey) {
01195 Fatal(error,"cannot export user proxy - unable to read key/cert from BIO",-1);
01196 } else {
01197 int wk = PEM_write_PrivateKey(fout, pkey, EVP_des_ede3_cbc(),(unsigned char*)XrdSecProtocolssl::sslserverexportpassword,EXPORTKEYSTRENGTH,0,0);
01198 EVP_PKEY_free(pkey);
01199
01200 if (!wk) {
01201 Fatal(error,"cannot export user proxy - unable to write private key",-1);
01202 } else {
01203
01204 char* certificatebuffer = 0;
01205 certificatebuffer = Entity.endorsements;
01206 while ((certificatebuffer = strstr(certificatebuffer,"-----BEGIN CERTIFICATE-----"))) {
01207
01208 BIO* bp = BIO_new_mem_buf( (void *)certificatebuffer, strlen(certificatebuffer)+1);
01209 if (bp) {
01210 x509 = NULL;
01211 x509 = PEM_read_bio_X509(bp, &x509,0,0);
01212 BIO_free(bp);
01213 if (x509) {
01214 int wc = PEM_write_X509(fout,x509);
01215 X509_free(x509);
01216 if (!wc) {
01217 Fatal(error,"cannto export user proxy - unable to write certificate",-1);
01218 break;
01219 }
01220 }
01221 } else {
01222 Fatal(error,"cannot export user proxy - unable to allocate BIO to read private key",-1);
01223 }
01224 certificatebuffer++;
01225 }
01226 }
01227 }
01228 } else {
01229 Fatal(error,"cannot export user proxy - unable to allocate BIO to read private key",-1);
01230 }
01231
01232 fclose(fout);
01233 if ( rename(outputproxytmp.c_str(),outputproxy.c_str()) ) {
01234 unlink(outputproxytmp.c_str());
01235 Fatal(error,"cannot rename temporary export proxy",-1);
01236 }
01237 }
01238 }
01239
01240 StoreMutex.UnLock();
01241 }
01242
01243
01244 TRACE(Identity,"[usermapping] name=|" << Entity.name << "| role=|" << (Entity.role?Entity.role:"-") << "| grps=|"<< (Entity.grps?Entity.grps:"-") << "| DN=|" << clientdn.c_str() << "| VOMS=|" << vomsroles.c_str() << "|");
01245
01246 if (ssl) {
01247 SSL_free(ssl);ssl = 0;
01248 }
01249
01250 ERR_remove_state(0);
01251 SSLMutex.UnLock();
01252 return;
01253 }
01254
01255 int
01256 XrdSecProtocolssl::GenerateSession(const SSL* ssl, unsigned char *id, unsigned int *id_len) {
01257 EPNAME("GenerateSession");
01258 unsigned int count = 0;
01259 do {
01260 RAND_pseudo_bytes(id, *id_len);
01261
01262
01263
01264
01265
01266 memcpy(id, "xrootdssl",
01267 (strlen("xrootdssl") < *id_len) ?
01268 strlen("xrootdssl") : *id_len);
01269 TRACE(Authen,"Generated SSID **********************");
01270 }
01271 while(SSL_has_matching_session_id(ssl, id, *id_len) &&
01272 (++count < MAX_SESSION_ID_ATTEMPTS));
01273 if(count >= MAX_SESSION_ID_ATTEMPTS)
01274 return 0;
01275 return 1;
01276 }
01277
01278 int
01279 XrdSecProtocolssl::NewSession(SSL* ssl, SSL_SESSION *session) {
01280 EPNAME("NewSession");
01281 TRACE(Authen,"Creating new Session");
01282 char session_id[1024];
01283 for (int i=0; i< (int)session->session_id_length; i++) {
01284 sprintf(session_id+(i*2),"%02x",session->session_id[i]);
01285 }
01286 DEBUG("Info: ("<<__FUNCTION__<<") Session Id: "<< session_id << " Verify: " << session->verify_result << " (" << X509_verify_cert_error_string(session->verify_result) << ")");
01287
01288 SSL_set_timeout(session, sslsessionlifetime);
01289 return 0;
01290 }
01291
01292
01293 void
01294 XrdSecProtocolssl::ReloadGridMapFile()
01295 {
01296 EPNAME("ReloadGridMapFile");
01297
01298 static time_t GridMapMtime=0;
01299 static time_t GridMapCheckTime=0;
01300 int now = time(NULL);
01301
01302 if ((!GridMapCheckTime) || ((now >GridMapCheckTime + 60)) ) {
01303
01304 struct stat buf;
01305 if (!::stat(gridmapfile,&buf)) {
01306 if (buf.st_mtime != GridMapMtime) {
01307 GridMapMutex.Lock();
01308
01309 GridMapMtime = buf.st_mtime;
01310
01311 GridMapCheckTime = now;
01312
01313 gridmapstore.Purge();
01314
01315 FILE* mapin = fopen(gridmapfile,"r");
01316 if (!mapin) {
01317
01318 TRACE(Authen,"Unable to open gridmapfile " << XrdOucString(gridmapfile) << " - no mapping!");
01319 } else {
01320 char userdnin[4096];
01321 char usernameout[4096];
01322 int nitems;
01323
01324 while ( (nitems = fscanf(mapin,"\"%[^\"]\" %s\n", userdnin,usernameout)) == 2) {
01325 XrdOucString dn = userdnin;
01326 dn.replace("\"","");
01327
01328 int pos = dn.find("CN=");
01329 int pos2 = dn.find("/",pos);
01330 if (pos2>0) dn.erase(pos2);
01331
01332 if (!gridmapstore.Find(dn.c_str())) {
01333 gridmapstore.Add(dn.c_str(), new XrdOucString(usernameout));
01334 TRACE(Authen, "gridmapfile Mapping Added: " << dn.c_str() << " |=> " << usernameout);
01335 }
01336 }
01337 fclose(mapin);
01338 }
01339 GridMapMutex.UnLock();
01340 } else {
01341
01342 }
01343 } else {
01344 TRACE(Authen,"Unable to stat gridmapfile " << XrdOucString(gridmapfile) << " - no mapping!");
01345 }
01346 }
01347 }
01348
01349
01350
01351 void
01352 XrdSecProtocolssl::ReloadVomsMapFile()
01353 {
01354 EPNAME("ReloadVomsMapFile");
01355
01356 static time_t VomsMapMtime=0;
01357 static time_t VomsMapCheckTime=0;
01358 int now = time(NULL);
01359
01360 if ((!VomsMapCheckTime) || ((now >VomsMapCheckTime + 60 )) ) {
01361
01362 struct stat buf;
01363 if (!::stat(vomsmapfile,&buf)) {
01364 if (buf.st_mtime != VomsMapMtime) {
01365 VomsMapMutex.Lock();
01366
01367 VomsMapMtime = buf.st_mtime;
01368
01369 VomsMapCheckTime = now;
01370
01371 vomsmapstore.Purge();
01372
01373 FILE* mapin = fopen(vomsmapfile,"r");
01374 if (!mapin) {
01375
01376 TRACE(Authen,"Unable to open vomsmapfile " << XrdOucString(vomsmapfile) << " - no mapping!");
01377 } else {
01378 char userdnin[4096];
01379 char usernameout[4096];
01380 int nitems;
01381
01382 while ( (nitems = fscanf(mapin,"\"%[^\"]\" %s\n", userdnin,usernameout)) == 2) {
01383 XrdOucString dn = userdnin;
01384 dn.replace("\"","");
01385 if (!vomsmapstore.Find(dn.c_str())) {
01386 vomsmapstore.Add(dn.c_str(), new XrdOucString(usernameout));
01387 TRACE(Authen,"vomsmapfile Mapping Added: " << dn.c_str() << " |=> " << usernameout);
01388 }
01389 }
01390 fclose(mapin);
01391 }
01392 VomsMapMutex.UnLock();
01393 } else {
01394
01395 }
01396 } else {
01397 TRACE(Authen,"Unable to stat vomsmapfile " << XrdOucString(vomsmapfile) << " - no mapping!");
01398 }
01399 }
01400 }
01401
01402
01403
01404 bool
01405 XrdSecProtocolssl::VomsMapGroups(const char* groups, XrdOucString& allgroups, XrdOucString& defaultgroup)
01406 {
01407 EPNAME("VomsMapGroups");
01408 ReloadVomsMapFile();
01409
01410 XrdOucString vomsline = groups;
01411 allgroups = ":";
01412 defaultgroup = "";
01413 vomsline.replace(":","\n");
01414 XrdOucTokenizer vomsgroups((char*)vomsline.c_str());
01415 const char* stoken;
01416 int ntoken=0;
01417 XrdOucString* vomsmaprole;
01418 while( (stoken = vomsgroups.GetLine())) {
01419 if ((vomsmaprole = XrdSecProtocolssl::vomsmapstore.Find(stoken))) {
01420 allgroups += vomsmaprole->c_str();
01421 allgroups += ":";
01422 if (ntoken == 0) {
01423 defaultgroup = vomsmaprole->c_str();
01424 }
01425 ntoken++;
01426 } else {
01427
01428 XrdOucString vomsattribute = stoken;
01429 int rpos=STR_NPOS;
01430 while ((rpos = vomsattribute.rfind("/",rpos))!=STR_NPOS) {
01431 rpos--;
01432 XrdOucString wildcardattribute = vomsattribute;
01433 wildcardattribute.erase(rpos+2);
01434 wildcardattribute += "*";
01435 if ((vomsmaprole = XrdSecProtocolssl::vomsmapstore.Find(wildcardattribute.c_str()))) {
01436 allgroups += vomsmaprole->c_str();
01437 allgroups += ":";
01438 if (ntoken == 0) {
01439 defaultgroup = vomsmaprole->c_str();
01440 }
01441 ntoken++;
01442 break;
01443 }
01444 if ( rpos < 0) {
01445 break;
01446 }
01447 }
01448 }
01449 }
01450
01451 if (allgroups == ":") {
01452 TRACE(Authen,"No VOMS mapping found for " << XrdOucString(stoken) << " using default group");
01453 return false;
01454 }
01455 return true;
01456 }
01457
01458
01459
01460
01461
01462 extern "C"
01463 {
01464 char *XrdSecProtocolsslInit(const char mode,
01465 const char *parms,
01466 XrdOucErrInfo *erp)
01467 {
01468 EPNAME("ProtocolsslInit");
01469
01470 XrdSecProtocolssl::ssleDest.logger(&XrdSecProtocolssl::Logger);
01471
01472 GRSTerrorLogFunc = &MyGRSTerrorLogFunc;
01473 static bool serverinitialized = false;
01474
01475
01476 if (!SSLxTrace)
01477 SSLxTrace = new XrdOucTrace(&XrdSecProtocolssl::ssleDest);
01478
01479 for (int i=0; i< PROTOCOLSSL_MAX_CRYPTO_MUTEX; i++) {
01480 XrdSecProtocolssl::CryptoMutexPool[i] = new XrdSysMutex();
01481 }
01482
01483
01484
01485 if ( (mode == 's') && (!serverinitialized) ) {
01486 XrdSecProtocolssl::sslcertfile = strdup("/etc/grid-security/hostcert.pem");
01487 XrdSecProtocolssl::sslkeyfile = strdup("/etc/grid-security/hostkey.pem");
01488 XrdSecProtocolssl::sslcadir = strdup("/etc/grid-security/certificates");
01489 XrdSecProtocolssl::sslvomsdir = (char*)"/etc/grid-security/vomsdir";
01490
01491 XrdSecProtocolssl::isServer = 1;
01492 serverinitialized = true;
01493 if (parms){
01494
01495 char parmbuff[1024];
01496 strlcpy(parmbuff, parms, sizeof(parmbuff));
01497
01498
01499 XrdOucTokenizer inParms(parmbuff);
01500 char *op;
01501
01502 while (inParms.GetLine()) {
01503 while ((op = inParms.GetToken())) {
01504 if (!strncmp(op, "-d:",3)) {
01505 XrdSecProtocolssl::debug = atoi(op+3);
01506 } else if (!strncmp(op, "-cadir:",7)) {
01507 XrdSecProtocolssl::sslcadir = strdup(op+7);
01508 } else if (!strncmp(op, "-vomsdir:",6)) {
01509 XrdSecProtocolssl::sslvomsdir = strdup(op+6);
01510 } else if (!strncmp(op, "-cert:",6)) {
01511 XrdSecProtocolssl::sslcertfile = strdup(op+6);
01512 } else if (!strncmp(op, "-key:",5)) {
01513 XrdSecProtocolssl::sslkeyfile = strdup(op+5);
01514 } else if (!strncmp(op, "-ca:",4)) {
01515 XrdSecProtocolssl::verifydepth = atoi(op+4);
01516 } else if (!strncmp(op, "-t:",3)) {
01517 XrdSecProtocolssl::sslsessionlifetime = atoi(op+3);
01518 } else if (!strncmp(op, "-export:",8)) {
01519 XrdSecProtocolssl::sslproxyexportdir = strdup(op+8);
01520 } else if (!strncmp(op, "-gridmapfile:",13)) {
01521 XrdSecProtocolssl::gridmapfile = strdup(op+13);
01522 } else if (!strncmp(op, "-vomsmapfile:",13)) {
01523 XrdSecProtocolssl::vomsmapfile = strdup(op+13);
01524 } else if (!strncmp(op, "-mapuser:",9)) {
01525 XrdSecProtocolssl::mapuser = (bool) atoi(op+9);
01526 } else if (!strncmp(op, "-mapnobody:",11)) {
01527 XrdSecProtocolssl::mapnobody = (bool) atoi(op+11);
01528 } else if (!strncmp(op, "-mapgroup:",10)) {
01529 XrdSecProtocolssl::mapgroup = (bool) atoi(op+10);
01530 } else if (!strncmp(op, "-mapcernuser:",13)) {
01531 XrdSecProtocolssl::mapcerncertificates = (bool) atoi(op+13);
01532 } else if (!strncmp(op, "-sessioncachesize:", 18)) {
01533 XrdSecProtocolssl::sslsessioncachesize = atoi(op+18);
01534 } else if (!strncmp(op, "-selecttimeout:", 15)) {
01535 XrdSecProtocolssl::sslselecttimeout = atoi(op + 15);
01536 if ( XrdSecProtocolssl::sslselecttimeout < 5) {
01537 XrdSecProtocolssl::sslselecttimeout = 5;
01538 }
01539 } else if (!strncmp(op, "-procdir:",9)) {
01540 XrdSecProtocolssl::procdir = strdup(op+9);
01541 XrdSecProtocolssl::proc = new XrdSecProtocolsslProc(XrdSecProtocolssl::procdir, false);
01542 if (XrdSecProtocolssl::proc) {
01543 if (!XrdSecProtocolssl::proc->Open()) {
01544 delete XrdSecProtocolssl::proc;
01545 XrdSecProtocolssl::proc = NULL;
01546 }
01547 }
01548 time_t now = time(NULL);
01549
01550 if (XrdSecProtocolssl::proc) {
01551 XrdSecProtocolsslProcFile* pf;
01552 XrdOucString ID = XrdSecProtocolsslCVSID;
01553 ID+="\n";
01554 pf= XrdSecProtocolssl::proc->Handle("version"); pf && pf->Write(ID.c_str());
01555 pf= XrdSecProtocolssl::proc->Handle("start"); pf && pf->Write(ctime(&now));
01556 }
01557 }
01558 }
01559 }
01560 }
01561 } else {
01562 if ( (mode == 'c') || (serverinitialized)) {
01563 if (mode == 'c') {
01564 for (int i=0; i< PROTOCOLSSL_MAX_CRYPTO_MUTEX; i++) {
01565 XrdSecProtocolssl::CryptoMutexPool[i] = 0;
01566 }
01567 XrdSecProtocolssl::sslcertfile = strdup("/etc/grid-security/hostcert.pem");
01568 XrdSecProtocolssl::sslkeyfile = strdup("/etc/grid-security/hostkey.pem");
01569 XrdSecProtocolssl::sslcadir = strdup("/etc/grid-security/certificates");
01570 XrdSecProtocolssl::sslvomsdir = (char*)"/etc/grid-security/vomsdir";
01571 }
01572 XrdSecProtocolssl::GetEnvironment();
01573 XrdSecProtocolssl::isServer = 0;
01574 if (serverinitialized) {
01575 XrdSecProtocolssl::sslproxyexportplain = 0;
01576 }
01577 }
01578 }
01579
01580 if (XrdSecProtocolssl::debug >= 4) {
01581 SSLxTrace->What = TRACE_ALL | TRACE_Debug;
01582 } else if (XrdSecProtocolssl::debug == 3 ) {
01583 SSLxTrace->What |= TRACE_Authen;
01584 SSLxTrace->What |= TRACE_Debug;
01585 SSLxTrace->What |= TRACE_Identity;
01586 } else if (XrdSecProtocolssl::debug == 2) {
01587 SSLxTrace->What = TRACE_Debug;
01588 } else if (XrdSecProtocolssl::debug == 1) {
01589 SSLxTrace->What = TRACE_Identity;
01590 } else SSLxTrace->What = 0;
01591
01592
01593 if (PROTOCOLSSL_MAX_CRYPTO_MUTEX < CRYPTO_num_locks() ) {
01594 fprintf(stderr,"Error: (%s) I don't have enough crypto mutexes as required by crypto_ssl [recompile increasing PROTOCOLSSL_MAX_CRYPTO_MUTEX to %d] \n",__FUNCTION__,CRYPTO_num_locks());
01595 TRACE(Authen,"Error: I don't have enough crypto mutexes as required by crypto_ssl [recompile increasing PROTOCOLSSL_MAX_CRYPTO_MUTEX to " << (int)CRYPTO_num_locks() << "]");
01596 } else {
01597 TRACE(Authen,"====> SSL requires " << (int)CRYPTO_num_locks() << " mutexes for thread-safety");
01598 }
01599
01600 #if defined(OPENSSL_THREADS)
01601
01602 TRACE(Authen,"====> SSL with thread support!");
01603 #else
01604 fprintf(stderr,"Error: (%s) SSL lacks thread support: Abort!");
01605 TRACE(Authen,"Error: SSL lacks thread support: Abort!");
01606 #endif
01607
01608
01609 CRYPTO_set_locking_callback(protocolssl_lock);
01610 CRYPTO_set_id_callback(protocolssl_id_callback);
01611
01612
01613
01614
01615 if (XrdSecProtocolssl::isServer) {
01616 TRACE(Authen,"====> debug = " << XrdSecProtocolssl::debug);
01617 TRACE(Authen,"====> cadir = " << XrdSecProtocolssl::sslcadir);
01618 TRACE(Authen,"====> keyfile = " << XrdSecProtocolssl::sslkeyfile);
01619 TRACE(Authen,"====> certfile = " << XrdSecProtocolssl::sslcertfile);
01620 TRACE(Authen,"====> verify depth = " << XrdSecProtocolssl::verifydepth);
01621 TRACE(Authen,"====> sess.lifetime = " << XrdSecProtocolssl::sslsessionlifetime);
01622 TRACE(Authen,"====> gridmapfile = " << XrdSecProtocolssl::gridmapfile);
01623 TRACE(Authen,"====> vomsmapfile = " << XrdSecProtocolssl::vomsmapfile);
01624 TRACE(Authen,"====> mapuser = " << XrdSecProtocolssl::mapuser);
01625 TRACE(Authen,"====> mapnobody = " << XrdSecProtocolssl::mapnobody);
01626 TRACE(Authen,"====> mapgroup = " << XrdSecProtocolssl::mapgroup);
01627 TRACE(Authen,"====> mapcernuser = " << XrdSecProtocolssl::mapcerncertificates);
01628 TRACE(Authen,"====> selecttimeout = " << XrdSecProtocolssl::sslselecttimeout);
01629 TRACE(Authen,"====> sessioncachesize = " << XrdSecProtocolssl::sslsessioncachesize);
01630 TRACE(Authen,"====> procdir = " << XrdSecProtocolssl::procdir);
01631 char Info[16384];
01632 sprintf(Info,"debug = %d\ncadir = %s\nkeyfile = %s\ncertfile = %s\nverify depth = %d\nsess.lifetime = %ld\ngridmapfile = %s\nvomsmapfile = %s\nmapuser = %d\nmapnobody = %d\nmapgroup = %d\nmapcernuser = %d\nselecttimeout = %d\nprocdir = %s\nsessioncachesz = %d\n",XrdSecProtocolssl::debug,XrdSecProtocolssl::sslcadir, XrdSecProtocolssl::sslkeyfile, XrdSecProtocolssl::sslcertfile, XrdSecProtocolssl::verifydepth, XrdSecProtocolssl::sslsessionlifetime, XrdSecProtocolssl::gridmapfile, XrdSecProtocolssl::vomsmapfile, XrdSecProtocolssl::mapuser, XrdSecProtocolssl::mapnobody, XrdSecProtocolssl::mapgroup, XrdSecProtocolssl::mapcerncertificates, XrdSecProtocolssl::sslselecttimeout, XrdSecProtocolssl::procdir, XrdSecProtocolssl::sslsessioncachesize);
01633 if (XrdSecProtocolssl::proc) {
01634 XrdSecProtocolsslProcFile* pf;
01635 pf= XrdSecProtocolssl::proc->Handle("info"); pf && pf->Write(Info);
01636 }
01637 } else {
01638 if (XrdSecProtocolssl::debug) {
01639 TRACE(Authen,"====> debug = " << XrdSecProtocolssl::debug);
01640 TRACE(Authen,"====> cadir = " << XrdSecProtocolssl::sslcadir);
01641 TRACE(Authen,"====> keyfile = " << XrdSecProtocolssl::sslkeyfile);
01642 TRACE(Authen,"====> certfile = " << XrdSecProtocolssl::sslcertfile);
01643 TRACE(Authen,"====> verify depth = " << XrdSecProtocolssl::verifydepth);
01644 }
01645 }
01646
01647 if (XrdSecProtocolssl::isServer) {
01648 XrdSecProtocolssl::sslproxyexportplain=0;
01649
01650 if (XrdSecProtocolssl::mapuser && access(XrdSecProtocolssl::gridmapfile,R_OK)) {
01651 fprintf(stderr,"Error: (%s) cannot access gridmapfile %s\n",__FUNCTION__,XrdSecProtocolssl::gridmapfile);
01652 TRACE(Authen,"Error: cannot access gridmapfile "<< XrdOucString(XrdSecProtocolssl::gridmapfile));
01653 return 0;
01654 }
01655
01656 if (XrdSecProtocolssl::mapgroup && access(XrdSecProtocolssl::vomsmapfile,R_OK)) {
01657 fprintf(stderr,"Error: (%s) cannot access vomsmapfile %s\n",__FUNCTION__,XrdSecProtocolssl::vomsmapfile);
01658 TRACE(Authen,"Error: cannot access vomsmapfile "<< XrdOucString(XrdSecProtocolssl::vomsmapfile));
01659 return 0;
01660 }
01661
01662 XrdOucString exportplain=XrdSecProtocolssl::sslproxyexportdir;
01663
01664 if (exportplain.beginswith("plain:")) {
01665 XrdSecProtocolssl::sslproxyexportdir+=6;
01666 XrdSecProtocolssl::sslproxyexportplain=true;
01667 TRACE(Authen,"====> export plain proxy (warning: can be re-used out of daemon context) to dir: " << XrdSecProtocolssl::sslproxyexportdir);
01668 }
01669 if (XrdSecProtocolssl::sslproxyexportdir && access(XrdSecProtocolssl::sslproxyexportdir,R_OK | W_OK)) {
01670 fprintf(stderr,"Error: (%s) cannot read/write proxy export directory %s\n",__FUNCTION__,XrdSecProtocolssl::sslproxyexportdir);
01671 TRACE(Authen,"Error: cannot access proxyexportdir "<< XrdOucString(XrdSecProtocolssl::sslproxyexportdir));
01672 return 0;
01673 }
01674 }
01675
01676 if (XrdSecProtocolssl::isServer) {
01677 SSL_METHOD *meth;
01678
01679 SSL_load_error_strings();
01680 SSLeay_add_ssl_algorithms();
01681
01682 meth = (SSL_METHOD*)SSLv23_server_method();
01683
01684 XrdSecProtocolssl::ctx = SSL_CTX_new (meth);
01685 if (!XrdSecProtocolssl::ctx) {
01686 ERR_print_errors_fp(stderr);
01687 return 0;
01688 }
01689
01690 if (SSL_CTX_use_certificate_file(XrdSecProtocolssl::ctx, XrdSecProtocolssl::sslcertfile, SSL_FILETYPE_PEM) <= 0) {
01691 ERR_print_errors_fp(stderr);
01692 return 0;
01693 }
01694
01695 if (SSL_CTX_use_PrivateKey_file(XrdSecProtocolssl::ctx,XrdSecProtocolssl::sslkeyfile, SSL_FILETYPE_PEM) <= 0) {
01696 ERR_print_errors_fp(stderr);
01697 return 0;
01698 }
01699
01700 if (!SSL_CTX_check_private_key(XrdSecProtocolssl::ctx)) {
01701 fprintf(stderr,"Private key does not match the certificate public key\n");
01702 return 0;
01703 }
01704
01705 XrdSecProtocolssl::sslserverkeyfile=XrdSecProtocolssl::sslkeyfile;
01706
01707 memset(XrdSecProtocolssl::sslserverexportpassword,0,EXPORTKEYSTRENGTH);
01708
01709 unsigned int seed = (unsigned int) (time(NULL) + (unsigned int) random());
01710 srand(seed);
01711 char rexportkey[16384];
01712 rexportkey[0]=0;
01713 for (int i=0; i < EXPORTKEYSTRENGTH; i++) {
01714 XrdSecProtocolssl::sslserverexportpassword[i] = (unsigned char)(rand()%256);
01715 if (!XrdSecProtocolssl::sslserverexportpassword[i]) XrdSecProtocolssl::sslserverexportpassword[i]++;
01716 sprintf(rexportkey,"%s%x",rexportkey,XrdSecProtocolssl::sslserverexportpassword[i]);
01717 }
01718 XrdSecProtocolssl::sslserverexportpassword[EXPORTKEYSTRENGTH] = 0;
01719 sprintf((char*)XrdSecProtocolssl::sslserverexportpassword,"1234567890");
01720
01721 DEBUG("Created random export key: "<< rexportkey);
01722 SSL_CTX_load_verify_locations(XrdSecProtocolssl::ctx, NULL,XrdSecProtocolssl::sslcadir);
01723
01724
01725 if (!XrdSecProtocolssl::store) {
01726 DEBUG("Created SSL CRL store: " << XrdSecProtocolssl::store);
01727 XrdSecProtocolssl::store = SSL_X509_STORE_create(NULL,XrdSecProtocolssl::sslcadir);
01728 X509_STORE_set_flags(XrdSecProtocolssl::store,0);
01729 XrdSecProtocolssl::storeLoadTime = time(NULL);
01730 }
01731
01732 XrdSecProtocolssl::ctx->verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
01733
01734 grst_cadir = XrdSecProtocolssl::sslcadir;
01735 grst_vomsdir = XrdSecProtocolssl::sslvomsdir;
01736 grst_depth = XrdSecProtocolssl::verifydepth;
01737
01738 SSL_CTX_set_cert_verify_callback(XrdSecProtocolssl::ctx,
01739 GRST_verify_cert_wrapper,
01740 (void *) NULL);
01741
01742 SSL_CTX_set_verify(XrdSecProtocolssl::ctx, XrdSecProtocolssl::ctx->verify_mode,GRST_callback_SSLVerify_wrapper);
01743 SSL_CTX_set_verify_depth(XrdSecProtocolssl::ctx, XrdSecProtocolssl::verifydepth + 1);
01744
01745 if(!SSL_CTX_set_generate_session_id(XrdSecProtocolssl::ctx, XrdSecProtocolssl::GenerateSession)) {
01746 TRACE(Authen,"Cannot set session generator");
01747 return 0;
01748 }
01749
01750 SSL_CTX_set_options(XrdSecProtocolssl::ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
01751
01752 SSL_CTX_sess_set_cache_size(XrdSecProtocolssl::ctx,XrdSecProtocolssl::sslsessioncachesize);
01753
01754 if (XrdSecProtocolssl::sslsessioncachesize) {
01755 SSL_CTX_set_session_cache_mode(XrdSecProtocolssl::ctx, SSL_SESS_CACHE_BOTH);
01756 } else {
01757 SSL_CTX_set_session_cache_mode(XrdSecProtocolssl::ctx, SSL_SESS_CACHE_OFF | SSL_SESS_CACHE_NO_INTERNAL );
01758
01759 }
01760
01761 SSL_CTX_set_session_id_context(XrdSecProtocolssl::ctx,(const unsigned char*) XrdSecProtocolssl::SessionIdContext, strlen(XrdSecProtocolssl::SessionIdContext));
01762 SSL_CTX_sess_set_new_cb(XrdSecProtocolssl::ctx, XrdSecProtocolssl::NewSession);
01763 }
01764 return (char *)"";
01765 }
01766 }
01767
01768
01769
01770
01771
01772 extern "C"
01773 {
01774 XrdSecProtocol *XrdSecProtocolsslObject(const char mode,
01775 const char *hostname,
01776 const struct sockaddr &netaddr,
01777 const char *parms,
01778 XrdOucErrInfo *erp)
01779 {
01780 XrdSecProtocolssl *prot;
01781
01782
01783
01784 if (!(prot = new XrdSecProtocolssl(hostname, &netaddr)))
01785 {const char *msg = "Secssl: Insufficient memory for protocol.";
01786 if (erp) erp->setErrInfo(ENOMEM, msg);
01787 else cerr <<msg <<endl;
01788 return (XrdSecProtocol *)0;
01789 }
01790
01791
01792
01793 return prot;
01794 }
01795 }
01796