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 == 201) ss << "Created";
1603 else if (code == 206) ss << "Partial Content";
1604 else if (code == 302) ss << "Redirect";
1605 else if (code == 307) ss << "Temporary Redirect";
1606 else if (code == 400) ss << "Bad Request";
1607 else if (code == 401) ss << "Unauthorized";
1608 else if (code == 403) ss << "Forbidden";
1609 else if (code == 404) ss << "Not Found";
1610 else if (code == 405) ss << "Method Not Allowed";
1611 else if (code == 409) ss << "Conflict";
1612 else if (code == 416) ss << "Range Not Satisfiable";
1613 else if (code == 423) ss << "Locked";
1614 else if (code == 500) ss << "Internal Server Error";
1615 else if (code == 502) ss << "Bad Gateway";
1616 else if (code == 504) ss << "Gateway Timeout";
1617 else ss << "Unknown";
1618 }
1619 ss << crlf;
1620 if (keepalive && (code != 100))
1621 ss << "Connection: Keep-Alive" << crlf;
1622 else
1623 ss << "Connection: Close" << crlf;
1624
1625 ss << "Server: XrootD/" << XrdVSTRING << crlf;
1626
1629 ss << iter->second;
1630 } else {
1632 }
1633
1634 if ((bodylen >= 0) && (code != 100))
1635 ss << "Content-Length: " << bodylen << crlf;
1636
1637 if (header_to_add && (header_to_add[0] != '\0'))
1638 ss << header_to_add << crlf;
1639
1640 ss << crlf;
1641
1642 const std::string &outhdr = ss.str();
1643 TRACEI(RSP,
"Sending resp: " << code <<
" header len:" << outhdr.size());
1644 if (SendData(outhdr.c_str(), outhdr.size()))
1645 return -1;
1646
1647 return 0;
1648}
1649
1650
1651
1652
1653
1654int XrdHttpProtocol::StartChunkedResp(int code, const char *desc, const char *header_to_add, long long bodylen, bool keepalive) {
1655 const std::string crlf = "\r\n";
1656 std::stringstream ss;
1657
1658 if (header_to_add && (header_to_add[0] != '\0')) {
1659 ss << header_to_add << crlf;
1660 }
1661
1662 ss << "Transfer-Encoding: chunked";
1663 TRACEI(RSP,
"Starting chunked response");
1664 return StartSimpleResp(code, desc, ss.str().c_str(), bodylen, keepalive);
1665}
1666
1667
1668
1669
1670
1671int XrdHttpProtocol::ChunkResp(const char *body, long long bodylen) {
1672 long long content_length = (bodylen <= 0) ? (body ? strlen(body) : 0) : bodylen;
1673 if (ChunkRespHeader(content_length))
1674 return -1;
1675
1676 if (body && SendData(body, content_length))
1677 return -1;
1678
1679 return ChunkRespFooter();
1680}
1681
1682
1683
1684
1685
1686int XrdHttpProtocol::ChunkRespHeader(long long bodylen) {
1687 const std::string crlf = "\r\n";
1688 std::stringstream ss;
1689
1690 ss << std::hex << bodylen << std::dec << crlf;
1691
1692 const std::string &chunkhdr = ss.str();
1693 TRACEI(RSP,
"Sending encoded chunk of size " << bodylen);
1694 return (SendData(chunkhdr.c_str(), chunkhdr.size())) ? -1 : 0;
1695}
1696
1697
1698
1699
1700
1701int XrdHttpProtocol::ChunkRespFooter() {
1702 const std::string crlf = "\r\n";
1703 return (SendData(crlf.c_str(), crlf.size())) ? -1 : 0;
1704}
1705
1706
1707
1708
1709
1713
1714int XrdHttpProtocol::SendSimpleResp(int code, const char *desc, const char *header_to_add, const char *body, long long bodylen, bool keepalive) {
1715
1716 long long content_length = bodylen;
1717 if (bodylen <= 0) {
1718 content_length = body ? strlen(body) : 0;
1719 }
1720
1721 if (StartSimpleResp(code, desc, header_to_add, content_length, keepalive) < 0)
1722 return -1;
1723
1724
1725
1726
1727 if (body)
1728 return SendData(body, content_length);
1729
1730 return 0;
1731}
1732
1733
1734
1735
1736
1738
1739
1740
1741
1742
1743
1744
1745
1746 char *rdf;
1747
1748
1749
1752
1756
1758
1759
1760
1762
1763 {
1764 char buf[16];
1765 sprintf(buf,
"%d",
Port);
1767 }
1768
1769
1770
1771 rdf = (parms && *parms ? parms : pi->
ConfigFN);
1772 if (rdf && Config(rdf, pi->
theEnv))
return 0;
1774
1775
1777 if ((rdf = getenv("XRDROLE"))) {
1779
1780 if (!strcasecmp(rdf, "manager") || !strcasecmp(rdf, "supervisor")) {
1782 eDest.
Emsg(
"Config",
"Configured as HTTP(s) redirector.");
1783 } else {
1784
1785 eDest.
Emsg(
"Config",
"Configured as HTTP(s) data server.");
1786 }
1787
1788 } else {
1789 eDest.
Emsg(
"Config",
"No XRDROLE specified.");
1790 }
1791
1792
1793
1797
1798
1799
1800
1801 return 1;
1802}
1803
1804
1805
1806
1808 char *val, keybuf[1024], parmbuf[1024];
1809 char *parm;
1810
1811
1813 if (!val || !val[0]) {
1814 err.
Emsg(
"Config",
"No headerkey specified.");
1815 return 1;
1816 } else {
1817
1818
1819 while ( *val && !isalnum(*val) ) val++;
1820 strcpy(keybuf, val);
1821
1822
1823 char *pp;
1824 pp = keybuf + strlen(keybuf) - 1;
1825 while ( (pp >= keybuf) && (!isalnum(*pp)) ) {
1826 *pp = '\0';
1827 pp--;
1828 }
1829
1831
1832
1833 if(!parm || !parm[0]) {
1834 err.
Emsg(
"Config",
"No header2cgi value specified. key: '", keybuf,
"'");
1835 return 1;
1836 }
1837
1838
1839 while ( *parm && !isalnum(*parm) ) parm++;
1840 strcpy(parmbuf, parm);
1841
1842
1843 pp = parmbuf + strlen(parmbuf) - 1;
1844 while ( (pp >= parmbuf) && (!isalnum(*pp)) ) {
1845 *pp = '\0';
1846 pp--;
1847 }
1848
1849
1850 try {
1851 header2cgi[keybuf] = parmbuf;
1852 } catch ( ... ) {
1853 err.
Emsg(
"Config",
"Can't insert new header2cgi rule. key: '", keybuf,
"'");
1854 return 1;
1855 }
1856
1857 }
1858 return 0;
1859}
1860
1861
1862
1863
1864
1865
1866bool XrdHttpProtocol::InitTLS() {
1867
1871
1872
1873
1876
1879
1880
1881
1884 return false;
1885 }
1886
1887
1888
1889
1890
1891 static const char *sess_ctx_id = "XrdHTTPSessionCtx";
1892 unsigned int n =(unsigned int)(strlen(sess_ctx_id)+1);
1894
1895
1896
1898 {
eDest.
Say(
"Config failure: ",
"Unable to set allowable https ciphers!");
1899 return false;
1900 }
1901
1902
1903
1904 return true;
1905}
1906
1907
1908
1909
1910
1911void XrdHttpProtocol::Cleanup() {
1912
1913 TRACE(ALL,
" Cleanup");
1914
1915 if (
BPool && myBuff) {
1916 BuffConsume(BuffUsed());
1918 myBuff = 0;
1919 }
1920
1921 if (ssl) {
1922
1923
1924
1925
1926
1927
1928
1929
1930 int ret = SSL_shutdown(ssl);
1931 if (ret != 1) {
1932 if(ret == 0) {
1933
1934 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1935 ERR_remove_thread_state(nullptr);
1936 #endif
1937 } else {
1938
1939 TRACE(ALL,
" SSL_shutdown failed");
1940 ERR_print_errors(sslbio_err);
1941 }
1942 }
1943
1944 if (secxtractor)
1946
1947 SSL_free(ssl);
1948
1949 }
1950
1951
1952 ssl = 0;
1953 sbio = 0;
1954
1963
1965
1968}
1969
1970
1971
1972
1973
1974void XrdHttpProtocol::Reset() {
1975
1976 TRACE(ALL,
" Reset");
1980
1981 if (myBuff) {
1983 myBuff = 0;
1984 }
1985 myBuffStart = myBuffEnd = 0;
1986
1987 DoingLogin = false;
1988 DoneSetInfo = false;
1989
1990 ResumeBytes = 0;
1991 Resume = 0;
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2008 ishttps = false;
2009 ssldone = false;
2010
2012 ssl = 0;
2013 sbio = 0;
2014
2015}
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032int XrdHttpProtocol::xhttpsmode(
XrdOucStream & Config) {
2033 char *val;
2034
2035
2036
2038 if (!val || !val[0]) {
2039 eDest.
Emsg(
"Config",
"httpsmode parameter not specified");
2040 return 1;
2041 }
2042
2043
2044
2048 else {
eDest.
Emsg(
"Config",
"invalid httpsmode parameter - ", val);
2049 return 1;
2050 }
2051 return 0;
2052}
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067int XrdHttpProtocol::xsslverifydepth(
XrdOucStream & Config) {
2068 char *val;
2069
2070
2071
2073 if (!val || !val[0]) {
2074 eDest.
Emsg(
"Config",
"sslverifydepth value not specified");
2075 return 1;
2076 }
2077
2078
2079
2081
2083 return 0;
2084}
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2100 char *val;
2101
2102
2103
2105 if (!val || !val[0]) {
2106 eDest.
Emsg(
"Config",
"HTTP X509 certificate not specified");
2107 return 1;
2108 }
2109
2110
2111
2114
2115
2116
2118 return 0;
2119}
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2135 char *val;
2136
2137
2138
2140 if (!val || !val[0]) {
2141 eDest.
Emsg(
"Config",
"HTTP X509 key not specified");
2142 return 1;
2143 }
2144
2145
2146
2149
2151 return 0;
2152}
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2172 char *val;
2173
2174
2175
2177 if (!val || !val[0]) {
2178 eDest.
Emsg(
"Config",
"HTTP X509 gridmap file location not specified");
2179 return 1;
2180 }
2181
2182
2183
2184 if (!strncmp(val, "required", 8)) {
2187
2188 if (!val || !val[0]) {
2189 eDest.
Emsg(
"Config",
"HTTP X509 gridmap file missing after [required] "
2190 "parameter");
2191 return 1;
2192 }
2193 }
2194
2195
2196
2197 if (!strcmp(val, "compatNameGeneration")) {
2200 if (!val || !val[0]) {
2201 eDest.
Emsg(
"Config",
"HTTP X509 gridmap file missing after "
2202 "[compatNameGeneration] parameter");
2203 return 1;
2204 }
2205 }
2206
2207
2208
2209
2212 return 0;
2213}
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228int XrdHttpProtocol::xsslcafile(
XrdOucStream & Config) {
2229 char *val;
2230
2231
2232
2234 if (!val || !val[0]) {
2235 eDest.
Emsg(
"Config",
"HTTP X509 CAfile not specified");
2236 return 1;
2237 }
2238
2239
2240
2243
2245 return 0;
2246}
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261int XrdHttpProtocol::xsecretkey(
XrdOucStream & Config) {
2262 char *val;
2263 bool inFile = false;
2264
2265
2266
2268 if (!val || !val[0]) {
2269 eDest.
Emsg(
"Config",
"Shared secret key not specified");
2270 return 1;
2271 }
2272
2273
2274
2275
2276
2277 if (val[0] == '/') {
2279 inFile = true;
2280 int fd =
open(val, O_RDONLY);
2281
2282 if ( fd == -1 ) {
2283 eDest.
Emsg(
"Config", errno,
"open shared secret key file", val);
2284 return 1;
2285 }
2286
2287 if (
fstat(fd, &st) != 0 ) {
2288 eDest.
Emsg(
"Config", errno,
"fstat shared secret key file", val);
2290 return 1;
2291 }
2292
2293 if ( st.st_mode & S_IWOTH & S_IWGRP & S_IROTH) {
2295 "For your own security, the shared secret key file cannot be world readable or group writable '", val, "'");
2297 return 1;
2298 }
2299
2300 FILE *fp = fdopen(fd, "r");
2301
2302 if ( fp == nullptr ) {
2303 eDest.
Emsg(
"Config", errno,
"fdopen shared secret key file", val);
2305 return 1;
2306 }
2307
2308 char line[1024];
2309 while( fgets(line, 1024, fp) ) {
2310 char *pp;
2311
2312
2313 pp = line + strlen(line) - 1;
2314 while ( (pp >= line) && (!isalnum(*pp)) ) {
2315 *pp = '\0';
2316 pp--;
2317 }
2318
2319
2320 pp = line;
2321 while ( *pp && !isalnum(*pp) ) pp++;
2322
2323 if ( strlen(pp) >= 32 ) {
2324 eDest.
Say(
"Config",
"Secret key loaded.");
2325
2328
2330 return 0;
2331 }
2332
2333 }
2334
2336 eDest.
Emsg(
"Config",
"Cannot find useful secretkey in file '", val,
"'");
2337 return 1;
2338
2339 }
2340
2341 if ( strlen(val) < 32 ) {
2342 eDest.
Emsg(
"Config",
"Secret key is too short");
2343 return 1;
2344 }
2345
2346
2349 if (!inFile)
Config.noEcho();
2350
2351 return 0;
2352}
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2368 char *val;
2369
2370
2371
2373 if (!val || !val[0]) {
2374 eDest.
Emsg(
"Config",
"listingdeny flag not specified");
2375 return 1;
2376 }
2377
2378
2379
2380 listdeny = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2381
2382
2383 return 0;
2384}
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399int XrdHttpProtocol::xlistredir(
XrdOucStream & Config) {
2400 char *val;
2401
2402
2403
2405 if (!val || !val[0]) {
2406 eDest.
Emsg(
"Config",
"listingredir flag not specified");
2407 return 1;
2408 }
2409
2410
2411
2414
2415
2416 return 0;
2417}
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432int XrdHttpProtocol::xdesthttps(
XrdOucStream & Config) {
2433 char *val;
2434
2435
2436
2438 if (!val || !val[0]) {
2439 eDest.
Emsg(
"Config",
"desthttps flag not specified");
2440 return 1;
2441 }
2442
2443
2444
2445 isdesthttps = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2446
2447
2448 return 0;
2449}
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464int XrdHttpProtocol::xembeddedstatic(
XrdOucStream & Config) {
2465 char *val;
2466
2467
2468
2470 if (!val || !val[0]) {
2471 eDest.
Emsg(
"Config",
"embeddedstatic flag not specified");
2472 return 1;
2473 }
2474
2475
2476
2477 embeddedstatic = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2478
2479
2480 return 0;
2481}
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496int XrdHttpProtocol::xstaticredir(
XrdOucStream & Config) {
2497 char *val;
2498
2499
2500
2502 if (!val || !val[0]) {
2503 eDest.
Emsg(
"Config",
"staticredir url not specified");
2504 return 1;
2505 }
2506
2507
2508
2511
2512 return 0;
2513}
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531int XrdHttpProtocol::xstaticpreload(
XrdOucStream & Config) {
2532 char *val, *k, key[1024];
2533
2534
2535
2537 if (!k || !k[0]) {
2538 eDest.
Emsg(
"Config",
"preloadstatic urlpath not specified");
2539 return 1;
2540 }
2541
2542 strcpy(key, k);
2543
2544
2545
2547 if (!val || !val[0]) {
2548 eDest.
Emsg(
"Config",
"preloadstatic filename not specified");
2549 return 1;
2550 }
2551
2552
2553 int fp =
open(val, O_RDONLY);
2554 if( fp < 0 ) {
2555 eDest.
Emsg(
"Config", errno,
"open preloadstatic filename", val);
2556 return 1;
2557 }
2558
2559 StaticPreloadInfo *nfo = new StaticPreloadInfo;
2560
2561 nfo->data = (char *)malloc(65536);
2562 nfo->len =
read(fp, (
void *)nfo->data, 65536);
2564
2565 if (nfo->len <= 0) {
2566 eDest.
Emsg(
"Config", errno,
"read from preloadstatic filename", val);
2567 return 1;
2568 }
2569
2570 if (nfo->len >= 65536) {
2571 eDest.
Emsg(
"Config",
"Truncated preloadstatic filename. Max is 64 KB '", val,
"'");
2572 return 1;
2573 }
2574
2575
2576
2579
2581 return 0;
2582}
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601int XrdHttpProtocol::xstaticheader(
XrdOucStream & Config) {
2602 auto val =
Config.GetWord();
2603 std::vector<std::string> verbs;
2604 while (true) {
2605 if (!val || !val[0]) {
2606 eDest.
Emsg(
"Config",
"http.staticheader requires the header to be specified");
2607 return 1;
2608 }
2609
2610 std::string match_verb;
2611 std::string_view val_str(val);
2612 if (val_str.substr(0, 6) == "-verb=") {
2613 verbs.emplace_back(val_str.substr(6));
2614 } else if (val_str == "-") {
2615 eDest.
Emsg(
"Config",
"http.staticheader is ignoring unknown flag: ", val_str.data());
2616 } else {
2617 break;
2618 }
2619
2621 }
2622 if (verbs.empty()) {
2623 verbs.emplace_back();
2624 }
2625
2626 std::string header = val;
2627
2629 std::string header_value;
2630 if (val && val[0]) {
2631 header_value = val;
2632 }
2633
2634 for (const auto &verb : verbs) {
2637 if (!header_value.empty())
2639 } else if (header_value.empty()) {
2640 iter->second.clear();
2641 } else {
2642 iter->second.emplace_back(header, header_value);
2643 }
2644 }
2645
2646 return 0;
2647}
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663int XrdHttpProtocol::xselfhttps2http(
XrdOucStream & Config) {
2664 char *val;
2665
2666
2667
2669 if (!val || !val[0]) {
2670 eDest.
Emsg(
"Config",
"selfhttps2http flag not specified");
2671 return 1;
2672 }
2673
2674
2675
2676 selfhttps2http = (!strcasecmp(val,
"true") || !strcasecmp(val,
"yes") || !strcmp(val,
"1"));
2677
2678
2679 return 0;
2680}
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698int XrdHttpProtocol::xsecxtractor(
XrdOucStream& Config) {
2699 char *val;
2700
2701
2702
2704 if (!val || !val[0]) {
2705 eDest.
Emsg(
"Config",
"No security extractor plugin specified.");
2706 return 1;
2707 } else {
2708
2709
2710 if (!strncmp(val, "required", 8)) {
2711 isRequiredXtractor = true;
2713
2714 if (!val || !val[0]) {
2715 eDest.
Emsg(
"Config",
"No security extractor plugin after [required] "
2716 "parameter");
2717 return 1;
2718 }
2719 }
2720
2721 char libName[4096];
2722 strlcpy(libName, val,
sizeof(libName));
2723 libName[sizeof(libName) - 1] = '\0';
2724 char libParms[4096];
2725
2726 if (!
Config.GetRest(libParms, 4095)) {
2727 eDest.
Emsg(
"Config",
"secxtractor config params longer than 4k");
2728 return 1;
2729 }
2730
2731
2732
2733 if (LoadSecXtractor(&
eDest, libName, libParms)) {
2734 return 1;
2735 }
2736 }
2737
2738 return 0;
2739}
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2759 std::vector<extHInfo> &hiVec) {
2760 char *val, path[1024], namebuf[1024];
2761 char *parm;
2762
2763 bool noTlsOK = false;
2764
2765
2766
2768 if (!val || !val[0]) {
2769 eDest.
Emsg(
"Config",
"No instance name specified for an http external handler plugin.");
2770 return 1;
2771 }
2772 if (strlen(val) >= 16) {
2773 eDest.
Emsg(
"Config",
"Instance name too long for an http external handler plugin.");
2774 return 1;
2775 }
2776 strncpy(namebuf, val, sizeof(namebuf));
2777 namebuf[ sizeof(namebuf)-1 ] = '\0';
2778
2779
2781
2782 if(val && !strcmp("+notls",val)) {
2783 noTlsOK = true;
2785 }
2786
2787
2788
2789 if (!val || !val[0]) {
2790 eDest.
Emsg(
"Config",
"No http external handler plugin specified.");
2791 return 1;
2792 }
2793 if (strlen(val) >= (int)sizeof(path)) {
2794 eDest.
Emsg(
"Config",
"Path too long for an http external handler plugin.");
2795 return 1;
2796 }
2797
2798 strcpy(path, val);
2799
2800
2801
2803
2804
2805
2806 for (int i = 0; i < (int)hiVec.size(); i++)
2807 {if (hiVec[i].extHName == namebuf) {
2808 eDest.
Emsg(
"Config",
"Instance name already present for "
2809 "http external handler plugin",
2810 hiVec[i].extHPath.c_str());
2811 return 1;
2812 }
2813 }
2814
2815
2816
2818 eDest.
Emsg(
"Config",
"Cannot load one more exthandler. Max is 4");
2819 return 1;
2820 }
2821
2822
2823
2824 hiVec.push_back(extHInfo(namebuf, path, (parm ? parm : ""), noTlsOK));
2825
2826 return 0;
2827}
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845int XrdHttpProtocol::xheader2cgi(
XrdOucStream & Config) {
2847}
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2863 char *val;
2864
2865
2866
2868 if (!val || !val[0]) {
2869 eDest.
Emsg(
"Config",
"HTTP X509 CAdir not specified");
2870 return 1;
2871 }
2872
2873
2874
2877
2879 return 0;
2880}
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896int XrdHttpProtocol::xsslcipherfilter(
XrdOucStream & Config) {
2897 char *val;
2898
2899
2900
2902 if (!val || !val[0]) {
2903 eDest.
Emsg(
"Config",
"SSL cipherlist filter string not specified");
2904 return 1;
2905 }
2906
2907
2908
2911
2912 return 0;
2913}
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2927
2928 char *val;
2929
2930
2931
2933 if (!val || !val[0])
2934 {
eDest.
Emsg(
"Config",
"tlsreuse argument not specified");
return 1;}
2935
2936
2937
2938 if (!strcmp(val, "off"))
2940 return 0;
2941 }
2942
2943
2944
2945 if (!strcmp(val, "on"))
2947 return 0;
2948 }
2949
2950
2951
2952 eDest.
Emsg(
"config",
"invalid tlsreuse parameter -", val);
2953 return 1;
2954}
2955
2957 char *val =
Config.GetWord();
2958 if(val) {
2959 if(!strcmp("tpc",val)) {
2960 if(!(val =
Config.GetWord())) {
2961 eDest.
Emsg(
"Config",
"http.auth tpc value not specified.");
return 1;
2962 } else {
2963 if(!strcmp("fcreds",val)) {
2965 } else {
2966 eDest.
Emsg(
"Config",
"http.auth tpc value is invalid");
return 1;
2967 }
2968 }
2969 } else {
2970 eDest.
Emsg(
"Config",
"http.auth value is invalid");
return 1;
2971 }
2972 }
2973 return 0;
2974}
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2991
2992 char *val;
2993
2994 static struct traceopts {
2995 const char *opname;
2996 int opval;
2997 } tropts[] = {
3005 };
3006 int i, neg, trval = 0, numopts = sizeof (tropts) / sizeof (struct traceopts);
3007
3008 if (!(val =
Config.GetWord())) {
3009 eDest.
Emsg(
"config",
"trace option not specified");
3010 return 1;
3011 }
3012 while (val) {
3013 if (!strcmp(val, "off")) trval = 0;
3014 else {
3015 if ((neg = (val[0] == '-' && val[1]))) val++;
3016 for (i = 0; i < numopts; i++) {
3017 if (!strcmp(val, tropts[i].opname)) {
3018 if (neg) trval &= ~tropts[i].opval;
3019 else trval |= tropts[i].opval;
3020 break;
3021 }
3022 }
3023 if (i >= numopts)
3024 eDest.
Emsg(
"config",
"invalid trace option", val);
3025 }
3027 }
3029 return 0;
3030}
3031
3033 int l;
3034 bool b;
3038
3043 l = strlen(fname) + 1;
3045
3048 if (!b) {
3049 return -1;
3050 }
3051
3052
3053 return 0;
3054}
3055
3056
3057
3058
3059
3061 size_t length;
3068 length = fname.
length() + 1;
3070
3072
3074}
3075
3076
3077static XrdVERSIONINFODEF(compiledVer, XrdHttpProtocolTest, XrdVNUMBER, XrdVERSION);
3078
3079
3080int XrdHttpProtocol::LoadSecXtractor(
XrdSysError *myeDest,
const char *libName,
3081 const char *libParms) {
3082
3083
3084
3085 if (secxtractor) return 1;
3086
3087 XrdOucPinLoader myLib(myeDest, &compiledVer,
"secxtractorlib", libName);
3089
3090
3091
3093 if (ep && (secxtractor = ep(myeDest, NULL, libParms))) return 0;
3094 myLib.Unload();
3095 return 1;
3096}
3097
3098
3099
3100
3101int XrdHttpProtocol::LoadExtHandlerNoTls(std::vector<extHInfo> &hiVec,
const char *cFN,
XrdOucEnv &myEnv) {
3102 for (int i = 0; i < (int) hiVec.size(); i++) {
3103 if(hiVec[i].extHNoTlsOK) {
3104
3105 if (LoadExtHandler(&
eDest, hiVec[i].extHPath.c_str(), cFN,
3106 hiVec[i].extHParm.c_str(), &myEnv,
3107 hiVec[i].extHName.c_str()))
3108 return 1;
3109 }
3110 }
3111 return 0;
3112}
3113
3114int XrdHttpProtocol::LoadExtHandler(std::vector<extHInfo> &hiVec,
3116
3117
3118
3123
3124
3125
3126 for (int i = 0; i < (int)hiVec.size(); i++) {
3127
3128
3129 if(!ExtHandlerLoaded(hiVec[i].extHName.c_str())) {
3130 if (LoadExtHandler(&
eDest, hiVec[i].extHPath.c_str(), cFN,
3131 hiVec[i].extHParm.c_str(), &myEnv,
3132 hiVec[i].extHName.c_str())) return 1;
3133 }
3134 }
3135 return 0;
3136}
3137
3138
3139int XrdHttpProtocol::LoadExtHandler(
XrdSysError *myeDest,
const char *libName,
3140 const char *configFN, const char *libParms,
3141 XrdOucEnv *myEnv,
const char *instName) {
3142
3143
3144
3145 if (ExtHandlerLoaded(instName)) {
3146 eDest.
Emsg(
"Config",
"Instance name already present for an http external handler plugin.");
3147 return 1;
3148 }
3150 eDest.
Emsg(
"Config",
"Cannot load one more exthandler. Max is 4");
3151 return 1;
3152 }
3153
3154 XrdOucPinLoader myLib(myeDest, &compiledVer,
"exthandlerlib", libName);
3156
3157
3158
3160
3162 if (ep && (newhandler = ep(myeDest, configFN, libParms, myEnv))) {
3163
3164
3165 strncpy( exthandler[exthandlercnt].name, instName, 16 );
3166 exthandler[exthandlercnt].name[15] = '\0';
3167 exthandler[exthandlercnt++].ptr = newhandler;
3168
3169 return 0;
3170 }
3171
3172 myLib.Unload();
3173 return 1;
3174}
3175
3176
3177
3178
3179
3180bool XrdHttpProtocol::ExtHandlerLoaded(const char *handlername) {
3181 for (int i = 0; i < exthandlercnt; i++) {
3182 if ( !strncmp(exthandler[i].name, handlername, 15) ) {
3183 return true;
3184 }
3185 }
3186 return false;
3187}
3188
3189
3190
3192
3193 for (int i = 0; i < exthandlercnt; i++) {
3195 return exthandler[i].ptr;
3196 }
3197 }
3198 return NULL;
3199}
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.