[0001]
[0002]
[0003]
[0004]
[0005]
[0006]
[0007]
[0008]
[0009]
[0010]
[0011]
[0012]
[0013]
[0014]
[0015]
[0016]
[0017]
[0018]
[0019]
[0020]
[0021]
[0022]
[0023]
[0024]
[0025]
[0026]
[0027]
[0028]
[0029]
[0030]
[0031]
[0032]
[0033]
[0034]
[0035]
[0036]
[0037]
[0038]
[0039]
[0040]
[0041]
[0042]
[0043]
[0044]
[0045]
[0046]
[0047]
[0048]
[0049]
[0050]
[0051]
[0052]
[0053]
[0054]
[0055]
[0056]
[0057]
[0058]
[0059]
[0060]
[0061]
[0062]
[0063]
[0064]
[0065]
[0066]
[0067]
[0068]
[0069]
[0070]
[0071]
[0072]
[0073]
[0074]
[0075]
[0076]
[0077]
[0078]
[0079]
[0080]
[0081]
[0082]
[0083]
[0084]
[0085]
[0086]
[0087]
[0088]
[0089]
[0090]
[0091]
[0092]
[0093]
[0094]
[0095]
[0096]
[0097]
[0098]
[0099]
[0100]
[0101]
[0102]
[0103]
[0104]
[0105]
[0106]
[0107]
[0108]
[0109]
[0110]
[0111]
[0112]
[0113]
[0114]
[0115]
[0116]
[0117]
[0118]
[0119]
[0120]
[0121]
[0122]
[0123]
[0124]
[0125]
[0126]
[0127]
[0128]
[0129]
[0130]
[0131]
[0132]
[0133]
[0134]
[0135]
[0136]
[0137]
[0138]
[0139]
[0140]
[0141]
[0142]
[0143]
[0144]
[0145]
[0146]
[0147]
[0148]
[0149]
[0150]
[0151]
[0152]
[0153]
[0154]
[0155]
[0156]
[0157]
[0158]
[0159]
[0160]
[0161]
[0162]
[0163]
[0164]
[0165]
[0166]
[0167]
[0168]
[0169]
[0170]
[0171]
[0172]
[0173]
[0174]
[0175]
[0176]
[0177]
[0178]
[0179]
[0180]
[0181]
[0182]
[0183]
[0184]
[0185]
[0186]
[0187]
[0188]
[0189]
[0190]
[0191]
[0192]
[0193]
[0194]
[0195]
[0196]
[0197]
[0198]
[0199]
[0200]
[0201]
[0202]
[0203]
[0204]
[0205]
[0206]
[0207]
[0208]
[0209]
[0210]
[0211]
[0212]
[0213]
[0214]
[0215]
[0216]
[0217]
[0218]
[0219]
[0220]
[0221]
[0222]
[0223]
[0224]
[0225]
[0226]
[0227]
[0228]
[0229]
[0230]
[0231]
[0232]
[0233]
[0234]
[0235]
[0236]
[0237]
[0238]
[0239]
[0240]
[0241]
[0242]
[0243]
[0244]
[0245]
[0246]
[0247]
[0248]
[0249]
[0250]
[0251]
[0252]
[0253]
[0254]
[0255]
[0256]
[0257]
[0258]
[0259]
[0260]
[0261]
[0262]
[0263]
[0264]
[0265]
[0266]
[0267]
[0268]
[0269]
[0270]
[0271]
[0272]
[0273]
[0274]
[0275]
[0276]
[0277]
[0278]
[0279]
[0280]
[0281]
[0282]
[0283]
[0284]
[0285]
[0286]
[0287]
[0288]
[0289]
[0290]
[0291]
[0292]
[0293]
[0294]
[0295]
[0296]
[0297]
[0298]
[0299]
[0300]
[0301]
[0302]
[0303]
[0304]
[0305]
[0306]
[0307]
[0308]
[0309]
[0310]
[0311]
[0312]
[0313]
[0314]
[0315]
[0316]
[0317]
[0318]
[0319]
[0320]
[0321]
[0322]
[0323]
[0324]
[0325]
[0326]
[0327]
[0328]
[0329]
[0330]
[0331]
[0332]
[0333]
[0334]
[0335]
[0336]
[0337]
[0338]
[0339]
[0340]
[0341]
[0342]
[0343]
[0344]
[0345]
[0346]
[0347]
[0348]
[0349]
[0350]
[0351]
[0352]
[0353]
[0354]
[0355]
[0356]
[0357]
[0358]
[0359]
[0360]
[0361]
[0362]
[0363]
[0364]
[0365]
[0366]
[0367]
[0368]
[0369]
[0370]
[0371]
[0372]
[0373]
[0374]
[0375]
[0376]
[0377]
[0378]
[0379]
[0380]
[0381]
[0382]
[0383]
[0384]
[0385]
[0386]
[0387]
[0388]
[0389]
[0390]
[0391]
[0392]
[0393]
[0394]
[0395]
[0396]
[0397]
[0398]
[0399]
[0400]
[0401]
[0402]
[0403]
[0404]
[0405]
[0406]
[0407]
[0408]
[0409]
[0410]
[0411]
[0412]
[0413]
[0414]
[0415]
[0416]
[0417]
[0418]
[0419]
[0420]
[0421]
[0422]
[0423]
[0424]
[0425]
[0426]
[0427]
[0428]
[0429]
[0430]
[0431]
[0432]
[0433]
[0434]
[0435]
[0436]
[0437]
[0438]
[0439]
[0440]
[0441]
[0442]
[0443]
[0444]
[0445]
[0446]
[0447]
[0448]
[0449]
[0450]
[0451]
[0452]
[0453]
[0454]
[0455]
[0456]
[0457]
[0458]
[0459]
[0460]
[0461]
[0462]
[0463]
[0464]
[0465]
[0466]
[0467]
[0468]
[0469]
[0470]
[0471]
[0472]
[0473]
[0474]
[0475]
[0476]
[0477]
[0478]
[0479]
[0480]
[0481]
[0482]
[0483]
[0484]
[0485]
[0486]
[0487]
[0488]
[0489]
[0490]
[0491]
[0492]
[0493]
[0494]
[0495]
[0496]
[0497]
[0498]
[0499]
[0500]
[0501]
[0502]
[0503]
[0504]
[0505]
[0506]
[0507]
[0508]
[0509]
[0510]
[0511]
[0512]
[0513]
[0514]
[0515]
[0516]
[0517]
[0518]
[0519]
[0520]
[0521]
[0522]
[0523]
[0524]
[0525]
[0526]
[0527]
[0528]
[0529]
[0530]
[0531]
[0532]
[0533]
[0534]
[0535]
[0536]
[0537]
[0538]
[0539]
[0540]
[0541]
[0542]
[0543]
[0544]
[0545]
[0546]
[0547]
[0548]
[0549]
[0550]
[0551]
[0552]
[0553]
[0554]
[0555]
[0556]
[0557]
[0558]
[0559]
[0560]
[0561]
[0562]
[0563]
[0564]
[0565]
[0566]
[0567]
[0568]
[0569]
[0570]
[0571]
[0572]
[0573]
[0574]
[0575]
[0576]
[0577]
[0578]
[0579]
[0580]
[0581]
[0582]
[0583]
[0584]
[0585]
[0586]
[0587]
[0588]
[0589]
[0590]
[0591]
[0592]
[0593]
[0594]
[0595]
[0596]
[0597]
[0598]
[0599]
[0600]
[0601]
[0602]
[0603]
[0604]
[0605]
[0606]
[0607]
[0608]
[0609]
[0610]
[0611]
[0612]
[0613]
[0614]
[0615]
[0616]
[0617]
[0618]
[0619]
[0620]
[0621]
[0622]
[0623]
[0624]
[0625]
[0626]
[0627]
[0628]
[0629]
[0630]
[0631]
[0632]
[0633]
[0634]
[0635]
[0636]
[0637]
[0638]
[0639]
[0640]
[0641]
[0642]
[0643]
[0644]
[0645]
[0646]
[0647]
[0648]
[0649]
[0650]
[0651]
[0652]
[0653]
[0654]
[0655]
[0656]
[0657]
[0658]
[0659]
[0660]
[0661]
[0662]
[0663]
[0664]
[0665]
[0666]
[0667]
[0668]
[0669]
[0670]
[0671]
[0672]
[0673]
[0674]
[0675]
[0676]
[0677]
[0678]
[0679]
[0680]
[0681]
[0682]
[0683]
[0684]
[0685]
[0686]
[0687]
[0688]
[0689]
[0690]
[0691]
[0692]
[0693]
[0694]
[0695]
[0696]
[0697]
[0698]
[0699]
[0700]
[0701]
[0702]
[0703]
[0704]
[0705]
[0706]
[0707]
[0708]
[0709]
[0710]
[0711]
[0712]
[0713]
[0714]
[0715]
[0716]
[0717]
[0718]
[0719]
[0720]
[0721]
[0722]
[0723]
[0724]
[0725]
[0726]
[0727]
[0728]
[0729]
[0730]
[0731]
[0732]
[0733]
[0734]
[0735]
[0736]
[0737]
[0738]
[0739]
[0740]
[0741]
[0742]
[0743]
[0744]
[0745]
[0746]
[0747]
[0748]
[0749]
[0750]
[0751]
[0752]
[0753]
[0754]
[0755]
[0756]
[0757]
[0758]
[0759]
[0760]
[0761]
[0762]
[0763]
[0764]
[0765]
[0766]
[0767]
[0768]
[0769]
[0770]
[0771]
[0772]
[0773]
[0774]
[0775]
[0776]
[0777]
[0778]
[0779]
[0780]
[0781]
[0782]
[0783]
[0784]
[0785]
[0786]
[0787]
[0788]
[0789]
[0790]
[0791]
[0792]
[0793]
[0794]
[0795]
[0796]
[0797]
[0798]
[0799]
[0800]
[0801]
[0802]
[0803]
[0804]
[0805]
[0806]
[0807]
[0808]
[0809]
[0810]
[0811]
[0812]
[0813]
[0814]
[0815]
[0816]
[0817]
[0818]
[0819]
[0820]
[0821]
[0822]
[0823]
[0824]
[0825]
[0826]
[0827]
[0828]
[0829]
[0830]
[0831]
[0832]
[0833]
[0834]
[0835]
[0836]
[0837]
[0838]
[0839]
[0840]
[0841]
[0842]
[0843]
[0844]
[0845]
[0846]
[0847]
[0848]
[0849]
[0850]
[0851]
[0852]
[0853]
[0854]
[0855]
[0856]
[0857]
[0858]
[0859]
[0860]
[0861]
[0862]
[0863]
[0864]
[0865]
[0866]
[0867]
[0868]
[0869]
[0870]
[0871]
[0872]
[0873]
[0874]
[0875]
[0876]
[0877]
[0878]
[0879]
[0880]
[0881]
[0882]
[0883]
[0884]
[0885]
[0886]
[0887]
[0888]
[0889]
[0890]
[0891]
[0892]
[0893]
[0894]
[0895]
[0896]
[0897]
[0898]
[0899]
[0900]
[0901]
[0902]
[0903]
[0904]
[0905]
[0906]
[0907]
[0908]
[0909]
[0910]
[0911]
[0912]
[0913]
[0914]
[0915]
[0916]
[0917]
[0918]
[0919]
[0920]
[0921]
[0922]
[0923]
[0924]
[0925]
[0926]
[0927]
[0928]
[0929]
[0930]
[0931]
[0932]
[0933]
[0934]
[0935]
[0936]
[0937]
[0938]
[0939]
[0940]
[0941]
[0942]
[0943]
[0944]
[0945]
[0946]
[0947]
[0948]
[0949]
[0950]
[0951]
[0952]
[0953]
[0954]
[0955]
[0956]
[0957]
[0958]
[0959]
[0960]
[0961]
[0962]
[0963]
[0964]
[0965]
[0966]
[0967]
[0968]
[0969]
[0970]
[0971]
[0972]
[0973]
[0974]
[0975]
[0976]
[0977]
[0978]
[0979]
[0980]
[0981]
[0982]
[0983]
[0984]
[0985]
[0986]
[0987]
[0988]
[0989]
[0990]
[0991]
[0992]
[0993]
[0994]
[0995]
[0996]
[0997]
[0998]
[0999]
[1000]
[1001]
[1002]
[1003]
[1004]
[1005]
[1006]
[1007]
[1008]
[1009]
[1010]
[1011]
[1012]
[1013]
[1014]
[1015]
[1016]
[1017]
[1018]
[1019]
[1020]
[1021]
[1022]
[1023]
[1024]
[1025]
[1026]
[1027]
[1028]
[1029]
[1030]
[1031]
[1032]
[1033]
[1034]
[1035]
[1036]
[1037]
[1038]
[1039]
[1040]
[1041]
[1042]
[1043]
[1044]
[1045]
[1046]
[1047]
[1048]
[1049]
[1050]
[1051]
[1052]
[1053]
[1054]
[1055]
[1056]
[1057]
[1058]
[1059]
[1060]
[1061]
[1062]
[1063]
[1064]
[1065]
[1066]
[1067]
[1068]
[1069]
[1070]
[1071]
[1072]
[1073]
[1074]
[1075]
[1076]
[1077]
[1078]
[1079]
[1080]
[1081]
[1082]
[1083]
[1084]
[1085]
[1086]
[1087]
[1088]
[1089]
[1090]
[1091]
[1092]
[1093]
[1094]
[1095]
[1096]
[1097]
[1098]
[1099]
[1100]
[1101]
[1102]
[1103]
[1104]
[1105]
[1106]
[1107]
[1108]
[1109]
[1110]
[1111]
[1112]
[1113]
[1114]
[1115]
[1116]
[1117]
[1118]
[1119]
[1120]
[1121]
[1122]
[1123]
[1124]
[1125]
[1126]
[1127]
[1128]
[1129]
[1130]
[1131]
[1132]
[1133]
[1134]
[1135]
[1136]
[1137]
[1138]
[1139]
[1140]
[1141]
[1142]
[1143]
[1144]
[1145]
[1146]
[1147]
[1148]
[1149]
[1150]
[1151]
[1152]
[1153]
[1154]
[1155]
[1156]
[1157]
[1158]
[1159]
[1160]
[1161]
[1162]
[1163]
[1164]
[1165]
[1166]
[1167]
[1168]
[1169]
[1170]
[1171]
[1172]
[1173]
[1174]
[1175]
[1176]
[1177]
[1178]
[1179]
[1180]
[1181]
[1182]
[1183]
[1184]
[1185]
[1186]
[1187]
[1188]
[1189]
[1190]
[1191]
[1192]
[1193]
[1194]
[1195]
[1196]
[1197]
[1198]
[1199]
[1200]
[1201]
[1202]
[1203]
[1204]
[1205]
[1206]
[1207]
[1208]
[1209]
[1210]
[1211]
[1212]
[1213]
[1214]
[1215]
[1216]
[1217]
[1218]
[1219]
[1220]
[1221]
[1222]
[1223]
[1224]
[1225]
[1226]
[1227]
[1228]
[1229]
[1230]
[1231]
[1232]
[1233]
[1234]
[1235]
[1236]
[1237]
[1238]
[1239]
[1240]
[1241]
[1242]
[1243]
[1244]
[1245]
[1246]
[1247]
[1248]
[1249]
[1250]
[1251]
[1252]
[1253]
[1254]
[1255]
[1256]
[1257]
[1258]
[1259]
[1260]
[1261]
[1262]
[1263]
[1264]
[1265]
[1266]
[1267]
[1268]
[1269]
[1270]
[1271]
[1272]
[1273]
[1274]
[1275]
[1276]
[1277]
[1278]
[1279]
[1280]
[1281]
[1282]
[1283]
[1284]
[1285]
[1286]
[1287]
[1288]
[1289]
[1290]
[1291]
[1292]
[1293]
[1294]
[1295]
[1296]
[1297]
[1298]
[1299]
[1300]
[1301]
[1302]
[1303]
[1304]
[1305]
[1306]
[1307]
[1308]
[1309]
[1310]
[1311]
[1312]
[1313]
[1314]
[1315]
[1316]
[1317]
[1318]
[1319]
[1320]
[1321]
[1322]
[1323]
[1324]
[1325]
[1326]
[1327]
[1328]
[1329]
[1330]
[1331]
[1332]
[1333]
[1334]
[1335]
[1336]
[1337]
[1338]
[1339]
[1340]
[1341]
[1342]
[1343]
[1344]
[1345]
[1346]
[1347]
[1348]
[1349]
[1350]
[1351]
[1352]
[1353]
[1354]
[1355]
[1356]
[1357]
[1358]
[1359]
[1360]
[1361]
[1362]
[1363]
[1364]
[1365]
[1366]
[1367]
[1368]
[1369]
[1370]
[1371]
[1372]
[1373]
[1374]
[1375]
[1376]
[1377]
[1378]
[1379]
[1380]
[1381]
[1382]
[1383]
[1384]
[1385]
[1386]
[1387]
[1388]
[1389]
[1390]
[1391]
[1392]
[1393]
[1394]
[1395]
[1396]
[1397]
[1398]
[1399]
[1400]
[1401]
[1402]
[1403]
[1404]
[1405]
[1406]
[1407]
[1408]
[1409]
[1410]
[1411]
[1412]
[1413]
[1414]
[1415]
[1416]
[1417]
[1418]
[1419]
[1420]
[1421]
[1422]
[1423]
[1424]
[1425]
[1426]
[1427]
[1428]
[1429]
[1430]
[1431]
[1432]
[1433]
[1434]
[1435]
[1436]
[1437]
[1438]
[1439]
[1440]
[1441]
[1442]
[1443]
[1444]
[1445]
[1446]
[1447]
[1448]
[1449]
[1450]
[1451]
[1452]
[1453]
[1454]
[1455]
[1456]
[1457]
[1458]
[1459]
[1460]
[1461]
[1462]
[1463]
[1464]
[1465]
[1466]
[1467]
[1468]
[1469]
[1470]
[1471]
[1472]
[1473]
[1474]
[1475]
[1476]
[1477]
[1478]
[1479]
[1480]
[1481]
[1482]
[1483]
[1484]
[1485]
[1486]
[1487]
[1488]
[1489]
[1490]
[1491]
[1492]
[1493]
[1494]
[1495]
[1496]
[1497]
[1498]
[1499]
[1500]
[1501]
[1502]
[1503]
[1504]
[1505]
[1506]
[1507]
[1508]
[1509]
[1510]
[1511]
[1512]
[1513]
[1514]
[1515]
[1516]
[1517]
[1518]
[1519]
[1520]
[1521]
[1522]
[1523]
[1524]
[1525]
[1526]
[1527]
[1528]
[1529]
[1530]
[1531]
[1532]
[1533]
[1534]
[1535]
[1536]
[1537]
[1538]
[1539]
[1540]
[1541]
[1542]
[1543]
[1544]
[1545]
[1546]
[1547]
[1548]
[1549]
[1550]
[1551]
[1552]
[1553]
[1554]
[1555]
[1556]
[1557]
[1558]
[1559]
[1560]
[1561]
[1562]
[1563]
[1564]
[1565]
[1566]
[1567]
[1568]
[1569]
[1570]
[1571]
[1572]
[1573]
[1574]
[1575]
[1576]
[1577]
[1578]
[1579]
[1580]
[1581]
[1582]
[1583]
[1584]
[1585]
[1586]
[1587]
[1588]
[1589]
[1590]
[1591]
[1592]
[1593]
[1594]
[1595]
[1596]
[1597]
[1598]
[1599]
[1600]
[1601]
[1602]
[1603]
[1604]
[1605]
[1606]
[1607]
[1608]
[1609]
[1610]
[1611]
[1612]
[1613]
[1614]
[1615]
[1616]
[1617]
[1618]
[1619]
[1620]
[1621]
[1622]
[1623]
[1624]
[1625]
[1626]
[1627]
[1628]
[1629]
[1630]
[1631]
[1632]
[1633]
[1634]
[1635]
[1636]
[1637]
[1638]
[1639]
[1640]
[1641]
[1642]
[1643]
[1644]
[1645]
[1646]
[1647]
[1648]
[1649]
[1650]
[1651]
[1652]
[1653]
[1654]
[1655]
[1656]
[1657]
[1658]
[1659]
[1660]
[1661]
[1662]
[1663]
[1664]
[1665]
[1666]
[1667]
[1668]
[1669]
[1670]
[1671]
[1672]
[1673]
[1674]
[1675]
[1676]
[1677]
[1678]
[1679]
[1680]
[1681]
[1682]
[1683]
[1684]
[1685]
[1686]
[1687]
[1688]
[1689]
[1690]
[1691]
[1692]
[1693]
[1694]
[1695]
[1696]
[1697]
[1698]
[1699]
[1700]
[1701]
[1702]
[1703]
[1704]
[1705]
[1706]
[1707]
[1708]
[1709]
[1710]
[1711]
[1712]
[1713]
[1714]
[1715]
[1716]
[1717]
[1718]
[1719]
[1720]
[1721]
[1722]
[1723]
[1724]
[1725]
[1726]
[1727]
[1728]
[1729]
[1730]
[1731]
[1732]
[1733]
[1734]
[1735]
[1736]
[1737]
[1738]
[1739]
[1740]
[1741]
[1742]
[1743]
[1744]
[1745]
[1746]
[1747]
[1748]
[1749]
[1750]
[1751]
[1752]
[1753]
[1754]
[1755]
[1756]
[1757]
[1758]
[1759]
[1760]
[1761]
[1762]
[1763]
[1764]
[1765]
[1766]
[1767]
[1768]
[1769]
[1770]
[1771]
[1772]
[1773]
[1774]
[1775]
[1776]
[1777]
[1778]
[1779]
[1780]
[1781]
[1782]
[1783]
[1784]
[1785]
[1786]
[1787]
[1788]
[1789]
[1790]
[1791]
[1792]
[1793]
[1794]
[1795]
[1796]
[1797]
[1798]
[1799]
[1800]
[1801]
[1802]
[1803]
[1804]
[1805]
[1806]
[1807]
[1808]
[1809]
[1810]
[1811]
[1812]
[1813]
[1814]
[1815]
[1816]
[1817]
[1818]
[1819]
[1820]
[1821]
[1822]
[1823]
[1824]
[1825]
[1826]
[1827]
[1828]
[1829]
[1830]
[1831]
[1832]
[1833]
[1834]
[1835]
[1836]
[1837]
[1838]
[1839]
[1840]
[1841]
[1842]
[1843]
[1844]
[1845]
[1846]
[1847]
[1848]
[1849]
[1850]
[1851]
[1852]
[1853]
[1854]
[1855]
[1856]
[1857]
[1858]
[1859]
[1860]
[1861]
[1862]
[1863]
[1864]
[1865]
[1866]
[1867]
[1868]
[1869]
[1870]
[1871]
[1872]
[1873]
[1874]
[1875]
[1876]
[1877]
[1878]
[1879]
[1880]
[1881]
[1882]
[1883]
[1884]
[1885]
[1886]
[1887]
[1888]
[1889]
[1890]
[1891]
[1892]
[1893]
[1894]
[1895]
[1896]
[1897]
[1898]
[1899]
[1900]
[1901]
[1902]
[1903]
[1904]
[1905]
[1906]
[1907]
[1908]
[1909]
[1910]
[1911]
[1912]
[1913]
[1914]
[1915]
[1916]
[1917]
[1918]
[1919]
[1920]
[1921]
[1922]
[1923]
[1924]
[1925]
[1926]
[1927]
[1928]
[1929]
[1930]
[1931]
[1932]
[1933]
[1934]
[1935]
[1936]
[1937]
[1938]
[1939]
[1940]
[1941]
[1942]
[1943]
[1944]
[1945]
[1946]
[1947]
[1948]
[1949]
[1950]
[1951]
[1952]
[1953]
[1954]
[1955]
[1956]
[1957]
[1958]
[1959]
[1960]
[1961]
[1962]
[1963]
[1964]
[1965]
[1966]
[1967]
[1968]
[1969]
[1970]
[1971]
[1972]
[1973]
[1974]
[1975]
[1976]
[1977]
[1978]
[1979]
[1980]
[1981]
[1982]
[1983]
[1984]
[1985]
[1986]
[1987]
[1988]
[1989]
[1990]
[1991]
[1992]
[1993]
[1994]
[1995]
[1996]
[1997]
[1998]
[1999]
[2000]
[2001]
[2002]
[2003]
[2004]
[2005]
[2006]
[2007]
[2008]
[2009]
[2010]
[2011]
[2012]
[2013]
[2014]
[2015]
[2016]
[2017]
[2018]
[2019]
[2020]
[2021]
[2022]
[2023]
[2024]
[2025]
[2026]
[2027]
[2028]
[2029]
[2030]
[2031]
[2032]
[2033]
[2034]
[2035]
[2036]
[2037]
[2038]
[2039]
[2040]
[2041]
[2042]
[2043]
[2044]
[2045]
[2046]
[2047]
[2048]
[2049]
[2050]
[2051]
[2052]
[2053]
[2054]
[2055]
[2056]
[2057]
[2058]
[2059]
[2060]
[2061]
[2062]
[2063]
[2064]
[2065]
[2066]
[2067]
[2068]
[2069]
[2070]
[2071]
[2072]
[2073]
[2074]
[2075]
[2076]
[2077]
[2078]
[2079]
[2080]
[2081]
[2082]
[2083]
[2084]
[2085]
[2086]
[2087]
[2088]
[2089]
[2090]
[2091]
[2092]
[2093]
[2094]
[2095]
[2096]
[2097]
[2098]
[2099]
[2100]
[2101]
[2102]
[2103]
[2104]
[2105]
[2106]
[2107]
[2108]
[2109]
[2110]
[2111]
[2112]
[2113]
[2114]
[2115]
[2116]
[2117]
[2118]
[2119]
[2120]
[2121]
[2122]
[2123]
[2124]
[2125]
[2126]
[2127]
[2128]
[2129]
[2130]
[2131]
[2132]
[2133]
[2134]
[2135]
[2136]
[2137]
[2138]
[2139]
[2140]
[2141]
[2142]
[2143]
[2144]
[2145]
[2146]
[2147]
|1Authentication and Authorization|

