983 {
986 std::vector<extHInfo> extHIVec;
987 char *var;
988 int cfgFD, GoNo, NoGo = 0, ismine;
989
990 var = nullptr;
993
994 pmarkHandle = (
XrdNetPMark* ) myEnv->GetPtr(
"XrdNetPMark*");
995
996 cksumHandler.configure(xrd_cslist);
997 auto nonIanaChecksums = cksumHandler.getNonIANAConfiguredCksums();
998 if(nonIanaChecksums.size()) {
999 std::stringstream warningMsgSS;
1000 warningMsgSS << "Config warning: the following checksum algorithms are not IANA compliant: [";
1001 std::string unknownCksumString;
1002 for(auto unknownCksum: nonIanaChecksums) {
1003 unknownCksumString += unknownCksum + ",";
1004 }
1005 unknownCksumString.erase(unknownCksumString.size() - 1);
1006 warningMsgSS << unknownCksumString << "]" << ". They therefore cannot be queried by a user via HTTP." ;
1007 eDest.
Say(warningMsgSS.str().c_str());
1008 }
1009
1010
1011 if (!m_bio_type) {
1012
1013 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1014 m_bio_type = (26|0x0400|0x0100);
1015 m_bio_method = static_cast<BIO_METHOD*>(OPENSSL_malloc(sizeof(BIO_METHOD)));
1016
1017 if (m_bio_method) {
1018 memset(m_bio_method, '\0', sizeof(BIO_METHOD));
1019 m_bio_method->type = m_bio_type;
1025 }
1026 #else
1027
1028
1029 m_bio_type = BIO_get_new_index();
1030 m_bio_method = BIO_meth_new(m_bio_type, "xrdhttp-bio-method");
1031
1032 if (m_bio_method) {
1038 }
1039
1040 #endif
1041 }
1042
1043
1044
1045
1047
1048
1049
1050 if ((cfgFD =
open(ConfigFN, O_RDONLY, 0)) < 0)
1051 return eDest.
Emsg(
"Config", errno,
"open config file", ConfigFN);
1053 static const char *cvec[] = { "*** http protocol config:", 0 };
1055
1056
1057
1058 while ((var =
Config.GetMyFirstWord())) {
1059 if ((ismine = !strncmp("http.", var, 5)) && var[5]) var += 5;
1060
1061 if (ismine) {
1062 if TS_Xeq(
"trace", xtrace);
1063 else if TS_Xeq(
"cert", xsslcert);
1064 else if TS_Xeq(
"key", xsslkey);
1065 else if TS_Xeq(
"cadir", xsslcadir);
1066 else if TS_Xeq(
"cipherfilter", xsslcipherfilter);
1067 else if TS_Xeq(
"gridmap", xgmap);
1068 else if TS_Xeq(
"cafile", xsslcafile);
1069 else if TS_Xeq(
"secretkey", xsecretkey);
1070 else if TS_Xeq(
"desthttps", xdesthttps);
1071 else if TS_Xeq(
"secxtractor", xsecxtractor);
1072 else if TS_Xeq3(
"exthandler", xexthandler);
1073 else if TS_Xeq(
"selfhttps2http", xselfhttps2http);
1074 else if TS_Xeq(
"embeddedstatic", xembeddedstatic);
1075 else if TS_Xeq(
"listingredir", xlistredir);
1076 else if TS_Xeq(
"staticredir", xstaticredir);
1077 else if TS_Xeq(
"staticpreload", xstaticpreload);
1078 else if TS_Xeq(
"staticheader", xstaticheader);
1079 else if TS_Xeq(
"listingdeny", xlistdeny);
1080 else if TS_Xeq(
"header2cgi", xheader2cgi);
1081 else if TS_Xeq(
"httpsmode", xhttpsmode);
1082 else if TS_Xeq(
"tlsreuse", xtlsreuse);
1083 else if TS_Xeq(
"auth", xauth);
1084 else {
1085 eDest.
Say(
"Config warning: ignoring unknown directive '", var,
"'.");
1087 continue;
1088 }
1089 if (GoNo) {
1091 NoGo = 1;
1092 }
1093 }
1094 }
1095
1096
1097
1098
1099 if (NoGo)
1100 {
eDest.
Say(
"Config failure: one or more directives are flawed!");
1101 return 1;
1102 }
1103
1104
1105
1106 hdr2cgimap["Cache-Control"] = "cache-control";
1107
1108
1109 if (getenv(
"XRDCL_EC"))
usingEC =
true;
1110
1111
1112
1113 const auto default_verb = m_staticheader_map.find("");
1114 std::string default_static_headers;
1115 if (default_verb != m_staticheader_map.end()) {
1116 for (const auto &header_entry : default_verb->second) {
1117 default_static_headers += header_entry.first + ": " + header_entry.second + "\r\n";
1118 }
1119 }
1120 m_staticheaders[""] = default_static_headers;
1121 for (const auto &item : m_staticheader_map) {
1122 if (item.first.empty()) {
1123 continue;
1124 }
1125 auto headers = default_static_headers;
1126 for (const auto &header_entry : item.second) {
1127 headers += header_entry.first + ": " + header_entry.second + "\r\n";
1128 }
1129
1130 m_staticheaders[item.first] = headers;
1131 }
1132
1133
1134
1135 if (myEnv->Get("XrdCache")) hasCache = true;
1136
1137
1138
1139
1140
1141
1144 : "was not configured.");
1145 const char *what = Configed();
1146
1147 eDest.
Say(
"Config warning: HTTPS functionality ", why);
1149
1150 LoadExtHandlerNoTls(extHIVec, ConfigFN, *myEnv);
1151 if (what)
1152 {
eDest.
Say(
"Config failure: ", what,
" HTTPS but it ", why);
1153 NoGo = 1;
1154 }
1155 return NoGo;
1156 }
1157
1158
1159
1160
1161 if (sslkey && !sslcert)
1162 {
eDest.
Say(
"Config warning: specifying http.key without http.cert "
1163 "is meaningless; ignoring key!");
1164 free(sslkey); sslkey = 0;
1165 }
1166
1167
1168
1170 {if (!sslcert)
1171 {
eDest.
Say(
"Config failure: 'httpsmode manual' requires atleast a "
1172 "a cert specification!");
1173 return 1;
1174 }
1175 }
1176
1177
1178
1179
1180
1183 const char *what1 = 0, *what2 = 0, *what3 = 0;
1184
1185 if (!sslcert && cP->
cert.size())
1186 {sslcert = strdup(cP->
cert.c_str());
1187 if (cP->
pkey.size()) sslkey = strdup(cP->
pkey.c_str());
1188 what1 = "xrd.tls to supply 'cert' and 'key'.";
1189 }
1190 if (!sslcadir && cP->
cadir.size())
1191 {sslcadir = strdup(cP->
cadir.c_str());
1192 what2 = "xrd.tlsca to supply 'cadir'.";
1193 }
1194 if (!sslcafile && cP->
cafile.size())
1195 {sslcafile = strdup(cP->
cafile.c_str());
1196 what2 = (what2 ? "xrd.tlsca to supply 'cadir' and 'cafile'."
1197 : "xrd.tlsca to supply 'cafile'.");
1198 }
1200 crlRefIntervalSec = cP->
crlRT;
1201 what3 = "xrd.tlsca to supply 'refresh' interval.";
1202 }
1206 }
1207
1208
1209
1210 if (!(sslcadir || sslcafile))
1211 {const char *what = Configed();
1212 const char *why = (
httpsspec ?
"a cadir or cafile was not specified!"
1213 : "'xrd.tlsca noverify' was specified!");
1214 if (what)
1215 {
eDest.
Say(
"Config failure: ", what,
" cert verification but ", why);
1216 return 1;
1217 }
1218 }
1220
1221
1222
1223 sslbio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
1224
1225
1226
1227
1228 const char *how = "completed.";
1229 eDest.
Say(
"++++++ HTTPS initialization started.");
1230 if (!InitTLS()) {NoGo = 1; how = "failed.";}
1231 eDest.
Say(
"------ HTTPS initialization ", how);
1232 if (NoGo) return NoGo;
1233
1234
1235
1236 if (LoadExtHandler(extHIVec, ConfigFN, *myEnv)) return 1;
1237
1238
1239
1240 return (InitSecurity() ? NoGo : 1);
1241}
1242
1243
1244
1245
1246
1247const char *XrdHttpProtocol::Configed()
1248{
1249 if (secxtractor &&
gridmap)
return "gridmap and secxtractor require";
1250 if (secxtractor) return "secxtractor requires";
1251 if (
gridmap)
return "gridmap requires";
1252 return 0;
1253}
1254
1255
1256
1257
1258
1260
1262
1263 dest = "";
1264 char save;
1265
1266
1267 if (myBuffEnd >= myBuffStart) {
1268 int l = 0;
1269 for (char *p = myBuffStart; p < myBuffEnd; p++) {
1270 l++;
1271 if (*p == '\n') {
1272 save = *(p+1);
1273 *(p+1) = '\0';
1274 dest.
assign(myBuffStart, 0, l-1);
1275 *(p+1) = save;
1276
1277
1278
1279 BuffConsume(l);
1280
1281
1282 return l;
1283 }
1284
1285 }
1286
1287 return 0;
1288 } else {
1289
1290
1291
1292 int l = 0;
1293 for (
char *p = myBuffStart; p < myBuff->
buff + myBuff->
bsize; p++) {
1294 l++;
1295 if ((*p == '\n') || (*p == '\0')) {
1296 save = *(p+1);
1297 *(p+1) = '\0';
1298 dest.
assign(myBuffStart, 0, l-1);
1299 *(p+1) = save;
1300
1301
1302
1303 BuffConsume(l);
1304
1305
1306 return l;
1307 }
1308
1309 }
1310
1311
1312
1313 l = 0;
1314 for (
char *p = myBuff->
buff; p < myBuffEnd; p++) {
1315 l++;
1316 if ((*p == '\n') || (*p == '\0')) {
1317 save = *(p+1);
1318 *(p+1) = '\0';
1319
1320 int l1 = myBuff->
buff + myBuff->
bsize - myBuffStart;
1321
1322 dest.
assign(myBuffStart, 0, l1-1);
1323
1324 BuffConsume(l1);
1325
1326 dest.
insert(myBuffStart, l1, l-1);
1327
1328
1329 BuffConsume(l);
1330
1331 *(p+1) = save;
1332
1333
1334 return l + l1;
1335 }
1336
1337 }
1338
1339
1340
1341 }
1342
1343 return 0;
1344}
1345
1346
1347
1348
1349
1350int XrdHttpProtocol::getDataOneShot(int blen, bool wait) {
1351 int rlen, maxread;
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365 maxread = std::min(blen, BuffAvailable());
1366 TRACE(
DEBUG,
"getDataOneShot BuffAvailable: " << BuffAvailable() <<
" maxread: " << maxread);
1367
1368 if (!maxread)
1369 return 2;
1370
1371 if (ishttps) {
1372 int sslavail = maxread;
1373
1374 if (!wait) {
1375 int l = SSL_pending(ssl);
1376 if (l > 0)
1377 sslavail = std::min(maxread, SSL_pending(ssl));
1378 }
1379
1380 if (sslavail < 0) {
1382 ERR_print_errors(sslbio_err);
1383 return -1;
1384 }
1385
1386 TRACE(
DEBUG,
"getDataOneShot sslavail: " << sslavail);
1387 if (sslavail <= 0) return 0;
1388
1389 if (myBuffEnd - myBuff->
buff >= myBuff->
bsize) {
1391 myBuffEnd = myBuff->
buff;
1392 }
1393
1394 rlen = SSL_read(ssl, myBuffEnd, sslavail);
1395 if (rlen <= 0) {
1397 ERR_print_errors(sslbio_err);
1398 return -1;
1399 }
1400
1401
1402 } else {
1403
1404 if (myBuffEnd - myBuff->
buff >= myBuff->
bsize) {
1406 myBuffEnd = myBuff->
buff;
1407 }
1408
1409 if (wait)
1411 else
1412 rlen =
Link->
Recv(myBuffEnd, maxread);
1413
1414
1415 if (rlen == 0) {
1417 return -1;
1418 }
1419
1420 if (rlen < 0) {
1422 return -1;
1423 }
1424 }
1425
1426 myBuffEnd += rlen;
1427
1428 TRACE(REQ,
"read " << rlen <<
" of " << blen <<
" bytes");
1429
1430 return 0;
1431}
1432
1434
1435int XrdHttpProtocol::BuffAvailable() {
1436 int r;
1437
1438 if (myBuffEnd >= myBuffStart)
1439 r = myBuff->
buff + myBuff->
bsize - myBuffEnd;
1440 else
1441 r = myBuffStart - myBuffEnd;
1442
1443 if ((r < 0) || (r > myBuff->
bsize)) {
1444 TRACE(REQ,
"internal error, myBuffAvailable: " << r <<
" myBuff->bsize " << myBuff->
bsize);
1445 abort();
1446 }
1447
1448 return r;
1449}
1450
1451
1452
1453
1454
1456
1457int XrdHttpProtocol::BuffUsed() {
1458 int r;
1459
1460 if (myBuffEnd >= myBuffStart)
1461 r = myBuffEnd - myBuffStart;
1462 else
1463
1464 r = myBuff->
bsize - (myBuffStart - myBuffEnd);
1465
1466 if ((r < 0) || (r > myBuff->
bsize)) {
1467 TRACE(REQ,
"internal error, myBuffUsed: " << r <<
" myBuff->bsize " << myBuff->
bsize);
1468 abort();
1469 }
1470
1471 return r;
1472}
1473
1474
1475
1476
1477
1479
1480int XrdHttpProtocol::BuffFree() {
1481 return (myBuff->
bsize - BuffUsed());
1482}
1483
1484
1485
1486
1487
1488void XrdHttpProtocol::BuffConsume(int blen) {
1489
1490 if (blen > myBuff->
bsize) {
1491 TRACE(REQ,
"internal error, BuffConsume(" << blen <<
") smaller than buffsize");
1492 abort();
1493 }
1494
1495 if (blen > BuffUsed()) {
1496 TRACE(REQ,
"internal error, BuffConsume(" << blen <<
") larger than BuffUsed:" << BuffUsed());
1497 abort();
1498 }
1499
1500 myBuffStart = myBuffStart + blen;
1501
1502 if (myBuffStart >= myBuff->
buff + myBuff->
bsize)
1503 myBuffStart -= myBuff->
bsize;
1504
1505 if (myBuffEnd >= myBuff->
buff + myBuff->
bsize)
1506 myBuffEnd -= myBuff->
bsize;
1507
1508 if (BuffUsed() == 0)
1509 myBuffStart = myBuffEnd = myBuff->
buff;
1510}
1511
1512
1513
1514
1515
1524int XrdHttpProtocol::BuffgetData(int blen, char **data, bool wait) {
1525 int rlen;
1526
1527 TRACE(
DEBUG,
"BuffgetData: requested " << blen <<
" bytes");
1528
1529
1530 if (wait) {
1531
1532 if (blen > BuffUsed()) {
1533 TRACE(REQ,
"BuffgetData: need to read " << blen - BuffUsed() <<
" bytes");
1534 if ( getDataOneShot(blen - BuffUsed(), true) )
1535
1536 return 0;
1537 }
1538 } else {
1539
1540 if ( !BuffUsed() ) {
1541 if ( getDataOneShot(blen, false) )
1542
1543 return -1;
1544 }
1545 }
1546
1547
1548
1549 if (myBuffStart <= myBuffEnd) {
1550 rlen = std::min( (long) blen, (long)(myBuffEnd - myBuffStart) );
1551
1552 } else
1553 rlen = std::min( (
long) blen, (
long)(myBuff->
buff + myBuff->
bsize - myBuffStart) );
1554
1555 *data = myBuffStart;
1556 BuffConsume(rlen);
1557 return rlen;
1558}
1559
1560
1561
1562
1563
1565
1566int XrdHttpProtocol::SendData(const char *body, int bodylen) {
1567
1568 int r;
1569
1570 if (body && bodylen) {
1571 TRACE(REQ,
"Sending " << bodylen <<
" bytes");
1572 if (ishttps) {
1573 r = SSL_write(ssl, body, bodylen);
1574 if (r <= 0) {
1575 ERR_print_errors(sslbio_err);
1576 return -1;
1577 }
1578
1579 } else {
1581 if (r <= 0) return -1;
1582 }
1583 }
1584
1585 return 0;
1586}
1587
1588
1589
1590
1591
1592int XrdHttpProtocol::StartSimpleResp(int code, const char *desc, const char *header_to_add, long long bodylen, bool keepalive) {
1593 std::stringstream ss;
1594 const std::string crlf = "\r\n";
1595
1596 ss << "HTTP/1.1 " << code << " ";
1597 if (desc) {
1598 ss << desc;
1599 } else {
1600 if (code == 200) ss << "OK";
1601 else if (code == 100) ss << "Continue";
1602 else if (code == 206) ss << "Partial Content";
1603 else if (code == 302) ss << "Redirect";
1604 else if (code == 307) ss << "Temporary Redirect";
1605 else if (code == 400) ss << "Bad Request";
1606 else if (code == 403) ss << "Forbidden";
1607 else if (code == 404) ss << "Not Found";
1608 else if (code == 405) ss << "Method Not Allowed";
1609 else if (code == 416) ss << "Range Not Satisfiable";
1610 else if (code == 500) ss << "Internal Server Error";
1611 else if (code == 502) ss << "Bad Gateway";
1612 else if (code == 504) ss << "Gateway Timeout";
1613 else ss << "Unknown";
1614 }
1615 ss << crlf;
1616 if (keepalive && (code != 100))
1617 ss << "Connection: Keep-Alive" << crlf;
1618 else
1619 ss << "Connection: Close" << crlf;
1620
1621 ss << "Server: XrootD/" << XrdVSTRING << crlf;
1622
1625 ss << iter->second;
1626 } else {
1628 }
1629
1630 if ((bodylen >= 0) && (code != 100))
1631 ss << "Content-Length: " << bodylen << crlf;
1632
1633 if (header_to_add && (header_to_add[0] != '\0'))
1634 ss << header_to_add << crlf;
1635
1636 ss << crlf;
1637
1638 const std::string &outhdr = ss.str();
1639 TRACEI(RSP,
"Sending resp: " << code <<
" header len:" << outhdr.size());
1640 if (SendData(outhdr.c_str(), outhdr.size()))
1641 return -1;
1642
1643 return 0;
1644}
1645
1646
1647
1648
1649
1650int XrdHttpProtocol::StartChunkedResp(int code, const char *desc, const char *header_to_add, long long bodylen, bool keepalive) {
1651 const std::string crlf = "\r\n";
1652 std::stringstream ss;
1653
1654 if (header_to_add && (header_to_add[0] != '\0')) {
1655 ss << header_to_add << crlf;
1656 }
1657
1658 ss << "Transfer-Encoding: chunked";
1659 TRACEI(RSP,
"Starting chunked response");
1660 return StartSimpleResp(code, desc, ss.str().c_str(), bodylen, keepalive);
1661}
1662
1663
1664
1665
1666
1667int XrdHttpProtocol::ChunkResp(const char *body, long long bodylen) {
1668 long long content_length = (bodylen <= 0) ? (body ? strlen(body) : 0) : bodylen;
1669 if (ChunkRespHeader(content_length))
1670 return -1;
1671
1672 if (body && SendData(body, content_length))
1673 return -1;
1674
1675 return ChunkRespFooter();
1676}
1677
1678
1679
1680
1681
1682int XrdHttpProtocol::ChunkRespHeader(long long bodylen) {
1683 const std::string crlf = "\r\n";
1684 std::stringstream ss;
1685
1686 ss << std::hex << bodylen << std::dec << crlf;
1687
1688 const std::string &chunkhdr = ss.str();
1689 TRACEI(RSP,
"Sending encoded chunk of size " << bodylen);
1690 return (SendData(chunkhdr.c_str(), chunkhdr.size())) ? -1 : 0;
1691}
1692
1693
1694
1695
1696
1697int XrdHttpProtocol::ChunkRespFooter() {
1698 const std::string crlf = "\r\n";
1699 return (SendData(crlf.c_str(), crlf.size())) ? -1 : 0;
1700}
1701
1702
1703
1704
1705
1709
1710int XrdHttpProtocol::SendSimpleResp(int code, const char *desc, const char *header_to_add, const char *body, long long bodylen, bool keepalive) {
1711
1712 long long content_length = bodylen;
1713 if (bodylen <= 0) {
1714 content_length = body ? strlen(body) : 0;
1715 }
1716
1717 if (StartSimpleResp(code, desc, header_to_add, content_length, keepalive) < 0)
1718 return -1;
1719
1720
1721
1722
1723 if (body)
1724 return SendData(body, content_length);
1725
1726 return 0;
1727}
1728
1729
1730
1731
1732
1734
1735
1736
1737
1738
1739
1740
1741
1742 char *rdf;
1743
1744
1745
1748
1752
1754
1755
1756
1758
1759 {
1760 char buf[16];
1761 sprintf(buf,
"%d",
Port);
1763 }
1764
1765
1766
1767 rdf = (parms && *parms ? parms : pi->
ConfigFN);
1768 if (rdf && Config(rdf, pi->
theEnv))
return 0;
1770
1771
1773 if ((rdf = getenv("XRDROLE"))) {
1775
1776 if (!strcasecmp(rdf, "manager") || !strcasecmp(rdf, "supervisor")) {
1778 eDest.
Emsg(
"Config",
"Configured as HTTP(s) redirector.");
1779 } else {
1780
1781 eDest.
Emsg(
"Config",
"Configured as HTTP(s) data server.");
1782 }
1783
1784 } else {
1785 eDest.
Emsg(
"Config",
"No XRDROLE specified.");
1786 }
1787
1788
1789
1793
1794
1795
1796
1797 return 1;
1798}
1799
1800
1801
1802
1804 char *val, keybuf[1024], parmbuf[1024];
1805 char *parm;
1806
1807
1809 if (!val || !val[0]) {
1810 err.
Emsg(
"Config",
"No headerkey specified.");
1811 return 1;
1812 } else {
1813
1814
1815 while ( *val && !isalnum(*val) ) val++;
1816 strcpy(keybuf, val);
1817
1818
1819 char *pp;
1820 pp = keybuf + strlen(keybuf) - 1;
1821 while ( (pp >= keybuf) && (!isalnum(*pp)) ) {
1822 *pp = '\0';
1823 pp--;
1824 }
1825
1827
1828
1829 if(!parm || !parm[0]) {
1830 err.
Emsg(
"Config",
"No header2cgi value specified. key: '", keybuf,
"'");
1831 return 1;
1832 }
1833
1834
1835 while ( *parm && !isalnum(*parm) ) parm++;
1836 strcpy(parmbuf, parm);
1837
1838
1839 pp = parmbuf + strlen(parmbuf) - 1;
1840 while ( (pp >= parmbuf) && (!isalnum(*pp)) ) {
1841 *pp = '\0';
1842 pp--;
1843 }
1844
1845
1846 try {
1847 header2cgi[keybuf] = parmbuf;
1848 } catch ( ... ) {
1849 err.
Emsg(
"Config",
"Can't insert new header2cgi rule. key: '", keybuf,
"'");
1850 return 1;
1851 }
1852
1853 }
1854 return 0;
1855}
1856
1857
1858
1859
1860
1861
1862bool XrdHttpProtocol::InitTLS() {
1863
1867
1868
1869
1872
1875
1876
1877
1880 return false;
1881 }
1882
1883
1884
1885
1886
1887 static const char *sess_ctx_id = "XrdHTTPSessionCtx";
1888 unsigned int n =(unsigned int)(strlen(sess_ctx_id)+1);
1890
1891
1892
1894 {
eDest.
Say(
"Config failure: ",
"Unable to set allowable https ciphers!");
1895 return false;
1896 }
1897
1898
1899
1900 return true;
1901}
1902
1903
1904
1905
1906
1907void XrdHttpProtocol::Cleanup() {
1908
1909 TRACE(ALL,
" Cleanup");
1910
1911 if (
BPool && myBuff) {
1912 BuffConsume(BuffUsed());
1914 myBuff = 0;
1915 }
1916
1917 if (ssl) {
1918
1919
1920
1921
1922
1923
1924
1925
1926 int ret = SSL_shutdown(ssl);
1927 if (ret != 1) {
1928 if(ret == 0) {
1929
1930 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1931 ERR_remove_thread_state(nullptr);
1932 #endif
1933 } else {
1934
1935 TRACE(ALL,
" SSL_shutdown failed");
1936 ERR_print_errors(sslbio_err);
1937 }
1938 }
1939
1940 if (secxtractor)
1942
1943 SSL_free(ssl);
1944
1945 }
1946
1947
1948 ssl = 0;
1949 sbio = 0;
1950
1959
1961
1964}
1965
1966
1967
1968
1969
1970void XrdHttpProtocol::Reset() {
1971
1972 TRACE(ALL,
" Reset");
1976
1977 if (myBuff) {
1979 myBuff = 0;
1980 }
1981 myBuffStart = myBuffEnd = 0;
1982
1983 DoingLogin = false;
1984 DoneSetInfo = false;
1985
1986 ResumeBytes = 0;
1987 Resume = 0;
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2004 ishttps = false;
2005 ssldone = false;
2006
2008 ssl = 0;
2009 sbio = 0;
2010
2011}
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028int XrdHttpProtocol::xhttpsmode(
XrdOucStream & Config) {
2029 char *val;
2030
2031
2032
2034 if (!val || !val[0]) {
2035 eDest.
Emsg(
"Config",
"httpsmode parameter not specified");
2036 return 1;
2037 }
2038
2039
2040
2044 else {
eDest.
Emsg(
"Config",
"invalid httpsmode parameter - ", val);
2045 return 1;
2046 }
2047 return 0;
2048}
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063int XrdHttpProtocol::xsslverifydepth(
XrdOucStream & Config) {
2064 char *val;
2065
2066
2067
2069 if (!val || !val[0]) {
2070 eDest.
Emsg(
"Config",
"sslverifydepth value not specified");
2071 return 1;
2072 }
2073
2074
2075
2077
2079 return 0;
2080}
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2096 char *val;
2097
2098
2099
2101 if (!val || !val[0]) {
2102 eDest.
Emsg(
"Config",
"HTTP X509 certificate not specified");
2103 return 1;
2104 }
2105
2106
2107
2110
2111
2112
2114 return 0;
2115}
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2131 char *val;
2132
2133
2134
2136 if (!val || !val[0]) {
2137 eDest.
Emsg(
"Config",
"HTTP X509 key not specified");
2138 return 1;
2139 }
2140
2141
2142
2145
2147 return 0;
2148}
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2168 char *val;
2169
2170
2171
2173 if (!val || !val[0]) {
2174 eDest.
Emsg(
"Config",
"HTTP X509 gridmap file location not specified");
2175 return 1;
2176 }
2177
2178
2179
2180 if (!strncmp(val, "required", 8)) {
2183
2184 if (!val || !val[0]) {
2185 eDest.
Emsg(
"Config",
"HTTP X509 gridmap file missing after [required] "
2186 "parameter");
2187 return 1;
2188 }
2189 }
2190
2191
2192
2193 if (!strcmp(val, "compatNameGeneration")) {
2196 if (!val || !val[0]) {
2197 eDest.
Emsg(
"Config",
"HTTP X509 gridmap file missing after "
2198 "[compatNameGeneration] parameter");
2199 return 1;
2200 }
2201 }
2202
2203
2204
2205
2208 return 0;
2209}
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224int XrdHttpProtocol::xsslcafile(
XrdOucStream & Config) {
2225 char *val;
2226
2227
2228
2230 if (!val || !val[0]) {
2231 eDest.
Emsg(
"Config",
"HTTP X509 CAfile not specified");
2232 return 1;
2233 }
2234
2235
2236
2239
2241 return 0;
2242}
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257int XrdHttpProtocol::xsecretkey(
XrdOucStream & Config) {
2258 char *val;
2259 bool inFile = false;
2260
2261
2262
2264 if (!val || !val[0]) {
2265 eDest.
Emsg(
"Config",
"Shared secret key not specified");
2266 return 1;
2267 }
2268
2269
2270
2271
2272
2273 if (val[0] == '/') {
2275 inFile = true;
2276 int fd =
open(val, O_RDONLY);
2277
2278 if ( fd == -1 ) {
2279 eDest.
Emsg(
"Config", errno,
"open shared secret key file", val);
2280 return 1;
2281 }
2282
2283 if (
fstat(fd, &st) != 0 ) {
2284 eDest.
Emsg(
"Config", errno,
"fstat shared secret key file", val);
2286 return 1;
2287 }
2288
2289 if ( st.st_mode & S_IWOTH & S_IWGRP & S_IROTH) {
2291 "For your own security, the shared secret key file cannot be world readable or group writable '", val, "'");
2293 return 1;
2294 }
2295
2296 FILE *fp = fdopen(fd, "r");
2297
2298 if ( fp == nullptr ) {
2299 eDest.
Emsg(
"Config", errno,
"fdopen shared secret key file", val);
2301 return 1;
2302 }
2303
2304 char line[1024];
2305 while( fgets(line, 1024, fp) ) {
2306 char *pp;
2307
2308
2309 pp = line + strlen(line) - 1;
2310 while ( (pp >= line) && (!isalnum(*pp)) ) {
2311 *pp = '\0';
2312 pp--;
2313 }
2314
2315
2316 pp = line;
2317 while ( *pp && !isalnum(*pp) ) pp++;
2318
2319 if ( strlen(pp) >= 32 ) {
2320 eDest.
Say(
"Config",
"Secret key loaded.");
2321
2324
2326 return 0;
2327 }
2328
2329 }
2330
2332 eDest.
Emsg(
"Config",
"Cannot find useful secretkey in file '", val,
"'");
2333 return 1;
2334
2335 }
2336
2337 if ( strlen(val) < 32 ) {
2338 eDest.
Emsg(
"Config",
"Secret key is too short");
2339 return 1;
2340 }
2341
2342
2345 if (!inFile)
Config.noEcho();
2346
2347 return 0;
2348}
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2364 char *val;
2365
2366
2367
2369 if (!val || !val[0]) {
2370 eDest.
Emsg(
"Config",
"listingdeny flag not specified");
2371 return 1;
2372 }
2373
2374
2375
2376 listdeny = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2377
2378
2379 return 0;
2380}
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395int XrdHttpProtocol::xlistredir(
XrdOucStream & Config) {
2396 char *val;
2397
2398
2399
2401 if (!val || !val[0]) {
2402 eDest.
Emsg(
"Config",
"listingredir flag not specified");
2403 return 1;
2404 }
2405
2406
2407
2410
2411
2412 return 0;
2413}
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428int XrdHttpProtocol::xdesthttps(
XrdOucStream & Config) {
2429 char *val;
2430
2431
2432
2434 if (!val || !val[0]) {
2435 eDest.
Emsg(
"Config",
"desthttps flag not specified");
2436 return 1;
2437 }
2438
2439
2440
2441 isdesthttps = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2442
2443
2444 return 0;
2445}
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460int XrdHttpProtocol::xembeddedstatic(
XrdOucStream & Config) {
2461 char *val;
2462
2463
2464
2466 if (!val || !val[0]) {
2467 eDest.
Emsg(
"Config",
"embeddedstatic flag not specified");
2468 return 1;
2469 }
2470
2471
2472
2473 embeddedstatic = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2474
2475
2476 return 0;
2477}
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492int XrdHttpProtocol::xstaticredir(
XrdOucStream & Config) {
2493 char *val;
2494
2495
2496
2498 if (!val || !val[0]) {
2499 eDest.
Emsg(
"Config",
"staticredir url not specified");
2500 return 1;
2501 }
2502
2503
2504
2507
2508 return 0;
2509}
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527int XrdHttpProtocol::xstaticpreload(
XrdOucStream & Config) {
2528 char *val, *k, key[1024];
2529
2530
2531
2533 if (!k || !k[0]) {
2534 eDest.
Emsg(
"Config",
"preloadstatic urlpath not specified");
2535 return 1;
2536 }
2537
2538 strcpy(key, k);
2539
2540
2541
2543 if (!val || !val[0]) {
2544 eDest.
Emsg(
"Config",
"preloadstatic filename not specified");
2545 return 1;
2546 }
2547
2548
2549 int fp =
open(val, O_RDONLY);
2550 if( fp < 0 ) {
2551 eDest.
Emsg(
"Config", errno,
"open preloadstatic filename", val);
2552 return 1;
2553 }
2554
2555 StaticPreloadInfo *nfo = new StaticPreloadInfo;
2556
2557 nfo->data = (char *)malloc(65536);
2558 nfo->len =
read(fp, (
void *)nfo->data, 65536);
2560
2561 if (nfo->len <= 0) {
2562 eDest.
Emsg(
"Config", errno,
"read from preloadstatic filename", val);
2563 return 1;
2564 }
2565
2566 if (nfo->len >= 65536) {
2567 eDest.
Emsg(
"Config",
"Truncated preloadstatic filename. Max is 64 KB '", val,
"'");
2568 return 1;
2569 }
2570
2571
2572
2575
2577 return 0;
2578}
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597int XrdHttpProtocol::xstaticheader(
XrdOucStream & Config) {
2598 auto val =
Config.GetWord();
2599 std::vector<std::string> verbs;
2600 while (true) {
2601 if (!val || !val[0]) {
2602 eDest.
Emsg(
"Config",
"http.staticheader requires the header to be specified");
2603 return 1;
2604 }
2605
2606 std::string match_verb;
2607 std::string_view val_str(val);
2608 if (val_str.substr(0, 6) == "-verb=") {
2609 verbs.emplace_back(val_str.substr(6));
2610 } else if (val_str == "-") {
2611 eDest.
Emsg(
"Config",
"http.staticheader is ignoring unknown flag: ", val_str.data());
2612 } else {
2613 break;
2614 }
2615
2617 }
2618 if (verbs.empty()) {
2619 verbs.emplace_back();
2620 }
2621
2622 std::string header = val;
2623
2625 std::string header_value;
2626 if (val && val[0]) {
2627 header_value = val;
2628 }
2629
2630 for (const auto &verb : verbs) {
2634 } else if (header_value.empty()) {
2635 iter->second.clear();
2636 } else {
2637 iter->second.emplace_back(header, header_value);
2638 }
2639 }
2640
2641 return 0;
2642}
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658int XrdHttpProtocol::xselfhttps2http(
XrdOucStream & Config) {
2659 char *val;
2660
2661
2662
2664 if (!val || !val[0]) {
2665 eDest.
Emsg(
"Config",
"selfhttps2http flag not specified");
2666 return 1;
2667 }
2668
2669
2670
2671 selfhttps2http = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2672
2673
2674 return 0;
2675}
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693int XrdHttpProtocol::xsecxtractor(
XrdOucStream& Config) {
2694 char *val;
2695
2696
2697
2699 if (!val || !val[0]) {
2700 eDest.
Emsg(
"Config",
"No security extractor plugin specified.");
2701 return 1;
2702 } else {
2703
2704
2705 if (!strncmp(val, "required", 8)) {
2706 isRequiredXtractor = true;
2708
2709 if (!val || !val[0]) {
2710 eDest.
Emsg(
"Config",
"No security extractor plugin after [required] "
2711 "parameter");
2712 return 1;
2713 }
2714 }
2715
2716 char libName[4096];
2717 strlcpy(libName, val,
sizeof(libName));
2718 libName[sizeof(libName) - 1] = '\0';
2719 char libParms[4096];
2720
2721 if (!
Config.GetRest(libParms, 4095)) {
2722 eDest.
Emsg(
"Config",
"secxtractor config params longer than 4k");
2723 return 1;
2724 }
2725
2726
2727
2728 if (LoadSecXtractor(&
eDest, libName, libParms)) {
2729 return 1;
2730 }
2731 }
2732
2733 return 0;
2734}
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2754 std::vector<extHInfo> &hiVec) {
2755 char *val, path[1024], namebuf[1024];
2756 char *parm;
2757
2758 bool noTlsOK = false;
2759
2760
2761
2763 if (!val || !val[0]) {
2764 eDest.
Emsg(
"Config",
"No instance name specified for an http external handler plugin.");
2765 return 1;
2766 }
2767 if (strlen(val) >= 16) {
2768 eDest.
Emsg(
"Config",
"Instance name too long for an http external handler plugin.");
2769 return 1;
2770 }
2771 strncpy(namebuf, val, sizeof(namebuf));
2772 namebuf[ sizeof(namebuf)-1 ] = '\0';
2773
2774
2776
2777 if(val && !strcmp("+notls",val)) {
2778 noTlsOK = true;
2780 }
2781
2782
2783
2784 if (!val || !val[0]) {
2785 eDest.
Emsg(
"Config",
"No http external handler plugin specified.");
2786 return 1;
2787 }
2788 if (strlen(val) >= (int)sizeof(path)) {
2789 eDest.
Emsg(
"Config",
"Path too long for an http external handler plugin.");
2790 return 1;
2791 }
2792
2793 strcpy(path, val);
2794
2795
2796
2798
2799
2800
2801 for (int i = 0; i < (int)hiVec.size(); i++)
2802 {if (hiVec[i].extHName == namebuf) {
2803 eDest.
Emsg(
"Config",
"Instance name already present for "
2804 "http external handler plugin",
2805 hiVec[i].extHPath.c_str());
2806 return 1;
2807 }
2808 }
2809
2810
2811
2813 eDest.
Emsg(
"Config",
"Cannot load one more exthandler. Max is 4");
2814 return 1;
2815 }
2816
2817
2818
2819 hiVec.push_back(extHInfo(namebuf, path, (parm ? parm : ""), noTlsOK));
2820
2821 return 0;
2822}
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840int XrdHttpProtocol::xheader2cgi(
XrdOucStream & Config) {
2842}
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2858 char *val;
2859
2860
2861
2863 if (!val || !val[0]) {
2864 eDest.
Emsg(
"Config",
"HTTP X509 CAdir not specified");
2865 return 1;
2866 }
2867
2868
2869
2872
2874 return 0;
2875}
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891int XrdHttpProtocol::xsslcipherfilter(
XrdOucStream & Config) {
2892 char *val;
2893
2894
2895
2897 if (!val || !val[0]) {
2898 eDest.
Emsg(
"Config",
"SSL cipherlist filter string not specified");
2899 return 1;
2900 }
2901
2902
2903
2906
2907 return 0;
2908}
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2922
2923 char *val;
2924
2925
2926
2928 if (!val || !val[0])
2929 {
eDest.
Emsg(
"Config",
"tlsreuse argument not specified");
return 1;}
2930
2931
2932
2933 if (!strcmp(val, "off"))
2935 return 0;
2936 }
2937
2938
2939
2940 if (!strcmp(val, "on"))
2942 return 0;
2943 }
2944
2945
2946
2947 eDest.
Emsg(
"config",
"invalid tlsreuse parameter -", val);
2948 return 1;
2949}
2950
2952 char *val =
Config.GetWord();
2953 if(val) {
2954 if(!strcmp("tpc",val)) {
2955 if(!(val =
Config.GetWord())) {
2956 eDest.
Emsg(
"Config",
"http.auth tpc value not specified.");
return 1;
2957 } else {
2958 if(!strcmp("fcreds",val)) {
2960 } else {
2961 eDest.
Emsg(
"Config",
"http.auth tpc value is invalid");
return 1;
2962 }
2963 }
2964 } else {
2965 eDest.
Emsg(
"Config",
"http.auth value is invalid");
return 1;
2966 }
2967 }
2968 return 0;
2969}
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2986
2987 char *val;
2988
2989 static struct traceopts {
2990 const char *opname;
2991 int opval;
2992 } tropts[] = {
3000 };
3001 int i, neg, trval = 0, numopts = sizeof (tropts) / sizeof (struct traceopts);
3002
3003 if (!(val =
Config.GetWord())) {
3004 eDest.
Emsg(
"config",
"trace option not specified");
3005 return 1;
3006 }
3007 while (val) {
3008 if (!strcmp(val, "off")) trval = 0;
3009 else {
3010 if ((neg = (val[0] == '-' && val[1]))) val++;
3011 for (i = 0; i < numopts; i++) {
3012 if (!strcmp(val, tropts[i].opname)) {
3013 if (neg) trval &= ~tropts[i].opval;
3014 else trval |= tropts[i].opval;
3015 break;
3016 }
3017 }
3018 if (i >= numopts)
3019 eDest.
Emsg(
"config",
"invalid trace option", val);
3020 }
3022 }
3024 return 0;
3025}
3026
3028 int l;
3029 bool b;
3033
3038 l = strlen(fname) + 1;
3040
3043 if (!b) {
3044 return -1;
3045 }
3046
3047
3048 return 0;
3049}
3050
3051
3052
3053
3054
3056 size_t length;
3063 length = fname.
length() + 1;
3065
3067
3069}
3070
3071
3072static XrdVERSIONINFODEF(compiledVer, XrdHttpProtocolTest, XrdVNUMBER, XrdVERSION);
3073
3074
3075int XrdHttpProtocol::LoadSecXtractor(
XrdSysError *myeDest,
const char *libName,
3076 const char *libParms) {
3077
3078
3079
3080 if (secxtractor) return 1;
3081
3082 XrdOucPinLoader myLib(myeDest, &compiledVer,
"secxtractorlib", libName);
3084
3085
3086
3088 if (ep && (secxtractor = ep(myeDest, NULL, libParms))) return 0;
3089 myLib.Unload();
3090 return 1;
3091}
3092
3093
3094
3095
3096int XrdHttpProtocol::LoadExtHandlerNoTls(std::vector<extHInfo> &hiVec,
const char *cFN,
XrdOucEnv &myEnv) {
3097 for (int i = 0; i < (int) hiVec.size(); i++) {
3098 if(hiVec[i].extHNoTlsOK) {
3099
3100 if (LoadExtHandler(&
eDest, hiVec[i].extHPath.c_str(), cFN,
3101 hiVec[i].extHParm.c_str(), &myEnv,
3102 hiVec[i].extHName.c_str()))
3103 return 1;
3104 }
3105 }
3106 return 0;
3107}
3108
3109int XrdHttpProtocol::LoadExtHandler(std::vector<extHInfo> &hiVec,
3111
3112
3113
3118
3119
3120
3121 for (int i = 0; i < (int)hiVec.size(); i++) {
3122
3123
3124 if(!ExtHandlerLoaded(hiVec[i].extHName.c_str())) {
3125 if (LoadExtHandler(&
eDest, hiVec[i].extHPath.c_str(), cFN,
3126 hiVec[i].extHParm.c_str(), &myEnv,
3127 hiVec[i].extHName.c_str())) return 1;
3128 }
3129 }
3130 return 0;
3131}
3132
3133
3134int XrdHttpProtocol::LoadExtHandler(
XrdSysError *myeDest,
const char *libName,
3135 const char *configFN, const char *libParms,
3136 XrdOucEnv *myEnv,
const char *instName) {
3137
3138
3139
3140 if (ExtHandlerLoaded(instName)) {
3141 eDest.
Emsg(
"Config",
"Instance name already present for an http external handler plugin.");
3142 return 1;
3143 }
3145 eDest.
Emsg(
"Config",
"Cannot load one more exthandler. Max is 4");
3146 return 1;
3147 }
3148
3149 XrdOucPinLoader myLib(myeDest, &compiledVer,
"exthandlerlib", libName);
3151
3152
3153
3155
3157 if (ep && (newhandler = ep(myeDest, configFN, libParms, myEnv))) {
3158
3159
3160 strncpy( exthandler[exthandlercnt].name, instName, 16 );
3161 exthandler[exthandlercnt].name[15] = '\0';
3162 exthandler[exthandlercnt++].ptr = newhandler;
3163
3164 return 0;
3165 }
3166
3167 myLib.Unload();
3168 return 1;
3169}
3170
3171
3172
3173
3174
3175bool XrdHttpProtocol::ExtHandlerLoaded(const char *handlername) {
3176 for (int i = 0; i < exthandlercnt; i++) {
3177 if ( !strncmp(exthandler[i].name, handlername, 15) ) {
3178 return true;
3179 }
3180 }
3181 return false;
3182}
3183
3184
3185
3187
3188 for (int i = 0; i < exthandlercnt; i++) {
3190 return exthandler[i].ptr;
3191 }
3192 }
3193 return NULL;
3194}
struct ClientQueryRequest query
struct ClientStatRequest stat
#define XrdHttpExtHandlerArgs
static int BIO_XrdLink_create(BIO *bio)
const char * XrdHttpSecEntityTident
int BIO_XrdLink_write(BIO *bio, const char *data, size_t datal, size_t *written)
#define HTTPS_ALERT(x, y, z)
static long BIO_XrdLink_ctrl(BIO *bio, int cmd, long num, void *ptr)
XrdSysTrace XrdHttpTrace("http")
static int BIO_XrdLink_read(BIO *bio, char *data, size_t datal, size_t *read)
static int BIO_XrdLink_destroy(BIO *bio)
static XrdVERSIONINFODEF(compiledVer, XrdHttpProtocolTest, XrdVNUMBER, XrdVERSION)
#define MAX_XRDHTTPEXTHANDLERS
#define XrdHttpSecXtractorArgs
#define TLS_SET_VDEPTH(cOpts, vdv)
#define TLS_SET_REFINT(cOpts, refi)
void Release(XrdBuffer *bp)
static char * secretkey
The key used to calculate the url hashes.
static char * gridmap
Gridmap file location. The same used by XrdSecGsi.
static XrdScheduler * Sched
static kXR_int32 myRole
Our role.
static char * Port_str
Our port, as a string.
XrdXrootd::Bridge * Bridge
The Bridge that we use to exercise the xrootd internals.
static char * staticredir
static bool selfhttps2http
If client is HTTPS, self-redirect with HTTP+token.
int doChksum(const XrdOucString &fname)
Perform a checksum request.
static XrdOucHash< StaticPreloadInfo > * staticpreload
static char * xrd_cslist
The list of checksums that were configured via the xrd.cksum parameter on the server config file.
static char * sslcipherfilter
static std::map< std::string, std::string > hdr2cgimap
Rules that turn HTTP headers to cgi tokens in the URL, for internal comsumption.
static char * sslcert
OpenSSL stuff.
XrdLink * Link
The link we are bound to.
int doStat(char *fname)
Perform a Stat request.
static int readWait
Timeout for reading data.
static std::unordered_map< std::string, std::vector< std::pair< std::string, std::string > > > m_staticheader_map
The static headers to always return; map is from verb to a list of (header, val) pairs.
static bool compatNameGeneration
static bool isdesthttps
True if the redirections must be towards https targets.
static XrdObjectQ< XrdHttpProtocol > ProtStack
static bool isRequiredGridmap
static char * listredir
Url to redirect to in the case a listing is requested.
static int crlRefIntervalSec
CRL thread refresh interval.
static XrdBuffManager * BPool
static std::unordered_map< std::string, std::string > m_staticheaders
static bool tpcForwardCreds
If set to true, the HTTP TPC transfers will forward the credentials to redirected hosts.
static bool listdeny
If true, any form of listing is denied.
static int parseHeader2CGI(XrdOucStream &Config, XrdSysError &err, std::map< std::string, std::string > &header2cgi)
Use this function to parse header2cgi configurations.
XrdSecEntity SecEntity
Authentication area.
static bool embeddedstatic
If true, use the embedded css and icons.
static int sslverifydepth
Depth of verification of a certificate chain.
static int Configure(char *parms, XrdProtocol_Config *pi)
Read and apply the configuration.
static int Configure(XrdSysError &Eroute, const char *const parms, Configuration &cfg)
int reqstate
State machine to talk to the bridge.
XrdOucString resource
The resource specified by the request, stripped of opaque data.
ClientRequest xrdreq
The last issued xrd request, often pending.
virtual int FreeSSL(SSL *)
int setEtext(const char *text)
int Recv(char *buff, int blen)
int Send(const char *buff, int blen)
void Set(int inQMax, time_t agemax=1800)
static bool Import(const char *var, char *&val)
void Put(const char *varname, const char *value)
T * Rep(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
void insert(const int i, int start=-1)
void assign(const char *s, int j, int k=-1)
const char * c_str() const
char * vorg
Entity's virtual organization(s)
const char * tident
Trace identifier always preset.
char * caps
Entity's capabilities.
char * grps
Entity's group name(s)
void Reset(const char *spV=0)
char * name
Entity's name.
char * role
Entity's role(s)
char * endorsements
Protocol specific endorsements.
char * moninfo
Information for monitoring.
char * host
Entity's host name dnr dependent.
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
XrdSysLogger * logger(XrdSysLogger *lp=0)
void SetLogger(XrdSysLogger *logp)
int SessionCache(int opts=scNone, const char *id=0, int idlen=0)
static const int DEFAULT_CRL_REF_INT_SEC
Default CRL refresh interval in seconds.
static const uint64_t servr
This is a server context.
static const uint64_t rfCRL
Turn on the CRL refresh thread.
static const uint64_t logVF
Log verify failures.
static const uint64_t artON
Auto retry Handshake.
const CTX_Params * GetParams()
static const int scOff
Turn off cache.
bool SetContextCiphers(const char *ciphers)
static const int scSrvr
Turn on cache server mode (default)
virtual bool Run(const char *xreqP, char *xdataP=0, int xdataL=0)=0
std::string cafile
-> ca cert file.
std::string cadir
-> ca cert directory.
int crlRT
crl refresh interval time in seconds
std::string pkey
-> private key path.
std::string cert
-> certificate path.