00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "includes.h"
00038 #if defined(USE_BSM_AUDIT)
00039
00040 #include "ssh.h"
00041 #include "log.h"
00042 #include "auth.h"
00043 #include "xmalloc.h"
00044
00045 #ifndef AUE_openssh
00046 # define AUE_openssh 32800
00047 #endif
00048 #include <bsm/audit.h>
00049 #include <bsm/libbsm.h>
00050 #include <bsm/audit_uevents.h>
00051 #include <bsm/audit_record.h>
00052 #include <locale.h>
00053
00054 #if defined(HAVE_GETAUDIT_ADDR)
00055 #define AuditInfoStruct auditinfo_addr
00056 #define AuditInfoTermID au_tid_addr_t
00057 #define GetAuditFunc(a,b) getaudit_addr((a),(b))
00058 #define GetAuditFuncText "getaudit_addr"
00059 #define SetAuditFunc(a,b) setaudit_addr((a),(b))
00060 #define SetAuditFuncText "setaudit_addr"
00061 #define AUToSubjectFunc au_to_subject_ex
00062 #define AUToReturnFunc(a,b) au_to_return32((a), (int32_t)(b))
00063 #else
00064 #define AuditInfoStruct auditinfo
00065 #define AuditInfoTermID au_tid_t
00066 #define GetAuditFunc(a,b) getaudit(a)
00067 #define GetAuditFuncText "getaudit"
00068 #define SetAuditFunc(a,b) setaudit(a)
00069 #define SetAuditFuncText "setaudit"
00070 #define AUToSubjectFunc au_to_subject
00071 #define AUToReturnFunc(a,b) au_to_return((a), (u_int)(b))
00072 #endif
00073
00074 extern int cannot_audit(int);
00075 extern void aug_init(void);
00076 extern dev_t aug_get_port(void);
00077 extern int aug_get_machine(char *, u_int32_t *, u_int32_t *);
00078 extern void aug_save_auid(au_id_t);
00079 extern void aug_save_uid(uid_t);
00080 extern void aug_save_euid(uid_t);
00081 extern void aug_save_gid(gid_t);
00082 extern void aug_save_egid(gid_t);
00083 extern void aug_save_pid(pid_t);
00084 extern void aug_save_asid(au_asid_t);
00085 extern void aug_save_tid(dev_t, unsigned int);
00086 extern void aug_save_tid_ex(dev_t, u_int32_t *, u_int32_t);
00087 extern int aug_save_me(void);
00088 extern int aug_save_namask(void);
00089 extern void aug_save_event(au_event_t);
00090 extern void aug_save_sorf(int);
00091 extern void aug_save_text(char *);
00092 extern void aug_save_text1(char *);
00093 extern void aug_save_text2(char *);
00094 extern void aug_save_na(int);
00095 extern void aug_save_user(char *);
00096 extern void aug_save_path(char *);
00097 extern int aug_save_policy(void);
00098 extern void aug_save_afunc(int (*)(int));
00099 extern int aug_audit(void);
00100 extern int aug_na_selected(void);
00101 extern int aug_selected(void);
00102 extern int aug_daemon_session(void);
00103
00104 #ifndef HAVE_GETTEXT
00105 # define gettext(a) (a)
00106 #endif
00107
00108 extern Authctxt *the_authctxt;
00109 static AuditInfoTermID ssh_bsm_tid;
00110
00111
00112
00113
00114
00115
00116
00117 static int
00118 selected(char *username, uid_t uid, au_event_t event, int sf)
00119 {
00120 int rc, sorf;
00121 char naflags[512];
00122 struct au_mask mask;
00123
00124 mask.am_success = mask.am_failure = 0;
00125 if (uid < 0) {
00126
00127 rc = getacna(naflags, sizeof(naflags));
00128 if (rc == 0)
00129 (void) getauditflagsbin(naflags, &mask);
00130 } else
00131 rc = au_user_mask(username, &mask);
00132
00133 sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE;
00134 return(au_preselect(event, &mask, sorf, AU_PRS_REREAD));
00135 }
00136
00137 static void
00138 bsm_audit_record(int typ, char *string, au_event_t event_no)
00139 {
00140 int ad, rc, sel;
00141 uid_t uid = -1;
00142 gid_t gid = -1;
00143 pid_t pid = getpid();
00144 AuditInfoTermID tid = ssh_bsm_tid;
00145
00146 if (the_authctxt != NULL && the_authctxt->valid) {
00147 uid = the_authctxt->pw->pw_uid;
00148 gid = the_authctxt->pw->pw_gid;
00149 }
00150
00151 rc = (typ == 0) ? 0 : -1;
00152 sel = selected(the_authctxt->user, uid, event_no, rc);
00153 debug3("BSM audit: typ %d rc %d \"%s\"", typ, rc, string);
00154 if (!sel)
00155 return;
00156
00157 debug3("BSM audit: writing audit new record");
00158 ad = au_open();
00159
00160 (void) au_write(ad, AUToSubjectFunc(uid, uid, gid, uid, gid,
00161 pid, pid, &tid));
00162 (void) au_write(ad, au_to_text(string));
00163 (void) au_write(ad, AUToReturnFunc(typ, rc));
00164
00165 rc = au_close(ad, AU_TO_WRITE, event_no);
00166 if (rc < 0)
00167 error("BSM audit: %s failed to write \"%s\" record: %s",
00168 __func__, string, strerror(errno));
00169 }
00170
00171 static void
00172 bsm_audit_session_setup(void)
00173 {
00174 int rc;
00175 struct AuditInfoStruct info;
00176 au_mask_t mask;
00177
00178 if (the_authctxt == NULL) {
00179 error("BSM audit: session setup internal error (NULL ctxt)");
00180 return;
00181 }
00182
00183 if (the_authctxt->valid)
00184 info.ai_auid = the_authctxt->pw->pw_uid;
00185 else
00186 info.ai_auid = -1;
00187 info.ai_asid = getpid();
00188 mask.am_success = 0;
00189 mask.am_failure = 0;
00190
00191 (void) au_user_mask(the_authctxt->user, &mask);
00192
00193 info.ai_mask.am_success = mask.am_success;
00194 info.ai_mask.am_failure = mask.am_failure;
00195
00196 info.ai_termid = ssh_bsm_tid;
00197
00198 rc = SetAuditFunc(&info, sizeof(info));
00199 if (rc < 0)
00200 error("BSM audit: %s: %s failed: %s", __func__,
00201 SetAuditFuncText, strerror(errno));
00202 }
00203
00204 static void
00205 bsm_audit_bad_login(const char *what)
00206 {
00207 char textbuf[BSM_TEXTBUFSZ];
00208
00209 if (the_authctxt->valid) {
00210 (void) snprintf(textbuf, sizeof (textbuf),
00211 gettext("invalid %s for user %s"),
00212 what, the_authctxt->user);
00213 bsm_audit_record(4, textbuf, AUE_openssh);
00214 } else {
00215 (void) snprintf(textbuf, sizeof (textbuf),
00216 gettext("invalid user name \"%s\""),
00217 the_authctxt->user);
00218 bsm_audit_record(3, textbuf, AUE_openssh);
00219 }
00220 }
00221
00222
00223
00224 void
00225 audit_connection_from(const char *host, int port)
00226 {
00227 AuditInfoTermID *tid = &ssh_bsm_tid;
00228 char buf[1024];
00229
00230 if (cannot_audit(0))
00231 return;
00232 debug3("BSM audit: connection from %.100s port %d", host, port);
00233
00234
00235 #if defined(HAVE_GETAUDIT_ADDR)
00236 tid->at_port = (dev_t)port;
00237 aug_get_machine((char *)host, &(tid->at_addr[0]), &(tid->at_type));
00238 snprintf(buf, sizeof(buf), "%08x %08x %08x %08x", tid->at_addr[0],
00239 tid->at_addr[1], tid->at_addr[2], tid->at_addr[3]);
00240 debug3("BSM audit: iptype %d machine ID %s", (int)tid->at_type, buf);
00241 #else
00242
00243 tid->port = (dev_t)port;
00244 tid->machine = inet_addr(host);
00245 snprintf(buf, sizeof(buf), "%08x", tid->machine);
00246 debug3("BSM audit: machine ID %s", buf);
00247 #endif
00248 }
00249
00250 void
00251 audit_run_command(const char *command)
00252 {
00253
00254 }
00255
00256 void
00257 audit_session_open(const char *ttyn)
00258 {
00259
00260 }
00261
00262 void
00263 audit_session_close(const char *ttyn)
00264 {
00265
00266 }
00267
00268 void
00269 audit_event(ssh_audit_event_t event)
00270 {
00271 char textbuf[BSM_TEXTBUFSZ];
00272 static int logged_in = 0;
00273 const char *user = the_authctxt ? the_authctxt->user : "(unknown user)";
00274
00275 if (cannot_audit(0))
00276 return;
00277
00278 switch(event) {
00279 case SSH_AUTH_SUCCESS:
00280 logged_in = 1;
00281 bsm_audit_session_setup();
00282 snprintf(textbuf, sizeof(textbuf),
00283 gettext("successful login %s"), user);
00284 bsm_audit_record(0, textbuf, AUE_openssh);
00285 break;
00286
00287 case SSH_CONNECTION_CLOSE:
00288
00289
00290
00291
00292 if (logged_in) {
00293 snprintf(textbuf, sizeof(textbuf),
00294 gettext("sshd logout %s"), the_authctxt->user);
00295 bsm_audit_record(0, textbuf, AUE_logout);
00296 } else {
00297 debug("%s: connection closed without authentication",
00298 __func__);
00299 }
00300 break;
00301
00302 case SSH_NOLOGIN:
00303 bsm_audit_record(1,
00304 gettext("logins disabled by /etc/nologin"), AUE_openssh);
00305 break;
00306
00307 case SSH_LOGIN_EXCEED_MAXTRIES:
00308 snprintf(textbuf, sizeof(textbuf),
00309 gettext("too many tries for user %s"), the_authctxt->user);
00310 bsm_audit_record(1, textbuf, AUE_openssh);
00311 break;
00312
00313 case SSH_LOGIN_ROOT_DENIED:
00314 bsm_audit_record(2, gettext("not_console"), AUE_openssh);
00315 break;
00316
00317 case SSH_AUTH_FAIL_PASSWD:
00318 bsm_audit_bad_login("password");
00319 break;
00320
00321 case SSH_AUTH_FAIL_KBDINT:
00322 bsm_audit_bad_login("interactive password entry");
00323 break;
00324
00325 default:
00326 debug("%s: unhandled event %d", __func__, event);
00327 }
00328 }
00329 #endif