1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* plugins/audit/au_simple_main.c - Sample Audit plugin implementation */
3 /*
4  * Copyright (C) 2013 by the Massachusetts Institute of Technology.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  *
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in
16  *   the documentation and/or other materials provided with the
17  *   distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30  * OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * This is a demo implementation of Audit JSON-based module.
35  * It utilizes MIT Kerberos <kdc_j_encode.h> routines for JSON processing and
36  * the Fedora/Debian libaudit library for audit logs.
37  */
38 
39 #include <k5-int.h>
40 #include <krb5/audit_plugin.h>
41 #include <libaudit.h>
42 #include <kdc_j_encode.h>
43 
44 krb5_error_code
45 audit_simple_initvt(krb5_context context, int maj_ver, int min_ver,
46                     krb5_plugin_vtable vtable);
47 
48 struct krb5_audit_moddata_st {
49     int fd;
50 };
51 
52 /* Open connection to the audit system. Returns 0 on success. */
53 static krb5_error_code
open_au(krb5_audit_moddata * auctx_out)54 open_au(krb5_audit_moddata *auctx_out)
55 {
56     krb5_error_code ret;
57     int fd = 0;
58     krb5_audit_moddata auctx;
59 
60     auctx = k5calloc(1, sizeof(*auctx), &ret);
61     if (ret)
62         return ENOMEM;
63     fd = audit_open();
64     if (fd < 0)
65         return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
66 
67     auctx->fd = fd;
68     *auctx_out = auctx;
69 
70     return 0;
71 }
72 
73 /* Close connection to the audit system. Returns 0 on success. */
74 static krb5_error_code
close_au(krb5_audit_moddata auctx)75 close_au(krb5_audit_moddata auctx)
76 {
77     int fd = auctx->fd;
78 
79     audit_close(fd);
80     return 0;
81 }
82 
83 /* Log KDC-start event. Returns 0 on success. */
84 static krb5_error_code
j_kdc_start(krb5_audit_moddata auctx,krb5_boolean ev_success)85 j_kdc_start(krb5_audit_moddata auctx, krb5_boolean ev_success)
86 {
87     krb5_error_code ret = 0;
88     int local_type = AUDIT_USER_START;
89     int fd = auctx->fd;
90     char *jout = NULL;
91 
92     if (fd < 0)
93         return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
94 
95     ret = kau_j_kdc_start(ev_success, &jout);
96     if (ret)
97         return ret;
98     if (audit_log_user_message(fd, local_type, jout,
99                                NULL, NULL, NULL, ev_success) <= 0)
100         ret = EIO;
101     free(jout);
102     return ret;
103 }
104 
105 /* Log KDC-stop event. Returns 0 on success. */
106 static krb5_error_code
j_kdc_stop(krb5_audit_moddata auctx,krb5_boolean ev_success)107 j_kdc_stop(krb5_audit_moddata auctx, krb5_boolean ev_success)
108 {
109     krb5_error_code ret = 0;
110     int local_type = AUDIT_USER_END;
111     int fd = auctx->fd;
112     char *jout = NULL;
113 
114     if (fd < 0)
115         return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
116 
117     ret = kau_j_kdc_stop(ev_success, &jout);
118     if (ret)
119         return ret;
120     if (audit_log_user_message(fd, local_type, jout,
121                                NULL, NULL, NULL, ev_success) <= 0)
122         ret = EIO;
123     free(jout);
124     return ret;
125 }
126 
127 /* Log AS_REQ event. Returns 0 on success */
128 static krb5_error_code
j_as_req(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)129 j_as_req(krb5_audit_moddata auctx, krb5_boolean ev_success,
130          krb5_audit_state *state)
131 {
132     krb5_error_code ret = 0;
133     int local_type = AUDIT_USER_AUTH;
134     int fd = auctx->fd;
135     char *jout = NULL;
136 
137     if (fd < 0)
138         return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
139 
140     ret = kau_j_as_req(ev_success, state, &jout);
141     if (ret)
142         return ret;
143     if (audit_log_user_message(fd, local_type, jout,
144                                NULL, NULL, NULL, ev_success) <= 0)
145         ret = EIO;
146     free(jout);
147     return ret;
148 }
149 
150 /* Log TGS_REQ event. Returns 0 on success */
151 static krb5_error_code
j_tgs_req(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)152 j_tgs_req(krb5_audit_moddata auctx, krb5_boolean ev_success,
153           krb5_audit_state *state)
154 {
155     krb5_error_code ret = 0;
156     int local_type = AUDIT_USER_AUTH;
157     int fd = auctx->fd;
158     char *jout = NULL;
159 
160     if (fd < 0)
161         return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
162 
163     ret = kau_j_tgs_req(ev_success, state, &jout);
164     if (ret)
165         return ret;
166     if (audit_log_user_message(fd, local_type, jout,
167                                NULL, NULL, NULL, ev_success) <= 0)
168         ret = EIO;
169     free(jout);
170     return ret;
171 }
172 
173 /* Log S4U2SELF event. Returns 0 on success */
174 static krb5_error_code
j_tgs_s4u2self(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)175 j_tgs_s4u2self(krb5_audit_moddata auctx, krb5_boolean ev_success,
176                krb5_audit_state *state)
177 {
178     krb5_error_code ret = 0;
179     int local_type = AUDIT_USER_AUTH;
180     int fd = auctx->fd;
181     char *jout = NULL;
182 
183     if (fd < 0)
184         return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
185 
186     ret = kau_j_tgs_s4u2self(ev_success, state, &jout);
187     if (ret)
188         return ret;
189     if (audit_log_user_message(fd, local_type, jout,
190                                NULL, NULL, NULL, ev_success) <= 0)
191         ret = EIO;
192     free(jout);
193     return ret;
194 }
195 
196 /* Log S4U2PROXY event. Returns 0 on success */
197 static krb5_error_code
j_tgs_s4u2proxy(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)198 j_tgs_s4u2proxy(krb5_audit_moddata auctx, krb5_boolean ev_success,
199                 krb5_audit_state *state)
200 {
201     krb5_error_code ret = 0;
202     int local_type = AUDIT_USER_AUTH;
203     int fd = auctx->fd;
204     char *jout = NULL;
205 
206     if (fd < 0)
207         return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
208 
209     ret = kau_j_tgs_s4u2proxy(ev_success, state, &jout);
210     if (ret)
211         return ret;
212     if (audit_log_user_message(fd, local_type, jout,
213                                NULL, NULL, NULL, ev_success) <= 0)
214         ret = EIO;
215     free(jout);
216     return ret;
217 }
218 
219 /* Log user-to-user event. Returns 0 on success */
220 static krb5_error_code
j_tgs_u2u(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)221 j_tgs_u2u(krb5_audit_moddata auctx, krb5_boolean ev_success,
222           krb5_audit_state *state)
223 {
224     krb5_error_code ret = 0;
225     int local_type = AUDIT_USER_AUTH;
226     int fd = auctx->fd;
227     char *jout = NULL;
228 
229     if (fd < 0)
230         return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
231 
232     ret = kau_j_tgs_u2u(ev_success, state, &jout);
233     if (ret)
234         return ret;
235     if (audit_log_user_message(fd, local_type, jout,
236                                NULL, NULL, NULL, ev_success) <= 0)
237         ret = EIO;
238     free(jout);
239     return ret;
240 }
241 
242 krb5_error_code
audit_simple_initvt(krb5_context context,int maj_ver,int min_ver,krb5_plugin_vtable vtable)243 audit_simple_initvt(krb5_context context, int maj_ver,
244                     int min_ver, krb5_plugin_vtable vtable)
245 {
246     krb5_audit_vtable vt;
247 
248     if (maj_ver != 1)
249         return KRB5_PLUGIN_VER_NOTSUPP;
250 
251     vt = (krb5_audit_vtable)vtable;
252     vt->name = "simple";
253     vt->open = open_au;
254     vt->close = close_au;
255     vt->kdc_start = j_kdc_start;
256     vt->kdc_stop = j_kdc_stop;
257     vt->as_req = j_as_req;
258     vt->tgs_req = j_tgs_req;
259     vt->tgs_s4u2self = j_tgs_s4u2self;
260     vt->tgs_s4u2proxy = j_tgs_s4u2proxy;
261     vt->tgs_u2u = j_tgs_u2u;
262     return 0;
263 }
264