r8112: Remove extra headers, and add #ifdef to allow the 'not yet using
[jelmer/samba4-debian.git] / source / torture / auth / pac.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Validate the krb5 pac generation routines
5    
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25 #include "system/kerberos.h"
26 #include "auth/auth.h"
27 #include "auth/kerberos/kerberos.h"
28 #include "librpc/gen_ndr/ndr_krb5pac.h"
29
30 #ifdef HAVE_KRB5
31
32 static BOOL torture_pac_self_check(void) 
33 {
34         NTSTATUS nt_status;
35         TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC self check");
36         DATA_BLOB tmp_blob;
37         struct PAC_LOGON_INFO *pac_info;
38
39         /* Generate a nice, arbitary keyblock */
40         uint8_t server_bytes[16];
41         uint8_t krbtgt_bytes[16];
42         krb5_keyblock server_keyblock;
43         krb5_keyblock krbtgt_keyblock;
44         
45         krb5_error_code ret;
46
47         struct smb_krb5_context *smb_krb5_context;
48
49         struct auth_serversupplied_info *server_info;
50
51         ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
52
53         if (ret) {
54                 talloc_free(mem_ctx);
55                 return False;
56         }
57
58         generate_random_buffer(server_bytes, 16);
59         generate_random_buffer(krbtgt_bytes, 16);
60
61         ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
62                                  ENCTYPE_ARCFOUR_HMAC,
63                                  server_bytes, sizeof(server_bytes),
64                                  &server_keyblock);
65         if (ret) {
66                 DEBUG(1, ("Server Keyblock encoding failed: %s\n", 
67                           smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
68                                                      ret, mem_ctx)));
69
70                 talloc_free(mem_ctx);
71                 return False;
72         }
73
74         ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
75                                  ENCTYPE_ARCFOUR_HMAC,
76                                  krbtgt_bytes, sizeof(krbtgt_bytes),
77                                  &krbtgt_keyblock);
78         if (ret) {
79                 DEBUG(1, ("KRBTGT Keyblock encoding failed: %s\n", 
80                           smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
81                                                      ret, mem_ctx)));
82
83                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
84                                             &server_keyblock);
85                 talloc_free(mem_ctx);
86                 return False;
87         }
88
89         /* We need an input, and this one requires no underlying database */
90         nt_status = auth_anonymous_server_info(mem_ctx, &server_info);
91
92         if (!NT_STATUS_IS_OK(nt_status)) {
93                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
94                                             &server_keyblock);
95                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
96                                             &krbtgt_keyblock);
97                 talloc_free(mem_ctx);
98                 return False;
99         }
100         
101         /* OK, go ahead and make a PAC */
102         ret = kerberos_encode_pac(mem_ctx, server_info, 
103                                   smb_krb5_context->krb5_context,  
104                                   &krbtgt_keyblock,
105                                   &server_keyblock,
106                                   &tmp_blob);
107         
108         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
109                                     &krbtgt_keyblock);
110
111         if (ret) {
112                 DEBUG(1, ("PAC encoding failed: %s\n", 
113                           smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
114                                                      ret, mem_ctx)));
115
116                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
117                                             &server_keyblock);
118                 talloc_free(mem_ctx);
119                 return False;
120         }
121         
122         /* Now check that we can read it back */
123         nt_status = kerberos_decode_pac(mem_ctx, &pac_info,
124                                         tmp_blob,
125                                         smb_krb5_context,
126                                         &server_keyblock);
127         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
128                                     &server_keyblock);
129         if (ret) {
130                 DEBUG(1, ("PAC decoding failed: %s\n", 
131                           nt_errstr(nt_status)));
132
133                 talloc_free(mem_ctx);
134                 return False;
135         }
136
137         talloc_free(mem_ctx);
138         return True;
139 }
140
141
142 /* This is the PAC generated on my test network, by my test Win2k3 server.
143    -- abartlet 2005-07-04
144  */
145
146 static const char saved_pac[] = {
147         0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 
148         0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
149         0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
150         0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
151         0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
152         0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb, 
153         0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 
154         0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
155         0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
156         0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
157         0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
158         0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00, 
159         0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
160         0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161         0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
162         0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163         0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165         0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166         0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
167         0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
168         0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172         0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
173         0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
174         0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
175         0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
176         0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
177         0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
178         0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
179         0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
180         0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181         0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
182         0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
183         0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
184         0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
185         0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
186 };
187
188 /* Check with a known 'well formed' PAC, from my test server */
189 static BOOL torture_pac_saved_check(void) 
190 {
191         NTSTATUS nt_status;
192         TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC saved check");
193         DATA_BLOB tmp_blob;
194         struct PAC_LOGON_INFO *pac_info;
195         krb5_keyblock server_keyblock;
196         uint8_t server_bytes[16];
197         
198         krb5_error_code ret;
199
200         struct smb_krb5_context *smb_krb5_context;
201
202         ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
203
204         if (ret) {
205                 talloc_free(mem_ctx);
206                 return False;
207         }
208
209         /* The machine trust account in use when the above PAC 
210            was generated.  It used arcfour-hmac-md5, so this is easy */
211         E_md4hash("iqvwmii8CuEkyY", server_bytes);
212
213         ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
214                                  ENCTYPE_ARCFOUR_HMAC,
215                                  server_bytes, sizeof(server_bytes),
216                                  &server_keyblock);
217         if (ret) {
218                 DEBUG(1, ("Server Keyblock encoding failed: %s\n", 
219                           smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
220                                                      ret, mem_ctx)));
221
222                 talloc_free(mem_ctx);
223                 return False;
224         }
225
226         tmp_blob = data_blob_const(saved_pac, sizeof(saved_pac));
227
228         /* Decode and verify the signaure on the PAC */
229         nt_status = kerberos_decode_pac(mem_ctx, &pac_info,
230                                         tmp_blob,
231                                         smb_krb5_context,
232                                         &server_keyblock);
233         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, 
234                                     &server_keyblock);
235         if (ret) {
236                 DEBUG(1, ("PAC decoding failed: %s\n", 
237                           nt_errstr(nt_status)));
238
239                 talloc_free(mem_ctx);
240                 return False;
241         }
242         talloc_free(mem_ctx);
243         return True;
244 }
245
246 BOOL torture_pac(void) 
247 {
248         BOOL ret = True;
249         ret &= torture_pac_self_check();
250         ret &= torture_pac_saved_check();
251         return ret;
252 }
253
254 #else 
255
256 BOOL torture_pac(void) 
257 {
258         printf("Cannot do PAC test without Krb5\n");
259         return False;
260 }
261
262 #endif
263