This file is indexed.

/usr/include/dacs/auth.h is in libdacs-dev 1.4.28b-3ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
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
/*
 * Copyright (c) 2003-2012
 * Distributed Systems Software.  All rights reserved.
 * See the file LICENSE for redistribution information.
 *
 * $Id: auth.h 2594 2012-10-19 17:28:49Z brachman $
 */

/*****************************************************************************
 * COPYRIGHT AND PERMISSION NOTICE
 * 
 * Copyright (c) 2001-2003 The Queen in Right of Canada
 * 
 * All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, and/or sell
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, provided that the above copyright notice(s) and this
 * permission notice appear in all copies of the Software and that both the
 * above copyright notice(s) and this permission notice appear in supporting
 * documentation.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE 
 * BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
 * SOFTWARE.
 * 
 * Except as contained in this notice, the name of a copyright holder shall not
 * be used in advertising or otherwise to promote the sale, use or other
 * dealings in this Software without prior written authorization of the
 * copyright holder.
 ***************************************************************************/

#ifndef _AUTH_H_
#define _AUTH_H_

#include "local.h"

/* For byteorder stuff */
#include <netinet/in.h>
#include <sys/param.h>

/*
 * For Rijndael (AES), these three key sizes are valid:
 * 128 bits (16 bytes), 192 bits (24 bytes), and 256 bits (32 bytes)
 */
enum {
  AUTH_CRYPT_KEY_LENGTH = 16		/* in bytes */
};

/* Do not change these unless you understand exactly how they are used. */
enum {
  /*
   * A minimum random padding length of zero is allowed but is unwise and
   * may compromise security.  Use at least 8.
   * The maximum length should be "significant" but not so much as to
   * make cookies very large.
   */
  AUTH_MIN_RANDOM_PADDING_LENGTH	= 8,
  AUTH_MAX_RANDOM_PADDING_LENGTH    = 37,
  AUTH_MAX_CREDENTIALS				= 10,
  AUTH_MAX_ROLE_STR_LENGTH			= 200,
  AUTH_CREDENTIALS_UNIQUE_BYTES     = 8,

  /*
   * This selects the method to use for generating IVs for encryption.
   * See crypt.c:make_iv()
   */
  AUTH_USE_RANDOMIZED_IV		    = 0,

  /* Number of seconds to delay if authentication fails */
  AUTH_DEFAULT_FAIL_DELAY_SECS      = 8
};

/*
 * Raw USERNAME/PASSWORD/AUXILIARY limits - see auth.c
 * These are intended to be reasonable upper limits, but they may be
 * adjusted if necessary.
 */
enum {
  AUTH_MAX_INPUT_USERNAME_LENGTH    = 64,
  AUTH_MAX_INPUT_PASSWORD_LENGTH    = 128,
  AUTH_MAX_INPUT_AUX_LENGTH         = 128
};

/*
 * Bit flags
 * See authlib.c:auth_style_from_string()
 */
#define AUTH_STYLE_PASSWORD   (1 <<  0)
#define AUTH_STYLE_CERT       (1 <<  1)
#define AUTH_STYLE_PROMPTED   (1 <<  2)
#define AUTH_STYLE_NATIVE     (1 <<  3)
#define AUTH_STYLE_EXPR       (1 <<  4)
#define AUTH_STYLE_ADMIN      (1 <<  5)
#define AUTH_STYLE_IMPORTED   (1 <<  6)
#define AUTH_STYLE_ALIEN      (1 <<  7)
#define AUTH_STYLE_GENERATED  (1 <<  8)
#define AUTH_STYLE_DIGEST     (1 <<  9)
#define AUTH_STYLE_CAS        (1 << 10)
#define AUTH_STYLE_SIMPLE     (1 << 11)
#define AUTH_STYLE_ACS        (1 << 12)
#define AUTH_STYLE_MINFOCARD  (1 << 13)
#define AUTH_STYLE_SINFOCARD  (1 << 14)
#define AUTH_STYLE_INFOCARD   (1 << 15)
#define AUTH_STYLE_RLINK      (1 << 16)
#define AUTH_STYLE_SET_ROLES  (1 << 17)
#define AUTH_STYLE_ADD_ROLES  (1 << 18)
#define AUTH_STYLE_UNKNOWN    (1 << 19)

typedef int Auth_style;

/* Prefix of variable names used for prompting. */
#define AUTH_PROMPT_VAR_PREFIX      "AUTH_PROMPT_VAR"

#define AUTH_VALID_FOR_ACS			"acs"
#define AUTH_VALID_FOR_CHAINING		"chaining"
#define AUTH_VALID_FOR_IDENT		"ident"
#define AUTH_VALID_FOR_TRANSFER		"transfer"
#define AUTH_VALID_FOR_NOTHING		"nothing"

/*
 * This is the default lifetime, in seconds, of DACS admin credentials.
 * They are used in certain internal (DACS-to-DACS) transactions.
 * Although they are only supposed to be held by trusted components, because
 * they can convey special privileges their lifetime should not be any
 * longer than necessary.  It is sometimes necessary to increase this lifetime
 * when debugging or if a recipient server is slow.
 */
#define AUTH_CREDENTIALS_ADMIN_DEFAULT_LIFETIME_SECS	"20"

/*
 * At least one of these two strings must contain one or more characters
 * that are rejected by is_valid_auth_username().
 * Do not change these unless you fully understand how they are used.
 */
#define AUTH_ADMIN_USERNAME_PREFIX_STR	"*"
#define AUTH_ADMIN_USERNAME_SUFFIX_STR	"*"

/*
 * Credentials describe an authenticated user (i.e., a DACS identity).
 * Externally, an XML representation is encrypted and then encoded as text
 * for transmission as the value part of a cookie, an HTTP extension header,
 * and so on.
 *
 * A (presumably) unique string identifies these credentials (and is used
 * to establish an audit trail and to associate proxy authorization with
 * particular credentials).
 *
 * XXX We assume that a time_t is an unsigned long.
 */
typedef struct Credentials {
  char *federation;
  char *username;			/* User's name within the home_jurisdiction */
  char *home_jurisdiction;	/* Jurisdiction that authenticated */
  char *ip_address;			/* User's IP address, maybe */
  char *role_str;
  time_t auth_time;			/* Absolute date/time of creation */
  time_t expires_secs;		/* Absolute date/time of expiry, relative to */
                            /* the clock at home_jurisdiction */
  Auth_style auth_style;
  char *version;
  char *valid_for;			/* Values: "acs", "chaining", or "ident" */
  char *imported_by;		/* Importing jurisdiction, if non-NULL */
  char *ua_hash;
  char *unique;				/* Unique identifier for these credentials */

  /* The following fields are not used externally */
  Group_name **roles;
  char *cookie_name;		/* Corresponding cookie name */
  int selected;
  struct Credentials *next;
} Credentials;

typedef struct Scredentials_selected {
  char *federation;
  char *jurisdiction;
  char *username;
  char *unique;
  char *version;
  struct Scredentials_selected *next;
} Scredentials_selected;

typedef struct Scredentials_unauth {
  char *federation;
} Scredentials_unauth;

typedef struct Scredentials {
  Scredentials_selected *selected;
  Scredentials_unauth *unauth;
} Scredentials;

