~ubuntu-branches/ubuntu/trusty/pam-pkcs11/trusty-proposed

« back to all changes in this revision

Viewing changes to src/pam_pkcs11/pam_pkcs11.c

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Rousseau
  • Date: 2010-06-12 17:50:06 UTC
  • mfrom: (2.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100612175006-4pjjf211vq5bcroo
Tags: 0.6.4-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
13
 * Lesser General Public License for more details.
14
14
 *
15
 
 * $Id: pam_pkcs11.c 422 2010-04-10 14:47:04Z ludovic.rousseau $
 
15
 * $Id: pam_pkcs11.c 437 2010-06-08 08:01:32Z ludovic.rousseau $
16
16
 */
17
17
 
18
18
/* We have to make this definitions before we include the pam header files! */
43
43
#include "pam_config.h"
44
44
#include "mapper_mgr.h"
45
45
 
46
 
#if ENABLE_NLS
 
46
#ifdef ENABLE_NLS
47
47
#include <libintl.h>
48
48
#include <locale.h>
49
49
#define _(string) gettext(string)
83
83
 
84
84
  msg.msg_style = style;
85
85
  msg.msg = text;
86
 
  rv = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
 
86
  rv = pam_get_item(pamh, PAM_CONV, &conv);
87
87
  if (rv != PAM_SUCCESS)
88
88
    return rv;
89
89
  if ((conv == NULL) || (conv->conv == NULL))
90
90
    return PAM_CRED_INSUFFICIENT;
91
 
  rv = conv->conv(1, (const struct pam_message **)msgp, &resp, conv->appdata_ptr);
 
91
  rv = conv->conv(1, msgp, &resp, conv->appdata_ptr);
92
92
  if (rv != PAM_SUCCESS)
93
93
    return rv;
94
94
  if ((resp == NULL) || (resp[0].resp == NULL))
132
132
  /* use stored password if variable oitem is set */
133
133
  if ((oitem == PAM_AUTHTOK) || (oitem == PAM_OLDAUTHTOK)) {
134
134
    /* try to get stored item */
135
 
    rv = pam_get_item(pamh, oitem, (const void **) &old_pwd);
 
135
    rv = pam_get_item(pamh, oitem, &old_pwd);
136
136
    if (rv != PAM_SUCCESS)
137
137
      return rv;
138
138
    if (old_pwd != NULL) {
145
145
  if (text != NULL) {
146
146
    msg.msg_style = PAM_PROMPT_ECHO_OFF;
147
147
    msg.msg = text;
148
 
    rv = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
 
148
    rv = pam_get_item(pamh, PAM_CONV, &conv);
149
149
    if (rv != PAM_SUCCESS)
150
150
      return rv;
151
151
    if ((conv == NULL) || (conv->conv == NULL))
152
152
      return PAM_CRED_INSUFFICIENT;
153
 
    rv = conv->conv(1, (const struct pam_message **)msgp, &resp, conv->appdata_ptr);
 
153
    rv = conv->conv(1, msgp, &resp, conv->appdata_ptr);
154
154
    if (rv != PAM_SUCCESS)
155
155
      return rv;
156
156
    if ((resp == NULL) || (resp[0].resp == NULL))
175
175
  int i, rv;
176
176
  const char *user = NULL;
177
177
  char *password;
 
178
  char password_prompt[128];
178
179
  unsigned int slot_num = 0;
179
180
  int is_a_screen_saver = 0;
180
181
  struct configuration_st *configuration;
217
218
  {
218
219
          char *display = getenv("DISPLAY");
219
220
 
220
 
          if (display && (display[0] != ':') && (display[0] != '\0'))
 
221
          if (display)
221
222
          {
222
 
                ERR1("Remote login (from %s) is not (yet) supported", display);
223
 
                pam_syslog(pamh, LOG_ERR,
224
 
                        "Remote login (from %s) is not (yet) supported",
225
 
                        display);
226
 
                return PAM_AUTHINFO_UNAVAIL;
 
223
                  if (strncmp(display, "localhost:", 10) != 0 && (display[0] != ':')
 
224
                          && (display[0] != '\0')) {
 
225
                          ERR1("Remote login (from %s) is not (yet) supported", display);
 
226
                          pam_syslog(pamh, LOG_ERR,
 
227
                                  "Remote login (from %s) is not (yet) supported", display);
 
228
                          return PAM_AUTHINFO_UNAVAIL;
 
229
                  }
227
230
          }
228
231
  }
229
232
 
263
266
        char *service;
264
267
        if (configuration->screen_savers) {
265
268
            DBG("Is it a screen saver?");
266
 
            rv = pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
 
269
            rv = pam_get_item(pamh, PAM_SERVICE, &service);
267
270
            for (i=0; configuration->screen_savers[i]; i++) {
268
271
                if (strcmp(configuration->screen_savers[i], service) == 0) {
269
272
                    is_a_screen_saver = 1;
275
278
        pkcs11_pam_fail = PAM_CRED_INSUFFICIENT;
276
279
 
277
280
        /* look to see if username is already set */
278
 
        rv = pam_get_item(pamh, PAM_USER, (const void **) &user);
 
281
        rv = pam_get_item(pamh, PAM_USER, &user);
279
282
        if (user) {
280
283
            DBG1("explicit username = [%s]", user);
281
284
        }
282
285
  } else {
283
 
        rv = pam_get_item(pamh, PAM_USER, (const void **) &user);
 
286
        rv = pam_get_item(pamh, PAM_USER, &user);
284
287
        if (rv != PAM_SUCCESS || user == NULL || user[0] == '\0') {
285
 
          pam_prompt(pamh, PAM_TEXT_INFO, NULL,
 
288
          snprintf(password_prompt, sizeof(password_prompt),
286
289
                  _("Please insert your %s or enter your username."),
287
290
                  _(configuration->token_type));
 
291
          pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
288
292
          /* get user name */
289
293
          rv = pam_get_user(pamh, &user, NULL);
290
294
 
350
354
     * or because we used one to log in */
351
355
    if (login_token_name || configuration->wait_for_card) {
352
356
      if (login_token_name) {
353
 
        pam_prompt(pamh, PAM_TEXT_INFO, NULL,
 
357
        snprintf(password_prompt, sizeof(password_prompt),
354
358
                        _("Please insert your smart card called \"%.32s\"."),
355
359
                        login_token_name);
 
360
        pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
356
361
      } else {
357
362
        pam_prompt(pamh, PAM_TEXT_INFO, NULL,
358
363
                 _("Please insert your smart card."));
377
382
    } else {
378
383
      /* we haven't prompted for the user yet, get the user and see if
379
384
       * the smart card has been inserted in the mean time */
380
 
      pam_prompt(pamh, PAM_TEXT_INFO, NULL,
 
385
      snprintf(password_prompt, sizeof(password_prompt),
381
386
                _("Please insert your %s or enter your username."),
382
387
                _(configuration->token_type));
 
388
      pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
383
389
      rv = pam_get_user(pamh, &user, NULL);
384
390
 
385
391
      /* check one last time for the smart card before bouncing to the next
398
404
      }
399
405
    }
400
406
  } else {
401
 
      pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Found the %s."),
402
 
         _(configuration->token_type));
 
407
      snprintf(password_prompt, sizeof(password_prompt),
 
408
                  _("Found the %s."), _(configuration->token_type));
 
409
      pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
403
410
  }
404
411
  rv = open_pkcs11_session(ph, slot_num);
405
412
  if (rv != 0) {
418
425
      pam_syslog(pamh, LOG_ERR, "get_slot_login_required() failed: %s", get_error());
419
426
    return pkcs11_pam_fail;
420
427
  } else if (rv) {
421
 
        char password_prompt[70];
422
 
 
423
428
    /* get password */
424
 
    pam_prompt(pamh, PAM_TEXT_INFO, NULL, _("Welcome %.32s!"),
425
 
                get_slot_tokenlabel(ph));
426
 
    sprintf(password_prompt, _("%s PIN: "), _(configuration->token_type));
427
 
    if (configuration->use_first_pass) {
428
 
      rv = pam_get_pwd(pamh, &password, NULL, PAM_AUTHTOK, 0);
429
 
    } else if (configuration->try_first_pass) {
430
 
      rv = pam_get_pwd(pamh, &password, password_prompt, PAM_AUTHTOK,
431
 
        PAM_AUTHTOK);
432
 
    } else {
433
 
      rv = pam_get_pwd(pamh, &password, password_prompt, 0, PAM_AUTHTOK);
434
 
    }
435
 
    if (rv != PAM_SUCCESS) {
436
 
      release_pkcs11_module(ph);
437
 
      pam_syslog(pamh, LOG_ERR,
438
 
        "pam_get_pwd() failed: %s", pam_strerror(pamh, rv));
439
 
      return pkcs11_pam_fail;
440
 
    }
 
429
        snprintf(password_prompt, sizeof(password_prompt),
 
430
                _("Welcome %.32s!"), get_slot_tokenlabel(ph));
 
431
        pam_prompt(pamh, PAM_TEXT_INFO, NULL, password_prompt);
 
432
 
 
433
        /* no CKF_PROTECTED_AUTHENTICATION_PATH */
 
434
        rv = get_slot_protected_authentication_path(ph);
 
435
        if ((-1 == rv) || (0 == rv))
 
436
        {
 
437
                sprintf(password_prompt, _("%s PIN: "), _(configuration->token_type));
 
438
                if (configuration->use_first_pass) {
 
439
                        rv = pam_get_pwd(pamh, &password, NULL, PAM_AUTHTOK, 0);
 
440
                } else if (configuration->try_first_pass) {
 
441
                        rv = pam_get_pwd(pamh, &password, password_prompt, PAM_AUTHTOK,
 
442
                                        PAM_AUTHTOK);
 
443
                } else {
 
444
                        rv = pam_get_pwd(pamh, &password, password_prompt, 0, PAM_AUTHTOK);
 
445
                }
 
446
                if (rv != PAM_SUCCESS) {
 
447
                        release_pkcs11_module(ph);
 
448
                        pam_syslog(pamh, LOG_ERR,
 
449
                                        "pam_get_pwd() failed: %s", pam_strerror(pamh, rv));
 
450
                        return pkcs11_pam_fail;
 
451
                }
441
452
#ifndef DEBUG_HIDE_PASSWORD
442
 
    DBG1("password = [%s]", password);
 
453
                DBG1("password = [%s]", password);
443
454
#endif
444
455
 
445
 
    /* check password length */
446
 
    if (!configuration->nullok && strlen(password) == 0) {
447
 
      release_pkcs11_module(ph);
448
 
      memset(password, 0, strlen(password));
449
 
      free(password);
450
 
      pam_syslog(pamh, LOG_ERR,
451
 
        "password length is zero but the 'nullok' argument was not defined.");
452
 
      return PAM_AUTH_ERR;
453
 
    }
 
456
                /* check password length */
 
457
                if (!configuration->nullok && strlen(password) == 0) {
 
458
                        release_pkcs11_module(ph);
 
459
                        memset(password, 0, strlen(password));
 
460
                        free(password);
 
461
                        pam_syslog(pamh, LOG_ERR,
 
462
                                        "password length is zero but the 'nullok' argument was not defined.");
 
463
                        return PAM_AUTH_ERR;
 
464
                }
 
465
        }
 
466
        else
 
467
        {
 
468
                pam_prompt(pamh, PAM_TEXT_INFO, NULL,
 
469
                        _("Enter your %s PIN on the pinpad"), _(configuration->token_type));
 
470
                /* use pin pad */
 
471
                password = NULL;
 
472
        }
454
473
 
455
474
    /* call pkcs#11 login to ensure that the user is the real owner of the card
456
475
     * we need to do thise before get_certificate_list because some tokens
457
476
     * can not read their certificates until the token is authenticated */
458
477
    rv = pkcs11_login(ph, password);
459
478
    /* erase and free in-memory password data asap */
460
 
    memset(password, 0, strlen(password));
461
 
    free(password);
 
479
        if (password)
 
480
        {
 
481
                memset(password, 0, strlen(password));
 
482
                free(password);
 
483
        }
462
484
    if (rv != 0) {
463
485
      ERR1("open_pkcs11_login() failed: %s", get_error());
464
486
      if (!configuration->quiet)