summaryrefslogtreecommitdiffstats
path: root/src/lib/gssapi/krb5/gssapiP_krb5.h
blob: 01678168f020203ccc98910c93a301b1404a3b0c (plain)
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
/* -*- mode: c; indent-tabs-mode: nil -*- */
/*
 * Copyright 2000, 2008 by the Massachusetts Institute of Technology.
 * All Rights Reserved.
 *
 * Export of this software from the United States of America may
 *   require a specific license from the United States Government.
 *   It is the responsibility of any person or organization contemplating
 *   export to obtain such a license before exporting.
 *
 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
 * distribute this software and its documentation for any purpose and
 * without fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation, and that
 * the name of M.I.T. not be used in advertising or publicity pertaining
 * to distribution of the software without specific, written prior
 * permission.  Furthermore if you modify this software you must label
 * your software as modified software and not distribute it in such a
 * fashion that it might be confused with the original M.I.T. software.
 * M.I.T. makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is" without express
 * or implied warranty.
 *
 */
/*
 * Copyright 1993 by OpenVision Technologies, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appears in all copies and
 * that both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of OpenVision not be used
 * in advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission. OpenVision makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL OPENVISION BE LIABLE FOR 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.
 */

#ifndef _GSSAPIP_KRB5_H_
#define _GSSAPIP_KRB5_H_

#include <k5-int.h>

#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif

/* work around sunos braindamage */
#ifdef major
#undef major
#endif
#ifdef minor
#undef minor
#endif

#include "gssapiP_generic.h"

/* The include of gssapi_krb5.h will dtrt with the above #defines in
 * effect.
 */
#include "gssapi_krb5.h"
#include "gssapi_err_krb5.h"
#include "gssapi_ext.h"

/* for debugging */
#undef CFX_EXERCISE

/** constants **/

#define GSS_MECH_KRB5_OID_LENGTH 9
#define GSS_MECH_KRB5_OID "\052\206\110\206\367\022\001\002\002"

#define GSS_MECH_KRB5_OLD_OID_LENGTH 5
#define GSS_MECH_KRB5_OLD_OID "\053\005\001\005\002"

/* Incorrect krb5 mech OID emitted by MS. */
#define GSS_MECH_KRB5_WRONG_OID_LENGTH 9
#define GSS_MECH_KRB5_WRONG_OID "\052\206\110\202\367\022\001\002\002"

/* IAKERB variant */
#define GSS_MECH_IAKERB_OID_LENGTH 6
#define GSS_MECH_IAKERB_OID "\053\006\001\005\002\005"

#define CKSUMTYPE_KG_CB         0x8003

#define KG_TOK_CTX_AP_REQ       0x0100
#define KG_TOK_CTX_AP_REP       0x0200
#define KG_TOK_CTX_ERROR        0x0300
#define KG_TOK_SIGN_MSG         0x0101
#define KG_TOK_SEAL_MSG         0x0201
#define KG_TOK_MIC_MSG          0x0101
#define KG_TOK_WRAP_MSG         0x0201
#define KG_TOK_DEL_CTX          0x0102
#define KG2_TOK_MIC_MSG         0x0404
#define KG2_TOK_WRAP_MSG        0x0504
#define KG2_TOK_DEL_CTX         0x0405
#define IAKERB_TOK_PROXY        0x0501

#define KRB5_GSS_FOR_CREDS_OPTION 1

#define KG2_RESP_FLAG_ERROR             0x0001
#define KG2_RESP_FLAG_DELEG_OK          0x0002

/** CFX flags **/
#define FLAG_SENDER_IS_ACCEPTOR 0x01
#define FLAG_WRAP_CONFIDENTIAL  0x02
#define FLAG_ACCEPTOR_SUBKEY    0x04

/* These are to be stored in little-endian order, i.e., des-mac is
   stored as 02 00.  */
enum sgn_alg {
    SGN_ALG_DES_MAC_MD5           = 0x0000,
    SGN_ALG_MD2_5                 = 0x0001,
    SGN_ALG_DES_MAC               = 0x0002,
    SGN_ALG_3                     = 0x0003, /* not published */
    SGN_ALG_HMAC_MD5              = 0x0011, /* microsoft w2k;  */
    SGN_ALG_HMAC_SHA1_DES3_KD     = 0x0004
};
enum seal_alg {
    SEAL_ALG_NONE            = 0xffff,
    SEAL_ALG_DES             = 0x0000,
    SEAL_ALG_1               = 0x0001, /* not published */
    SEAL_ALG_MICROSOFT_RC4   = 0x0010, /* microsoft w2k;  */
    SEAL_ALG_DES3KD          = 0x0002
};

/* for 3DES */
#define KG_USAGE_SEAL 22
#define KG_USAGE_SIGN 23
#define KG_USAGE_SEQ  24

/* for draft-ietf-krb-wg-gssapi-cfx-01 */
#define KG_USAGE_ACCEPTOR_SEAL  22
#define KG_USAGE_ACCEPTOR_SIGN  23
#define KG_USAGE_INITIATOR_SEAL 24
#define KG_USAGE_INITIATOR_SIGN 25

enum qop {
    GSS_KRB5_INTEG_C_QOP_MD5       = 0x0001, /* *partial* MD5 = "MD2.5" */
    GSS_KRB5_INTEG_C_QOP_DES_MD5   = 0x0002,
    GSS_KRB5_INTEG_C_QOP_DES_MAC   = 0x0003,
    GSS_KRB5_INTEG_C_QOP_HMAC_SHA1 = 0x0004,
    GSS_KRB5_INTEG_C_QOP_MASK      = 0x00ff,
    GSS_KRB5_CONF_C_QOP_DES        = 0x0100,
    GSS_KRB5_CONF_C_QOP_DES3_KD    = 0x0200,
    GSS_KRB5_CONF_C_QOP_MASK       = 0xff00
};

/** internal types **/

typedef struct _krb5_gss_name_rec {
    krb5_principal princ;       /* immutable */
    char *service;              /* immutable */
    char *host;                 /* immutable */
    k5_mutex_t lock;            /* protects ad_context only for now */
    krb5_authdata_context ad_context;
} krb5_gss_name_rec, *krb5_gss_name_t;