typedef struct Cookie_name {
  char *app_name;		/* Always "DACS" */
  char *federation;
  char *jurisdiction;
  char *username;
  char *special;		/* e.g., "SELECTED" */
} Cookie_name;

typedef enum {
  COOKIE_NETSCAPE      = 0,
  COOKIE_EXT_NETSCAPE  = 1,
  COOKIE_RFC2109       = 2,
  COOKIE_RFC2965       = 3
} Cookie_syntax;

/* Netscape format plus RFC extensions */
typedef struct Cookie {
  Cookie_syntax syntax;
  char *str;			/* The unparsed string for this cookie */
  char *name;			/* The unparsed name of this cookie */
  Cookie_name *parsed_name;
  char *value;
  char *domain;
  char *path;
  char *expires;
  char *max_age;		/* RFC 2109/2965 */
  char *comment;		/* RFC 2109/2965 */
  char *version;		/* RFC 2109/2965 */
  char *comment_url;	/* RFC 2965 */
  char *discard;		/* RFC 2965 */
  char *port;			/* RFC 2965 */
  int secure;
  int httponly;			/* Microsoft extension */
  int set_void;			/* If non-zero, ask client to delete it */
  struct Cookie *next;
} Cookie;

#ifdef CURRENT_CREDENTIALS
typedef struct Current_credentials {
  char *federation;
  char *username;
  char *home_jurisdiction;
  char *unique;
  struct Current_credentials *next;
} Current_credentials;
#endif

/* Reasons why authentication can fail. */
typedef enum {
  AUTH_FAILURE_REASON_INVALID_INFO   = 800,
  AUTH_FAILURE_REASON_INTERNAL_ERROR = 801,
  AUTH_FAILURE_REASON_USER_ERROR     = 802,
  AUTH_FAILURE_REASON_ABORT          = 803,
  AUTH_FAILURE_REASON_UNKNOWN        = 899
} Auth_failure_reason;

typedef enum {
  AUTH_REVOKE_DENY         = 1,
  AUTH_REVOKE_REVOKE       = 2,
  AUTH_REVOKE_COMMENT      = 3,
  AUTH_REVOKE_DISABLE      = 4,
  AUTH_REVOKE_BLOCK        = 5
} Revocation_type;

typedef struct Revocation {
  Revocation_type type;
  char *item;
} Revocation;

typedef struct Cred_cache {
  Cookie *cookies;
  Dsvec *auth;
} Cred_cache;

typedef struct Cred_auth_url {
  char *name;
  char *url;
} Cred_auth_url;

/*****************************************************/

typedef struct Roles_reply_ok {
  char *roles;
} Roles_reply_ok;

typedef struct Roles_reply_failed {
  char *reason;
} Roles_reply_failed;

typedef struct Roles_reply {
  Roles_reply_ok *ok;
  Roles_reply_failed *failed;
  Common_status *status;
} Roles_reply;

/*****************************************************/

typedef struct Auth_reply_ok {
  char *username;
  char *lifetime;
  Roles_reply *roles_reply;
} Auth_reply_ok;

typedef struct Auth_reply_failed {
  char *username;
  char *redirect_url;
} Auth_reply_failed;

#ifdef NOTDEF
typedef struct Auth_reply_error {
  char *reason;
} Auth_reply_error;
#endif

typedef struct Auth_prompt {
  char *type;
  char *label;
  char *varname;
  struct Auth_prompt *next;
} Auth_prompt;

typedef struct Auth_prompts {
  char *transid;
  Auth_prompt *head;
} Auth_prompts;

typedef struct Auth_reply {
  Auth_reply_ok *ok;
  Auth_reply_failed *failed;
  Common_status *status;
  Auth_prompts *prompts;
} Auth_reply;

/*****************************************************/

/* Used by local_cas_authenticate. */

typedef struct Cas_auth {
  char *server_uri;
  char *redirect_args;
  char *session_ticket;
  char *redirect_url;
  char *username;		/* The username, if determined by CAS */
  char *roles;			/* For DACS, non-standard */
} Cas_auth;

/*****************************************************/

/* Used by local_http_authenticate. */
typedef struct Url_auth {
  Http_method method;
  char *url;
  char *username_parameter;
  char *password_parameter;
  Dsvec *options;
} Url_auth;

/*****************************************************/

/* Used by local_pam_authenticate. */

enum {
  /* Maximum time for pamd to wait for a reply from the client. */
  PAMD_USER_TIMEOUT_SECS = 60,
  /* Maximum time for local_pam_authenticate to wait for a reply from pamd. */
  PAMD_PAMD_TIMEOUT_SECS = 20
};

/*
 * This is (optionally) used to find the port used for pamd in /etc/services
 * and /etc/inetd.conf.
 */
#define PAMD_SERVICE_NAME	"dacs-pamd"

/*
 * The name of the default PAM policy.
 */
#define PAMD_DEFAULT_POLICY	"dacs"

/* Transaction/session identification (transid or tid) information. */
typedef struct Pam_auth_tid {
  char *str;
  char *host;
  in_port_t port;
  pid_t pid;
  char *unique;
} Pam_auth_tid;

/*****************************************************/

/* Used by local_grid_authenticate. */

enum {
  AUTH_GRID_NCOLS            = 10,
  AUTH_GRID_NROWS            = 10,
  AUTH_GRID_MIN_COLS         = 3,
  AUTH_GRID_MIN_ROWS         = 3,
  AUTH_GRID_MAX_COLS         = 26,
  AUTH_GRID_MAX_ROWS         = 99,
  AUTH_GRID_SERIAL_LENGTH    = 8,
  AUTH_GRID_CHALLENGE_LENGTH = 4,
  AUTH_GRID_CHALLENGE_SECS   = 60,
  AUTH_GRID_MIN_CHALLENGE    = 3,
  AUTH_GRID_PIN_LENGTH       = 2,
  AUTH_GRID_LIFETIME_SECS    = (60 * 60 * 24 * 7)	/* One week */
};

typedef struct Auth_grid {
  char *username;
  int enabled;
  int nrows;
  int ncols;
  char *serial;
  Dsvec *grid;
  char *pin;
  time_t date_created;
} Auth_grid;

/*****************************************************/

/* Used by dacstoken and local_token_authenticate. */

enum {
  TOKEN_HOTP_DEFAULT_ACCEPT_WINDOW  = 3,
  TOKEN_HOTP_SYNC_OTPS              = 3,
  TOKEN_HOTP_COUNTER_LENGTH         = 8,		/* in bytes (RFC 4226) */
  TOKEN_HOTP_NDIGITS                = 6,		/* the minimum (RFC 4226) */
  TOKEN_HOTP_BASE                   = 10,		/* recommended (RFC 4226) */
  TOKEN_HOTP_MAX_SYNC               = 10000,
  TOKEN_TOTP_NDIGITS                = 8,
  TOKEN_TOTP_BASE                   = 10,
  TOKEN_TOTP_DEFAULT_TIME_STEP_SECS = 30,
  TOKEN_TOTP_DEFAULT_DRIFT_WINDOW   = 2,
  TOKEN_TOTP_MAX_SYNC               = 20,
  TOKEN_MIN_NDIGITS                 = 6,
  TOKEN_MAX_NDIGITS                 = 9,
  TOKEN_MIN_KEY_LENGTH_BYTES        = 16		/* in bytes (RFC 4226) */
};

