示例#1
0
void securid_session_free(rlm_securid_t *inst,REQUEST *request,
			  SECURID_SESSION *session)
{
	if (!session)
		return;

	RDEBUG2("Freeing session id=%d identity='%s' state='%s'",
			 session->session_id,SAFE_STR(session->identity),session->state);

	if (session->identity) {
		free(session->identity);
		session->identity = NULL;
	}
	if (session->pin) {
		free(session->pin);
		session->pin = NULL;
	}

	if (session->sdiHandle != SDI_HANDLE_NONE) {
		SD_Close(session->sdiHandle);
		session->sdiHandle = SDI_HANDLE_NONE;
	}

	free(session);
}
static SECURID_AUTH_RC securidAuth(void *instance, REQUEST *request,
				   const char* username, 
				   const char* passcode,
				   char* replyMsgBuffer,int replyMsgBufferSize)
{
	rlm_securid_t *inst = (rlm_securid_t *) instance;
	int         acmRet;
	SD_PIN pinParams;
	char newPin[10];
	char format[30];
	SECURID_SESSION *pSecurid_session=NULL;
	int rc=-1;

	if (!username) {
		radlog(L_ERR, "SecurID username is NULL");
		return RC_SECURID_AUTH_FAILURE;		
	}

	if (!passcode) {
		radlog(L_ERR, "SecurID passcode is NULL for %s user",username);
		return RC_SECURID_AUTH_FAILURE;		
	}

	*replyMsgBuffer = '\0';

	pSecurid_session = securid_sessionlist_find(inst,request);
	if (pSecurid_session == NULL) {
		/* securid session not found */
		SDI_HANDLE  sdiHandle = SDI_HANDLE_NONE;

		acmRet = SD_Init(&sdiHandle);
		if (acmRet != ACM_OK) {
			radlog(L_ERR, "Cannot communicate with the ACE/Server");
			return -1;
		}

		acmRet = SD_Lock(sdiHandle, (SD_CHAR*)username);
		if (acmRet != ACM_OK) {
			radlog(L_ERR,"SecurID: Access denied. Name [%s] lock failed.",username);
			return -2;
		}

		acmRet = SD_Check(sdiHandle, (SD_CHAR*) passcode,
				  (SD_CHAR*) username);
		switch (acmRet) {
		case ACM_OK:
			/* we are in now */
			RDEBUG("SecurID authentication successful for %s.",
			       username);
			SD_Close(sdiHandle);

			return RC_SECURID_AUTH_SUCCESS;

		case ACM_ACCESS_DENIED:         
			/* not this time */
			RDEBUG("SecurID Access denied for %s", username);
			SD_Close(sdiHandle);
			return RC_SECURID_AUTH_ACCESS_DENIED_FAILURE;

		case ACM_INVALID_SERVER:
			radlog(L_ERR,"SecurID: Invalid ACE server.");
			return RC_SECURID_AUTH_INVALID_SERVER_FAILURE;

		case ACM_NEW_PIN_REQUIRED:
			RDEBUG2("SeecurID new pin required for %s",
				username);

			/* create a new session */
			pSecurid_session = securid_session_alloc();
			pSecurid_session->sdiHandle = sdiHandle; /* save ACE handle for future use */
			pSecurid_session->securidSessionState = NEW_PIN_REQUIRED_STATE;
			pSecurid_session->identity = strdup(username);
			 
			/* Get PIN requirements */
			acmRet = AceGetPinParams(sdiHandle, &pinParams);
			 
			/* If a system-generated PIN is required */
			if (pinParams.Selectable == CANNOT_CHOOSE_PIN) {
				/* Prompt user to accept a system generated PIN */
				snprintf(replyMsgBuffer, replyMsgBufferSize,
					 "\r\nAre you prepared to accept a new system-generated PIN [y/n]?");
				pSecurid_session->securidSessionState = NEW_PIN_SYSTEM_ACCEPT_STATE;

			} else if (pinParams.Selectable == USER_SELECTABLE) { //may be returned by AM 6.x servers.
				snprintf(replyMsgBuffer, replyMsgBufferSize,
					 "\r\nPress 'y' to generate a new PIN\r\nOR\r\n'n'to enter a new PIN yourself [y/n]");
				pSecurid_session->securidSessionState = NEW_PIN_USER_SELECT_STATE;

			} else {
				if (pinParams.Alphanumeric) {
					strcpy(format, "alphanumeric characters");
				} else {
					strcpy(format, "digits");
				}
				snprintf(replyMsgBuffer, replyMsgBufferSize,
					 " \r\n   Enter your new PIN of %d to %d %s,\r\n                or\r\n   <Ctrl-D> to cancel the New PIN procedure:",
					 pinParams.Min, pinParams.Max, format);
			}

			/* insert new session in the session list */
			securid_sessionlist_add(inst,request,pSecurid_session);
			 
			return RC_SECURID_AUTH_CHALLENGE;

		case ACM_NEXT_CODE_REQUIRED:
			RDEBUG2("Next securid token code required for %s",
				username);

			/* create a new session */
			pSecurid_session = securid_session_alloc();
			pSecurid_session->sdiHandle = sdiHandle;
			pSecurid_session->securidSessionState = NEXT_CODE_REQUIRED_STATE;
			pSecurid_session->identity = strdup(username);

			/* insert new session in the session list */
			securid_sessionlist_add(inst,request,pSecurid_session);
		     
			strlcpy(replyMsgBuffer, "\r\nPlease Enter the Next Code from Your Token:", replyMsgBufferSize);
			return RC_SECURID_AUTH_CHALLENGE;
		default:
			radlog(L_ERR,"SecurID: Unexpected error from ACE/Agent API acmRet=%d",acmRet);
			return RC_SECURID_AUTH_FAILURE;
  
			
		}
	} else {
		/* existing session found */
		RDEBUG("Continuing previous session found for user [%s]",username);

		/* continue previous session */
		switch (pSecurid_session->securidSessionState) {
		case NEXT_CODE_REQUIRED_STATE:
			DEBUG2("Securid NEXT_CODE_REQUIRED_STATE: User [%s]",username);
			/* next token code mode */

			acmRet = SD_Next(pSecurid_session->sdiHandle, (SD_CHAR*)passcode);
			if (acmRet == ACM_OK) {
				radlog(L_INFO,"Next SecurID token accepted for [%s].",pSecurid_session->identity);
				rc = RC_SECURID_AUTH_SUCCESS;

			} else {
				radlog(L_INFO,"SecurID: Next token rejected for [%s].",pSecurid_session->identity);
				rc = RC_SECURID_AUTH_FAILURE;
			}

			/* deallocate session */
			securid_session_free(inst,request,pSecurid_session);
			return rc;

		case NEW_PIN_REQUIRED_STATE:
			RDEBUG2("SecurID NEW_PIN_REQUIRED_STATE for %s",
				username);

			/* save the previous pin */
			if (pSecurid_session->pin) {
				free(pSecurid_session->pin);
				pSecurid_session->pin = NULL;
			}
			pSecurid_session->pin = strdup(passcode);

			strlcpy(replyMsgBuffer,"\r\n                 Please re-enter new PIN:", replyMsgBufferSize);

			/* set next state */
			pSecurid_session->securidSessionState = NEW_PIN_USER_CONFIRM_STATE;

			/* insert the updated session in the session list */
			securid_sessionlist_add(inst,request,pSecurid_session);
			return RC_SECURID_AUTH_CHALLENGE;
			  
		case NEW_PIN_USER_CONFIRM_STATE:
			RDEBUG2("SecurID NEW_PIN_USER_CONFIRM_STATE: User [%s]",username);
			/* compare previous pin and current pin */
			if (!pSecurid_session->pin || strcmp(pSecurid_session->pin,passcode)) {
				RDEBUG2("Pin confirmation failed. Pins do not match [%s] and [%s]",
				       SAFE_STR(pSecurid_session->pin),
				       passcode);
				/* pins do not match */

				/* challenge the user again */
				AceGetPinParams(pSecurid_session->sdiHandle, &pinParams);
				if (pinParams.Alphanumeric) {
					strcpy(format, "alphanumeric characters");
				} else {
					strcpy(format, "digits");
				}
				snprintf(replyMsgBuffer, replyMsgBufferSize,
					 " \r\n   Pins do not match--Please try again.\r\n   Enter your new PIN of %d to %d %s,\r\n                or\r\n   <Ctrl-D> to cancel the New PIN procedure:",
					 pinParams.Min, pinParams.Max, format);

				pSecurid_session->securidSessionState = NEW_PIN_REQUIRED_STATE;

				/* insert the updated session in the session list */
				securid_sessionlist_add(inst,request,pSecurid_session);
				rc = RC_SECURID_AUTH_CHALLENGE;

			} else {
				/* pins match */
				RDEBUG2("Pin confirmation succeeded. Pins match");
				acmRet = SD_Pin(pSecurid_session->sdiHandle, (SD_CHAR*)passcode);
				if (acmRet == ACM_NEW_PIN_ACCEPTED) {
					RDEBUG("New SecurID pin accepted for %s.",pSecurid_session->identity);

					pSecurid_session->securidSessionState = NEW_PIN_AUTH_VALIDATE_STATE;

					/* insert the updated session in the session list */
					securid_sessionlist_add(inst,request,pSecurid_session);

					rc = RC_SECURID_AUTH_CHALLENGE;
					strlcpy(replyMsgBuffer," \r\n\r\nWait for the code on your card to change, then enter new PIN and TokenCode\r\n\r\nEnter PASSCODE:", replyMsgBufferSize);
				} else {
					RDEBUG("SecurID: New SecurID pin rejected for %s.",pSecurid_session->identity);
					SD_Pin(pSecurid_session->sdiHandle, (SD_CHAR*)"");  /* cancel PIN */
					

					rc = RC_SECURID_AUTH_FAILURE;

					/* deallocate session */
					securid_session_free(inst, request,
							     pSecurid_session);
				}
			}
			return rc;		  
		case NEW_PIN_AUTH_VALIDATE_STATE:
			acmRet = SD_Check(pSecurid_session->sdiHandle, (SD_CHAR*)passcode, (SD_CHAR*)username);
			if (acmRet == ACM_OK) {
				RDEBUG("New SecurID passcode accepted for %s.",
				       pSecurid_session->identity);
				rc = RC_SECURID_AUTH_SUCCESS;

			} else {
				radlog(L_INFO,"SecurID: New passcode rejected for [%s].",pSecurid_session->identity);
				rc = RC_SECURID_AUTH_FAILURE;
			}

			/* deallocate session */
			securid_session_free(inst,request,pSecurid_session);

			return rc;
		case NEW_PIN_SYSTEM_ACCEPT_STATE:
			if (!strcmp(passcode, "y")) {
				AceGetSystemPin(pSecurid_session->sdiHandle, newPin);
					
				/* Save the PIN for the next session
				 * continuation */
				if (pSecurid_session->pin) {
					free(pSecurid_session->pin);
					pSecurid_session->pin = NULL;
				}
				pSecurid_session->pin = strdup(newPin);
					
				snprintf(replyMsgBuffer, replyMsgBufferSize,
					 "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?",
					 newPin);
				pSecurid_session->securidSessionState = NEW_PIN_SYSTEM_CONFIRM_STATE;
					
				/* insert the updated session in the
				 * session list */
				securid_sessionlist_add(inst, request,
							pSecurid_session);
					
				rc = RC_SECURID_AUTH_CHALLENGE;

			} else {
				SD_Pin(pSecurid_session->sdiHandle, (SD_CHAR*)""); //Cancel new PIN
					
				/* deallocate session */
				securid_session_free(inst, request,
						     pSecurid_session);
					
				rc = RC_SECURID_AUTH_FAILURE;
			}
				
			return rc;				
			 
		case NEW_PIN_SYSTEM_CONFIRM_STATE:
			acmRet = SD_Pin(pSecurid_session->sdiHandle, (SD_CHAR*)pSecurid_session->pin);
			if (acmRet == ACM_NEW_PIN_ACCEPTED) {
				strlcpy(replyMsgBuffer," \r\n\r\nPin Accepted. Wait for the code on your card to change, then enter new PIN and TokenCode\r\n\r\nEnter PASSCODE:",replyMsgBufferSize);
				pSecurid_session->securidSessionState = NEW_PIN_AUTH_VALIDATE_STATE;
				/* insert the updated session in the session list */
				securid_sessionlist_add(inst,request,pSecurid_session);
				rc = RC_SECURID_AUTH_CHALLENGE;

			} else {
				SD_Pin(pSecurid_session->sdiHandle, (SD_CHAR*)""); //Cancel new PIN
				strlcpy(replyMsgBuffer," \r\n\r\nPin Rejected. Wait for the code on your card to change, then try again.\r\n\r\nEnter PASSCODE:",replyMsgBufferSize);
				/* deallocate session */
				securid_session_free(inst, request,
						     pSecurid_session);
				rc = RC_SECURID_AUTH_FAILURE;
			}
				
			return rc;
			 
			/* USER_SELECTABLE state should be implemented to preserve compatibility with AM 6.x servers, which can return this state */
		case NEW_PIN_USER_SELECT_STATE:
			if (!strcmp(passcode, "y")) {
				/* User has opted for a system-generated PIN */
				AceGetSystemPin(pSecurid_session->sdiHandle, newPin);
				snprintf(replyMsgBuffer, replyMsgBufferSize,
					 "\r\nYour new PIN is: %s\r\nDo you accept this [y/n]?",
					 newPin);
				pSecurid_session->securidSessionState = NEW_PIN_SYSTEM_CONFIRM_STATE;
					
				/* insert the updated session in the session list */
				securid_sessionlist_add(inst, request,
							pSecurid_session);
				rc = RC_SECURID_AUTH_CHALLENGE;

			} else {
				/* User has opted for a user-defined PIN */
				AceGetPinParams(pSecurid_session->sdiHandle,
						&pinParams);
				if (pinParams.Alphanumeric) {
					strcpy(format, "alphanumeric characters");
				} else {
					strcpy(format, "digits");
				}
					
				snprintf(replyMsgBuffer, replyMsgBufferSize,
					 " \r\n   Enter your new PIN of %d to %d %s,\r\n                or\r\n   <Ctrl-D> to cancel the New PIN procedure:",
					 pinParams.Min, pinParams.Max, format);
				pSecurid_session->securidSessionState = NEW_PIN_REQUIRED_STATE;
					
				/* insert the updated session in the session list */
				securid_sessionlist_add(inst, request,
							pSecurid_session);
				rc = RC_SECURID_AUTH_CHALLENGE;
			}
				
			return rc;
				
		default:
			radlog(L_ERR|L_CONS, "rlm_securid: Invalid session state %d for user [%s]",
			       pSecurid_session->securidSessionState,
			       username);
			break;	
		}
	}
	
	return 0;
		
}
示例#3
0
文件: securid5.c 项目: millert/sudo
/*
 * securid_verify - Authenticates user and handles ACE responses
 *
 * Arguments in:
 *     pw - struct passwd for username
 *     pass - UNUSED
 *     auth - sudo authentication structure for SecurID handle
 *
 * Results out:
 *     return code - Success on successful authentication, failure on
 *                   incorrect authentication, fatal on errors
 */