typedef struct _krb5_gss_cred_id_rec {
    /* protect against simultaneous accesses */
    k5_mutex_t lock;

    /* name/type of credential */
    gss_cred_usage_t usage;
    krb5_gss_name_t name;
    krb5_principal impersonator;
    unsigned int default_identity : 1;
    unsigned int iakerb_mech : 1;
    unsigned int destroy_ccache : 1;

    /* keytab (accept) data */
    krb5_keytab keytab;
    krb5_rcache rcache;

    /* ccache (init) data */
    krb5_ccache ccache;
    krb5_keytab client_keytab;
    krb5_boolean have_tgt;
    krb5_timestamp expire;
    krb5_timestamp refresh_time;
    krb5_enctype *req_enctypes;  /* limit negotiated enctypes to this list */
    char *password;
} krb5_gss_cred_id_rec, *krb5_gss_cred_id_t;

typedef struct _krb5_gss_ctx_ext_rec {
    struct {
        krb5_data *conv;
        int verified;
    } iakerb;
} krb5_gss_ctx_ext_rec, *krb5_gss_ctx_ext_t;

typedef struct _krb5_gss_ctx_id_rec {
    krb5_magic magic;
    unsigned int initiate : 1;   /* nonzero if initiating, zero if accepting */
    unsigned int established : 1;
    unsigned int have_acceptor_subkey : 1;
    unsigned int seed_init : 1;  /* XXX tested but never actually set */
    OM_uint32 gss_flags;
    unsigned char seed[16];
    krb5_gss_name_t here;
    krb5_gss_name_t there;
    krb5_key subkey; /* One of two potential keys to use with RFC 4121
                      * packets; this key must always be set. */
    int signalg;
    size_t cksum_size;
    int sealalg;
    krb5_key enc; /* RFC 1964 encryption key; seq xored with a constant
                   * for DES, seq for other RFC 1964 enctypes  */
    krb5_key seq; /* RFC 1964 sequencing key */
    krb5_ticket_times krb_times;
    krb5_flags krb_flags;
    /* XXX these used to be signed.  the old spec is inspecific, and
       the new spec specifies unsigned.  I don't believe that the change
       affects the wire encoding. */
    gssint_uint64 seq_send;
    gssint_uint64 seq_recv;
    void *seqstate;
    krb5_context k5_context;
    krb5_auth_context auth_context;
    gss_OID_desc *mech_used;
    /* Protocol spec revision for sending packets
       0 => RFC 1964 with 3DES and RC4 enhancements
       1 => RFC 4121
       No others defined so far.  It is always permitted to receive
       tokens in RFC 4121 format.  If enc is non-null, receiving RFC
       1964 tokens is permitted.*/
    int proto;
    krb5_cksumtype cksumtype;    /* for "main" subkey */
    krb5_key acceptor_subkey; /* CFX only */
    krb5_cksumtype acceptor_subkey_cksumtype;
    int cred_rcache;             /* did we get rcache from creds? */
    krb5_authdata **authdata;
} krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;

extern g_set kg_vdb;

#ifndef LEAN_CLIENT
extern k5_mutex_t gssint_krb5_keytab_lock;
#endif /* LEAN_CLIENT */

/** helper functions **/

OM_uint32 kg_get_defcred
(OM_uint32 *minor_status,
 gss_cred_id_t *cred);

krb5_error_code kg_checksum_channel_bindings
(krb5_context context, gss_channel_bindings_t cb,
 krb5_checksum *cksum);

krb5_error_code kg_make_seq_num (krb5_context context,
                                 krb5_key key,
                                 int direction, krb5_ui_4 seqnum, unsigned char *cksum,
                                 unsigned char *buf);

krb5_error_code kg_get_seq_num (krb5_context context,
                                krb5_key key,
                                unsigned char *cksum, unsigned char *buf, int *direction,
                                krb5_ui_4 *seqnum);

krb5_error_code kg_make_seed (krb5_context context,
                              krb5_key key,
                              unsigned char *seed);

krb5_error_code
kg_setup_keys(krb5_context context,
              krb5_gss_ctx_id_rec *ctx,
              krb5_key subkey,
              krb5_cksumtype *cksumtype);

int kg_confounder_size (krb5_context context, krb5_enctype enctype);

krb5_error_code kg_make_confounder (krb5_context context,
                                    krb5_enctype enctype, unsigned char *buf);

krb5_error_code kg_encrypt (krb5_context context,
                            krb5_key key, int usage,
                            krb5_pointer iv,
                            krb5_const_pointer in,
                            krb5_pointer out,
                            unsigned int length);

/* Encrypt length bytes at ptr in place, with the given key and usage.  If
 * iv is not NULL, use it as the cipher state. */
krb5_error_code kg_encrypt_inplace(krb5_context context, krb5_key key,
                                   int usage, krb5_pointer iv,
                                   krb5_pointer ptr, unsigned int length);

krb5_error_code kg_encrypt_iov (krb5_context context,
                                int proto, int dce_style,
                                size_t ec, size_t rrc,
                                krb5_key key, int usage,
                                krb5_pointer iv,
                                gss_iov_buffer_desc *iov,
                                int iov_count);

krb5_error_code
kg_arcfour_docrypt (const krb5_keyblock *keyblock, int usage,
                    const unsigned char *kd_data, size_t kd_data_len,
                    const unsigned char *input_buf, size_t input_len,
                    unsigned char *output_buf);

krb5_error_code
kg_arcfour_docrypt_iov (krb5_context context,
                        const krb5_keyblock *keyblock, int usage,
                        const unsigned char *kd_data, size_t kd_data_len,
                        gss_iov_buffer_desc *iov,
                        int iov_count);

krb5_error_code kg_decrypt (krb5_context context,
                            krb5_key key,  int usage,
                            krb5_pointer iv,
                            krb5_const_pointer in,
                            krb5_pointer out,
                            unsigned int length);