|^ |*Authentication| is the verification of a user's identity, usually through
username/password credentials. |*Authorization| is allowing a certain action
to be applied to a particular path based on authentication of the originator.

|^ Generally, authorization is a two step process. First authentication,
using a username/password database. Second authorization, determining what
the username is allowed to do for this transaction.

|^ Basic authorization was discussed in
|link%|../config/##Authorization Configuration (Basics)++of++WASD Configuration||.
This section discusses all the aspects of WASD authentication and authorization.

|0Overview|

|^ By default, the logical name |*WASD_CONFIG_AUTH| locates a common
authorization rule file.  Simple editing of the file and reloading into the
running server changes the processing rules.

|^ Server authorization is performed using a configuration file, authentication
source, and optional full-access and read-only authorization grouping sources,
and is based on per-path directives. There is no user-configured authorization
necessary, or possible! In the configuration file paths are associated with the
authentication and authorization environments, and so become subject to the
HTTPd authorization mechanism. Reiterating |...| WASD HTTPd authorization
administration involves those two aspects, setting authorization against paths
and administering the authentication and authorization sources.

|^ |*Authorization is applied to the request path (i.e. the path in the URL
used by the client).  Sometimes it is possible to access the same resource
using different paths.  Where this can occur care must be exercised to
authorize all possible paths.|