int
sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_conv_callback *callback)
{
    SDI_HANDLE *sd = (SDI_HANDLE *) auth->data;
    int ret;
    debug_decl(sudo_securid_verify, SUDOERS_DEBUG_AUTH)

    pass = auth_getpass("Enter your PASSCODE: ", SUDO_CONV_PROMPT_ECHO_OFF,
	callback);

    /* Have ACE verify password */
    switch (SD_Check(*sd, pass, pw->pw_name)) {
	case ACM_OK:
		ret = AUTH_SUCESS;
		break;

	case ACE_UNDEFINED_PASSCODE:
		sudo_warnx(U_("invalid passcode length for SecurID"));
		ret = AUTH_FATAL;
		break;

	case ACE_UNDEFINED_USERNAME:
		sudo_warnx(U_("invalid username length for SecurID"));
		ret = AUTH_FATAL;
		break;

	case ACE_ERR_INVALID_HANDLE:
		sudo_warnx(U_("invalid Authentication Handle for SecurID"));
		ret = AUTH_FATAL;
		break;

	case ACM_ACCESS_DENIED:
		ret = AUTH_FAILURE;
		break;

	case ACM_NEXT_CODE_REQUIRED:
                /* Sometimes (when current token close to expire?)
                   ACE challenges for the next token displayed
                   (entered without the PIN) */
		if (pass != NULL) {
		    memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass));
		    free(pass);
		}
        	pass = auth_getpass("\
!!! ATTENTION !!!\n\
Wait for the token code to change, \n\
then enter the new token code.\n", \
		SUDO_CONV_PROMPT_ECHO_OFF, callback);

		if (SD_Next(*sd, pass) == ACM_OK) {
			ret = AUTH_SUCCESS;
			break;
		}

		ret = AUTH_FAILURE;
		break;

	case ACM_NEW_PIN_REQUIRED:
                /*
		 * This user's SecurID has not been activated yet,
                 * or the pin has been reset
		 */
		/* XXX - Is setting up a new PIN within sudo's scope? */
		SD_Pin(*sd, "");
		sudo_printf(SUDO_CONV_ERROR_MSG, 
		    "Your SecurID access has not yet been set up.\n");
		sudo_printf(SUDO_CONV_ERROR_MSG, 
		    "Please set up a PIN before you try to authenticate.\n");
		ret = AUTH_FATAL;
		break;

	default:
		sudo_warnx(U_("unknown SecurID error"));
		ret = AUTH_FATAL;
		break;
    }

    /* Free resources */
    SD_Close(*sd);

    if (pass != NULL) {
	memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass));
	free(pass);
    }

    /* Return stored state to calling process */
    debug_return_int(ret);
}
示例#4
0
krb5_error_code
verify_securid_data_2(krb5_context context, krb5_db_entry *client,
                      krb5_sam_response_2 *sr2,
                      krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *pa,
                      krb5_sam_challenge_2 **sc2_out)
{
    krb5_error_code retval;
    int new_pin = 0;
    krb5_key_data *client_key_data = NULL;
    krb5_keyblock client_key;
    krb5_data scratch;
    krb5_enc_sam_response_enc_2 *esre2 = NULL;
    struct securid_track_data sid_track_data, *trackp = NULL;
    krb5_data tmp_data;
    SDI_HANDLE sd_handle = SDI_HANDLE_NONE;
    krb5_sam_challenge_2 *sc2p = NULL;
    char *cp, *user = NULL;
    char *securid_user = NULL;
    char passcode[LENPRNST+1];
    char max_pin_len, min_pin_len, alpha_pin;

    memset(&client_key, 0, sizeof(client_key));
    memset(&scratch, 0, sizeof(scratch));
    *sc2_out = NULL;

    retval = krb5_unparse_name(context, client->princ, &user);
    if (retval != 0) {
        com_err("krb5kdc", retval,
                "while unparsing client name in verify_securid_data_2");
        return retval;
    }

    if ((sr2->sam_enc_nonce_or_sad.ciphertext.data == NULL) ||
        (sr2->sam_enc_nonce_or_sad.ciphertext.length <= 0)) {
          retval = KRB5KDC_ERR_PREAUTH_FAILED;
          krb5_set_error_message(context, retval,
                                 "No preauth data supplied in "
                                 "verify_securid_data_2 (%s)", user);
          goto cleanup;
    }

    retval = krb5_dbe_find_enctype(context, client,
                                   sr2->sam_enc_nonce_or_sad.enctype,
                                   KRB5_KDB_SALTTYPE_NORMAL,
                                   sr2->sam_enc_nonce_or_sad.kvno,
                                   &client_key_data);
    if (retval) {
        com_err("krb5kdc", retval,
                "while getting client key in verify_securid_data_2 (%s)",
                user);
        goto cleanup;
    }

    retval = krb5_dbe_decrypt_key_data(context, NULL, client_key_data,
                                       &client_key, NULL);
    if (retval != 0) {
        com_err("krb5kdc", retval,
                "while decrypting client key in verify_securid_data_2 (%s)",
                user);
        goto cleanup;
    }

    scratch.length = sr2->sam_enc_nonce_or_sad.ciphertext.length;
    scratch.data = k5alloc(scratch.length, &retval);
    if (retval)
        goto cleanup;
    retval = krb5_c_decrypt(context, &client_key,
                            KRB5_KEYUSAGE_PA_SAM_RESPONSE, 0,
                            &sr2->sam_enc_nonce_or_sad, &scratch);
    if (retval) {
        com_err("krb5kdc", retval,
                "while decrypting SAD in verify_securid_data_2 (%s)", user);
        goto cleanup;
    }

    retval = decode_krb5_enc_sam_response_enc_2(&scratch, &esre2);
    if (retval) {
        com_err("krb5kdc", retval,
                "while decoding SAD in verify_securid_data_2 (%s)", user);
        esre2 = NULL;
        goto cleanup;
    }

    if (sr2->sam_nonce != esre2->sam_nonce) {
        com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
                "while checking nonce in verify_securid_data_2 (%s)", user);
        retval = KRB5KDC_ERR_PREAUTH_FAILED;
        goto cleanup;
    }

    if (esre2->sam_sad.length == 0 || esre2->sam_sad.data == NULL) {
        com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
                "No SecurID passcode in verify_securid_data_2 (%s)", user);
        retval = KRB5KDC_ERR_PREAUTH_FAILED;
        goto cleanup;
    }

    /* Copy out SAD to null-terminated buffer */
    memset(passcode, 0, sizeof(passcode));
    if (esre2->sam_sad.length > (sizeof(passcode) - 1)) {
        retval = KRB5KDC_ERR_PREAUTH_FAILED;
        com_err("krb5kdc", retval,
                "SecurID passcode/PIN too long (%d bytes) in "
                "verify_securid_data_2 (%s)",
                esre2->sam_sad.length, user);
        goto cleanup;
    }
    memcpy(passcode, esre2->sam_sad.data, esre2->sam_sad.length);

    securid_user = strdup(user);
    if (!securid_user) {
        retval = ENOMEM;
        com_err("krb5kdc", ENOMEM,
                "while copying user name in verify_securid_data_2 (%s)", user);
        goto cleanup;
    }
    cp = strchr(securid_user, '@');
    if (cp != NULL)
        *cp = '\0';

    /* Check for any track_id data that may have state from a previous attempt
     * at SecurID authentication. */

    if (sr2->sam_track_id.data && (sr2->sam_track_id.length > 0)) {
        krb5_data track_id_data;

        memset(&track_id_data, 0, sizeof(track_id_data));
        retval = securid_decrypt_track_data_2(context, client,
                                              &sr2->sam_track_id,
                                              &track_id_data);
        if (retval) {
            com_err("krb5kdc", retval,
                    "while decrypting SecurID trackID in "
                    "verify_securid_data_2 (%s)", user);
           goto cleanup;
        }
        if (track_id_data.length < sizeof (struct securid_track_data)) {
            retval = KRB5KDC_ERR_PREAUTH_FAILED;
            com_err("krb5kdc", retval, "Length of track data incorrect");
            goto cleanup;
        }
        trackp = (struct securid_track_data *)track_id_data.data;

        if(trackp->hostid != gethostid()) {
            krb5_klog_syslog(LOG_INFO, "Unexpected challenge response");
            retval = KRB5KDC_ERR_DISCARD;
            goto cleanup;
        }

        switch(trackp->state) {
        case SECURID_STATE_INITIAL:
            goto initial;
            break;
        case SECURID_STATE_NEW_PIN_AGAIN:
        {
            int pin1_len, pin2_len;

            trackp->handle = ntohl(trackp->handle);
            pin2_len = strlen(passcode);
            pin1_len = strlen(trackp->passcode);

            if ((pin1_len != pin2_len) ||
                (memcmp(passcode, trackp->passcode, pin1_len) != 0)) {
                retval = KRB5KDC_ERR_PREAUTH_FAILED;
                krb5_klog_syslog(LOG_INFO, "New SecurID PIN Failed for user "
                                 "%s: PIN mis-match", user);
                break;
            }
            retval = SD_Pin(trackp->handle, passcode);
            SD_Close(trackp->handle);
            if (retval == ACM_NEW_PIN_ACCEPTED) {
                enc_tkt_reply->flags|=  TKT_FLG_HW_AUTH;
                enc_tkt_reply->flags|=  TKT_FLG_PRE_AUTH;
                krb5_klog_syslog(LOG_INFO, "SecurID PIN Accepted for %s in "
                                 "verify_securid_data_2",
                                 securid_user);
                retval = 0;
            } else {
                retval = KRB5KDC_ERR_PREAUTH_FAILED;
                krb5_klog_syslog(LOG_INFO,
                                 "SecurID PIN Failed for user %s (AceServer "
                                 "returns %d) in verify_securid_data_2",
                                 user, retval);
            }
            break;
        }
        case SECURID_STATE_NEW_PIN: {
            krb5_sam_challenge_2_body sc2b;
            sc2p = k5alloc(sizeof *sc2p, &retval);
            if (retval)
                goto cleanup;
            memset(sc2p, 0, sizeof(*sc2p));
            memset(&sc2b, 0, sizeof(sc2b));
            sc2b.sam_type = PA_SAM_TYPE_SECURID;
            sc2b.sam_response_prompt.data = NEW_PIN_AGAIN_message;
            sc2b.sam_response_prompt.length =
                strlen(sc2b.sam_response_prompt.data);
            sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
            sc2b.sam_etype = client_key.enctype;

            tmp_data.data = (char *)&sc2b.sam_nonce;
            tmp_data.length = sizeof(sc2b.sam_nonce);
            if ((retval = krb5_c_random_make_octets(context, &tmp_data))) {
                com_err("krb5kdc", retval,
                        "while making nonce for SecurID new "
                        "PIN2 SAM_CHALLENGE_2 (%s)", user);
                goto cleanup;
            }
            sid_track_data.state = SECURID_STATE_NEW_PIN_AGAIN;
            sid_track_data.handle = trackp->handle;
            sid_track_data.hostid = gethostid();
            /* Should we complain if sizes don't work ??  */
            memcpy(sid_track_data.passcode, passcode,
                   sizeof(sid_track_data.passcode));
            tmp_data.data = (char *)&sid_track_data;
            tmp_data.length = sizeof(sid_track_data);
            if ((retval = securid_encrypt_track_data_2(context, client,
                                                       &tmp_data,
                                                       &sc2b.sam_track_id))) {
                com_err("krb5kdc", retval,
                        "while encrypting NEW PIN2 SecurID "
                        "track data for SAM_CHALLENGE_2 (%s)",
                        securid_user);
                goto cleanup;
            }
            retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
                                                            &sc2b,
                                                            &client_key);
            if (retval) {
                com_err("krb5kdc", retval,
                        "while making cksum for "
                        "SAM_CHALLENGE_2 (new PIN2) (%s)", securid_user);
                goto cleanup;
            }
            krb5_klog_syslog(LOG_INFO,
                             "Requesting verification of new PIN for user %s",
                             securid_user);
            *sc2_out = sc2p;
            sc2p = NULL;
            /*sc2_out may be set even on error path*/
            retval = KRB5KDC_ERR_PREAUTH_REQUIRED;
            goto cleanup;
        }
        case SECURID_STATE_NEXT_CODE:
            trackp->handle = ntohl(trackp->handle);
            retval = SD_Next(trackp->handle, passcode);
            SD_Close(trackp->handle);
            if (retval == ACM_OK) {
                enc_tkt_reply->flags |=  TKT_FLG_HW_AUTH | TKT_FLG_PRE_AUTH;

                krb5_klog_syslog(LOG_INFO, "Next SecurID Code Accepted for "
                                 "user %s", securid_user);
                retval = 0;
            } else {
                krb5_klog_syslog(LOG_INFO, "Next SecurID Code Failed for user "
                                 "%s (AceServer returns %d) in "
                                 "verify_securid_data_2", user, retval);
                retval = KRB5KDC_ERR_PREAUTH_FAILED;
            }
            break;
        }
    } else {            /* No track data, this is first of N attempts */
    initial:
        retval = SD_Init(&sd_handle);
        if (retval) {
            com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
                    "SD_Init() returns error %d in verify_securid_data_2 (%s)",
                    retval, securid_user);
            retval = KRB5KDC_ERR_PREAUTH_FAILED;
            goto cleanup;
        }

        retval = SD_Lock(sd_handle, securid_user);
        if (retval != ACM_OK) {
            SD_Close(sd_handle);
            retval = KRB5KDC_ERR_PREAUTH_FAILED;
            krb5_klog_syslog(LOG_INFO,
                             "SD_Lock() failed (AceServer returns %d) for %s",
                             retval, securid_user);
            goto cleanup;
        }

        retval = SD_Check(sd_handle, passcode, securid_user);
        switch (retval) {
        case ACM_OK:
            SD_Close(sd_handle);
            enc_tkt_reply->flags|=  TKT_FLG_HW_AUTH;
            enc_tkt_reply->flags|=  TKT_FLG_PRE_AUTH;
            krb5_klog_syslog(LOG_INFO, "SecurID passcode accepted for user %s",
                             user);
            retval = 0;
            break;
        case ACM_ACCESS_DENIED:
            SD_Close(sd_handle);
            retval = KRB5KDC_ERR_PREAUTH_FAILED;
            krb5_klog_syslog(LOG_INFO, "AceServer returns Access Denied for "
                             "user %s (SAM2)", user);
            goto cleanup;
        case ACM_NEW_PIN_REQUIRED:
            new_pin = 1;
            /*fall through*/
        case ACM_NEXT_CODE_REQUIRED: {
            krb5_sam_challenge_2_body sc2b;
            sc2p = k5alloc(sizeof *sc2p, &retval);
            if (retval)
                goto cleanup;

            memset(sc2p, 0, sizeof(*sc2p));
            memset(&sc2b, 0, sizeof(sc2b));

            sc2b.sam_type = PA_SAM_TYPE_SECURID;
            sc2b.sam_response_prompt.data = NEXT_PASSCODE_message;
            sc2b.sam_response_prompt.length =
                strlen(sc2b.sam_response_prompt.data);
            sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
            sc2b.sam_etype = client_key.enctype;
            if (new_pin) {
                if ((AceGetMaxPinLen(sd_handle, &max_pin_len) == ACE_SUCCESS)
                    && (AceGetMinPinLen(sd_handle,
                                        &min_pin_len) == ACE_SUCCESS)
                    && (AceGetAlphanumeric(sd_handle,
                                           &alpha_pin) == ACE_SUCCESS)) {
                    sprintf(PIN_message,
                            "New PIN must contain %d to %d %sdigits",
                            min_pin_len, max_pin_len,
                            (alpha_pin == 0) ? "" : "alphanumeric ");
                    sc2b.sam_challenge_label.data = PIN_message;
                    sc2b.sam_challenge_label.length =
                        strlen(sc2b.sam_challenge_label.data);
                } else {
                    sc2b.sam_challenge_label.length = 0;
                }
            }

            tmp_data.data = (char *)&sc2b.sam_nonce;
            tmp_data.length = sizeof(sc2b.sam_nonce);
            if ((retval = krb5_c_random_make_octets(context, &tmp_data))) {
                com_err("krb5kdc", retval,
                        "while making nonce for SecurID SAM_CHALLENGE_2 (%s)",
                        user);
                goto cleanup;
            }
            if (new_pin)
                sid_track_data.state = SECURID_STATE_NEW_PIN;
            else
                sid_track_data.state = SECURID_STATE_NEXT_CODE;
            sid_track_data.handle = htonl(sd_handle);
            sid_track_data.hostid = gethostid();
            tmp_data.data = (char *)&sid_track_data;
            tmp_data.length = sizeof(sid_track_data);
            retval = securid_encrypt_track_data_2(context, client, &tmp_data,
                                                  &sc2b.sam_track_id);
            if (retval) {
                   com_err("krb5kdc", retval,
                           "while encrypting SecurID track "
                           "data for SAM_CHALLENGE_2 (%s)",
                           securid_user);
                   goto cleanup;
            }
            retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
                                                            &sc2b,
                                                            &client_key);
            if (retval) {
                com_err("krb5kdc", retval,
                        "while making cksum for SAM_CHALLENGE_2 (%s)",
                        securid_user);
            }
            if (new_pin)
                krb5_klog_syslog(LOG_INFO, "New SecurID PIN required for "
                                 "user %s", securid_user);
            else
                krb5_klog_syslog(LOG_INFO, "Next SecurID passcode required "
                                 "for user %s", securid_user);
            *sc2_out = sc2p;
            sc2p = NULL;
            retval = KRB5KDC_ERR_PREAUTH_REQUIRED;
            /*sc2_out is permitted as an output on error path*/
            goto cleanup;
        }
        default:
            com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
                    "AceServer returns unknown error code %d "
                    "in verify_securid_data_2\n", retval);
            retval = KRB5KDC_ERR_PREAUTH_FAILED;
            goto cleanup;
        }
    }   /* no track_id data */