krb5_error_code kg_decrypt_iov (krb5_context context,
                                int proto, int dce_style,
                                size_t ec, size_t rrc,
                                krb5_key key,  int usage,
                                krb5_pointer iv,
                                gss_iov_buffer_desc *iov,
                                int iov_count);

OM_uint32 kg_seal (OM_uint32 *minor_status,
                   gss_ctx_id_t context_handle,
                   int conf_req_flag,
                   gss_qop_t qop_req,
                   gss_buffer_t input_message_buffer,
                   int *conf_state,
                   gss_buffer_t output_message_buffer,
                   int toktype);

OM_uint32 kg_unseal (OM_uint32 *minor_status,
                     gss_ctx_id_t context_handle,
                     gss_buffer_t input_token_buffer,
                     gss_buffer_t message_buffer,
                     int *conf_state,
                     gss_qop_t *qop_state,
                     int toktype);

OM_uint32 kg_seal_size (OM_uint32 *minor_status,
                        gss_ctx_id_t context_handle,
                        int conf_req_flag,
                        gss_qop_t qop_req,
                        OM_uint32 output_size,
                        OM_uint32 *input_size);

krb5_error_code kg_ctx_size (krb5_context kcontext,
                             krb5_pointer arg,
                             size_t *sizep);

krb5_error_code kg_ctx_externalize (krb5_context kcontext,
                                    krb5_pointer arg,
                                    krb5_octet **buffer,
                                    size_t *lenremain);

krb5_error_code kg_ctx_internalize (krb5_context kcontext,
                                    krb5_pointer *argp,
                                    krb5_octet **buffer,
                                    size_t *lenremain);

OM_uint32 kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status);

OM_uint32 kg_caller_provided_ccache_name (OM_uint32 *minor_status,
                                          int *out_caller_provided_name);

OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status,
                              const char **out_name);

OM_uint32 kg_set_ccache_name (OM_uint32 *minor_status,
                              const char *name);

/* AEAD */

krb5_error_code gss_krb5int_make_seal_token_v3_iov(krb5_context context,
                           krb5_gss_ctx_id_rec *ctx,
                           int conf_req_flag,
                           int *conf_state,
                           gss_iov_buffer_desc *iov,
                           int iov_count,
                           int toktype);

OM_uint32 gss_krb5int_unseal_v3_iov(krb5_context context,
                          OM_uint32 *minor_status,
                          krb5_gss_ctx_id_rec *ctx,
                          gss_iov_buffer_desc *iov,
                          int iov_count,
                          int *conf_state,
                          gss_qop_t *qop_state,
                          int toktype);

gss_iov_buffer_t kg_locate_iov (gss_iov_buffer_desc *iov,
              int iov_count,
              OM_uint32 type);

gss_iov_buffer_t kg_locate_header_iov(gss_iov_buffer_desc *iov, int iov_count,
                                      int toktype);

void kg_iov_msglen(gss_iov_buffer_desc *iov,
              int iov_count,
              size_t *data_length,
              size_t *assoc_data_length);

void kg_release_iov(gss_iov_buffer_desc *iov,
               int iov_count);

krb5_error_code kg_make_checksum_iov_v1(krb5_context context,
                krb5_cksumtype type,
                size_t token_cksum_len,
                krb5_key seq,
                krb5_key enc, /* for conf len */
                krb5_keyusage sign_usage,
                gss_iov_buffer_desc *iov,
                int iov_count,
                int toktype,
                krb5_checksum *checksum);

krb5_error_code kg_make_checksum_iov_v3(krb5_context context,
                krb5_cksumtype type,
                size_t rrc,
                krb5_key key,
                krb5_keyusage sign_usage,
                gss_iov_buffer_desc *iov,
                int iov_count,
                int toktype);

krb5_error_code kg_verify_checksum_iov_v3(krb5_context context,
                krb5_cksumtype type,
                size_t rrc,
                krb5_key key,
                krb5_keyusage sign_usage,
                gss_iov_buffer_desc *iov,
                int iov_count,
                int toktype,
                krb5_boolean *valid);

OM_uint32 kg_seal_iov (OM_uint32 *minor_status,
            gss_ctx_id_t context_handle,
            int conf_req_flag,
            gss_qop_t qop_req,
            int *conf_state,
            gss_iov_buffer_desc *iov,
            int iov_count,
            int toktype);

OM_uint32 kg_unseal_iov (OM_uint32 *minor_status,
            gss_ctx_id_t context_handle,
            int *conf_state,
            gss_qop_t *qop_state,
            gss_iov_buffer_desc *iov,
            int iov_count,
            int toktype);

OM_uint32 kg_seal_iov_length(OM_uint32 *minor_status,
           gss_ctx_id_t context_handle,
           int conf_req_flag,
           gss_qop_t qop_req,
           int *conf_state,
           gss_iov_buffer_desc *iov,
           int iov_count,
           int toktype);

krb5_cryptotype kg_translate_flag_iov(OM_uint32 type);

OM_uint32 kg_fixup_padding_iov(OM_uint32 *minor_status,
        gss_iov_buffer_desc *iov,
        int iov_count);

krb5_boolean kg_integ_only_iov(gss_iov_buffer_desc *iov, int iov_count);

krb5_error_code kg_allocate_iov(gss_iov_buffer_t iov, size_t size);

krb5_error_code
krb5_to_gss_cred(krb5_context context,
                 krb5_creds *creds,
                 krb5_gss_cred_id_t *out_cred);

krb5_boolean
kg_cred_time_to_refresh(krb5_context context, krb5_gss_cred_id_rec *cred);

void
kg_cred_set_initial_refresh(krb5_context context, krb5_gss_cred_id_rec *cred,
                            krb5_ticket_times *times);

OM_uint32
kg_cred_resolve(OM_uint32 *minor_status, krb5_context context,
                gss_cred_id_t cred_handle, gss_name_t target_name);

/** declarations of internal name mechanism functions **/

