(root)/
Linux-PAM-1.5.3/
libpam/
pam_prelude.c
       1  /*
       2   * pam_prelude.c -- prelude reporting
       3   * http://www.prelude-ids.org
       4   *
       5   * (C) Sebastien Tricaud 2005 <toady@gscore.org>
       6   */
       7  
       8  #include <stdio.h>
       9  #include <syslog.h>
      10  
      11  #ifdef PRELUDE
      12  
      13  #include <libprelude/prelude.h>
      14  #include <libprelude/prelude-log.h>
      15  #include <libprelude/idmef-message-print.h>
      16  
      17  #include "pam_prelude.h"
      18  #include "pam_private.h"
      19  
      20  
      21  #define ANALYZER_CLASS "pam"
      22  #define ANALYZER_MODEL "PAM"
      23  #define ANALYZER_MANUFACTURER "Sebastien Tricaud, http://www.kernel.org/pub/linux/libs/pam/"
      24  
      25  #define DEFAULT_ANALYZER_NAME "PAM"
      26  
      27  static const char *
      28  pam_get_item_service(const pam_handle_t *pamh)
      29  {
      30          const void *service = NULL;
      31  
      32  	pam_get_item(pamh, PAM_SERVICE, &service);
      33  
      34          return service;
      35  }
      36  
      37  static const char *
      38  pam_get_item_user(const pam_handle_t *pamh)
      39  {
      40          const void *user = NULL;
      41  
      42  	pam_get_item(pamh, PAM_USER, &user);
      43  
      44          return user;
      45  }
      46  
      47  static const char *
      48  pam_get_item_user_prompt(const pam_handle_t *pamh)
      49  {
      50          const void *user_prompt = NULL;
      51  
      52  	pam_get_item(pamh, PAM_USER_PROMPT, &user_prompt);
      53  
      54          return user_prompt;
      55  }
      56  
      57  static const char *
      58  pam_get_item_tty(const pam_handle_t *pamh)
      59  {
      60          const void *tty = NULL;
      61  
      62  	pam_get_item(pamh, PAM_TTY, &tty);
      63  
      64          return tty;
      65  }
      66  
      67  static const char *
      68  pam_get_item_ruser(const pam_handle_t *pamh)
      69  {
      70          const void *ruser = NULL;
      71  
      72  	pam_get_item(pamh, PAM_RUSER, &ruser);
      73  
      74          return ruser;
      75  }
      76  
      77  static const char *
      78  pam_get_item_rhost(const pam_handle_t *pamh)
      79  {
      80          const void *rhost = NULL;
      81  
      82  	pam_get_item(pamh, PAM_RHOST, &rhost);
      83  
      84          return rhost;
      85  }
      86  
      87  /* Courteously stolen from prelude-lml */
      88  static int
      89  generate_additional_data(idmef_alert_t *alert, const char *meaning,
      90  			 const char *data)
      91  {
      92          int ret;
      93          prelude_string_t *str;
      94          idmef_additional_data_t *adata;
      95  
      96          ret = idmef_alert_new_additional_data(alert, &adata, -1);
      97          if ( ret < 0 )
      98                  return ret;
      99  
     100          ret = idmef_additional_data_new_meaning(adata, &str);
     101          if ( ret < 0 )
     102                  return ret;
     103  
     104          ret = prelude_string_set_ref(str, meaning);
     105          if ( ret < 0 )
     106                  return ret;
     107  
     108          return idmef_additional_data_set_string_ref(adata, data);
     109  }
     110  
     111  static int
     112  setup_analyzer(const pam_handle_t *pamh, idmef_analyzer_t *analyzer)
     113  {
     114          int ret;
     115          prelude_string_t *string;
     116  
     117          ret = idmef_analyzer_new_model(analyzer, &string);
     118          if ( ret < 0 )
     119                  goto err;
     120          prelude_string_set_constant(string, ANALYZER_MODEL);
     121  
     122  	ret = idmef_analyzer_new_class(analyzer, &string);
     123          if ( ret < 0 )
     124                  goto err;
     125          prelude_string_set_constant(string, ANALYZER_CLASS);
     126  
     127  	ret = idmef_analyzer_new_manufacturer(analyzer, &string);
     128          if ( ret < 0 )
     129                  goto err;
     130          prelude_string_set_constant(string, ANALYZER_MANUFACTURER);
     131  
     132  	ret = idmef_analyzer_new_version(analyzer, &string);
     133          if ( ret < 0 )
     134                  goto err;
     135          prelude_string_set_constant(string, PAM_VERSION);
     136  
     137  
     138          return 0;
     139  
     140   err:
     141          pam_syslog(pamh, LOG_WARNING,
     142                     "%s: IDMEF error: %s.\n",
     143                     prelude_strsource(ret), prelude_strerror(ret));
     144  
     145          return -1;
     146  }
     147  
     148  static void
     149  pam_alert_prelude(const char *msg, void *data,
     150  		  pam_handle_t *pamh, int authval)
     151  {
     152          int ret;
     153          idmef_time_t *clienttime;
     154          idmef_alert_t *alert;
     155          prelude_string_t *str;
     156          idmef_message_t *idmef = NULL;
     157          idmef_classification_t *class;
     158          prelude_client_t *client = (prelude_client_t *)data;
     159          idmef_source_t *source;
     160          idmef_target_t *target;
     161          idmef_user_t *user;
     162          idmef_user_id_t *user_id;
     163          idmef_process_t *process;
     164          idmef_classification_t *classification;
     165          idmef_impact_t *impact;
     166          idmef_assessment_t *assessment;
     167          idmef_node_t *node;
     168  	idmef_analyzer_t *analyzer;
     169  
     170  
     171          ret = idmef_message_new(&idmef);
     172          if ( ret < 0 )
     173                  goto err;
     174  
     175          ret = idmef_message_new_alert(idmef, &alert);
     176          if ( ret < 0 )
     177                  goto err;
     178  
     179          ret = idmef_alert_new_classification(alert, &class);
     180          if ( ret < 0 )
     181                  goto err;
     182  
     183          ret = idmef_classification_new_text(class, &str);
     184          if ( ret < 0 )
     185                  goto err;
     186  
     187          ret = prelude_string_new_ref(&str, msg);
     188          if ( ret < 0 )
     189                  goto err;
     190  
     191          idmef_classification_set_text(class, str);
     192  
     193          ret = idmef_time_new_from_gettimeofday(&clienttime);
     194          if ( ret < 0 )
     195                  goto err;
     196          idmef_alert_set_create_time(alert, clienttime);
     197  
     198          idmef_alert_set_analyzer(alert,
     199                                   idmef_analyzer_ref(prelude_client_get_analyzer(client)),
     200                                   0);
     201  
     202          /**********
     203           * SOURCE *
     204           **********/
     205          ret = idmef_alert_new_source(alert, &source, -1);
     206          if ( ret < 0 )
     207                  goto err;
     208  
     209          /* BEGIN: Sets the user doing authentication stuff */
     210          ret = idmef_source_new_user(source, &user);
     211          if ( ret < 0 )
     212                  goto err;
     213          idmef_user_set_category(user, IDMEF_USER_CATEGORY_APPLICATION);
     214  
     215          ret = idmef_user_new_user_id(user, &user_id, 0);
     216          if ( ret < 0 )
     217                  goto err;
     218          idmef_user_id_set_type(user_id, IDMEF_USER_ID_TYPE_ORIGINAL_USER);
     219  
     220  	if ( pam_get_item_ruser(pamh) ) {
     221  	        ret = prelude_string_new(&str);
     222                  if ( ret < 0 )
     223                          goto err;
     224  
     225  	        ret = prelude_string_set_ref(str, pam_get_item_ruser(pamh));
     226                  if ( ret < 0 )
     227                          goto err;
     228  
     229  	        idmef_user_id_set_name(user_id, str);
     230  	}
     231          /* END */
     232          /* BEGIN: Adds TTY infos */
     233  	if ( pam_get_item_tty(pamh) ) {
     234  	        ret = prelude_string_new(&str);
     235                  if ( ret < 0 )
     236                          goto err;
     237  
     238  	        ret = prelude_string_set_ref(str, pam_get_item_tty(pamh));
     239                  if ( ret < 0 )
     240                          goto err;
     241  
     242                  idmef_user_id_set_tty(user_id, str);
     243  	}
     244          /* END */
     245          /* BEGIN: Sets the source node (rhost) */
     246          ret = idmef_source_new_node(source, &node);
     247          if ( ret < 0 )
     248                  goto err;
     249          idmef_node_set_category(node, IDMEF_NODE_CATEGORY_HOSTS);
     250  
     251  	if ( pam_get_item_rhost(pamh) ) {
     252  	        ret = prelude_string_new(&str);
     253                  if ( ret < 0 )
     254                          goto err;
     255  
     256  		ret = prelude_string_set_ref(str, pam_get_item_rhost(pamh));
     257                  if ( ret < 0 )
     258                          goto err;
     259  
     260  		idmef_node_set_name(node, str);
     261  	}
     262          /* END */
     263          /* BEGIN: Describe the service */
     264          ret = idmef_source_new_process(source, &process);
     265          if ( ret < 0 )
     266                  goto err;
     267          idmef_process_set_pid(process, getpid());
     268  
     269  	if ( pam_get_item_service(pamh) ) {
     270  	        ret = prelude_string_new(&str);
     271                  if ( ret < 0 )
     272                          goto err;
     273  
     274  		ret = prelude_string_set_ref(str, pam_get_item_service(pamh));
     275                  if ( ret < 0 )
     276                          goto err;
     277  
     278  		idmef_process_set_name(process, str);
     279  	}
     280          /* END */
     281  
     282          /**********
     283           * TARGET *
     284           **********/
     285  
     286          ret = idmef_alert_new_target(alert, &target, -1);
     287          if ( ret < 0 )
     288                  goto err;
     289  
     290  
     291          /* BEGIN: Sets the target node  */
     292  	analyzer = prelude_client_get_analyzer(client);
     293          if ( ! analyzer ) goto err;
     294  
     295  	node = idmef_analyzer_get_node(analyzer);
     296          if ( ! node ) goto err;
     297  	idmef_target_set_node(target, node);
     298  	node = idmef_node_ref(node);
     299          if ( ! node ) goto err;
     300  	/* END */
     301          /* BEGIN: Sets the user doing authentication stuff */
     302          ret = idmef_target_new_user(target, &user);
     303          if ( ret < 0 )
     304                  goto err;
     305          idmef_user_set_category(user, IDMEF_USER_CATEGORY_APPLICATION);
     306  
     307          ret = idmef_user_new_user_id(user, &user_id, 0);
     308          if ( ret < 0 )
     309                  goto err;
     310          idmef_user_id_set_type(user_id, IDMEF_USER_ID_TYPE_TARGET_USER);
     311  
     312  	if ( pam_get_item_user(pamh) ) {
     313  	        ret = prelude_string_new(&str);
     314                  if ( ret < 0 )
     315                          goto err;
     316  
     317  		ret = prelude_string_set_ref(str, pam_get_item_user(pamh));
     318                  if ( ret < 0 )
     319                          goto err;
     320  
     321  		idmef_user_id_set_name(user_id, str);
     322  	}
     323          /* END */
     324          /* BEGIN: Short description of the alert */
     325          ret = idmef_alert_new_classification(alert, &classification);
     326          if ( ret < 0 )
     327                  goto err;
     328  
     329          ret = prelude_string_new(&str);
     330          if ( ret < 0 )
     331                  goto err;
     332  
     333          ret = prelude_string_set_ref(str,
     334                                       authval == PAM_SUCCESS ?
     335                                       "Authentication Success" : "Authentication Failure");
     336          if ( ret < 0 )
     337                  goto err;
     338  
     339          idmef_classification_set_text(classification, str);
     340          /* END */
     341          /* BEGIN: Long description of the alert */
     342          ret = idmef_alert_new_assessment(alert, &assessment);
     343          if ( ret < 0 )
     344                  goto err;
     345  
     346          ret = idmef_assessment_new_impact(assessment, &impact);
     347          if ( ret < 0 )
     348                  goto err;
     349  
     350          ret = prelude_string_new(&str);
     351          if ( ret < 0 )
     352                  goto err;
     353  
     354          ret = prelude_string_set_ref(str, pam_strerror (pamh, authval));
     355          if ( ret < 0 )
     356                  goto err;
     357  
     358          idmef_impact_set_description(impact, str);
     359          /* END */
     360          /* BEGIN: Adding additional data */
     361  	if ( pam_get_item_user_prompt(pamh) ) {
     362  	        ret = generate_additional_data(alert, "Local User Prompt",
     363                                                 pam_get_item_user_prompt(pamh));
     364                  if ( ret < 0 )
     365                          goto err;
     366          }
     367          /* END */
     368  
     369          prelude_client_send_idmef(client, idmef);
     370  
     371          if ( idmef )
     372                  idmef_message_destroy(idmef);
     373  
     374  	return;
     375   err:
     376          pam_syslog(pamh, LOG_WARNING, "%s: IDMEF error: %s.\n",
     377                     prelude_strsource(ret), prelude_strerror(ret));
     378  
     379          if ( idmef )
     380                  idmef_message_destroy(idmef);
     381  
     382  }
     383  
     384  static int
     385  pam_alert_prelude_init(pam_handle_t *pamh, int authval)
     386  {
     387  
     388          int ret;
     389          prelude_client_t *client = NULL;
     390  
     391          ret = prelude_init(NULL, NULL);
     392          if ( ret < 0 ) {
     393                  pam_syslog(pamh, LOG_WARNING,
     394                           "%s: Unable to initialize the Prelude library: %s.\n",
     395                           prelude_strsource(ret), prelude_strerror(ret));
     396                  return -1;
     397          }
     398  
     399          ret = prelude_client_new(&client, DEFAULT_ANALYZER_NAME);
     400          if ( ! client ) {
     401                  pam_syslog(pamh, LOG_WARNING,
     402                           "%s: Unable to create a prelude client object: %s.\n",
     403                           prelude_strsource(ret), prelude_strerror(ret));
     404  
     405                  return -1;
     406          }
     407  
     408  
     409          ret = setup_analyzer(pamh, prelude_client_get_analyzer(client));
     410          if ( ret < 0 ) {
     411                  pam_syslog(pamh, LOG_WARNING,
     412                           "%s: Unable to setup analyzer: %s\n",
     413                           prelude_strsource(ret), prelude_strerror(ret));
     414  
     415  		prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
     416  
     417  		return -1;
     418          }
     419  
     420          ret = prelude_client_start(client);
     421          if ( ret < 0 ) {
     422                  pam_syslog(pamh, LOG_WARNING,
     423                           "%s: Unable to initialize prelude client: %s.\n",
     424                           prelude_strsource(ret), prelude_strerror(ret));
     425  
     426  		prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
     427  
     428                  return -1;
     429          }
     430  
     431          pam_alert_prelude("libpam alert" , client, pamh, authval);
     432  
     433  	prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS);
     434  
     435          return 0;
     436  }
     437  
     438  void
     439  prelude_send_alert(pam_handle_t *pamh, int authval)
     440  {
     441  
     442          int ret;
     443  
     444          prelude_log_set_flags(PRELUDE_LOG_FLAGS_SYSLOG);
     445  
     446          ret = pam_alert_prelude_init(pamh, authval);
     447          if ( ret < 0 )
     448                  pam_syslog(pamh, LOG_WARNING, "No prelude alert sent");
     449  
     450  	prelude_deinit();
     451  
     452  }
     453  
     454  #endif /* PRELUDE */