/* These are bit flags. */
enum {
  TOKEN_MODE_UNKNOWN  = 0x00,		/* Must be zero */
  TOKEN_MODE_COUNTER  = 0x01,		/* HOTP authentication */
  TOKEN_MODE_TIME     = 0x02,		/* TOTP authentication */
  TOKEN_MODE_MASK     = 0x0f,		/* 4 bits for the operation mode */
  TOKEN_MODE_DISABLED = 0x10,
  TOKEN_MODE_DEFAULT  = TOKEN_MODE_COUNTER
};

typedef enum {
  TOKEN_IGNORABLE_PIN = 0,
  TOKEN_REQUIRE_PIN   = 1
} Token_pin_mode;

typedef unsigned int Auth_token_mode;
#define AUTH_TOKEN_COUNTER_T unsigned long long
typedef AUTH_TOKEN_COUNTER_T Auth_token_counter;

#define TOKEN_HOTP_DEFAULT_HASH		"SHA1"
#define TOKEN_TOTP_DEFAULT_HASH		"SHA1"

/* Representation of a hardware token device, in memory. */
typedef struct Auth_token {
  char *username;				/* For internal use only */
  Auth_token_mode mode;			/* TOKEN_MODE_COUNTER or TOKEN_MODE_TIME */
  char *item_type;				/* For internal use only */
  char *digest_name;
  char *serial;					/* Device's serial number */
  unsigned char *counter;		/* Current counter value (HOTP only) */
  unsigned char *key;			/* Device's secret key/seed */
  unsigned int keylen;			/* For internal use only */
  unsigned int time_step;		/* In seconds (TOTP only) */
  int drift;					/* In seconds (TOTP only) */
  unsigned int ndigits;
  unsigned int base;
  char *pin_hash;				/* Digest of user's PIN (optional) */
  time_t last_update;			/* Date of last modification of this info */
} Auth_token;

/*****************************************************/

/* Used by local_apache_authenticate. */

/*
 * This indicates which module's authentication method needs to be reproduced.
 */
typedef enum {
  MOD_AUTH        = 0,
  MOD_AUTH_DBM    = 1,
  MOD_AUTH_DIGEST = 2,
  MOD_AUTH_NONE   = 3
} Apache_module;

/*
 * For MOD_AUTH_DBM, the database types that are supported by htdbm
 */
typedef enum {
  DBM_SDBM = 0,
  DBM_GDBM = 1,
  DBM_NDBM = 2,
  DBM_DB   = 3,
  DBM_NONE = 4
} Apache_dbm;

/*
 * The various hashes used by MOD_AUTH and MOD_AUTH_DBM
 */
typedef enum {
  HASH_MD5, HASH_CRYPT, HASH_SHA1, HASH_PLAIN
} Apache_hash;

typedef enum {
  AUTH_REQUIRED        = 1,
  AUTH_REQUISITE       = 2,
  AUTH_OPTIONAL        = 3,
  AUTH_SUFFICIENT      = 4,
  AUTH_USER_SUFFICIENT = 5
} Auth_control_flag;

typedef struct Auth_password_audit {
  char *varname;
  char *constraints;
} Auth_password_audit;

typedef struct Auth_module {
  char *id;
  Kwv_vartab *auth_vartab;
  char *url;
  char *url_eval;
  char *expr;
  char *init_eval;
  char *exit_eval;
  Auth_style style;
  Auth_control_flag control_flag;
  char *predicate;
  char **flags;
  Dsvec *options;
  Dsvec *options_eval;
  Dsvec *dsv_audits;
  Kwv *kwv_options;
  Kwv *kwv_conf;
  int have_req_auth;
  int result;
  Dsvec *argv_spec;
  struct Auth_module *next;
} Auth_module;

typedef struct Auth_module_info {
  Auth_module *modules;
  int mcount;
  int have_req_auth;
  int saw_expr;
  int saw_native;
  int saw_prompted;
  int saw_set_roles;
  int saw_add_roles;
} Auth_module_info;

/*
 * Each builtin authentication module is assigned an internal identifier
 * to avoid some string comparisons and to ensure consistent recognition of
 * abbreviated module names.
 */
typedef enum {
  AUTH_MODULE_EXPR     = 1,
  AUTH_MODULE_PASSWD   = 2,
  AUTH_MODULE_SIMPLE   = 3,
  AUTH_MODULE_INFOCARD = 4,
  AUTH_MODULE_UNIX     = 5,
  AUTH_MODULE_NTLM     = 6,
  AUTH_MODULE_APACHE   = 7,
  AUTH_MODULE_CAS      = 8,
  AUTH_MODULE_GRID     = 9,
  AUTH_MODULE_HTTP     = 10,
  AUTH_MODULE_TOKEN    = 11,
  AUTH_MODULE_PAM      = 12,
  AUTH_MODULE_UNKNOWN  = -1
} Auth_module_id;

#define AUTH_MODULE_MAX_ALIASES		5

typedef struct Auth_module_desc {
  Auth_module_id id;
  int is_builtin;			/* Currently, only builtins. */
  Auth_style style;
  char *canonical_name;
  char *aliases[AUTH_MODULE_MAX_ALIASES];
} Auth_module_desc;

#include "acs.h"

typedef struct Roles_module {
  char *id;
  Kwv_vartab *roles_vartab;
  char *predicate;
  char *url;
  char *url_eval;
  char *expr;
  char *init_eval;
  char *exit_eval;
  Dsvec *options;
  Dsvec *options_eval;
  char *username;
  Kwv *kwv_options;
  Kwv *kwv_conf;
  Dsvec *argv_spec;
  struct Roles_module *next;
} Roles_module;

typedef struct Roles_module_info {
  Roles_module *modules;
  int mcount;
} Roles_module_info;

typedef enum {
  ROLES_MODULE         = 1,
  ROLES_MODULE_UNIX    = 2,
  ROLES_MODULE_EXPR    = 3,
  ROLES_MODULE_UNKNOWN = -1
} Roles_module_id;

#define ROLES_MODULE_MAX_ALIASES	5

typedef struct Roles_module_desc {
  Roles_module_id id;
  int is_builtin;
  char *canonical_name;
  char *aliases[ROLES_MODULE_MAX_ALIASES];
} Roles_module_desc;

/*****************************************************/

typedef enum {
  HTTP_AUTH_BASIC    = 0,
  HTTP_AUTH_DIGEST   = 1,
  HTTP_AUTH_EXCEPT   = 2,
  HTTP_AUTH_UNKNOWN  = 3
} Http_auth_scheme;

/* An HTTP_AUTH configuration directive */
typedef struct Http_auth {
  Http_auth_scheme scheme;
  char *scheme_name;
  char *realm;
  Dsvec *url_patterns;
  int pre_flag;
  char *param;
  Auth_module *auth_modules;
  Roles_module *roles_modules;
} Http_auth;

/* A parsed WWW-Authentication response header */
typedef struct Http_auth_www_authenticate {
  char *www_authenticate;	/* The header value; its parsed fields follow */
  Http_auth_scheme scheme;
  char *scheme_name;
  char *realm;
  char *domain;
  char *nonce;
  char *opaque;
  char *stale;
  char *algorithm;
  char *qop_options;
  char *auth_param;
} Http_auth_www_authenticate;