OM_uint32 KRB5_CALLCONV krb5_gss_acquire_cred
(OM_uint32*,       /* minor_status */
 gss_name_t,       /* desired_name */
 OM_uint32,        /* time_req */
 gss_OID_set,      /* desired_mechs */
 gss_cred_usage_t, /* cred_usage */
 gss_cred_id_t*,   /* output_cred_handle */
 gss_OID_set*,     /* actual_mechs */
 OM_uint32*        /* time_rec */
);

OM_uint32 KRB5_CALLCONV iakerb_gss_acquire_cred
(OM_uint32*,       /* minor_status */
 gss_name_t,       /* desired_name */
 OM_uint32,        /* time_req */
 gss_OID_set,      /* desired_mechs */
 gss_cred_usage_t, /* cred_usage */
 gss_cred_id_t*,   /* output_cred_handle */
 gss_OID_set*,     /* actual_mechs */
 OM_uint32*        /* time_rec */
);

OM_uint32 KRB5_CALLCONV
krb5_gss_acquire_cred_with_password(
    OM_uint32 *minor_status,
    const gss_name_t desired_name,
    const gss_buffer_t password,
    OM_uint32 time_req,
    const gss_OID_set desired_mechs,
    int cred_usage,
    gss_cred_id_t *output_cred_handle,
    gss_OID_set *actual_mechs,
    OM_uint32 *time_rec);

OM_uint32 KRB5_CALLCONV
iakerb_gss_acquire_cred_with_password(
    OM_uint32 *minor_status,
    const gss_name_t desired_name,
    const gss_buffer_t password,
    OM_uint32 time_req,
    const gss_OID_set desired_mechs,
    int cred_usage,
    gss_cred_id_t *output_cred_handle,
    gss_OID_set *actual_mechs,
    OM_uint32 *time_rec);

OM_uint32 KRB5_CALLCONV krb5_gss_release_cred
(OM_uint32*,       /* minor_status */
 gss_cred_id_t*    /* cred_handle */
);

OM_uint32 KRB5_CALLCONV krb5_gss_init_sec_context
(OM_uint32*,       /* minor_status */
 gss_cred_id_t,    /* claimant_cred_handle */
 gss_ctx_id_t*,    /* context_handle */
 gss_name_t,       /* target_name */
 gss_OID,          /* mech_type */
 OM_uint32,        /* req_flags */
 OM_uint32,        /* time_req */
 gss_channel_bindings_t,
 /* input_chan_bindings */
 gss_buffer_t,     /* input_token */
 gss_OID*,         /* actual_mech_type */
 gss_buffer_t,     /* output_token */
 OM_uint32*,       /* ret_flags */
 OM_uint32*        /* time_rec */
);

OM_uint32 krb5_gss_init_sec_context_ext
(OM_uint32*,       /* minor_status */
 gss_cred_id_t,    /* claimant_cred_handle */
 gss_ctx_id_t*,    /* context_handle */
 gss_name_t,       /* target_name */
 gss_OID,          /* mech_type */
 OM_uint32,        /* req_flags */
 OM_uint32,        /* time_req */
 gss_channel_bindings_t,
 /* input_chan_bindings */
 gss_buffer_t,     /* input_token */
 gss_OID*,         /* actual_mech_type */
 gss_buffer_t,     /* output_token */
 OM_uint32*,       /* ret_flags */
 OM_uint32*,       /* time_rec */
 krb5_gss_ctx_ext_t /* exts */
);

#ifndef LEAN_CLIENT
OM_uint32 KRB5_CALLCONV krb5_gss_accept_sec_context
(OM_uint32*,       /* minor_status */
 gss_ctx_id_t*,    /* context_handle */
 gss_cred_id_t,    /* verifier_cred_handle */
 gss_buffer_t,     /* input_token_buffer */
 gss_channel_bindings_t,
 /* input_chan_bindings */
 gss_name_t*,      /* src_name */
 gss_OID*,         /* mech_type */
 gss_buffer_t,     /* output_token */
 OM_uint32*,       /* ret_flags */
 OM_uint32*,       /* time_rec */
 gss_cred_id_t*    /* delegated_cred_handle */
);

OM_uint32 KRB5_CALLCONV krb5_gss_accept_sec_context_ext
(OM_uint32*,       /* minor_status */
 gss_ctx_id_t*,    /* context_handle */
 gss_cred_id_t,    /* verifier_cred_handle */
 gss_buffer_t,     /* input_token_buffer */
 gss_channel_bindings_t,
 /* input_chan_bindings */
 gss_name_t*,      /* src_name */
 gss_OID*,         /* mech_type */
 gss_buffer_t,     /* output_token */
 OM_uint32*,       /* ret_flags */
 OM_uint32*,       /* time_rec */
 gss_cred_id_t*,   /* delegated_cred_handle */
 krb5_gss_ctx_ext_t/*exts */
);
#endif /* LEAN_CLIENT */

OM_uint32 KRB5_CALLCONV krb5_gss_process_context_token
(OM_uint32*,       /* minor_status */
 gss_ctx_id_t,     /* context_handle */
 gss_buffer_t      /* token_buffer */
);

OM_uint32 KRB5_CALLCONV krb5_gss_delete_sec_context
(OM_uint32*,       /* minor_status */
 gss_ctx_id_t*,    /* context_handle */
 gss_buffer_t      /* output_token */
);

OM_uint32 KRB5_CALLCONV krb5_gss_context_time
(OM_uint32*,       /* minor_status */
 gss_ctx_id_t,     /* context_handle */
 OM_uint32*        /* time_rec */
);

OM_uint32 KRB5_CALLCONV krb5_gss_display_status
(OM_uint32*,       /* minor_status */
 OM_uint32,        /* status_value */
 int,              /* status_type */
 gss_OID,          /* mech_type */
 OM_uint32*,       /* message_context */
 gss_buffer_t      /* status_string */
);

OM_uint32 KRB5_CALLCONV krb5_gss_indicate_mechs
(OM_uint32*,       /* minor_status */
 gss_OID_set*      /* mech_set */
);

OM_uint32 KRB5_CALLCONV krb5_gss_compare_name
(OM_uint32*,       /* minor_status */
 gss_name_t,       /* name1 */
 gss_name_t,       /* name2 */
 int*              /* name_equal */
);