|^ |*Where a request will result in script activation, authorization
is performed on both script and path components||. First script access is
checked for any authorization, then the path component is independently
authorized. Either may result in an authorization challenge/failure.  This
behaviour can be disabled using a path SETting rule, see
|link%|../config/##SET Rule++of++WASD Configuration||.

|^ The |*authentication source| name is refered to as the |/realm||, and
refers to a collection of usernames and passwords.  It can be the system's
SYSUAF database.

|^ The |*authorization source| is refered to as the |/group||, and commonly
refers to a collection of usernames and associated |/permissions||.

|2Rule Interpretation|

|^ The configuration file rules are scanned from first towards last, until a
matching rule is encountered (or end-of-file).  Generally a rule has a trailing
wildcard to indicate that all sub-paths are subject to the same authorization
requirements.

|0String Matching|

|^ Rule matching is string pattern matching, comparing
the request specified path, and optionally other components of the request when
using configuration conditionals
|link%|../config/##Conditional Configuration++of++WASD Configuration||,
to a series of patterns, until one of the patterns matches, at which stage
the authorization characteristics are applied to the request and authentication
processing is undertaken.  If a matching pattern (rule) is not found the path is
considered not to be subject to authorization.  Both wildcard and regular
expression based pattern matching is available
|link%|../config/##String Matching++of++WASD Configuration||.

|2Authentication Policy|

|^ A |/policy| regarding when and how authorization can be used may be
established on a per-server basis. This can restrict authentication challenges
to "https:" (SSL) requests (|link|Transport Layer Security||), thereby ensuring
that the authorization environment is not compromised by use in non-encrypted
transactions. Two server qualifiers provide this.

|bullet|

|item| |*./AUTHORIZE=|

|bullet|

|item| |*ALL| restricts |*all| requests to authorized paths.  If a path does
not have authorization configured  against it it is automatically denied
access.  This is an effective method of preventing inadvertant access to areas
in a site (|link|Securing All Requests||).

|item| |*SSL| restricts |*all|
authentication/authorization transactions to the SSL environment.

|item| |*(SSL,ALL)| combines the above two.

|!bullet|

|item| |*./SYSUAF=|

|bullet|

|item| Used without any keywords, this qualifier allows all current (non-expired,
non-disusered, etc.), non-privileged accounts to be used for authentication
purposes. 

|item| |*ID| restricts SYSUAF authenticated account to those possessing a
specific VMS resource identifier
(|link|Rights Identifiers||). 

|item| |*PROXY| allows non-SYSUAF to SYSUAF username proxying
(|link|VMS Account Proxying||).

|item| |*RELAXED| allows |*any| current account to
be authorized via the SYSUAF.  |*This is not recommended||, use rights
identifiers to allow some discrimination to be exercised.

|item| |*SSL| restricts only SYSUAF authenticated transactions to the SSL
environment.

|item| |*VMS| allows a combination of all current (non-expired,
non-disusered, etc.), non-privileged accounts to be used for authentication
purposes (the /SYSUAF without keywords behaviour), with the behaviours provided
by the ID keyword. 

|item| |*WASD| enables the deprecated, "hard-wired" WASD
identifier environment available to this server. See
|link|WASD "Hard-wired" Identifiers||.

|item| |*.(VMS,ID,SSL)| would allow these multiple keywords to be applied, etc.

|!bullet|

|!bullet|

|^ Note also that individual paths may be restricted to SSL requests using
either the mapping conditional rule configuration or the authorization
configuration files. See
|link%|../config/##Conditional Mapping++of++WASD Configuration||.

|^ In addition, the following configuration parameters have a direct role in
an established authorization policy.

|bullet|

|item| |*.[AuthFailureLimit]
[AuthFailurePeriod]
[AuthFailureTimeout]|
provide a similar break-in detection and evasion as with VMS. These three
directives parallel the functions of SYSGEN parameters LGI_BRK_LIM,
LGI_BRK_TMO, LGI_HID_TIM. A single authentication failure marks the particular
username in the particular realm as suspect.  Repeated failures up to
[AuthFailureLimit] attempts within the [AuthFailurePeriod] period puts it into
break-in evasion mode after which the period [AuthFailureTimeout] must expire
before further attempts have authentication performed and so have any chance to
succeed. (This is a change in behaviour to versions earlier than 8.3.)  If any
of the above three parameters are not specified they default to the
corresponding SYSGEN parameter.

|item| |*.[AuthRevalidateLoginCookie]| When user revalidation is in effect (see
immediately below), after having  previously closed the browser initial
authentication of a resource is immediately followed by another if a cached
entry on the server indicated revalidation was required.  This prevents this
second request.  Requires that browser cookies be enabled.

|item| |*.[AuthRevalidateUserMinutes]| sets the number of minutes between
successive authentication attempts before the user is forced to reenter the
authentication data (via a browser dialog).  Zero disables this function. When
enabling this feature is is inevitable that [AuthRevalidateLoginCookie] will
need to be enabled as well (described immediately above).  This is used to
suppress an unavoidable second username/password prompt from the browser. 

|note|
|0Authentication Cache and Revalidation|
User revalidation relies on an entry being maintained in the authentication
cache.  Each time the entry is flushed, for whatever reason (cache congestion,
command-line purge, server restart, etc.), the user will be prompted for
credentials.  It may be necessary to increase the size of the cache by
adjusting [AuthCacheEntriesMax] when this facility is enabled.
|!note|

|!bullet|

|0Authentication Failures|

|^ Details of authentication failures are logged to the server process log. 

|bullet|

|item| |*%HTTPD-W-AUTHFAIL| indicates a failure to authenticate (incorrect
username/password).  The number of failures, the realm name, the user name and
the originating host are provided. Isolated instances of this are only of
moderate interest.  Consecutive instances may indicate a user thrashing about
for the correct password, but they usually give up before a dozen attempts.

|item| |*%HTTPD-I-AUTHFAILOK| advises that a previous failure to
authenticate has now successfully done so.  This is essentially informational.

|item| |*%HTTPD-W-AUTHFAILIM| indicates the number of failures have exceeded
the [AuthFailureLimit], after which automatic refusal begins.  This message
should be of concern and the circumstances investigated, especially if the
number of attempts becomes excessive.

|!bullet|

|^ Failures may also be directed to the OPCOM facility
|link%|../config/##OPCOM Logging++of++WASD Configuration||.

|2Permissions, Path and User|

|^ |*Both paths and usernames have permissions associated with them.|  A path
may be specified as read-only, read and write, write-only (yes, I'm sure
someone will want this!), or none (permission to do nothing). A username may be
specified as read capable, read and write capable, or only write capable.  For
each transaction these two are combined to determine the maximum level of
access allowed. The allowed action is the logical AND of the path and username
permissions.

|^ The permissions may be described using the HTTP method names, or using the
more concise abbreviations R, W, and R+W.

|0HTTP Methods|

|table|

|~_ |: Path/User |: DELETE |: GET |: HEAD |: POST |: PROPFIND |: PUT |: WebDAV
|~
|~#* |. READ or R |. no |. yes |. yes |. no |. yes |. no |. no
|~ |. WRITE or W |. yes |. no |. no |. yes |. no |. yes |. yes
|~ |. R+W |. yes |. yes |. yes |. yes |. yes |. yes |. yes
|~ |. NONE |. no |. no |. no |. no |. no |. no |. no
|~
|~#^* |. DELETE |. yes |. yes |. no |. no |. no |. no |. no
|~ |. GET |. no |. yes |. no |. no |. no |. no |. no
|~ |. HEAD |. no |. no |. yes |. no |. no |. no |. no
|~ |. POST |. no |. no |. no |. yes |. no |. no |. no
|~ |. PROPFIND |. no |. no |. no |. no |. yes |. no |. no
|~ |. PUT |. no |. yes |. no |. no |. no |. yes |. no
|~ |. Other WebDAV |. no |. no |. no |. no |. no |. no |. yes
|!table|

|2Authorization Configuration File|

|^ Requiring a particular path to be authorized in the HTTP transaction is
accomplished by applying authorization requirements against that path in a
configuration file.  This is an activity distinct from setting up and
maintaining any authentication/authorization databases required for the
environment.

|^ By default, the system-table logical name |*WASD_CONFIG_AUTH|
locates a common authorization configuration file, unless an individual rule
file is specified using a job-table logical name.  Simple editing of the file
changes the configuration. Comment lines may be included by prefixing them with
the hash "#" character, and lines continued by placing the backslash
character "\\" as the last character on a line.