/* A parsed Authorization request header */
typedef struct Http_auth_authorization {
  char *authorization;		/* The header value; its parsed fields follow */
  Http_auth_scheme scheme;
  char *scheme_name;
  char *username;
  char *password;
  char *realm;
  char *nonce;
  char *digest_uri;
  char *response;
  char *algorithm;
  char *cnonce;
  char *opaque;
  char *message_qop;
  char *nonce_count;
  char *auth_param;
  /*
   * The following are not part of the header but are put here for
   * convenience.
   */
  char *http_method;			/* In the canonical syntax (upper case) */
  Http_auth_www_authenticate *www_auth;
} Http_auth_authorization;

static inline MAYBE_UNUSED Apache_module
lookup_module(char *module_name)
{

  if (strcaseeq(module_name, "mod_auth")
	  || strcaseeq(module_name, "htpasswd"))
	return(MOD_AUTH);
  else if (strcaseeq(module_name, "mod_auth_digest")
		   || strcaseeq(module_name, "htdigest"))
	return(MOD_AUTH_DIGEST);
  else if (strcaseeq(module_name, "mod_auth_dbm")
		   || strcaseeq(module_name, "htdbm"))
	return(MOD_AUTH_DBM);

  return(MOD_AUTH_NONE);
}

static inline MAYBE_UNUSED Apache_dbm
lookup_dbm_type(char *dbm_type)
{

  if (strcaseeq(dbm_type, "sdbm"))
	return(DBM_SDBM);
  else if (strcaseeq(dbm_type, "gdbm"))
	return(DBM_GDBM);
  else if (strcaseeq(dbm_type, "ndbm"))
	return(DBM_NDBM);
  else if (strcaseeq(dbm_type, "db"))
	return(DBM_DB);

  return(DBM_NONE);
}

/*****************************************************/

/*
 * This list may be extended but do not change the mapping because
 * the digest algorithm numbers are stored with the hashed passwords.
 * If you change a mapping, you will need to edit your DACS password files.
 */
typedef enum {
  PASSWD_ALG_CRYPT  = 0,
  PASSWD_ALG_MD5    = 1,
  PASSWD_ALG_SHA1   = 2,
  PASSWD_ALG_SHA224 = 3,
  PASSWD_ALG_SHA256 = 4,
  PASSWD_ALG_SHA384 = 5,
  PASSWD_ALG_SHA512 = 6,
  PASSWD_ALG_NONE   = 999
} Passwd_digest_alg;

/* If not configured, the default password hashing algorithm to use. */
#ifndef PASSWD_ALG_DEFAULT_NAME
#define PASSWD_ALG_DEFAULT_NAME		"SHA1"
#endif

enum {
  CRYPT_KEYS_RSA_KEY_LENGTH_1024 = 1024,
  CRYPT_KEYS_RSA_KEY_LENGTH_2048 = 2048,
  CRYPT_KEYS_RSA_KEY_LENGTH_4096 = 4096,
  CRYPT_KEYS_RSA_KEY_LENGTH_8192 = 8192,
  CRYPT_KEYS_RSA_KEY_LENGTH_DEFAULT = CRYPT_KEYS_RSA_KEY_LENGTH_2048
};

/*
 * Configuration for local DACS acounts.
 * Some of this is run-time configurable; see PASSWORD_* directives.
 */
enum {
  PASSWD_SALT_BYTES        = 16,
  PASSWD_MINIMUM_LENGTH    = 6,
  PASSWD_NEEDS_MIXED_CASE  = 0,		/* Set to zero to disable. */
  PASSWD_NEEDS_PUNCTUATION = 0,		/* Set to zero to disable. */
  PASSWD_NEEDS_DIGITS      = 0		/* Set to zero to disable. */
};

typedef enum {
  GET_PASSWD_FILE   = 0,
  GET_PASSWD_STDIN  = 1,
  GET_PASSWD_STREAM = 2,
  GET_PASSWD_PROMPT = 3
} Get_passwd_type;

typedef struct Pw_constraints {
  int minlen;
  int mixed_case;
  int punct;
  int digits;
} Pw_constraints;

/*
 * This character separates fields in a password entry.
 * It must be a printable character not produced by strba64().
 * If you change this, you will need to edit your DACS password files.
 */
#define PASSWD_SEP_CHAR		'|'

/*
 * If this character is the first one in the stored digest entry,
 * the entry is in the disabled state and cannot be authenticated against.
 * If you change this, you will need to edit your DACS password files.
 */
#define PASSWD_DISABLED_CHAR	'*'

typedef enum {
  PW_UNCHANGED = 0,
  PW_DISABLED  = 1,
  PW_ENABLED   = 2
} Pw_state;

/*
 * Although for the most part these operations on accounts are mutually
 * exclusive, bit flags are used because some of them can be combined.
 */
typedef enum {
  PW_OP_NONE           = 0,			/* This one must be zero. */
  PW_OP_ADD            = (1 <<  0),
  PW_OP_DELETE         = (1 <<  1),
  PW_OP_LIST           = (1 <<  2),
  PW_OP_RESET          = (1 <<  3),
  PW_OP_DISABLE        = (1 <<  4),
  PW_OP_ENABLE         = (1 <<  5),
  PW_OP_UPDATE         = (1 <<  6),
  PW_OP_MODIFY         = (1 <<  7),
  PW_OP_SET_DATA       = (1 <<  8),
  PW_OP_DELETE_DATA    = (1 <<  9),
  PW_OP_GET_DATA       = (1 << 10),
  PW_OP_TEST_EXISTS    = (1 << 11),
  PW_OP_TEST_DISABLED  = (1 << 12),
  PW_OP_TEST_ENABLED   = (1 << 13),
  PW_OP_TEST_PRIVATE   = (1 << 14),
  PW_OP_GET_DIGEST     = (1 << 15)
} Pw_op;

/* A password file entry in memory, as maintained by dacspasswd(1) etc. */
typedef struct Pw_entry {
  char *username;		/* In memory only */
  Pw_state state;
  Passwd_digest_alg alg;
  char *salt;
  char *digest;			/* The hash of a password and salt using alg */
  char *stored_digest;	/* The formatted alg, salt, and digest */
  char *entry;			/* The digest_str with encoded application data */
  Ds *private;			/* Arbitrary application data */
} Pw_entry;

/*****************************************************/

/*
 * Convention: names associated with self-issued InfoCards begin with
 * "sic_" ("Sic_" and "SIC_"), those associated with managed InfoCards begin
 * with "mic_" ("Mic_" and "MIC_"), and those that are generic (common to
 * both types) are prefixed by "ic_" ("Ic_" and "IC_").
 * When the distinction isn't important, "INFOCARD_" is often used.
 */

#define INFOCARD_DEFAULT_STS_TITLE		"DACS Managed InfoCard IP/STS"
#define INFOCARD_CARD_IMAGE_PASSWD		"dacs_username_password_credential.png"
#define INFOCARD_CARD_IMAGE_CERT		"dacs_x509certificate_credential.png"
#define INFOCARD_CARD_IMAGE_CARD		"dacs_selfissued_credential.png"
#define INFOCARD_DIGEST_DEFAULT_NAME	"SHA256"
#define INFOCARD_ASSERTION_ID_PREFIX	"uuid-"
#define INFOCARD_DEFAULT_CARDID_SUFFIX	"identity"
#define INFOCARD_DEFAULT_STS_USERNAME_PASSWD_PROMPT_FMT	\
  "Enter your %s username and password"