OM_uint32 KRB5_CALLCONV krb5_gss_display_name
(OM_uint32*,      /* minor_status */
 gss_name_t,      /* input_name */
 gss_buffer_t,    /* output_name_buffer */
 gss_OID*         /* output_name_type */
);


OM_uint32 KRB5_CALLCONV krb5_gss_import_name
(OM_uint32*,       /* minor_status */
 gss_buffer_t,     /* input_name_buffer */
 gss_OID,          /* input_name_type */
 gss_name_t*       /* output_name */
);

OM_uint32 KRB5_CALLCONV krb5_gss_release_name
(OM_uint32*,       /* minor_status */
 gss_name_t*       /* input_name */
);

OM_uint32 KRB5_CALLCONV krb5_gss_inquire_cred
(OM_uint32 *,      /* minor_status */
 gss_cred_id_t,    /* cred_handle */
 gss_name_t *,     /* name */
 OM_uint32 *,      /* lifetime */
 gss_cred_usage_t*,/* cred_usage */
 gss_OID_set *     /* mechanisms */
);

OM_uint32 KRB5_CALLCONV krb5_gss_inquire_context
(OM_uint32*,       /* minor_status */
 gss_ctx_id_t,     /* context_handle */
 gss_name_t*,      /* initiator_name */
 gss_name_t*,      /* acceptor_name */
 OM_uint32*,       /* lifetime_rec */
 gss_OID*,         /* mech_type */
 OM_uint32*,       /* ret_flags */
 int*,             /* locally_initiated */
 int*              /* open */
);

/* New V2 entry points */
OM_uint32 KRB5_CALLCONV krb5_gss_get_mic
(OM_uint32 *,           /* minor_status */
 gss_ctx_id_t,               /* context_handle */
 gss_qop_t,                  /* qop_req */
 gss_buffer_t,               /* message_buffer */
 gss_buffer_t                /* message_token */
);

OM_uint32 KRB5_CALLCONV krb5_gss_get_mic_iov
(OM_uint32 *,                /* minor_status */
 gss_ctx_id_t,               /* context_handle */
 gss_qop_t,                  /* qop_req */
 gss_iov_buffer_desc *,      /* iov */
 int                         /* iov_count */
);

OM_uint32 KRB5_CALLCONV krb5_gss_get_mic_iov_length
(OM_uint32 *,                /* minor_status */
 gss_ctx_id_t,               /* context_handle */
 gss_qop_t,                  /* qop_req */
 gss_iov_buffer_desc *,      /* iov */
 int                         /* iov_count */
);

OM_uint32 KRB5_CALLCONV krb5_gss_verify_mic
(OM_uint32 *,           /* minor_status */
 gss_ctx_id_t,               /* context_handle */
 gss_buffer_t,               /* message_buffer */
 gss_buffer_t,               /* message_token */
 gss_qop_t *                 /* qop_state */
);

OM_uint32 KRB5_CALLCONV krb5_gss_verify_mic_iov
(OM_uint32 *,                /* minor_status */
 gss_ctx_id_t,               /* context_handle */
 gss_qop_t *,                /* qop_state */
 gss_iov_buffer_desc *,      /* iov */
 int                         /* iov_count */
);

OM_uint32 KRB5_CALLCONV krb5_gss_wrap
(OM_uint32 *,           /* minor_status */
 gss_ctx_id_t,               /* context_handle */
 int,                        /* conf_req_flag */
 gss_qop_t,                  /* qop_req */
 gss_buffer_t,               /* input_message_buffer */
 int *,                      /* conf_state */
 gss_buffer_t                /* output_message_buffer */
);

OM_uint32 KRB5_CALLCONV krb5_gss_wrap_iov
(OM_uint32 *,           /* minor_status */
 gss_ctx_id_t,              /* context_handle */
 int,                       /* conf_req_flag */
 gss_qop_t,                 /* qop_req */
 int *,                     /* conf_state */
 gss_iov_buffer_desc *,     /* iov */
 int                        /* iov_count */
);

OM_uint32 KRB5_CALLCONV krb5_gss_wrap_iov_length
(OM_uint32 *,           /* minor_status */
 gss_ctx_id_t,              /* context_handle */
 int,                       /* conf_req_flag */
 gss_qop_t,                 /* qop_req */
 int *,                     /* conf_state */
 gss_iov_buffer_desc *,     /* iov */
 int                        /* iov_count */
);

OM_uint32 KRB5_CALLCONV krb5_gss_unwrap
(OM_uint32 *,           /* minor_status */
 gss_ctx_id_t,               /* context_handle */
 gss_buffer_t,               /* input_message_buffer */
 gss_buffer_t,               /* output_message_buffer */
 int *,                      /* conf_state */
 gss_qop_t *                 /* qop_state */
);

OM_uint32 KRB5_CALLCONV krb5_gss_unwrap_iov
(OM_uint32 *,           /* minor_status */
 gss_ctx_id_t,              /* context_handle */
 int *,                     /* conf_state */
 gss_qop_t *,               /* qop_state */
 gss_iov_buffer_desc *,     /* iov */
 int                        /* iov_count */
);

OM_uint32 KRB5_CALLCONV krb5_gss_wrap_size_limit
(OM_uint32 *,           /* minor_status */
 gss_ctx_id_t,               /* context_handle */
 int,                        /* conf_req_flag */
 gss_qop_t,                  /* qop_req */
 OM_uint32,                  /* req_output_size */
 OM_uint32 *                 /* max_input_size */
);

OM_uint32 KRB5_CALLCONV krb5_gss_import_name_object
(OM_uint32 *,           /* minor_status */
 void *,                     /* input_name */
 gss_OID,                    /* input_name_type */
 gss_name_t *                /* output_name */
);

OM_uint32 KRB5_CALLCONV krb5_gss_export_name_object
(OM_uint32 *,           /* minor_status */
 gss_name_t,                 /* input_name */
 gss_OID,                    /* desired_name_type */
 void * *                    /* output_name */
);