|^ The [IncludeFile] is a directive common to all WASD configuration, allowing
a separate file to be included as a part of the current configuration.  (see
|link%|../config/##Include File Directive++of++WASD Configuration||.

|^ Configuration directives begin either with a "[realm]", "[realm;group]" or
"[realm;group-r+w;group-r]" specification, with the forward-slash of a path
specification, or with a "[AuthProxy]" or "[AuthProxyFile]" introducing a proxy
mapping.  Following the path specification are HTTP method keywords controlling
group and world permissions to the path, and any |*access-restricting| request
scheme ("https:") and/or host address(es) and/or username(s).

|bullet|

|item| |*REALM|

|^ Square brackets are used to enclose a [realm;group;group] specification,
introducing a new authentication grouping.  Within  these brackets is specified
the realm name (authentication source), and then optional group (authorization
source) names separated by semi-colons. All path specifications following this
are authenticated against the specified realm database, and permissions
obtained from the group "[realm;group]" database (or authentication database if
group not specified), until the next [realm;group;group] specification.

|^ The following shows the format of an authentication source (realm) only
directive.

|code|
[authentication-source]
|!code|

|^ This one, the format of a directive using both authentication and
authorization sources (both realm and group).

|code|
[authentication-source ; authorization-source]
|!code|

|^ The third variation, using an authentication, full-access (read and write)
and read-only authorization sources (realm and two grouping).

|code|
[authentication-source ; full-access-source ; read-only-source]
|!code|

|^ The authentication source may also be given a description.  This is the
text the browser dialog presents during password prompting.  See 
|link|Realm Description||.

|item| |*PATH|

|^ Paths are usually specified terminated with an asterisk wildcard. This
implies that any directory tree below this is included  in the access control.
Wildcards may be used to match any portion of the specified path, or not at
all. Following the path specification are control keywords representing the
HTTP methods or permissions that can be applied against the path, and optional
access-restricting list of host address(es) and/or username(s), separated using
commas. Access control is against either or both the group and the world. The
group access is specified first followed by a semi-colon separated world
specification. The following show the format of the path directive, see the
examples below to further clarify the format.

|code|
/root/path/  group-access-list,group-permissions ; \\
             world-access-list,world-permissions
|!code|

|item| |*PROXY|

|^ The [AuthProxy] and [AuthProxyFile] directives introduces one or more
SYSUAF proxy mappings (|link|VMS Account Proxying||).

|!bullet|

|^ |*The same path cannot be specified against two different realms for the
same virtual service.| The reason lies in the HTTP authentication schema,
which allows for only one realm in an authentication dialog.  How would the
server decide which realm to use in the authentication challenge?  Of course,
different parts of a given tree may have different authorizations, however any
tree ending in an asterisk results in the entire sub-tree being controlled by
the specified authorization environment, unless a separate specification exists
for some inferior portion of the tree.

|^ There is a thirty-one character limit on authentication source names.

|0Reserved Names|

|^ The following realm names are reserved and have special functionality.

|bullet|

|item| |*EXTERNAL |-| | Any authentication and authorization will be done in
some way by an external CGI script.  None is attempted by the server.  The
server does pre-processs the supplied "Authorization:" field however and
ensures that any request against a path with this realm supplies authorization
credentials before any further request processing (script activation) occurs.

|item| |*NONE |-| | This refers to any request, is not authenticated
in a any way, and just marks the path as having been authorized for access
(|link|Securing All Requests||).

|item| |*OPAQUE |-| | Allows a script generating its own
challenge/response and doing all its own "Authorization:" field processing (a
little like EXTERNAL but the server does absolutely nothing).

|item| |*PROMISCUOUS |-| | This realm is only available while the
/PROMISCUOUS qualifier is in use (|link|Server Administration||).

|item| |*RFC1413 |-| | This IETF document describes an identification protocol
that can be used as a form of |/authentication| within this realm.

|item| |*TOKEN |-| | A |/token| is a short-lived, cookie delivered,
representation of authentication established in another context.

|item| |*WORLD |-| | This refers to any request and is not authenticated in any
way, only the permissions associated with the path are applied to the request. 
The reserved username "WORLD" becomes the  authenticated username.

|item| |*VMS |-| | Use the server system's SYSUAF database to authenticate the
username. For "http:" requests the username/password pairs are transmitted
encoded but not encrypted, |*&color:red;.so this is not recommended||.  For
"https:" requests, using the implicit security offered by SSL (|link|Transport
Layer Security||) the use of SYSUAF authentication is considered viable.

|^ By default accounts with SYSPRV authorized are always rejected to discourage
the use of potentially significant usernames (e.g. SYSTEM). Accounts that are
disusered, have passwords that have expired, or that are captive or restricted
are also automatically rejected.

|^ The authentication source may be disguised by giving it a specific
description.  This will the text the browser dialog presents during password
prompting.  See |link|Realm Description||.

|^ See |link|SYSUAF-Authenticated Users| for further information on these
topics. 

|item| |*X509 - | Uses X.509 v3 certificates (browser client certificates) to
establish identity (authentication) and based on that identity control access
to server resources (authorization).  This is only available for SSL
transactions.  See |link|Transport Layer Security| for further information on
SSL, and |link|Authorization Using X509 Certification| on X509 realm
authorization.

|!bullet|

|0Reserved Username|

|^ The following username is reserved.

|bullet|

|item| |*WORLD |-| | If a path is authorized using the WORLD realm the
pseudo-authenticated username becomes "WORLD".  Any log will reflect this 
username and scripts will access a WWW_REMOTE_USER containing this value. 
Although not forbidden, it is not recommended this string be used as a username
in other realms.

|!bullet|

|0Access Restriction Keywords|

|^ If a host name, protocol identifier or username is included in the path
configuration directive it acts to |*further| limit access to matching clients
(path and username permissions still apply). If more than one are included a
request must match each. If multiple host names and/or usernames are included
the client must match at least one of each. Host and username strings may
contains the asterisk wildcard, matching one or more consecutive characters.
This is most useful when restricting access to all hosts within a given domain,
etc. In addition a VMS security profile may be associated with the request.

|bullet|

|item| |*Host Names |-| | may be specified as either alphabetic (if DNS name
resolution is enabled, see [DNSlookup] configuration directive) or literal
addresses. When a host restriction occurs there is never an attempt to
authenticate any associated username. Hence applying host restrictions very
effectively prevents an attack from outside the allowed addresses. The reserved
word |/#localhost| refers to the host name the server is executing on.

|item| |*Network Mask |-| | The mask is a dotted-decimal network
address, a slash, then a dotted-decimal mask or VLSM (variable-length subnet
mask).  A network mask operates by bitwise-ANDing the client host address with
the mask, bitwise-ANDing the network address supplied with the mask, then
comparing the two results for equality.

|item| |*Request Scheme |-| | (protocol) either "http:" or secured via "https:"
(SSL)

|item| |*User Names |-| | are indicated by a leading tilde, the "~" character
(similar or username URL syntax).

|item| |*Profile |-| | a SYSUAF-authenticated username can have its VMS security
profile associated with the request.  When applied to a path this profile is
used to determine access to the file system.  The WASD_CONFIG_AUTH
configuration file can have the keyword "profile" added to the restriction list
(|link|SYSUAF Security Profile||).  In a manner-of-speaking this keyword lifts
a restriction.

|!bullet|

For example

|code|
/web/secret/* *.three.stooges,~Moe,~Larry,~Curly,read
|!code|

restricts read access to Curly, Larry and Moe accessing from within the
three.stooges network, while

|code|
/web/secret/* https:,*.three.stooges,~Moe,~Larry,~Curly,read
|!code|

applies the further restriction of access via "https:" (SSL) only.

|^ These examples show the use of a network mask to restrict based on the
source network of the client.  The first, four octets supplied as a mask.  The
second a VLSM used to specify the length of the network component of the
address.

|code|
/web/secret/* https:,#131.185.250.128/255.255.255.192,~Moe,~Larry,~Curly,read

/web/secret/* https:,#131.185.250.128/26,~Moe,~Larry,~Curly,read
|!code|

|^ These examples both specify a 6 bit subnet.  With the above examples the
host 131.185.250.250 would be accepted, but 131.185.250.50 would be rejected.

|^ Note that it more efficient to place |/protocol| and |/host| restrictions at
the front of a list.

|2Authentication Sources|

|^ Authentication credentials may be validated against one of several sources,
each with different characteristics.

|bullet|

|item| |*VMS Rights Identifier|

|^ An identifier is indicated by appending a "=ID" to the name of the
realm or group.  Also refer to |link|Rights Identifiers||.

|^ Whether or not any particular username is allowed to authenticate via the
SYSUAF may be controlled by that account holding or not holding a particular
rights identifier. Placing "=ID" against realm name implies the username
must exist in the SYSUAF and hold the specified identifier name.

|code|
[PROJECT_A=id]
|!code|

|^ When (and only when) a username has been authenticated via the SYSUAF,
rights identifiers associated with that account may be used to control the
level-of-access within that realm.  This is in addition to any identifier
controlling authentication itself.

|code|
[PROJECT_A=id;PROJECT_A_LIBRARIAN=id;PROJECT_A_USER=id]
|!code|

|^ In this example a username would need to hold the PROJECT_A identifier to
be able to authenticate, PROJECT_A_LIBRARIAN to write the path(s) (via POST,
PUT) and PROJECT_A_USER to be able to read the path(s).

|item| |*VMS Authentication|

|^ The server system SYSUAF may be used to authenticate usernames using the VMS
account name and password.  The realm being VMS may be indicated by using the
name "VMS", by appending "=VMS" to another name making it a |/VMS synonym||, or
by giving it a specific description
(|\|link|<REFERENCE>(hd_auth_realm_description)| in
|\|link|<REFERENCE>(hd_auth_sources)||).  Further information on SYSUAF
authentication may be found in |\|link|<REFERENCE>(hd_auth_sysuaf)||. These
examples illustrate the general idea. 

|code|
[VMS]
[LOCAL=vms]
[ANY_NAME_AT_ALL=vms]
|!code|

|item| |*ACME|

|^ Three Authentication and Credential Management Extension (ACME) agents are
currently available (as at VMS V8.3 and WASD v9.3), "VMS"  (SYSUAF), "MSV1_0"
(Microsoft domain authentication used by Advanced Server) and an LDAP kit. 
There is also an API that will allow local or third-party agents to be
developed.  WASD ACME authentication is completely asynchronous and so agents
that make network or other relatively latent queries will not add granularity
into server processing.  By default ACME is used to authenticate requests
against the SYSUAF on Alpha and Itanium running VMS V7.3 or later
(|link|ACME||).

|^ For authorization rules explicitly specifying ACME the Domain Of
Interpretation (DOI) becomes the realm name, interposed between the relam
description and the ACME authentication source keyword.  In this first example
the DOI is VMS and so all WASD SYSUAF authentication capabilities are
available.

|code|
["ACME Coyote"=VMS=ACME;JIN_PROJECT=id]
/a/path/* r+w,https:
|!code|

|^ In the second example authentication is performed using the same
credentials as Advanced Server running on the local system.

|code|
["PC Users"=MSV1_0=ACME]
/a/nuther/path/* r+w,https:
|!code|

|^ In this final example the DOI is a third-party agent.

|code|
["More ACME"=THIRD-PARTY=ACME]
/a/different/path/* r+w,https:
|!code|

|item| |*Simple List|

|^ A plain-text list may be used to provide usernames for group membership. 
The format is one username per line, at the start of the line, with optional,
white-space delimited text continuing along the line (which could be used as
documentation).  Blank lines and comment lines are ignored.  A line may be
continued by ending it with a "\\" character.  These files may, of course, be
created and maintained using any plain text editor.  They must exist in the
WASD_AUTH: directory, have an extension of ".$HTL", and do not need to be world
accessible.

|code|
# the stooges
curley     Jerome Horwitz
larry      Louis Feinberg
moe        Moses Horwitz
shemp      Samuel Horwitz
JoeBesser
JoeDeRita
|!code|

|^ Simple lists are indicated in the configuration by appending a
"=LIST" to the name.

|code|
[VMS;STOOGES=list]
|!code|

|^ It also possible to use a simple list for authentication purposes.  The
plain-text password is appended to the username with a trailing equate symbol.
Although in general this is not recommended as everything is stored as
plain-text it may be suitable as an ad hoc solution in some circumstances. The
following example shows the format.

|code|
# silly example
fred=dancesalittle  Guess who?
ginger=rogers       No second prizes!
|!code|

|item| |*HTA Database|

|^ These are binary, fixed 512 byte record files, containing authentication
and authorization information.  HTA databases may be used for authentication
and group membership purposes.  The content is much the same, the role differs
according to the location in the realm directive.  These databases may be
administered using the online Server Administration facility (|link|HTTPd
Server Revise||) or the HTAdmin command-line utility (|link|HTAdmin||). They
are located in the WASD_AUTH: directory and have an extension of ".$HTA".

|^ (Essentially for historical reasons) HTA databases are the default sources
for authorization information.  Therefore, using just a name, with no trailing
"=|/something||", will configure an HTA source.  Also, and recommended for
clearly showing the intention, appending the "=HTA" qualifier specifies an HTA
database.  The following example show some of the variations.

|code|
[VMS;PROJECT_A=hta]
[DEVELOPERS=hta;PROJECT_A=hta]
|!code|

|item| |*X.509 Client Certificate|

|^ Uses X.509 v3 certificates (browser client certificates) to establish
identity (authentication) and based on that identity control access to server
resources (authorization).  This is only available for SSL transactions.  See
|link|Transport Layer Security| for further information on SSL, and
|link|Authorization Using X509 Certification| on X509 realm authorization.

|item| |*RFC1413 Indentification Protocol|

|^ From RFC1413 (M. St.Johns, 1993) |...|

|quote| The Identification Protocol (a.k.a., "ident", a.k.a., "the Ident
Protocol")  provides a means to determine the identity of a user of a
particular TCP connection.  Given a TCP port number pair, it returns a
character string which identifies the owner of that connection on the server's
system.
|!quote|

and |...|

|quote|
The information returned by this protocol is at most as trustworthy as the host
providing it OR the organization operating the host.  For example, a PC in an
open lab has few if any controls on it to prevent a user from having this
protocol return any identifier the user wants.  Likewise, if the host has been
compromised the information returned may be completely erroneous and
misleading.


|^ The Identification Protocol is not intended as an authorization or access
control protocol.  At best, it provides some additional auditing information
with respect to TCP connections.  At worst, it can provide misleading,
incorrect, or maliciously incorrect information.
|!quote|

|^ Nevertheless, RFC1413 may be useful for some purposes in some heterogeneous
environments, and so has been made available for |/authentication|
purposes.

|code|
[RFC1413]
["Descriptions can be used!"=RFC1413;A_PROJECT=list]
|!code|

|^ The RFC1413 realm generates no browser username/password dialog.  It relies
on the system supporting the client to return a reliable identification of the
user accessing the HTTP server by looking-up the user of the server
connection's peer port.

|item| |*Authorization Agent|

|^ An authorization agent is a CGI-compliant CGIplus script that is specially
activated during the authorization processing.  Using CGI environment variables
it gets details of the request, makes an assessment based on its own internal
authentication/authorization processing, and using the script |/callout|
mechanism returns the results to the server, which then acting on these, allows
or denies access.

|^ Such agents allow a site to develop local authentication/authorization
mechnisms relatively easily, based on CGI principles.  A discussion of such a
development is not within the scope of this section, see the
|link%|../scripting/scripting.html|WASD Web Services - Scripting| document for information
on the use of callouts, and the example and working authorization agents
provided in the |link%|/wasd_root/src/agent/*.*|WASD_ROOT:[SRC.AGENT]|
directory. The description at the beginning of these programs covers these
topics in some detail.

|^ An authorization agent would be configured using something like the
following, where the "AUTHAGENT" is the actual script name doing the
authorization.  This has the the path "/cgiauth-bin/" prepended to it.

|code|
["Example Agent"=AUTHAGENT_EXAMPLE=agent]
/some/path/or/other/* r+w
|!code|

|^ It is possible to supply additional, per-path information to an agent. 
This can be any free-form text (up to a maximum length of 63 characters).  This
might be a configuration file location, as used in the example CEL
authenticator.  For example

|code|
["CEL Authenticator"=AUTHAGENT_CEL=agent]
/some/path/or/other/* r+w,param=WASD_ROOT:[LOCAL]CEL1.LIS
/a/nother/path/* r+w,param=WASD_ROOT:[LOCAL]CEL2.LIS
|!code|

|^ Generally authorization agent scripts use 401/WWW-Authorize: transactions
to establish identity and credentials.  It is possible for an agent to
establish identity outside of this using mechanisms available only to itself. 
In this case it is necessary suppress the usually automatic generation of
username/password dialogs using a realm of |/agent+opaque|

|code|
[AUTHAGENT_PAPI=agent+opaque]
/papi/path/or/other/* r+w
/a/nother/papi/path/* r+w
|!code|

|^ An older mechanism required a leading parameter of "/NO401".  It is
included here only for reference.  The |/agent+opaque| realm should
now always be used.

|code|
["Another Authenticator"=AUTHAGENT_ANOTHER=agent]
/some/path/or/other/* r+w,param="/NO401 MORE PARAMETERS CAN BE SUPPLIED"
/a/nother/path/* r+w,param="/NO401 OTHER PARAMETERS CAN BE SUPPLIED"
|!code|

|^ It is necessary to have the following entry in the WASD_CONFIG_MAP
configuration file:

|code|
exec+ /cgiauth-bin/* /cgi-bin/*
|!code|

|^ This allows authentication scripts to be located outside of the general
server tree if desired.

|item| |*Token|

|^ A |/token| is a short-lived, cookie delivered, representation of
authentication established in another context.  Originally devised to allow
controlled access to very large datasets without the overhead of SSL in the
transmission but with access credentials supplied in the privacy of an SSL
connection.  The cookie contains NO CREDENTIAL data at all and the
authenticator manages an internal database of these so it can determine whether
any supplied token is valid and when that token has expired.  By default (and
commonly) token authorisation occurs in non-SSL space (http:) and the
credential authorisation in SSL space (https:).

|^ Token authorisation is described in |link|Token Authentication||).

|item| |*Host Group|

|^ Instead of a list of usernames contained in a database, a group within a
realm (either or both |/full-access-source| or
|/read-only-source||, see |link|Authorization Configuration File||) may be
specified as a host, group of hosts or network mask.  This acts to restrict all
requests from clients not matching the IP address specification.  Unlike the
per-path access restrict list (|link|Access Restriction Keywords||) this
construct applies to all paths in the realm.  It also offers relative
efficiencies over restriction lists and lends itself to some environments based
on per-host identification (e.g. the RFC1413 realm).  Note that IP addresses
can be |/spoofed| (impersonated) so this form of access control should
be deployed with some caution.

|code|
[RFC1413;131.185.250.*]
/path1/to/be/authorized/* r+w

[RFC1413;131.185.250.0/24]
/path2/to/be/authorized/* r+w

[RFC1413;131.185.250.0/255.255.255.0]
/path3/to/be/authorized/* r+w
|!code|

|^ The examples of realm specifications above all act to restrict read-write
access via the RFC1413 realm to hosts within the 131.185.250.|/nnn| subnet.

|item| |*External|

|^ Generally the WASD model is for the server to perform authorisation
processing and so the password never becomes visible at the application level. 
For scripting environments performing their own authentication the server will
decode and parse the request "Authorization:" header for paths under the
EXTERNAL realm.  

|code|
[EXTERNAL]
/some/path/or/other/* r+w
|!code|

|^ The various authentication data are then provided in the CGI variables

|simple#|
|& AUTH_TYPE
|& AUTH_ACCESS
|& AUTH_PASSWORD
|& AUTH_REALM
|& AUTH_REALM_DESCRIPTION
|& HTTP_AUTHORIZATION
|& REMOTE_USER
|!simple|

|item| |*Opaque|

|^ If the script is performing its own authentication and authorisation using
the raw request header then the server needs to be advised of this by placing
the required paths under the OPAQUE realm.

|code|
[OPAQUE]
/another/path/* r+w
|!code|

|^ The server will then provide only the "Authorization:" header data
in the cgi variable HTTP_AUTHORIZATION from which the username and password may
processed.

|!bullet|

|0Multiple Source Types|

|^ A realm directive may contain one or more different types of authorization
information source, with the following restrictions.

|bullet|

|item| Rights identifiers may only be used with SYSUAF authenticated requests. 
The following combinations would therefore not be allowed.

|code|
[DEVELOPERS;PROJECT_A=id]
[DEVELOPERS=hta;LIBRARIAN=id;PROJECT_A=list]
[STOOGES=list;MOE_HOWARD=id]
|!code|

|item| WASD rights identifiers (deprecated) may only be used for group
membership when the /AUTHORIZE=WASD server qualifier has been specified at
startup, and the username has been authenticated using a WASD identifier.  See
|link|WASD "Hard-wired" Identifiers||.

|!bullet|

|0Realm Description|

|^ It is possible to supply text describing the authentication realm to the
browser user that differs from the actual source name.  This may be used to
disguise the  actual source or to provide a more informative description than
the source name conveys.

|^ Prefixing the actual realm source name with a double-quote delimited string
(of up to 31 characters) and an equate symbol will result in the string being
sent to a browser as the realm description during an authentication challenge. 
Here are some examples.

|code|
["the local host"=VMS]
["Social Club"=SOCIAL_CLUB_RW=id]
["Finance Staff"=FINANCE=list]
["Just Another Database"=DBACCESS=hta]
|!code|

|note|
The |/Digest| authentication scheme uses the realm description at both
server and browser in the encrypted password challenge and response.  When
passwords are stored in an HTA file this realm synonym cannot be changed
without causing these passwords to be rendered invalid.
|!note|

|2Realm, Full-Access, Read-Only|

|^ WASD authorization offers a number of combinations of access control.  This
is a summary.  Please note that when refering to the |/level-of-access| a
particular username may be allowed (read-only or full, read-write  access),
that it is always moderated by the level-of-access provided with a path
configured within that realm.  See |link|Permissions, Path and User||.

|bullet|

|item| |*Authentication Only|

|^ When a path is controlled by a realm that comprises an authentication
source only, as in this example

|code|
[authentication-source]
|!code|
 usernames authenticated using that are granted full (read and write)
access.

|item| |*Authentication and Group|

|^ Where a group membership source is provided following the authentication
source, as illustrated in this example

|code|
[authentication-source;group-source]
|!code|
 the level-of-access depends on the source of the group membership.  If
from a |/simple-list| of usernames or via a |/VMS rights
identifier| the username receives full (read and write) access.  If from an HTA
database the access is dependent on what is set against that user in the
database.  It can be either full or read-only.

|item| |*Authentication and Two Groups|

|^ When a second group is specified, as in

|code|
[authentication-source;group-source;group-source]
|!code|

the authentication is interpreted in a fixed fashion.  The first group
specified contains usernames to be granted full (read and write) access.  The
second group read-only access.  Should a username occur in both groups full
access takes precedence.

|^ The second group may be specified as an asterisk wildcard ("*") which is 
interpreted as |/everyone else| (i.e. everyone else gets read-only access).

|!bullet|

|2Virtual Servers|

|^ As described in
|link%|../config/##Virtual Services++of++WASD Configuration||,
virtual service syntax may be used with authorization mapping to selectively
apply rules to one specific service.  This example provides the essentials of
using this syntax.  Note that service-specific and service-common rules may be
mixed in any order allowing common authorization environments to be shared.

|code|
# authorization rules example for virtual servers
[[alpha.example.com:443]]
# ALPHA SSL is the only service permitting VMS (SYSUAF) authentication
[LOCAL=vms]
/web/* https:,r+w ; r
/httpd/-/admin/* ~daniel,https:,r+w
[[beta.example.com:80]]
# BETA has its own HTA database
[BETA_USER=hta]
/web/* r+w ; r
[[gamma.example.com:80]]
# GAMMA likewise
[GAMMA_DEVELOPER=id;PROJECT-A=list]
/web/project/a/* r+w ; r
[GAMMA_DEVELOPER=id;PROJECT-B=list]
/web/project/b/* r+w ; r
[[*]]
# allow anyone from the local subnet to upload to here
[WORLD]
/web/unload/* 131.185.200.*,r+w
|!code|

|^ The online Server Administration facility path authorization report
(|link|HTTPd Server Reports||) provides a selector allowing the viewing and
checking of rules showing all services or only one particular virtual server,
making it simpler to see exactly what any particular service is authorizing
against.

|2Authorization Configuration Examples|

|^ Mixed case is used in the configuration examples (and should be in
configuration files) to assist in readability.  Rule interpretation however is
completely case-insensitive.

|number|

|item| In the following example the authentication realm is "WASD", a
synonym for SYSUAF authentication, and the permissions group
"SOCIALCLUB", a simple list of usernames.  The directive allows those
authenticated from the WASD realm and in the SOCIALCLUB group full access (read
and write), and the world read-only.

|code|
[WASD=vms;SOCIALCLUB=list]
/web/socialclub/* r+w ; read
|!code|

|item| This example illustrates restricting access according internet address.
Both the group and world restriction is identical, but the group address is
being specified numerically, while the world access is being specified
alphabetically (just for the purposes of illustration). This access check is
done doing simple wildcard comparison, and makes numerical specifications
potentially more efficient because they are usually shorter. The second line
restricts that path's write access even further, to one username,
"BLOGGS".

|code|
[WASD=vms;SOCIALCLUB=list]
/web/socialclub/* 131.185.45.*,get,post; *.example.com,get
/web/socialclub/accounts/* 131.185.45.*,~BLOGGS,get,post; *.example.com,get
|!code|

|item| Three sources for authorization are specified in the following example. 
As the authentication source is VMS (by rights identifier), the full-access
group and read-only group can also be determined by possessing the specified
identifiers.  The first path can only be written to by those holding the
full-access identifier (librarian), the second path can only be read by both. 
The world has no access to these paths.

|code|
[DEVELOPER=id;PROJECT_A_LIBRARIAN=id;PROJECT_A_USER=id]
/web/projects/a/*  r+w
/web/projects/*    r
|!code|

|item| This example is the same as the one above, except in this case everyone
else (that can authenticate against the resource) gets read-only access to the
projects.

|code|
[DEVELOPER=id;PROJECT_A_LIBRARIAN=id;*]
/web/projects/a/*  r+w
/web/projects/*    r
|!code|

|item| In the following example the authentication realm and group are a single
HTA database, "ADMIN". The first directive allows those in the ADMIN group to
read and write, and the world to read ("get,post;get"). The second line
restricts write and even read access to ADMIN group, no world access at all
("get,post").

|code|
[ADMIN=hta]
/web/everyone/* get,post;get
/web/select/few/* get,post
|!code|

|item| With this example usernames are used to control access to the specified
paths. These usernames are authenticated from the COMPANY database.  The world
has read access in both cases.  Note the realm description, "The
Company".

|code|
["The Company"=COMPANY=hta]
/web/docs/* ~Howard,~George,~Fred,r+w ; r
/web/accounts/* ~George,r+w ; r
|!code|

|item| The following example shows a path specifying the local system's SYSUAF
being used to authenticate any usernames. Whenever using SYSUAF authentication
it is |*strongly recommended to limit the potential hosts| that can
authenticate in this way by always using a host-limiting access restriction
list. The world gets read access.

|code|
[VMS]
/web/local/area/* 131.185.250.*,r+w ; r
|!code|

|item| To restrict server administration to browsers executing on the server
system itself and the SYSUAF-authenticated username DANIEL use a restriction
list similar to the following.  It also shows the use of SYSUAF-authentication
being hidden by using a realm description.

|code|
["not the VMS SYSUAF"=VMS]
/httpd/-/admin/*  #localhost,~daniel,r+w
|!code|

|item| This example uses the RFC1413 |/identification protocol| as the
authentication source and a host group to control full access to paths in the
realm.

|code|
["Ident Protocol"=RFC1413;131.185.250.0/24]
/web/local/* r+w
|!code|

|item| The following example illustrates providing a read and writable area
(GET, POST and PUTable) to hosts in the local network |*without username
authentication| (careful!).

|code|
[WORLD]
/web/scratch/*  *.local.hosts.only,r+w
|!code|

|!number|

|3KISS|

|^ WASD authorization allows for very simple authorization environments and
provides the scope for quite complex ones.  The path authentication scheme
allows for multiple, individually-maintained authentication and authorization
databases that can then be administered by autonomous managers, applying to
widely diverse paths, all under the ultimate control of the overall Web
administrator.

|^ |*Fortunately great complexity is not generally necessary.|

|^ Most sites would be expected to require only an elementary setup allowing a
few selected Web information managers the ability to write to selected paths. 
This can best be provided with the one authentication database containing read
and write permissions against each user, with and access-restriction list
against individual paths.

|^ For example.  Consider a site with three departments, each of which wishes
to have three representatives capable of administering the departmental Web
information.  Authentication is via the SYSUAF.  Web administrators hold an
approriate VMS rights identifier, "WEBADMIN".  Department groupings are
provided by three simple lists of names, including the Web administrators
(whose rights identifier would not be applied if access control is via a simple
list), a fourth lists those with read-only access into the Finance area.  The
four grouping files would look like:

|code|
# Department 1            # Department 2
WEB1                      WEB1
WEB2                      WEB2
JOHN                      RINGO
PAUL                      CURLY
GEORGE                    LARRY

# Department 3            # Finance (read access)
WEB1                      PAUL
WEB2                      GEORGE
MOE                       JOHN
SHEMP                     RINGO
MAC
|!code|

|^ The authorization configuration file then contains:

|code|
#######################################################################

# allow web masters (!) to use the server administration facility
#                       to revise web configuration files
# world has no access (read or write)
# access is only allowed from a browser in the same subnet as the HTTPd
["Hypo Thetical Corp."=HYPOTHETICAL=vms;WEBADMIN=id]
/httpd/-/admin/*  #150.15.30.*,r+w
/wasd_root/local/*  #150.15.30.*,r+w

# allows Department 1 representatives to maintain their web
# this may only be done from within the company subnet
# world has read access
["Hypo Thetical Corp."=HYPOTHETICAL=vms;DEPARTMENT1=list]
/web/dept/general/*   150.15.30.*,r+w ; r

# and so on for the rest of the departments

["Hypo Thetical Corp."=HYPOTHETICAL=vms;DEPARTMENT2=list;FINANCE=list]
# no world read access into finance, only those in the FINANCE list
/web/dept/finance/*    150.15.30.*,r+w 

["Hypo Thetical Corp."=HYPOTHETICAL=vms;DEPARTMENT3=list]
/web/dept/inventory/*       150.15.30.*,r+w ; r
/web/dept/production/*      150.15.30.*,r+w ; r
# (the next uses line continuation just for illustration)
/web/dept/marketing/*       150.15.30.*,\\
                            r+w ;\\
                            read

# we need an area for general POSTing (just for illustration :-)
[WORLD]
/web/world/*  r+w 

#######################################################################
|!code|

|2Authorization Cache|

|^ Access to authentication sources, SYSUAF, simple lists and HTA databases,
are relatively expensive operations.  To reduce the impact of this activity on
request latency and general server performance, authentication and
realm-associated permissions for each authenticated username are stored in a
cache.  This means that only the initial request needs to be checked from
appropriate databases, subsequent ones are resolved more quickly and
efficiently from cache.

|^ Such cached entries have a finite lifetime associated with them.  This
ensures that authorization information associated with that user is regularly
refreshed.  This period, in minutes, is set using the [AuthCacheMinutes]
configuration parameter.  Zero disables caching with a consequent impact on
performance.

|0Implication|

|^ Where-ever a cache is employed there arises the problem of keeping the
contents current.  The simple lifetime on entries in the authentication cache
means they will only be checked for currency whenever it expires.  Changes may
have occured to the databases in the meantime.

|^ Generally there is are other considerations when adding user access. 
Previously the user attempt failed (and was evaluated each time), now the user
is allowed access and the result is cached.

|^ When removing or modifying access for a user the cached contents must be
taken into account.  The user will continue to experience the previous level of
access until the cache lifetime expires on the entry.  When making such changes
it is recommended to explicitly purge the authentication cache either from the
command line using /DO=AUTH=PURGE (|link|HTTPd Command Line||) or via the
Server Administration facility (|link|Server Administration||).  Of course the
other solution is just to disable caching, which is a less than optimal
solution.

|2SYSUAF-Authenticated Users|

|^ The ability to authenticate using the system's SYSUAF is controlled by the
server /SYSUAF[=keyword] qualifier. By default it is disabled.

|note><|
|0WARNING!|
|*SYSUAF authentication is not recommended except in the most secure
of LAN environments or when SSL is employed.|
|^- HTTP credentials (username and password) are transmitted as encoded
plain-text making them vulnerable to evesdropping.
|!note|

|^ By default accounts with SYSPRV authorized are always rejected to discourage
the use of potentially significant usernames (e.g. SYSTEM). This behaviour can
be changed through the use of specific identifiers, see |link|Rights
Identifiers| immediately below. Accounts that are disusered, have passwords
that have expired or that are captive or restricted are always rejected. 
Accounts that have access day/time restricting access will have those
restrictions honoured (see |link|Rights Identifiers| for a workaround for
this).

|^ Also see |link|Nil-Access VMS Accounts||.

|3ACME|

|^ By default the Authentication and Credential Management Extension (ACME) is
used to authenticate SYSUAF requests on Alpha and Itanium running VMS V7.3 or
later  (|link|Authentication Sources||). The advantage of ACME is with the
processing of the (rather complex) authentication requirements by a
vendor-supplied implementation.  It also allows SYSUAF password change to be
made subject to the full site policy (password history, dictionary checking,
etc.) which WASD does not implement.

|note><|
|0Should ACME be unavailable|
for whatever reason (x86-64 EAK for example) then define the logical name
WASD_NO_ACME to force reversion to SYSUAF authentication.
|!note|

|3Logon Type|

|^ By default SYSUAF authentication uses the NETWORK access restriction from
the account SYSUAF record.  Alternatives LOCAL, DIALUP and REMOTE may be
specified using global configuration directive

|code|
# WASD_CONFIG_GLOBAL
[AuthSYSUAFlogonType]  REMOTE
|!code|

and/or authorization rule parameter 'param="logon=REMOTE"'

|code|
["VMS Credentials"=WASD_VMS_RW=ID]
/secured/* r+w,https,param="logon=REMOTE"
|!code|

(which takes precedence).

|3Rights Identifiers|

|^ Whether or not any particular username is allowed to authenticate via the
SYSUAF may be controlled by that account holding or not holding a particular
VMS rights identifier. When a username has been authenticated via the SYSUAF,
rights identifiers associated with that account may be used to control the
level-of-access within that realm.

|^ Use of identifiers for these purposes are enabled using the /SYSUAF=ID
server startup qualifier.

|^ The first three reserved identifier names are optional.  A warning will be
reported during startup if these are not found.  The fourth must exist if
SYSUAF proxy mappings are used in a /SYSUAF=ID environment.

|bullet|

|item| |*WASD_HTTPS_ONLY |-| | restricts accounts holding it to authenticating
using SSL (https:).  Authentication via a standard "http:" will always be
denied.

|item| |*WASD_NIL_ACCESS |-| | allows accounts with access time restrictions to
authenticate via the SYSUAF.  This is particularly intended to support the use
of nil-access accounts, see |link|Nil-Access VMS Accounts||.

|item| |*WASD_PASSWORD_CHANGE |-| | allows an account to modify its SYSUAF
password, if this is configured for the server, see |link|User Password
Modification||.

|item| |*WASD_PROXY_ACCESS |-| | allows an account to be used for proxy access if
/SYSUAF=ID is in effect, see |link|VMS Account Proxying||.

|!bullet|

|^ Identifiers may be managed using the following commands.  If unsure of the
security implications of this action consult the relevant VMS system management
security documentation.

|code|
$ SET DEFAULT SYS$SYSTEM
$ MCR AUTHORIZE
UAF> ADD /IDENTIFIER WASD_HTTPS_ONLY
UAF> ADD /IDENTIFIER PROJECT_USER
UAF> ADD /IDENTIFIER PROJECT_DEVELOPER
UAF> ADD /IDENTIFIER PROJECT_LIBRARIAN
|!code|

|^ They can then be provided to desired accounts using commands similar to the
following:

|code|
UAF> GRANT /IDENTIFIER PROJECT_USER <account>
|!code|

and removed using:

|code|
UAF> REVOKE /IDENTIFIER PROJECT_USER <account>
|!code|

|^ Be aware that, as with all successful authentications, and due to the WASD
internal authentication cache, changing database contents does not immediately
affect access.  Any change in the RIGHTSLIST won't be reflected until the cache
entry expires or it is explicitly flushed
(|\|link|<REFERENCE>(hd_auth_cache)||).

|3WASD "Hard-Wired" Identifiers|

|note><|
|0Deprecated and Discouraged|
As this has been deprecated for some years now the documentation for this
functionality has been removed.
|!note|

|3VMS Account Proxying|
 
|^ Any authentication realm can have its usernames mapped into VMS usernames
and the VMS username used as if it had been authenticated from the SYSUAF.
This is a form of proxy access.

|note|
|0CAUTION|
This is an extremely powerful mechanism and as a consequence requires enabling
on the command-line at server startup using the /SYSUAF=PROXY qualifier and
keyword.  If identifiers are used to control SYSUAF authentication (i.e.
/SYSUAF=ID) then any account mapped by proxy access must hold the
WASD_PROXY_ACCESS identifier described in |link|Rights Identifiers|| (and
server startup would be something like "/SYSUAF=(ID,PROXY)").
|!note|

|^ When a proxy mapping occurs request user authorization detail reflects the
SYSUAF username characteristics, not the actual original authentication source. 
This includes username, user details (i.e. becomes that derived from the
|/owner| field in the SYSUAF), constraints on the username access (e.g. SSL
only), and user capabilities including any profile if enabled.  Authorization
source detail remains unchanged, reflecting the realm, realm description and
group of the original source.  For CGI scripting an additional variable,
WWW_AUTH_REMOTE_USER, provides the original remote username.

|^ For each realm, and even for each path, a different collection of mappings
can be applied.  Proxy  entries are strings containing no white space.  There
are three basic variations, each with an optional host or network mask
component.

|simple#|
|item| remote[@host\|@network/mask]=SYSUAF
|item| *[@host\|@network/mask]=SYSUAF
|item| *[@host\|@network/mask]=*
|!number|

|^ The "SYSUAF" is the VMS username being mapped to.  The |/remote|  is the
remote username (CGI variable WWW_REMOTE_USER).  The first variation maps a
matching  remote username (and optional host/network) onto the specific SYSUAF
username.  The second maps all remote usernames (and optional host/network) to
the one SYSUAF username (useful as a final mapping).  The third maps all remote
usernames (optionally on the remote host/network) into the same SYSUAF username
(again useful as a final mapping if there is a one-to-one equivalence between
the systems).

|^ Proxy mappings are processed sequentially from first to last until a
matching rule is encountered.  If none is found authorization is denied. 
Match-all and default mappings can be specified.

|code|
[RFC1413]
[AuthProxy] bloggs@131.185.250.1=fred
[AuthProxy] doe@131.185.250.*=john system=- *@131.185.252.0/24=*
[AuthProxy] *=GUEST
|!code|

|^ In this example the username |/bloggs| on system 131.185.250.1 can access
as if the request had been authenticated via the SYSUAF using the username and
password of |/FRED||, although of course no SYSUAF username or password needs
to  be supplied.  The same applies to the second mapping, |/doe| on the remote
system to |/JOHN| on the VMS system.  The third mapping disallows a |/system||
account ever being mapped to the VMS equivalent.  The fourth, wildcard mapping,
maps all accounts on all systems in 131.185.250.0 8 bit subnet to the same VMS
username on the server system.  The fifth mapping provides a default username
for all other remote usernames (and used like this would terminate further
mapping).

|^ Note that multiple, space-separated proxy entries may be placed on a single
line.  In this case they are processed from left to right and first to last.

|code|
["Just an Example"=EXAMPLE=list]
[AuthProxy] bloggs@131.185.250.1=fred doe@131.185.250.1=doe system=- \\
*@131.185.252.0/24=* *=GUEST
|!code|

|^ Proxy mapping rules should be placed after a realm specification and before
any authorization path rules in that realm.  In this way the mappings will
apply to all rules in that realm.  It is possible to change the mappings
between rules.  Just insert the new mappings before the (first) rule they apply
to.  This cancels any previous mappings and starts a new set.  This is an
example.

|code|
["A Bunch of Users"=USERS=hta]
[AuthProxy] bloggs@131.185.250.1=fred doe@131.185.250.1=john
/fred/and/johns/path/* r+w
[AuthProxy] *=GUEST
/other/path/* read
|!code|

|^ An alternative to in-line proxy mapping is to provide the mappings in one
or more independent files.  In-line and in-file mappings may be combined.

|code|
["Another Bunch of Users"=MORE_USERS=hta]
[AuthProxy] SYSTEM=-
[AuthProxyFile]  WASD_ROOT:[LOCAL]PROXY.CONF
/path/for/proxy* r+w
|!code|

|^ To cancel all mappings for following rules use an [AuthProxy] (with no
following mapping detail).  Previous mappings are always cancelled with the
start of a new realm specification.  Where proxy mapping is not enabled at the
command line or a proxy file cannot be loaded at startup a proxy entry is
inserted preventing |*all access| to the path.

|^ |*REMEMBER |-| | proxy processing can be observed using the WATCH facility.

|3Nil-Access VMS Accounts|

|^ It is possible, and may be quite effective for some environments, to have a
SYSUAF account or accounts strictly for HTTP authorization, with no actual
interactive or other access allowed to the VMS system itself.  This would relax
the caution on the use of SYSUAF authentication outside of SSL transactions. An
obvious use would be for the HTTP server administrator.  Additional accounts
could be provided for other authorization requirements, all without
compromising the system's security.

|^ In setting up such an environment it is vital to ensure the HTTPd server is
started using the /SYSUAF=ID qualifier (|link|Authentication Policy||).  This
will require all SYSUAF-authenticated accounts to possess a specific VMS
resource identifier, accounts that do not possess the identifier cannot be used
for HTTP authentication.  In addition the identifier WASD_NIL_ACCESS will need
to be held (|link|Rights Identifiers||), allowing the account to authenticate
despite being restricted by REMOTE and NETWORK time restrictions.

|^ To provide such an account select a group number that is currently unused
for any other purpose.  Create the desired account using whatever local utility
is used then activate VMS AUTHORIZE and effectively disable access to that
account from all sources and grant the appropriate access identifier (see
|link|Rights Identifiers| above).

|code|
$ SET DEFAULT SYS$SYSTEM
$ MCR AUTHORIZE
UAF> MODIFY <account> /NOINTERACTIVE /NONETWORK /NOBATCH /FLAG=DISMAIL
UAF> GRANT /IDENTIFIER WASD_NIL_ACCESS <account>
UAF> GRANT /IDENTIFIER WASD_VMS_RW <account>
|!code|

|3SYSUAF and SSL|

|^ When SSL is in use (|link|Transport Layer Security||) the username/password
authentication information is inherently secured via the encrypted
communications of SSL. To enforce access to be via SSL add the following to the
WASD_CONFIG_MAP configuration file:

|code|
/whatever/path/you/like/*  "403 Access denied."  ![sc:https]
|!code|

or alternatively the following to the WASD_CONFIG_AUTH configuration file:

|code|
[REALM]
/whatever/path/you/like/*  https:
|!code|

|^ Note that this mechanism is applied |*after| any path and method assessment
made by the server's authentication schema.

|^ The qualifier /SYSUAF=SSL provides a powerful mechanism for protecting
SYSUAF authentication, restricting SYSUAF authenticated transactions to the SSL
environment.  The combination /SYSUAF=(SSL,ID) is particularly effective.

|^ Also see |link|Authentication Policy||.

|3SYSUAF Security Profile|

|^ It is possible to control access to files and directories based on the VMS
security profile of a SYSUAF-authenticated remote user. This functionality is
implemented using VMS security system services involving SYSUAF and RIGHTSLIST
information. The feature must be explicitly allowed using the server /PROFILE
qualifier. By default it is disabled.

|note|
Use caution when deploying the /PROFILE qualifier.  It was really designed with 
a very specific environment in mind, that of an Intranet where the sole purpose
was to provide VMS users access to their normal VMS resources via a Web
interface.
|!note|

|^ When a SYSUAF-authenticated user (i.e. the VMS realm) is first authenticated
a VMS security-profile is created and stored in the authentication cache
(|link|Authorization Cache||). A cached profile is an efficient method of
implementing this as it obviously removes the need of creating a user profile
each time a resource is assessed. If this profile exists in the cache it is
attached to each request authenticated for that user. As it is cached for a
period, any change to a user's security profile in the SYSUAF or RIGHTSLIST
won't be reflected in the cached profile until the cache entry expires or it is
explicitly flushed (|link|HTTPd Server Action||).

|^ When a request has this security profile all accesses to files and
directories are assessed against it. When a file or directory access is
requested the security-profile is employed by a VMS security system service to
assess the access. If allowed, it is provided via the SYSTEM file protection
field. Hence it is possible to be eligible for access via the OWNER field but
not actually be able to access it because of SYSTEM field protections! If not
allowed, a "no privilege" error is generated.

|^ Once enabled using /PROFILE it can be applied to all SYSUAF authenticated
paths, but must be enabled on a per-path basis, using the WASD_CONFIG_AUTH
|/profile| keyword (|link|Access Restriction Keywords||) 

|code|
# WASD_CONFIG_AUTH
[VMS;VMS]
/wasd_root/local/* profile,https:,r+w
|!code|

or the WASD_CONFIG_MAP SET |/profile| and |/noprofile| mapping rules
(see |link%|../config/##SET Rule++of++WASD Configuration||).

|code|
# WASD_CONFIG_MAP
set /wasd_root/local/* profile
set * noprofile
|!code|

|^ Of course, this functionality only provides access for the server, IT DOES
NOT PROPAGATE TO ANY SCRIPT ACCESS. If scripts must have a similar ability
they should implement their own scheme (which is not too difficult,
see |link%|/wasd_root/src/misc/chkacc.c|WASD_ROOT:[SRC.MISC]CHKACC.C||)
based on the CGI variable WWW_AUTH_REALM which would be "VMS" indicating
SYSUAF-authentication, and the authenticated name in WWW_REMOTE_USER.

|0Performance Impact|

|^ If the /PROFILE qualifier has enabled SYSUAF-authenticated security
profiles,  whenever a file or directory is assessed for access an explicit VMS
security system service call is made.  This call builds a security profile of
the object being assessed, compares the cached user security profile and
returns an indication whether access is permitted or forbidden.  This is
addition to any such assessments made by the file system as it is accessed.

|^ This extra security assessment is not done for non-SYSUAF-authenticated
accesses within the same server.

|^ For file access this extra overhead is negligible but becomes more
significant with directory listings ("Index of") where each file in the
directory is independently assessed for access.

|3SYSUAF Profile For Full Site Access|

|^ Much of a site's package directory tree is inaccessible to the server
account.  One use of the SYSUAF profile functionality is to allow authenticated
accesss to all files in that tree.  This can accomplished by creating a
specific mapping for this purpose, subjecting that to SYSUAF authentication
with /PROFILE behaviour enabled (|link|SYSUAF Security Profile||), and limiting
the access to a SYSTEM group account.  As all files in the WASD package are
owned by SYSTEM the security profile used allows access to all files.

|^ The following example shows a path with a leading dollar (to differentiate
it from general access) being mapped into the package tree.  The
"set * noprofile" limits the application of this to the /$WASD_ROOT/
path (with the inline "profile").

|code|
# WASD_CONFIG_MAP
set * noprofile
  .
  .
  .
pass /wasd_root/* /wasd_root/*
pass /$WASD_ROOT/* /wasd_root/* profile
|!code|

|^ This path is then subjected to SYSUAF authentication with access limited to
an SSL request from a specific IP address (the site administrator's) and the
SYSTEM account.

|code|
# WASD_CONFIG_AUTH
[["/$WASD_ROOT/ Access"=WASD_TREE_ACCESS=id]]
/$WASD_ROOT/* https,10.1.1.2,~system,read
|!code|

|2Token Authentication|

|^ This is a niche authorisation environment for addressing niche requirements.

|^ A |/token| is an HTTP cookie delivered representation of authentication
established in another context.  Originally devised to allow controlled access
to very large datasets without the overhead of SSL in the transmission but with
access credentials supplied in the privacy of an SSL connection.

|^ A common scenario is where the client starts off attempting to access a
resource in non-SSL space which is controlled by token authentication.  In the
first instance the authenticator detects there is no access token present and
redirects the client (browser) to the SSL equivalent of that space, where
credentials can be supplied encrypted.  In this example scenario the SSL area
is controlled by WASD SYSUAF authentication (can be SSL client certificate,
etc.) and the username/password is prompted for.  When correctly entered this
generates a token.  The token is stored (with corresponding detail) as a record
in a server-internal database and then returned to the browser as a set-cookie
value.

|^ With the token data stored the browser is transparently redirected back to
the non-SSL space where the actual access is to be undertaken, this time the
browser presenting the cookie containing the token.  The authenticator examines
the token, looking it up in the database.  If found, has originated from the
same IP address, represents the same authentication realm, and has not expired,
it then allows the non-SSL space access to proceed, and in this example
scenario the dataset transfer is initiated (in unencrypted clear-text).  If the
token is not found in the database or has expired, then the process is repeated
with a redirect back into SSL space.  If the realms differ a 403 forbidden
response is issued (see configuration below).

|^ The token itself is a significant sequence of pseudo-random characters, is
short-lived (configurable as anything from a few seconds to a few tens of
seconds, or more), and as a consequence is frequently regenerated.  The token
is just that, containing no actual credential data at all.  It might be
possible to snoop but as it contains nothing of value in itself, expires
relatively quickly, and has an originating IP address check, the fairly remote
risk of playback is just that.

|^ The authenticator does all the work, implicitly redirecting the user
from non-SSL space to SSL space for the original authentication, and then
back again with the token used for access in the non-SSL space.  With the
expiry of a token it undertakes that cycle again, redirecting back to the
SSL-space where the browser-cached credentials will be supplied automatically
allowing the fresh token to be issued, and then redirected back into non-SSL
space for access.  To emphasise - all this is transparent to the user.

|^ As a consequence of this model the resource being controlled can ONLY be
accessed from non-SSL space using the controlled path.  To access the same
resource from SSL space a distinct path to the resource must be provided.

|0Configuration|

|^ As token authorisation relies on the client agent having HTTP cookies
enabled (globally or specifically for the site) it is useful to have this
tested for and/or advised about, on some related but other area of the site. 
There are simple techniques using JavaScript for detecting the availability of
cookie processing.  Search the Web for a suitable solution.
 
|^ The automatic authorisation and redirection occurs using a combination of
two distinguishable authorisation rules, one for supplying the credentials, the
other for using the token for authorisation.  In this example (and commonly)
the resources are at "/location/" and the configuration accepts user-supplied
credentials in SSL space and uses the token in non-SSL space.  The asterisk
just indicates that in the absence of any other parameter this authorisation
rule has a complementary token rule where access will actually occur.

|code|
# WASD_CONFIG_AUTH
if (ssl:) 
   ["VMS credentials"=WASD_VMS_RW=id+"TOKEN=*"]
   /location/* r+w
else
   [WASD_VMS_RW=TOKEN]
   /location/* r+w
endif
|!code|

|^ And in this example, the same arrangement but with non-standard ports
(specified using an integer with a leading colon).

|code|
# WASD_CONFIG_AUTH
if (ssl:) 
   ["VMS credentials"=WASD_VMS_RW=id+"TOKEN=:7080"]
   /location/* r+w
else
   [WASD_VMS_RW=TOKEN+"TOKEN=:7443"]
   /location/* r+w
endif
|!code|

|^ To prevent potential thrashing, where multiple, distinct realms within a
|/single| request are authorised using tokens, corresponding multiple token
(cookie) names must be used.  It is expected that this would be an uncommon but
not impossible scenario.  The "thrashing" would be a result of authorisation
associated with a single, particular token name.  Where a realm differs from a
previous token generated another is required.  The token authorisation scheme
forces the use of distinct token names by 403-forbidding change of realm using
the one token.   Use explicitly specified, independent token (cookie) names, or
an integer preceded by an ampersand (which appends the integer to the base
token name), ensuring the complementary rules are using the same name/integer.

|code|
# WASD_CONFIG_AUTH
if (ssl:) 
   ["VMS credentials"=WASD_VMS_RW=id+"TOKEN=&42"]
   /location/* r+w
else
   [WASD_VMS_RW=TOKEN+"TOKEN=&42"]
   /location/* r+w
endif
|!code|

|^ For the final example, the token is contained in the non-default cookie
named "Wasd_example" and the authentication performed using an X509 client
certificate (which can only be supplied via SSL).

|code|
# WASD_CONFIG_AUTH
if (ssl:) 
   [X509+"TOKEN=WaSd_example"]
   /location/* r+w
else
   [X509=TOKEN+"TOKEN=WaSd_example"]
   /location/* r+w
endif
|!code|

|^ Some additional detail is available from the AUTHTOKEN.C code module.

|2Skeleton-Key Authentication|

|^ Provides a username and password that is authenticated from data placed into
the global common (i.e. in memory) by the site administrator.  The username and
password expire (become non-effective) after a period, one hour by default or
an interval specified when the username and password are registered.

|^ It is a method for allowing ad hoc authenticated access to the server,
primarily intended for non-configured access to the online Server
Administration facilities (|link|Access Before Configuration||) but is
available for other purposes where a permanent username and password in an
authentication database is not necessary. A skeleton-key authenticated request
|*is subject to all other authorization processing| (i.e. access restrictions,
etc.), and can be controlled using the likes of '~_*', etc.

|^ The site administrator uses the command line directive

|code|
$ HTTPD /DO=AUTH=SKELKEY=|/_username:password[:period]|
|!code|

to set the username/password, and optionally the period in minutes.  This
authentication credential can be cancelled at any time using

|code|
$ HTTPD /DO=AUTH=SKELKEY=0
|!code|

|^ The username must begin with an underscore  (to reduce the chances of
clashing with a legitimate username) and have a minimum of 6 other characters. 
The password is delimited by a colon and must be at least 8 characters.  The
optional period in minutes can be from 1 to 10080 (one week).  If not supplied
it defaults to 60 (one hour).  After the period expires the skeleton key is no
longer accepted until reset.

|note><|
Choose username and password strings that are less-than-obvious and a period
that's sufficient to the task!
|^- After all, it's |*your site| that you might compromise!
|!note|

|^ The authentication process (with skeleton-key) is performed using these
basic steps.

|number|

|item| Is a skeleton-key set?  If not continue on with the normal authentication
process.

|item| If set then check the request username leading character for an
underscore.  If not then continue on with normal authentication.

|item| If it begins with an underscore then match the request and skeleton-key
usernames.  If they do not match then continue with normal authentication.

|item| If the usernames match then compare the request and skeleton-key
passwords.  If matched then it's authenticated.  If not it becomes an
authentication failure.

|!number|

|^ Note that the authenticator resumes looking for a username from a
configured authentication source unless the request and skeleton-key usernames
match.  After that the passwords either match allowing access or do not match
resulting in an authentication failure.

|0Examples|

|code|
$ HTTPD /DO=AUTH=SKELKEY=_FRED2ACC:USE82PA55

$ HTTPD /DO=AUTH=SKELKEY=_ANDY2WERP:EGGO4TEE:10
|!code|

|2Controlling Server Write Access|

|^ The server account should have no direct write access to into any directory
structure. Files in these areas should be owned by SYSTEM ([1,4]). Write access
for the server into VMS directories (using the POST or PUT HTTP methods) should
be controlled using VMS ACLs. |*This is in addition to the path authorization
of the server itself of course!| The recommendation to have no ownership of
files and provide an ACE on required directories prevents inadvertant
mapping/authorization of a path resulting in the ability to write somewhere not
intended.

|^ Two different ACEs implement two grades of access.

|number|

|item| If the ACE grants |*CONTROL| access to the server account
then only VMS-authenticated usernames with security profiles can potentially
write to the directory. Only potentially, because a further check is made to
assess whether that VMS account in particular has write access.

|^ This example shows a suitable ACE that applies only to the original
directory:

|code|
$ SET SECURITY directory.DIR -
  /ACL=(IDENT=HTTP$SERVER,ACCESS=READ+WRITE+EXECUTE+DELETE+CONTROL)
|!code|
|
This example shows setting an ACE that will propagate to created files and
importantly, subdirectories:
|
|code|
$ SET SECURITY directory.DIR -
  /ACL=((IDENT=HTTP$SERVER,OPTIONS=DEFAULT,ACCESS=READ+WRITE+EXECUTE+DELETE+CONTROL), -
        (IDENT=HTTP$SERVER,ACCESS=READ+WRITE+EXECUTE+DELETE+CONTROL))
|!code|

|item| If the ACE grants |*WRITE| access then the directory can be
written into by any authenticated username for the authorized path.

|^ This example shows a suitable ACE that applies only to the original
directory:

|code|
$ SET SECURITY directory.DIR -
  /ACL=(IDENT=HTTP$SERVER,ACCESS=READ+WRITE+EXECUTE+DELETE)
|!code|
 This example shows setting an ACE that will propagate to created files
and importantly, subdirectories:

|code|
$ SET SECURITY directory.DIR -
  /ACL=((IDENT=HTTP$SERVER,OPTIONS=DEFAULT,ACCESS=READ+WRITE+EXECUTE+DELETE), -
        (IDENT=HTTP$SERVER,ACCESS=READ+WRITE+EXECUTE+DELETE))
|!code|

|!number|

|^ To assist with the setting of the required ACEs an example,
general-purpose DCL procedure is provided,
|link%|/wasd_root/example/authace.com|WASD_ROOT:[EXAMPLE]AUTHACE.COM||).

|2Securing All Requests|

|^ Some sites may be sensitive enough about Web resources that the possibility
of providing inadvertant access to some area or another is of major concern. 
WASD provides a facility that will automatically deny access to any path that
does not appear in the authorization configuration file.  This does mean that
all paths requiring access must have authorization rules associated with them,
but if something is missed some resource does not unexpectedly become visible.

|^ At server startup the /AUTHORIZE=ALL qualifier enables this facility.

|^ For paths that require authentication and authorization the standard realms
and rules apply.  To indicate that a particular path should be allowed access,
but that no authorization applies the "NONE" realm may be used.  The following
example provides some indication of how it should be used.

|code|
# allow the librarian to update this area, world to read it
[VMS;LIBRARIAN=id]
/web/library/* r+w ; read
# indicate there is no authorization to be applied
[NONE]
# allow access to general web areas
/web/* read
# allow access to the WASD_ROOT tree
/wasd_root/* read
|!code|

|^ There is also a per-path equivalent of the /AUTHORIZE=ALL functionality,
described in |link%|../config/##SET Rule++of++WASD Configuration||).
This allows a path tree to be require authorization be enabled against it.

|code|
# avoid an absence of authorization allowing unintentional access
set /web/sensitive/* auth=all
|!code|

|2User Password Modification|

|^ The server provides for users to be able to change their own HTA passwords
(and SYSUAF if required). This functionality, though desirable from the
administrator's viewpoint, is not  mandatory if the administrator is content to
field any password changes, forgotten passwords, etc.  Keep in mind that
passwords, though not visible during entry, are passed to the server using
clear-text form fields (which is why SSL is recommended).

|^ Password modification is enabled by including a mapping rule to the internal
change script.  For example:

|code|
pass /httpd/-/change/* /httpd/-/change/*
|!code|

|^ Any database to be enabled for password modification must have a writable
authorization path associated with it.  For example:

|code|
[GROUP=id;GROUP=id]
/httpd/-/change/group/* r+w

[ANOTHER_GROUP=id;ANOTHER_GROUP=id]
/httpd/-/change/another_group/* r+w
|!code|

|note|
What looks like redundancy in specifying an identical realm and group
authorization is what allows multiple, independant identifiers to be
individually controlled for password change (i.e. one group of identifier
holders allowed to change the password, another not). 
|!note|


|^ Use some form of cautionary wrapper if providing this functionality over
something other than an Intranet or SSL connection:

|code|
<H2>Change Your Authentication</H2>

<blockquote>
Change the password used to identify yourself to the REALM Web environment for
some actions.  Note that this <u>not</u> an operating system password, nor has
it anything to do with it.  Due to the inherent weaknesses of using
non-encrypted password transmissions on networks <font color="#ff0000"><u>DO
NOT</U> use a password you have in use anywhere else, especially an operating
system password!</font> You need your current password to make the change.  If
you have forgotten what it is contact <a href="/web/webadmin.html">WebAdmin</a>,
preferably via e-mail, for the change to be made on your behalf.
</blockquote>

<ul>
<li><a href="/httpd/-/change/REALM/">REALM</a> realm.
</ul>
|!code|

|0Password Expiry|

|^ When using SYSUAF authentication it is possible for a password to
pre-expired, or when a password lifetime is set for a password to expire and
require respecification.  By default an expired password cannot be used for
access.  This may be overridden using the following global configuration
directive.

|code|
[AuthSYSUAFacceptExpPwd]  enabled
|!code|

|^ Expired passwords may be specially processed by specifying a URL with
WASD_CONFIG_GLOBAL [AuthSysUafPwdExpURL] configuration directive 
|link%|../config/##Alphabetic Listings++of++WASD Configuration||).

|^ The WASD_CONFIG_MAP |/set auth=sysuaf=pwdexpurl=<string>| rule allows the
same URL to be specified on a per-path basis. When this is set a request
requiring SYSUAF authentication that specifies a username with an expired
password is redirected to the specified URL.  This should directly or via an
explanatory (wrapper) page redirect to the password change path described
above.  The password change dialog will have a small note indicating the
password has expired and allows it to be changed.

|^ The following WASD_CONFIG_GLOBAL directive

|code|
# WASD_CONFIG_GLOBAL
[AuthSysUafPwdExpURL]  https:///httpd/-/change/

# WASD_CONFIG_AUTH
[WASD_VMS_ID=id;WASD_VMS_RW=id]
/httpd/-/change/* r+w
|!code|
 would allow expired passwords to be changed.

|^ It is also possible to redirect an expired password to a site-specific page
for input and change.  This allows some customization of the language and
content of the expired password change dialog.  An example document is provided
at |link%|/wasd_root/example/expired.shtml?httpd=content&type=text/plain|\
WASD_ROOT:[EXAMPLE]EXPIRED.SHTML| (|link%|/wasd_root/example/expired.shtml|what
it looks like||) ready for relocation and customisation.  Due to the
complexities of passing realm information and then submitting that information
to the server-internal change facility some dynamic processing is required via
an SSI document.

|^ This example assumes the site-specific document has been located at
WEB:[000000]EXPIRED.SHTML and is accessed using SSL.

|code|
# WASD_CONFIG_GLOBAL
[AuthSysUafPwdExpURL]  https:///web/expired.shtml?httpd=ignore&realm=vms

# WASD_CONFIG_AUTH
[WASD_VMS_ID=id;WASD_VMS_RW=id]
/httpd/-/change/vms/* r+w
/web/expired.shtml r+w
|!code|

|2Cancelling Authorization|

|^ The reason authorization information is not required to be reentered on
subsequent accesses to controlled paths is cached information the browser
maintains.  It is sometimes desirable to be able to access the same path using
different authentication credentials, and correspondingly it would be useful if
a browser had a |/purge authorization cache| button, but this is commonly not
the case.  To provide this functionality the server must be used to "trick" the
browser into cancelling the authorization information for a particular path.

|^ This is achieved by adding a specific query string to the path requiring
cancellation.  The server detects this and returns an authorization failure
status (401) regardless of the contents of request "Authorization:" field. 
This results in the browser flushing that path from the authorization cache,
effectively requiring new authorization information the next time that path is
accessed.

|^ There are two variations on this mechanism.

|number|

|item| The basic procedure is as follows:

|bullet|

|item| Add the query string "?httpd=logout" to the path in question (if
there is an existing query then replace it), as in the following example.
|code|
/the/current/path?httpd=logout
|!code|

|item| The browser will respond with an authorization failure, and prompting to
retry or reenter the username and password.

|item| It is necessary to clear at least the password (i.e. remove any password
from the appropriate field) and reenter.

|item| The browser again responds with an authorization failure.

|item| At this stage the authorization dialog can be cancelled, resulting in a
server authorization failure message.

|item| The original path can now be returned to and reaccessed.  The browser
should again prompt for authorization information at which point different
credentials may be supplied.

|!bullet|

|item| A little more functional, if using a revalidation period via
[AuthRevalidateUserMinutes]  or 'SET auth=revalidate=' (perhaps set to
something like 23:59:00, or one day), when the logout query string is supplied
the server resets the entry forcing any future access to require revalidation. 
A successful logout message is then generated, circumventing the need for the
username/password dialog described above. 

|bullet|

|item| Add or replace the query string "?httpd=logout" to the path in
question as in the following example. 
|code|
/the/current/path?httpd=logout
|!code|

|item| The browser will respond with a message stating that authentication has
been cancelled.  That's it!

|!bullet|

|^ Also when using logout with a revalidation period a redirection URL may be
appended to the logout query string.  It then redirects to the supplied URL. 
It is important that the redirection is returned to the browser and not handled
internally by WASD.  Normal WASD redirection functionality applies.

|code|
?httpd=logout&goto=///
?httpd=logout&goto=///help/logout.html
?httpd=logout&goto=http://the.host.name/
|!code|

|^ These examples redirect to

|simple#|
|& the local home page
|& a specific local page
|& a specific remote server
|!simple|

respectively.

|note|
|0Authentication Cache|
User revalidation relies on an entry being maintained in the authentication
cache.  Each time the entry is flushed, for whatever reason (cache congestion,
command-line purge, server restart, etc.), the user will be prompted for
credentials.  It may be necessary to increase the size of the cache by
adjusting [AuthCacheEntriesMax].
|!note|

|!number|