enum {
  INFOCARD_DEFAULT_CARD_LIFETIME_SECS   = (60 * 60 * 24 * 365),
  INFOCARD_DEFAULT_TOKEN_LIFETIME_SECS  = 10	/* As short as reasonable. */
};

#define SIC_USERNAME_PREFIX		"SU|"
#define SIC_HASHSTR_PREFIX		"SH|"
#define MIC_IDENTITY_PREFIX		"MI|"
#define MIC_CARD_ID_PREFIX		"MC|"

/*
 * Various maximum values - they're tunable here; some may be overridden by
 * configuration directives.
 */
enum {
  IC_MAX_TOKEN_SIZE     = 16384,
  IC_MAX_DRIFT_SECS     = (5 * 60)
};

/*
 * Various maximum values for the STATIC and ISTATIC types of managed InfoCard.
 * They're tunable here; in the future some might be overridden by
 * configuration directives.
 */
enum {
  MIC_MAX_STATIC_CLAIMS           = 10,
  MIC_MAX_STATIC_NAME_CLAIM_SIZE  = 32,
  MIC_MAX_STATIC_VALUE_CLAIM_SIZE = 64,
  MIC_MAX_STATIC_URI_CLAIM_SIZE   = 128,
  MIC_MAX_STATIC_LABEL_CLAIM_SIZE = 20,
  MIC_MAX_STATIC_DESC_CLAIM_SIZE  = 40
};

/*
 * Various maximum values for the DACS and DYNAMIC types of managed InfoCard,
 * where external web services provide claim definitions.
 * They're tunable here; in the future some might be overridden by
 * configuration directives.
 */
enum {
  MIC_MAX_DYNAMIC_CLAIMS           = 20,
  MIC_MAX_DYNAMIC_NAME_CLAIM_SIZE  = 32,
  MIC_MAX_DYNAMIC_VALUE_CLAIM_SIZE = 64,
  MIC_MAX_DYNAMIC_URI_CLAIM_SIZE   = 128,
  MIC_MAX_DYNAMIC_LABEL_CLAIM_SIZE = 20,
  MIC_MAX_DYNAMIC_DESC_CLAIM_SIZE  = 40
};

typedef enum {
  IC_UNKNOWN_TYPE     = 0,
  IC_SELF_ISSUED_TYPE = 1,
  IC_MANAGED_TYPE     = 2
} Ic_type;

typedef enum {
  IC_UNCHANGED = 0,
  IC_DISABLED  = 1,
  IC_ENABLED   = 2
} Ic_state;

/* Managed InfoCard claim definition/fill usage modes. */
typedef enum {
  IC_USE_MODE_DACS    = 0,
  IC_USE_MODE_STATIC  = 1,
  IC_USE_MODE_ISTATIC = 2,
  IC_USE_MODE_DYNAMIC = 3,
  IC_USE_MODE_UNKNOWN = -1
} Ic_use_mode;

/* Managed InfoCard IP/STS authentication credential types. */
typedef enum {
  INFOCARD_AUTHTYPE_NONE      = 0,
  INFOCARD_AUTHTYPE_PASSWD    = 1,
  INFOCARD_AUTHTYPE_CERT      = 2,
  INFOCARD_AUTHTYPE_CARD      = 3,
  INFOCARD_AUTHTYPE_KERBEROS  = 4		/* Not supported */
} Ic_sts_authtype;

/*
 * Although for the most part these operations on accounts are mutually
 * exclusive, bit flags are used because some of them can be combined.
 */
typedef enum {
  IC_OP_NONE           = 0,			/* This one must be zero. */
  IC_OP_MODIFY         = (1 << 0),
  IC_OP_REGISTER       = (1 << 1),
  IC_OP_DELETE         = (1 << 2),
  IC_OP_LIST           = (1 << 3),
  IC_OP_DISABLE        = (1 << 4),
  IC_OP_ENABLE         = (1 << 5),
  IC_OP_SET_DATA       = (1 << 6),
  IC_OP_DELETE_DATA    = (1 << 7),
  IC_OP_TEST_EXISTS    = (1 << 8),
  IC_OP_TEST_ENABLED   = (1 << 9),
  IC_OP_TEST_DISABLED  = (1 << 10),
  IC_OP_TEST_PRIVATE   = (1 << 11),
  IC_OP_GET_DIGEST     = (1 << 12),
  IC_OP_GET_DATA       = (1 << 13),
  IC_OP_UPDATE         = (1 << 14),
  IC_OP_LOOKUP         = (1 << 15),
  IC_OP_TOKEN_VALIDATE = (1 << 16),
  IC_OP_TOKEN_ATTRVALS = (1 << 17)
} Ic_op;

/*
 * Stuff extracted from either a self-issued or managed InfoCard account.
 */
typedef struct Ic_auth {
  Ic_type type;
  Ic_state state;
  Ic_use_mode use_mode;
  char *username;
  char *roles;
  Kwv *kwv_claims;
} Ic_auth;

/*
 * A self-issued InfoCard account entry, in memory.
 * Note that the PPID (private personal identifier) is not stored.
 * See dacsinfocard.c
 */
typedef struct Sic_entry {
  Ic_state state;
  Passwd_digest_alg alg;
  char *username;
  Ds *friendly_id;
  char *pubkey_modulus;
  char *pubkey_exponent;
  char *digest;
  Ds *private;
} Sic_entry;

typedef struct Mic_sts_auth {
  Ic_sts_authtype authtype;
  Passwd_digest_alg alg;		/* For "passwd" type */
  char *digest;					/* For "passwd" type, optional */
  char *self_issued_ppid;		/* For "card" type */
  Ds *thumbprint;				/* For "cert" type */
} Mic_sts_auth;

typedef struct Mic_entry {
  char *identity;				/* DACS identity associated with this card. */
  Ic_state state;				/* Usable for authentication? */
  Ic_use_mode use_mode;			/* Method to obtain claims */
  char *card_id;
  Mic_sts_auth *sts_auth;
  Dsvec *claims;				/* (Icx_claim *) */
} Mic_entry;

typedef struct Ic_entry {
  Mic_entry *mic;
  Sic_entry *sic;
} Ic_entry;

/*
 * Configuration parameters to override lower-level defaults.
 */
typedef struct Ic_config {
  char *certfile;
  char *keyfile;
  Dsvec *audience;
  char *issuer;
  int enable_replay_detection;
  int enable_signature_validation;
  size_t max_token_size;
  int max_drift_secs;
} Ic_config;

typedef enum {
  IC_CONFIRM_HOLDER = 0,
  IC_CONFIRM_BEARER = 1,
  IC_CONFIRM_ERROR  = -1
} Ic_subj_confirm_method;

/*
 * Fields extracted from a SAML token received by a Relying Party.
 */
typedef struct Ic_token {
  char *issuer;						/* NULL if self issued */
  Ic_subj_confirm_method confirm;
  Ds *ppid;
  Ds *exponent;
  Ds *modulus;
  Kwv *kwv_claims;			/* Claim type (full URI)/claim value pairs */
} Ic_token;