OM_uint32 KRB5_CALLCONV krb5_gss_inquire_cred_by_mech
(OM_uint32  *,          /* minor_status */
 gss_cred_id_t,              /* cred_handle */
 gss_OID,                    /* mech_type */
 gss_name_t *,               /* name */
 OM_uint32 *,                /* initiator_lifetime */
 OM_uint32 *,                /* acceptor_lifetime */
 gss_cred_usage_t *          /* cred_usage */
);
#ifndef LEAN_CLIENT
OM_uint32 KRB5_CALLCONV krb5_gss_export_sec_context
(OM_uint32 *,           /* minor_status */
 gss_ctx_id_t *,             /* context_handle */
 gss_buffer_t                /* interprocess_token */
);

OM_uint32 KRB5_CALLCONV krb5_gss_import_sec_context
(OM_uint32 *,           /* minor_status */
 gss_buffer_t,               /* interprocess_token */
 gss_ctx_id_t *              /* context_handle */
);
#endif /* LEAN_CLIENT */

krb5_error_code krb5_gss_ser_init(krb5_context);

OM_uint32 krb5_gss_release_oid
(OM_uint32 *,           /* minor_status */
 gss_OID *                   /* oid */
);

OM_uint32 KRB5_CALLCONV krb5_gss_internal_release_oid
(OM_uint32 *,           /* minor_status */
 gss_OID *                   /* oid */
);

OM_uint32 KRB5_CALLCONV krb5_gss_inquire_names_for_mech
(OM_uint32 *,           /* minor_status */
 gss_OID,                    /* mechanism */
 gss_OID_set *               /* name_types */
);

OM_uint32 krb5_gss_canonicalize_name
(OM_uint32  *,          /* minor_status */
 const gss_name_t,           /* input_name */
 const gss_OID,              /* mech_type */
 gss_name_t *                /* output_name */
);

OM_uint32 KRB5_CALLCONV krb5_gss_export_name
(OM_uint32  *,          /* minor_status */
 const gss_name_t,           /* input_name */
 gss_buffer_t                /* exported_name */
);

OM_uint32 KRB5_CALLCONV krb5_gss_duplicate_name
(OM_uint32  *,          /* minor_status */
 const gss_name_t,           /* input_name */
 gss_name_t *                /* dest_name */
);

OM_uint32 krb5_gss_validate_cred
(OM_uint32 *,           /* minor_status */
 gss_cred_id_t               /* cred */
);

OM_uint32 KRB5_CALLCONV krb5_gss_acquire_cred_impersonate_name(
    OM_uint32 *,            /* minor_status */
    const gss_cred_id_t,    /* impersonator_cred_handle */
    const gss_name_t,       /* desired_name */
    OM_uint32,              /* time_req */
    const gss_OID_set,      /* desired_mechs */
    gss_cred_usage_t,       /* cred_usage */
    gss_cred_id_t *,        /* output_cred_handle */
    gss_OID_set *,          /* actual_mechs */
    OM_uint32 *);           /* time_rec */

OM_uint32
krb5_gss_validate_cred_1(OM_uint32 * /* minor_status */,
                         gss_cred_id_t /* cred_handle */,
                         krb5_context /* context */);

gss_OID krb5_gss_convert_static_mech_oid(gss_OID oid);

krb5_error_code gss_krb5int_make_seal_token_v3(krb5_context,
                                               krb5_gss_ctx_id_rec *,
                                               const gss_buffer_desc *,
                                               gss_buffer_t,
                                               int, int);

OM_uint32 gss_krb5int_unseal_token_v3(krb5_context *contextptr,
                                      OM_uint32 *minor_status,
                                      krb5_gss_ctx_id_rec *ctx,
                                      unsigned char *ptr,
                                      unsigned int bodysize,
                                      gss_buffer_t message_buffer,
                                      int *conf_state, gss_qop_t *qop_state,
                                      int toktype);

int gss_krb5int_rotate_left (void *ptr, size_t bufsiz, size_t rc);

/* naming_exts.c */
#define KG_INIT_NAME_NO_COPY 0x1

krb5_error_code
kg_init_name(krb5_context context, krb5_principal principal,
             char *service, char *host, krb5_authdata_context ad_context,
             krb5_flags flags, krb5_gss_name_t *name);

krb5_error_code
kg_release_name(krb5_context context, krb5_gss_name_t *name);

krb5_error_code
kg_duplicate_name(krb5_context context, const krb5_gss_name_t src,
                  krb5_gss_name_t *dst);

krb5_boolean
kg_compare_name(krb5_context context,
                krb5_gss_name_t name1,
                krb5_gss_name_t name2);

krb5_boolean
kg_acceptor_princ(krb5_context context, krb5_gss_name_t name,
                  krb5_principal *princ_out);

OM_uint32 KRB5_CALLCONV
krb5_gss_display_name_ext(OM_uint32 *minor_status,
                          gss_name_t name,
                          gss_OID display_as_name_type,
                          gss_buffer_t display_name);

OM_uint32 KRB5_CALLCONV
krb5_gss_inquire_name(OM_uint32 *minor_status,
                      gss_name_t name,
                      int *name_is_MN,
                      gss_OID *MN_mech,
                      gss_buffer_set_t *attrs);

OM_uint32 KRB5_CALLCONV
krb5_gss_get_name_attribute(OM_uint32 *minor_status,
                            gss_name_t name,
                            gss_buffer_t attr,
                            int *authenticated,
                            int *complete,
                            gss_buffer_t value,
                            gss_buffer_t display_value,
                            int *more);

OM_uint32 KRB5_CALLCONV
krb5_gss_set_name_attribute(OM_uint32 *minor_status,
                            gss_name_t name,
                            int complete,
                            gss_buffer_t attr,
                            gss_buffer_t value);

OM_uint32 KRB5_CALLCONV
krb5_gss_delete_name_attribute(OM_uint32 *minor_status,
                               gss_name_t name,
                               gss_buffer_t attr);

OM_uint32 KRB5_CALLCONV
krb5_gss_export_name_composite(OM_uint32 *minor_status,
                               gss_name_t name,
                               gss_buffer_t exp_composite_name);