cleanup:
    krb5_free_keyblock_contents(context, &client_key);
    free(scratch.data);
    krb5_free_enc_sam_response_enc_2(context, esre2);
    free(user);
    free(securid_user);
    free(trackp);
    krb5_free_sam_challenge_2(context, sc2p);
    return retval;
}
示例#5
0
/*******************************************************************************
* Function Name  : main						    
* Description    : Main program
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{
	/* NVIC configuration */
  	NVIC_Configuration();

	initialisation();


	/* Initialisation of SD Card and creation of File */
	SD_Init();
	/* Blinkmuster laden */
	if( SD_Start("muster.txt", FA_OPEN_EXISTING | FA_READ) )
	{
		SD_Read(&muster,1);
	}
	SD_Close();
	
	/* LCD Initialisieren */
  GLCD_Init();
  GLCD_Clear(White);                    
	GLCD_SetTextColor(Red);
  GLCD_DisplayString(1, 1, 1, "Write to SD-Card");
	GLCD_DisplayString(8, 1, 1, "Press User to stop");
	GLCD_DisplayString(4, 1, 1, "Fit Card into Slot");
	
	/* Wait until SD Card is in Slot */
	while(!(SD_Start("time.txt", FA_CREATE_ALWAYS | FA_WRITE)))
	{
		
	}
	
	length=sprintf (buffer, "runtime: %d:%d:%d    ", hour, min, sek);
	GLCD_DisplayString(4, 1, 1, buffer);

	/*****************************
	*	ENDE  INITIALISIERUNG	 *
	******************************/

	
    GPIO_ResetBits(GPIOE,GPIO_Pin_All);				// LED off all pins


  	while(1)
  	{  
//		BFH_GLCD_UDP();
  	 	/* Alle 10ms wird das tickFlag gesetzt */
		if(tickFlag)
		{
	  		tickFlag=0;	// reset tickFlag
			if(write > 1)
			{
				/* Jede Sekunde einen Stamp ins File schreiben */
				if((write%1000) == 0)
				{
					/* Zeit hochzählen */
					sek++;
					if(sek==60)
					{
						sek=0;
						min++;
					}
					if(min==60)
					{
						min=0;
						hour++;
					}
					if(hour==24)
					{
						hour=0;
					}
					/* write time to Diaplay */
					length=sprintf (buffer, "runtime: %d:%d:%d    ", hour, min, sek);
					GLCD_DisplayString(4, 1, 1, buffer);
					/* write time to card */
					length=sprintf (buffer, "runtime: %d:%d:%d\ttext\r\n", hour, min, sek);
					SD_Write(buffer,length);
					/* switch LED */
					GPIOE->ODR ^= muster << 8;
				}
				write += 10;
			}  
			/* Close SD Card */
			else if (write == 1)
			{
				SD_Close();
				write--;
			}
			/* Schreiben beendet -> LED löschen */
			else
			{
				GPIOE->ODR |= muster << 8;
				GLCD_DisplayString(8, 1, 1, "Application stopped");
			}
		}
		/* Wenn Taste gedrückt wird, schreiben beenden */
		if((GPIOB->IDR&0x0080) == 0)
		{
			write = 1;
		}
  	}
}