/*****************************************************/

#include "dacs_crypto.h"

typedef struct Crypt_keys {
  char *fed_id;					/* Presumably unique federation id string */
  unsigned char *auth_key;		/* Binary key for authentication - internal */
  unsigned int auth_key_len;	/* Length of binary key, in bytes */
  char *auth_key_str;			/* Base-64 textual representation */
  unsigned char *hmac_key;		/* Binary key for keyed-hashing - internal */
  unsigned int hmac_key_len;	/* Length of HMAC key, in bytes */
  char *hmac_key_str;			/* Base-64 textual representation */
  char *public_key_str;			/* Base-64 representation of RSA public key */
  EVP_PKEY *public_key;			/* RSA public key - internal only */
  char *public_key_pem;			/* PEM version of RSA public key - internal */
  char *private_key_str;		/* Base-64 textual representation */
  EVP_PKEY *private_key;		/* RSA private key - Internal only */
  char *private_key_pem;		/* PEM version of RSA private key - internal */
} Crypt_keys;

extern char *non_auth_cookie_header;
extern Cookie *non_auth_cookies;
extern int debug_crypt;

/*****************************************************/

typedef enum {
  USERINFO_AUTH    = 0,
  USERINFO_SIGNOUT = 1,
  USERINFO_ACCESS  = 2,
  USERINFO_ERROR   = 3
} User_info_type;

typedef struct User_auth {
  char *ident;
  char *ip;
  char *auth_time;
  char *expires;
  char *jurisdiction;
  char *auth_style;
  char *valid_for;
  char *unique;
  char *imported_by;
} User_auth;

typedef struct User_signout {
  char *ident;
  char *ip;
  char *date;
  char *jurisdiction;
  char *unique;
} User_signout;

typedef struct User_access {
  char *ident;
  char *ip;
  char *date;
  char *jurisdiction;
  char *host;
  char *addr;
  char *unique;
  char *uri;
} User_access;

typedef struct User_info {
  User_info_type which;
  union {
	User_auth auth;
	User_signout signout;
	User_access acs;
  } info;
} User_info;

/*****************************************************/

typedef struct Auth_out {
  int result;			/* 0 = failed, 1 = succeeded, -1 = error */
  char *identity;		/* Authenticated identity, if result is 1. */
  char *username;		/* Username component of the authenticated identity. */
  char *role_string;	/* Role string, if result is 1 and roles obtained. */
} Auth_out;