OM_uint32 KRB5_CALLCONV
krb5_gss_map_name_to_any(OM_uint32 *minor_status,
                         gss_name_t name,
                         int authenticated,
                         gss_buffer_t type_id,
                         gss_any_t *output);

OM_uint32 KRB5_CALLCONV
krb5_gss_release_any_name_mapping(OM_uint32 *minor_status,
                                  gss_name_t name,
                                  gss_buffer_t type_id,
                                  gss_any_t *input);

OM_uint32 KRB5_CALLCONV
krb5_gss_pseudo_random(OM_uint32 *minor_status,
                       gss_ctx_id_t context,
                       int prf_key,
                       const gss_buffer_t prf_in,
                       ssize_t desired_output_len,
                       gss_buffer_t prf_out);

OM_uint32 KRB5_CALLCONV
krb5_gss_store_cred(OM_uint32 *minor_status,
                    gss_cred_id_t input_cred_handle,
                    gss_cred_usage_t cred_usage,
                    const gss_OID desired_mech,
                    OM_uint32 overwrite_cred,
                    OM_uint32 default_cred,
                    gss_OID_set *elements_stored,
                    gss_cred_usage_t *cred_usage_stored);

/* s4u_gss_glue.c */
OM_uint32
kg_compose_deleg_cred(OM_uint32 *minor_status,
                      krb5_gss_cred_id_t impersonator_cred,
                      krb5_creds *subject_creds,
                      OM_uint32 time_req,
                      krb5_gss_cred_id_t *output_cred,
                      OM_uint32 *time_rec,
                      krb5_context context);

/*
 * These take unglued krb5-mech-specific contexts.
 */

#define GSS_KRB5_GET_TKT_FLAGS_OID_LENGTH 11
#define GSS_KRB5_GET_TKT_FLAGS_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x01"

OM_uint32 gss_krb5int_get_tkt_flags
(OM_uint32 *minor_status,
 const gss_ctx_id_t context_handle,
 const gss_OID desired_object,
 gss_buffer_set_t *data_set);

#define GSS_KRB5_COPY_CCACHE_OID_LENGTH 11
#define GSS_KRB5_COPY_CCACHE_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x02"

OM_uint32 gss_krb5int_copy_ccache
(OM_uint32 *minor_status,
 gss_cred_id_t *cred_handle,
 const gss_OID desired_oid,
 const gss_buffer_t value);

#define GSS_KRB5_CCACHE_NAME_OID_LENGTH 11
#define GSS_KRB5_CCACHE_NAME_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x03"

struct krb5_gss_ccache_name_req {
    const char *name;
    const char **out_name;
};

OM_uint32
gss_krb5int_ccache_name(OM_uint32 *minor_status, const gss_OID, const gss_OID,
                        const gss_buffer_t);

#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH 11
#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"

OM_uint32
gss_krb5int_inq_session_key(OM_uint32 *, const gss_ctx_id_t, const gss_OID, gss_buffer_set_t *);

#define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID_LENGTH 11
#define GSS_KRB5_SET_ALLOWABLE_ENCTYPES_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x04"

struct krb5_gss_set_allowable_enctypes_req {
    OM_uint32 num_ktypes;
    krb5_enctype *ktypes;
};

OM_uint32
gss_krb5int_set_allowable_enctypes(OM_uint32 *minor_status,
                                   gss_cred_id_t *cred,
                                   const gss_OID desired_oid,
                                   const gss_buffer_t value);

#define GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH 11
#define GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x06"

OM_uint32
gss_krb5int_export_lucid_sec_context(OM_uint32 *minor_status,
                                     const gss_ctx_id_t context_handle,
                                     const gss_OID desired_object,
                                     gss_buffer_set_t *data_set);

#define GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID_LENGTH 11
#define GSS_KRB5_FREE_LUCID_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x07"

OM_uint32
gss_krb5int_free_lucid_sec_context(OM_uint32 *, const gss_OID,
                                   const gss_OID, gss_buffer_t);

extern k5_mutex_t kg_kdc_flag_mutex;
krb5_error_code krb5_gss_init_context (krb5_context *ctxp);

#define GSS_KRB5_USE_KDC_CONTEXT_OID_LENGTH 11
#define GSS_KRB5_USE_KDC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x08"

OM_uint32 krb5int_gss_use_kdc_context(OM_uint32 *, const gss_OID,
                                      const gss_OID, gss_buffer_t);

krb5_error_code krb5_gss_use_kdc_context(void);

#define GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID_LENGTH 11
#define GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x09"

OM_uint32
gss_krb5int_register_acceptor_identity(OM_uint32 *, const gss_OID, const gss_OID, gss_buffer_t);

#define GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH 11
#define GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0a"

OM_uint32
gss_krb5int_extract_authz_data_from_sec_context(OM_uint32 *minor_status,
                                                const gss_ctx_id_t context_handle,
                                                const gss_OID desired_object,
                                                gss_buffer_set_t *ad_data);

#define GSS_KRB5_SET_CRED_RCACHE_OID_LENGTH 11
#define GSS_KRB5_SET_CRED_RCACHE_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0b"

OM_uint32
gss_krb5int_set_cred_rcache(OM_uint32 *, gss_cred_id_t *, const gss_OID, const gss_buffer_t);

#define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH 11
#define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0c"

OM_uint32
gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *,
                                              const gss_ctx_id_t,
                                              const gss_OID,
                                              gss_buffer_set_t *);

#define GSS_KRB5_IMPORT_CRED_OID_LENGTH 11
#define GSS_KRB5_IMPORT_CRED_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0d"

struct krb5_gss_import_cred_req {
    krb5_ccache id;
    krb5_principal keytab_principal;
    krb5_keytab keytab;
};

OM_uint32
gss_krb5int_import_cred(OM_uint32 *minor_status,
                        gss_cred_id_t *cred,
                        const gss_OID desired_oid,
                        const gss_buffer_t value);