#ifdef __cplusplus
extern "C" {
#endif

extern Auth_module *auth_module_config(char **argv, int *ind,
									   Auth_module_info *ami);
extern Roles_module *roles_module_config(char **argv, int *ind);

extern int is_valid_username(const char *username);
extern int is_valid_auth_username(const char *username);
extern char *make_dacs_admin_name(char *basename);
extern int is_dacs_admin_name(char *username);

extern char *is_valid_valid_for(const char *valid_for);
extern void set_valid_for(Credentials *credentials, char *valid_for);

/* mkkey.c */
extern Crypt_keys *crypt_keys_from_vfs(char *vfs_ref);
extern Crypt_keys *crypt_keys_from_buf(char *keystr);
extern void crypt_keys_free(Crypt_keys *ck);
extern int parse_xml_crypt_keys(char *keyfile, Crypt_keys **crypt_keys);

extern int validate_credentials_ip(Credentials *cr, char *actual_ip_address,
								   char **errmsg);
extern int validate_credentials(Credentials *c, char *actual_ip_address,
								char **msg);
extern int verify_expiration(time_t expires_date, int *remaining);

extern int parse_xml_credentials(char *cookie, Credentials **credentials);
extern int parse_xml_auth_reply(char *reply_string, Auth_reply **auth_reply);
extern int parse_xml_roles_reply(char *reply_string, Roles_reply **rr);
extern time_t make_auth_expiry_delta(time_t auth_time, char *delta);
extern time_t make_auth_expiry(time_t auth_time, time_t delta_secs);
extern int crypt_init(void);
extern int crypt_md(unsigned char *inp,
					unsigned int len, int alg, unsigned char **outp);
extern int is_valid_role_str(char *role_str);

extern Credentials *make_credentials(char *fname, char *jname, char *username,
									 char *ip, char *role_str,
									 char *expires, Auth_style style,
									 char *validity, char *imported_by,
									 char *ua_str);
extern Credentials *make_admin_credentials(void);
extern Credentials *init_credentials(void);
extern int get_valid_credentials(Cookie *cookies, char *remote_addr,
								 int valid_for_acs, Credentials **credentials);
extern int credentials_to_auth_cookies(Credentials *credentials,
									   char **cookie_buf);
extern int credentials_externalize_with_keys(Credentials *credentials,
											 Crypt_keys *ck, char **buf);
extern int credentials_externalize(Credentials *credentials, char **buf);
extern int is_local_user_identity(Credentials *cr);

extern int make_set_cookie_header(char *cookie, char *lifetime, int for_acs,
								  int cookie_only, char **cookie_buf);
extern int make_set_void_cookie_header(char *cookie, int for_acs,
									   char **set_cookie_buf);
extern int make_set_auth_cookie_header(Credentials *credentials,
									   char *lifetime, int cookie_only,
									   char **cookie_buf);
extern char *make_auth_cookie_name(Credentials *cr);

extern int get_cookies(Kwv *kwv, Cookie **cookies, unsigned *ncookies);
extern void cookies_html(FILE *fp, Cookie *cookies);

extern int cookie_value_to_credentials(char *cookie_value, char *remote_addr,
									   Credentials **credentials);
extern int cookie_to_credentials(Cookie *cookie, char *remote_addr,
								 Credentials **credentials);
extern Cookie *cookie_parse(char *cookie_value, int *is_dacs_cookie);
extern int is_auth_cookie_name(char *cookie_name);
extern int set_cookie_output_syntax(Cookie_syntax syntax);
extern int configure_cookie_syntax(char *cookie_syntax, char **errmsg);

extern char *get_passwd(Get_passwd_type type, void *arg);

extern char *passwd_make_digest(Passwd_digest_alg alg, char *passwd,
								Pw_entry *);
extern int passwd_check_digest(Passwd_digest_alg alg, char *given_passwd,
							   Pw_entry *);
extern char *passwd_lookup_digest_name(Passwd_digest_alg alg);
extern Passwd_digest_alg passwd_lookup_digest_algorithm(char *digest_name);
extern int passwd_get_digest_algorithm(char **digest_name,
									   Passwd_digest_alg *alg);

extern char *make_hash_from_credentials(Credentials *cr);

extern char *get_revocations(char *item_type);
extern Dsvec *parse_revocations(char *buf, int check_exprs);
extern int check_revocation(Credentials *c, Kwv *kwv, char *item_type,
							int for_acs);

extern Http_auth *http_auth_match_directive(char *url_path);

extern Http_auth_authorization
	*http_auth_authorization_parse(char *enc_auth_info, char **errmsg);
extern Http_auth_authorization *http_auth_authorization_init(char *username,
															 char *scheme,
															 char *realm);
extern char *http_auth_basic_auth(Http_auth *auth);
extern char *http_auth_digest_auth(Http_auth *auth, char *domain);
extern int http_digest_auth(char *username, Http_auth_authorization *aa);
extern Http_auth_www_authenticate
	*http_auth_www_authenticate_parse(char *challenge, char **errmsg);
extern int http_digest_check(Http_auth_authorization *aa,
							 char *stored_password);

extern void make_randomized_from_passphrase(unsigned char *pp,
											unsigned int pplen,
											unsigned int needed,
											unsigned char **rbuf);
extern char *auth_style_to_string(Auth_style auth_style);
extern Auth_style auth_style_from_string(const char *str);

extern int pam_auth(Kwv *, char *username, Pam_auth_tid **tidp,
					char *hostname, in_port_t port,
					char **mapped_username, char **lifetime, char **xml,
					Auth_prompts **prompts);
extern int pamd_get_block(FILE *fp, Ds *buf, Kwv **kwvp);
extern in_port_t pam_get_pamd_port(char *portname, char **errmsg);
extern Pam_auth_tid *pam_new_tid(char *reply_addr, char *reply_port);
extern Pam_auth_tid *pam_parse_tid(char *str);
extern char *make_pam_prompt_form(Auth_prompts *prompts, char *jurisdiction,
								  char *action_url, char *action_query,
								  char *inputs);
extern int count_valid_credentials(Credentials *credentials);

extern char *auth_tracker(Credentials *cr);
extern char *auth_identity(char *federation, char *jurisdiction,
						   char *username, char *tracker);
extern char *auth_identity_mine(char *username);
extern char *auth_identity_from_credentials(Credentials *cr);
extern char *auth_identity_from_credentials_track(Credentials *cr);
extern char *auth_identities_from_credentials_track(Credentials *credentials);
extern char *auth_identity_from_cookie(Cookie *c);
extern int is_dacs_admin(Credentials *credentials);
extern int is_dacs_admin_identity(char *f, char *j, char *u);
extern int reset_scredentials(Credentials *credentials);
extern int make_scredentials_cookie(Credentials *credentials, char **buf);
extern int make_set_scredentials_cookie_header(Credentials *credentials,
											   char **cookie_buf);
extern int get_valid_scredentials(Cookie *cookies, char *remote_addr,
								  int valid_for_acs,
								  Credentials **credentials,
								  Credentials **selected,
								  Scredentials **scp);
extern int get_scredentials(Cookie *cookies, Scredentials **sp);
extern int make_set_void_selected_cookie_header(char **buf);
extern int is_selected_cookie_name(char *cookie_name);

extern int is_matching_user(char *user, Credentials *credentials,
							DACS_name_cmp cmp_mode,
							Credentials **matched, char **errmsg);
extern int is_matching_user_identity(char *user, Credentials *credentials,
									 DACS_name_cmp cmp_mode, char **errmsg);

extern int auth_add_success_expr(char *expr);
extern int auth_get_success_exprs(char ***list);
extern int auth_success(Kwv *kwv, Kwv *kwv_auth);

extern char *dacs_approval_create(char *uri, char *method, char *ident,
								  char *dn, EVP_PKEY *private_key);

extern int auth_add_option(char *option_str, Kwv *kwv_options, Dsvec *options,
						   Dsvec *argv_spec);
extern int auth_get_options_from_file(char *filename, Kwv *kwv_options,
									  Dsvec *options, Dsvec *argv_spec);


/* In commonjson.c */
extern char *make_json_common_status(Common_status *status);
extern char *make_json_roles_reply(Roles_reply *rr);
extern char *make_json_auth_reply_ok(Auth_reply_ok *ok);
extern char *make_json_auth_reply_failed(char *username, char *redirect_url);
extern char *make_json_auth_reply_status(char *context, char *code,
										 char *message);
extern char *make_json_auth_reply_prompt(char *prompt);
extern int make_json_credentials(Credentials *cr, char **credentials_str);
extern char *make_json_dacs_current_credentials(Credentials *selected,
												Dsvec *dsv_activity,
												int detailed);
extern int make_json_credentials(Credentials *credentials,
								 char **credentials_str);

/* In commonxml.c */
extern char *make_xml_auth_reply_ok(Auth_reply_ok *ok);
extern char *make_xml_auth_reply_failed(char *username, char *redirect_url);
extern char *make_xml_auth_reply_error(char *context, char *code,
									   char *message);
extern char *make_xml_auth_reply_prompt(char *prompt);
extern char *make_xml_roles_reply(Roles_reply *rr);
extern char *make_xml_common_status(Common_status *status);
extern int make_xml_credentials(Credentials *credentials,
								char **credentials_str);
extern char *make_xml_dacs_current_credentials(Credentials *selected,
											   Dsvec *dsv_activity,
											   int detailed);
extern char *make_xml_root_element(char *root);
extern int make_xml_init_xmlns(void);
extern int make_xml_add_xmlns(char *ns);

extern void emit_roles_reply_ok(FILE *fp, char *role_str);
extern void emit_roles_reply_failed(FILE *fp, char *reason);

extern char *get_role_string(char *vfs_uri, char *item_type, char *username,
							 char *fs);
extern Dsvec *get_roles(char *item_type, char *username, char *fs);

/* In pamlib.c */
extern int make_json_prompts(Auth_prompts *prompts, int html, char **json);
extern int make_xml_prompts(Auth_prompts *prompts, int html, char **xml);

/* In dacspasswd.c */
extern Pw_entry *pw_init_entry(Pw_entry *, char *);
extern char *pw_make_entry(Pw_entry *pw);
extern Pw_entry *pw_parse_entry(char *username, char *stored_digest);
extern int pw_check_passwd(Vfs_handle *h, char *username, char *given_passwd,
						   Passwd_digest_alg alg);
extern Pw_entry *pw_read_entry(Vfs_handle *h, char *username);
extern int pw_delete_entry(Vfs_handle *h, char *username);
extern int pw_exists_entry(Vfs_handle *h, char *username);
extern char *pw_getdigest_entry(Vfs_handle *h, char *username);
extern Ds *pw_getdata_entry(Vfs_handle *h, char *username);
extern int pw_test_entry(Vfs_handle *h, Pw_op op, char *username);
extern Dsvec *pw_list_entries(Vfs_handle *h);
extern int pw_add_entry(Vfs_handle *h, char *username, char *given_passwd,
						Passwd_digest_alg alg, Pw_state new_state, Ds *data);
extern int pw_reset_entry(Vfs_handle *h, char *username, char *given_passwd,
						  Passwd_digest_alg alg, Pw_state new_state,
						  Pw_op data_op, Ds *data);
extern int pw_rename_entry(Vfs_handle *h, char *old_username,
						   char *new_username);
extern int pw_replace_entry(Vfs_handle *h, char *username, char *given_passwd,
							Passwd_digest_alg alg, Pw_state new_state,
							Pw_op data_op, Ds *data);
extern int pw_update_entry(Vfs_handle *h, char *username, char *given_passwd,
						   Passwd_digest_alg alg, Pw_state new_state);
extern int pw_disable_entry(Vfs_handle *h, char *username);
extern int pw_enable_entry(Vfs_handle *h, char *username);
extern int pw_is_passwd_acceptable(char *passwd, char *constraints);
extern int pw_parse_constraints(char *constraint, Pw_constraints *conf);
extern char *pw_prompt_new_password(char *username, char *msg, char **errmsg);
extern int pw_check_username(char *username);

/* In auth_grid.c */
extern Auth_grid *auth_grid_unflatten(char *grid_str, int decrypt);
extern Dsvec *auth_grid_parse_challenge(char *challenge_str);
extern Auth_grid *auth_grid_get(char *item_type, char *username);
extern int auth_grid_verify(Auth_grid *grid, Dsvec *challenge, char *response,
							unsigned int grid_lifetime);
extern Dsvec *auth_grid_decrypt_challenge(char *ext_token,
										  unsigned int challenge_lifetime);
 
/* In dacsinfocard.c */
extern Mic_entry *mic_read(Vfs_handle *h, char *identity, char *ppid);
extern int mic_register_entry(Vfs_handle *h, char *identity, char *ppid,
							  Dsvec *claims, Ic_use_mode use_mode,
							  Mic_sts_auth *sts_auth, Ic_state state);
extern Ic_config *ic_config(void);
extern Ic_auth *ic_lookup_entry(Vfs_handle *h, char *xmlToken, Ic_config *conf);
extern Dsvec *ic_get_config_audience(void);
extern int ic_get_digest_algorithm(char **digest_name, Passwd_digest_alg *alg);
extern Ic_sts_authtype ic_lookup_sts_authtype(char *authtype_str);
extern int ic_lookup_sts_authtype_str(Ic_sts_authtype authtype,
									  char **short_str, char **long_str);

/* In auth_roles.c */
extern Acs_expr_result auth_eval(char *expr, Kwv *kwv, Kwv *kwv_auth,
								 Kwv *kwv_options, char **result_str);
extern Roles_module *roles_module_lookup(Roles_module_info *rmi, char *id);
extern Roles_module_info *
auth_parse_roles_clause_init(Roles_module_info *o_rmi);
extern Roles_module_info *auth_parse_roles_clauses(Roles_module_info *o_rmi);
extern int auth_process_roles_clause(Roles_module *m, char *username,
									 char *jurisdiction, Kwv *kwv,
									 Kwv *kwv_auth, char **role_str,
									 Common_status *common_status,
									 char **errmsg);
extern int roles_module_invoke(Roles_module *m, char *username, char *passwd,
							   char *jurisdiction, Kwv *kwv, Kwv *kwv_auth,
							   char **role_str, Common_status *common_status,
							   char **errmsg);
extern int collect_roles(char *username, char *jurisdiction, Kwv *kwv,
						 Kwv *kwv_auth, Ds **ds_roles,
						 Common_status *common_status,
						 Auth_failure_reason *failure_reason);


/* In auth_token.c */
extern char *auth_token(char *digest_name, unsigned char *key,
						unsigned int klen, unsigned char *value,
						unsigned int vlen, unsigned int ndigits,
						unsigned int base);
extern char *auth_hotp_value(unsigned char *key, unsigned int klen,
							 unsigned char *value, unsigned int vlen,
							 unsigned int ndigits, unsigned int base);
extern char *auth_totp_value(char *digest_name, unsigned char *key,
							 unsigned int klen, time_t *clock_val,
							 unsigned int time_step, int drift_adj,
							 unsigned int ndigits, unsigned int base,
							 char **mfp);
extern void auth_token_inc_counter(unsigned char *counter);
extern int auth_token_current(Auth_token *token, char **hvalp,
							  char **moving_factorp);
extern int auth_token_validate(Auth_token *token, char *otp_value,
							   char *pin, Token_pin_mode pin_mode,
							   char *challenge, unsigned int window);
extern int auth_hotp_token_validate(Auth_token *token, char *otp_value,
									char *pin, Token_pin_mode pin_mode,
									unsigned int window);
extern int auth_totp_token_validate(Auth_token *token, char *otp_value,
									char *pin, Token_pin_mode pin_mode,
									unsigned int time_step,
									int base_window_delta,
									unsigned int drift_window,
									unsigned int ndigits, unsigned int base,
									int *driftp);
extern Auth_token *auth_token_get(char *item_type, char *username);
extern int auth_token_update(Auth_token *token);


/* Local authentication modules */
#ifdef ENABLE_APACHE_AUTH
extern int local_apache_auth(char *username, char *password, char *aux,
							 Http_auth_authorization *aa,
							 Apache_module module, Apache_dbm dbm, char *path);
#endif

#ifdef ENABLE_CAS_AUTH
extern int local_cas_auth(char *username, char *password, char *aux,
						  Cas_auth *cas_auth);
#endif

#ifdef ENABLE_GRID_AUTH
extern int local_grid_auth(char *username, char *password, char *aux);
#endif

#ifdef ENABLE_HTTP_AUTH
extern int local_http_auth(char *username, char *password, char *aux,
						   Url_auth *url_auth);
#endif

#ifdef ENABLE_INFOCARD_AUTH
extern int local_infocard_auth(char *xmlToken, char *aux, Ic_auth *ic);
#endif

#ifdef ENABLE_LDAP_AUTH
extern int local_ldap_auth_by_dn(Uri *url, char *username, char *password,
								 struct timeval *timeout, Dsvec *avas);
extern int local_ldap_auth_by_attr(Uri *admin_url, char *admin_password,
								   char *root_dn, char *filter, char *password,
								   struct timeval *timeout, Dsvec *avas);
#endif
  
#ifdef ENABLE_NTLM_AUTH
extern int local_ntlm_auth(char *username, char *password, char *aux,
						   int smb_port, char *smb_server, char *smb_domain);
#endif

#ifdef ENABLE_PAM_AUTH
extern int local_pam_auth(Kwv *kwv_trans, char *username,
						  char *hostname, in_port_t port,
						  char **mapped_username, char **lifetime, char **xml,
						  Pam_auth_tid **tidp, Auth_prompts **prompts);
#endif

#ifdef ENABLE_PASSWD_AUTH
extern int local_passwd_auth(char *username, char *given_passwd, char *aux);
#endif

#ifdef ENABLE_SIMPLE_AUTH
extern int local_simple_auth(char *username, char *password, char *aux);
#endif

#ifdef ENABLE_TOKEN_AUTH
extern int local_token_auth(char *username, char *password, char *aux,
						   int accept_window);
#endif

#ifdef ENABLE_UNIX_AUTH
extern int local_unix_auth(char *username, char *password, char *aux);
#endif

/* Local roles modules */
extern int local_roles(char *username, char **role_str);

#ifdef ENABLE_UNIX_ROLES
extern int local_unix_roles(char *username, char **role_str);
#endif

extern char *user_info_service_uri(char *jurisdiction_name);
extern int parse_xml_user_info(char *user_info_rec, User_info **uip);
extern Dsvec *user_info_load(char *jurisdiction);
extern Dsvec *user_info_active(Dsvec *dsv, char *ident);
extern Dsvec *user_info_last_auth(Dsvec *dsv, char *ident);

#ifdef ENABLE_USER_INFO
extern void user_info_authenticate(Credentials *cr);
extern void user_info_signout(Credentials *cr);
extern void user_info_access(Credentials *cr, char *uri,
							 char *remote_addr, char *remote_host);
#endif

#ifdef __cplusplus
}
#endif

#endif