#ifdef _GSS_STATIC_LINK
int gss_krb5int_lib_init(void);
void gss_krb5int_lib_fini(void);
#endif /* _GSS_STATIC_LINK */

OM_uint32 gss_krb5int_initialize_library(void);
void gss_krb5int_cleanup_library(void);

/* For error message handling.  */
/* Returns a shared string, not a private copy!  */
extern char *
krb5_gss_get_error_message(OM_uint32 minor_code);
extern void
krb5_gss_save_error_string(OM_uint32 minor_code, char *msg);
extern void
krb5_gss_save_error_message(OM_uint32 minor_code, const char *format, ...)
#if !defined(__cplusplus) && (__GNUC__ > 2)
    __attribute__((__format__(__printf__, 2, 3)))
#endif
    ;
    extern void
    krb5_gss_save_error_info(OM_uint32 minor_code, krb5_context ctx);
#define get_error_message krb5_gss_get_error_message
#define save_error_string krb5_gss_save_error_string
#define save_error_message krb5_gss_save_error_message
#ifdef KRB5_KERNEL
/* Error messages aren't needed in the kernel, so reduce dependencies. */
#define save_error_info(x,y)
#else
#define save_error_info krb5_gss_save_error_info
#endif
extern void krb5_gss_delete_error_info(void *p);

/* Prefix concatenated with Kerberos encryption type */
#define GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH 10
#define GSS_KRB5_SESSION_KEY_ENCTYPE_OID  "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x04"

/* IAKERB */

OM_uint32 KRB5_CALLCONV
iakerb_gss_init_sec_context(OM_uint32 *minor_status,
                            gss_cred_id_t claimant_cred_handle,
                            gss_ctx_id_t *context_handle,
                            gss_name_t target_name,
                            gss_OID mech_type,
                            OM_uint32 req_flags,
                            OM_uint32 time_req,
                            gss_channel_bindings_t input_chan_bindings,
                            gss_buffer_t input_token,
                            gss_OID *actual_mech_type,
                            gss_buffer_t output_token,
                            OM_uint32 *ret_flags,
                            OM_uint32 *time_rec);

OM_uint32 KRB5_CALLCONV
iakerb_gss_accept_sec_context(OM_uint32 *minor_status,
                              gss_ctx_id_t *context_handler,
                              gss_cred_id_t verifier_cred_handle,
                              gss_buffer_t input_token,
                              gss_channel_bindings_t input_chan_bindings,
                              gss_name_t *src_name,
                              gss_OID *mech_type,
                              gss_buffer_t output_token,
                              OM_uint32 *ret_flags,
                              OM_uint32 *time_rec,
                              gss_cred_id_t *delegated_cred_handle);

OM_uint32 KRB5_CALLCONV
iakerb_gss_delete_sec_context(OM_uint32 *minor_status,
                              gss_ctx_id_t *context_handle,
                              gss_buffer_t output_token);

krb5_error_code
iakerb_make_finished(krb5_context context,
                     krb5_key key,
                     const krb5_data *conv,
                     krb5_data **finished);

krb5_error_code
iakerb_verify_finished(krb5_context context,
                       krb5_key key,
                       const krb5_data *conv,
                       const krb5_data *finished);

/*
 * Transfer contents of a krb5_data to a gss_buffer and invalidate the source
 * On unix, this is a simple pointer copy
 * On windows, memory is reallocated and copied.
 */
static inline krb5_error_code
data_to_gss(krb5_data *input_k5data, gss_buffer_t output_buffer)
{
    krb5_error_code code = 0;
    output_buffer->length = input_k5data->length;
#if defined(_WIN32) || defined(DEBUG_GSSALLOC)
    if (output_buffer->length > 0) {
        output_buffer->value = gssalloc_malloc(output_buffer->length);
        if (output_buffer->value)
            memcpy(output_buffer->value, input_k5data->data, output_buffer->length);
        else
            code = ENOMEM;
    } else {
        output_buffer->value = NULL;
    }
    free(input_k5data->data);
#else
    output_buffer->value = input_k5data->data;
#endif
    *input_k5data = empty_data();
    return code;
}

#define KRB5_GSS_EXTS_IAKERB_FINISHED 1


/* Credential store extensions */

#define KRB5_CS_CLI_KEYTAB_URN "client_keytab"
#define KRB5_CS_KEYTAB_URN "keytab"
#define KRB5_CS_CCACHE_URN "ccache"

OM_uint32
kg_value_from_cred_store(gss_const_key_value_set_t cred_store,
                         const char *type, const char **value);

OM_uint32 KRB5_CALLCONV
krb5_gss_acquire_cred_from(
    OM_uint32 *,               /* minor_status */
    const gss_name_t,          /* desired_name */
    OM_uint32,                 /* time_req */
    const gss_OID_set,         /* desired_mechs */
    gss_cred_usage_t,          /* cred_usage */
    gss_const_key_value_set_t, /* cred_store */
    gss_cred_id_t *,           /* output_cred_handle */
    gss_OID_set *,             /* actual_mechs */
    OM_uint32 *);              /* time_rec */

OM_uint32 KRB5_CALLCONV
krb5_gss_store_cred_into(
    OM_uint32 *,               /* minor_status */
    gss_cred_id_t,             /* input_cred_handle */
    gss_cred_usage_t,          /* input_usage */
    const gss_OID,             /* desired_mech */
    OM_uint32,                 /* overwrite_cred */
    OM_uint32,                 /* default_cred */
    gss_const_key_value_set_t, /* cred_store */
    gss_OID_set *,             /* elements_stored */
    gss_cred_usage_t *);       /* cred_usage_stored */

OM_uint32 KRB5_CALLCONV
krb5_gss_export_cred(OM_uint32 *minor_status, gss_cred_id_t cred_handle,
                     gss_buffer_t token);

OM_uint32 KRB5_CALLCONV
krb5_gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token,
                     gss_cred_id_t *cred_handle);

/* Magic string to identify exported krb5 GSS credentials.  Increment this if
 * the format changes. */
#define CRED_EXPORT_MAGIC "K5C1"

#endif /* _GSSAPIP_KRB5_H_ */