示例#1
0
void do_authentication(char *user, int privileged_port, int cipher_type)
{
    int type;
    int authenticated = 0;
    int authentication_type = 0;
    char *password;
    int row, col, xpixel, ypixel;
    int password_attempts = 0;

    if (strlen(user) > 255)
        do_authentication_fail_loop();

    /* Verify that the user is a valid user.  We disallow usernames starting
       with any characters that are commonly used to start NIS entries. */
    if (user[0] == '-' || user[0] == '+' || user[0] == '@')
        do_authentication_fail_loop();

    debug("Attempting authentication for %.100s.", user);

    /* If the user has no password, accept authentication immediately. */
    if (auth_password(user, "")) {
        /* Authentication with empty password succeeded. */
        authentication_type = SSH_AUTH_PASSWORD;
        authenticated = 1;
        /* Success packet will be sent after loop below. */
    } else {
        /* Indicate that authentication is needed. */
        packet_start(SSH_SMSG_FAILURE);
        packet_send();
        packet_write_wait();
    }

    /* Loop until the user has been authenticated or the connection is closed. */
    while (!authenticated) {
        /* Get a packet from the client. */
        type = packet_read();

        /* Process the packet. */
        switch (type) {

        case SSH_CMSG_AUTH_RHOSTS:
            packet_get_all();
            log_msg("Rhosts authentication disabled.");
            break;

        case SSH_CMSG_AUTH_RHOSTS_RSA:
            packet_get_all();
            log_msg("Rhosts with RSA authentication disabled.");
            break;

        case SSH_CMSG_AUTH_RSA:
            packet_get_all();
            log_msg("RSA authentication disabled.");
            break;

        case SSH_CMSG_AUTH_PASSWORD:
            if (cipher_type == SSH_CIPHER_NONE) {
                packet_get_all();
                log_msg("Password authentication not available for unencrypted session.");
                break;
            }

            /* Password authentication requested. */
            /* Read user password.  It is in plain text, but was transmitted
               over the encrypted channel so it is not visible to an outside
               observer. */
            password = packet_get_string(NULL);

            if (password_attempts >= 5) {       /* Too many password authentication attempts. */
                packet_disconnect("Too many password authentication attempts from %.100s for user %.100s.", get_canonical_hostname(), user);
             /*NOTREACHED*/}

            /* Count password authentication attempts, and log if appropriate. */
            if (password_attempts > 0) {
                /* Log failures if attempted more than once. */
                debug("Password authentication failed for user %.100s from %.100s.", user, get_canonical_hostname());
            }
            password_attempts++;

            /* Try authentication with the password. */
            if (auth_password(user, password)) {
                /* Successful authentication. */
                /* Clear the password from memory. */
                memset(password, 0, strlen(password));
                xfree(password);
                log_msg("Password authentication for %.100s accepted.", user);
                authentication_type = SSH_AUTH_PASSWORD;
                authenticated = 1;
                break;
            }
            debug("Password authentication for %.100s failed.", user);
            memset(password, 0, strlen(password));
            xfree(password);
            break;

        case SSH_CMSG_WINDOW_SIZE:
            debug("Window change received.");
            row = packet_get_int();
            col = packet_get_int();
            xpixel = packet_get_int();
            ypixel = packet_get_int();
            do_naws(row, col);
            break;
            
        default:
            /* Any unknown messages will be ignored (and failure returned)
               during authentication. */
            packet_get_all();
            log_msg("Unknown message during authentication: type %d", type);
            break;              /* Respond with a failure message. */
        }
        /* If successfully authenticated, break out of loop. */
        if (authenticated)
            break;

        /* Send a message indicating that the authentication attempt failed. */
        packet_start(SSH_SMSG_FAILURE);
        packet_send();
        packet_write_wait();
    }


    /* The user has been authenticated and accepted. */
    packet_start(SSH_SMSG_SUCCESS);
    packet_send();
    packet_write_wait();

    /* Perform session preparation. */
    do_authenticated(NULL);
}
示例#2
0
void do_authenticated(char *pw)
{
    int type;
    int compression_level = 0, enable_compression_after_reply = 0;
    int row, col, xpixel, ypixel;
    unsigned long max_size;
    char *display = NULL, *proto = NULL, *data = NULL;

    /* Cancel the alarm we set to limit the time taken for authentication. */
    alarm(0);

    /* Inform the channel mechanism that we are the server side and that
       the client may request to connect to any port at all.  (The user could
       do it anyway, and we wouldn\'t know what is permitted except by the
       client telling us, so we can equally well trust the client not to request
       anything bogus.) */

    /* We stay in this loop until the client requests to execute a shell or a
       command. */
    while (1) {
        /* Get a packet from the client. */
        type = packet_read();

        /* Process the packet. */
        switch (type) {
        case SSH_CMSG_REQUEST_COMPRESSION:
            /* COMMAN: k core said that compression is not useful */
            goto fail;
            compression_level = packet_get_int();
            if (compression_level < 1 || compression_level > 9) {
                packet_send_debug("Received illegal compression level %d.", compression_level);
                goto fail;
            }
            /* Enable compression after we have responded with SUCCESS. */
            enable_compression_after_reply = 1;
            break;

        case SSH_CMSG_MAX_PACKET_SIZE:
            /* Get maximum size from paket. */
            max_size = packet_get_int();

            /* Make sure that it is acceptable. */
            if (max_size < 4096 || max_size > 256 * 1024) {
                packet_send_debug("Received illegal max packet size %lu.", max_size);
                goto fail;
            }

            /* Set the size and return success. */
            packet_set_max_size(max_size);
            break;

        case SSH_CMSG_REQUEST_PTY:
            packet_get_string(NULL);
            row = packet_get_int();
            col = packet_get_int();
            xpixel = packet_get_int();
            ypixel = packet_get_int();
            do_naws(row, col);
            packet_get_all();
            debug("Allocating a pty not permitted for this authentication.");
            break;

        case SSH_CMSG_X11_REQUEST_FORWARDING:
            packet_get_all();
            debug("X11 forwarding disabled in this site.");
            packet_send_debug("X11 forwarding disabled in this site.");
            goto fail;

        case SSH_CMSG_AGENT_REQUEST_FORWARDING:
            packet_get_all();
            debug("Authentication agent forwarding not permitted for this authentication.");
            goto fail;
        case SSH_CMSG_PORT_FORWARD_REQUEST:
            packet_get_all();
            debug("All port forwardings disabled in this site.");
            packet_send_debug("All port forwardings disabled in this site.");
            goto fail;

        case SSH_CMSG_EXEC_SHELL:
            /* Set interactive/non-interactive mode. */
            packet_set_interactive(1, options.keepalives);

            if (forced_command != NULL)
                goto do_forced_command;
            debug("Forking shell.");
            do_exec_no_pty(NULL, pw, display, proto, data);
            return;

        case SSH_CMSG_EXEC_CMD:
            packet_get_all();
            debug("command executing disabled in this site.");
            packet_send_debug("command executing disabled in this site.");
            goto fail;

        case SSH_CMSG_WINDOW_SIZE:
            debug("Window change received.");
            row = packet_get_int();
            col = packet_get_int();
            xpixel = packet_get_int();
            ypixel = packet_get_int();
            do_naws(row, col);
            break;

        default:
            /* Any unknown messages in this phase are ignored, and a failure
               message is returned. */
            packet_get_all();
            log_msg("Unknown packet type received after authentication: %d", type);
            goto fail;
        }

        /* The request was successfully processed. */
        packet_start(SSH_SMSG_SUCCESS);
        packet_send();
        packet_write_wait();

        /* Enable compression now that we have replied if appropriate. */
        if (enable_compression_after_reply) {
            enable_compression_after_reply = 0;
            packet_start_compression(compression_level);
        }

        continue;

      fail:
        /* The request failed. */
        packet_get_all();
        packet_start(SSH_SMSG_FAILURE);
        packet_send();
        packet_write_wait();
        continue;

      do_forced_command:
        /* There is a forced command specified for this login.  Execute it. */
        debug("Executing forced command: %.900s", forced_command);
        return;
    }
}
示例#3
0
文件: auth2.c 项目: andreiw/polaris
void
userauth_finish(Authctxt *authctxt, char *method)
{
	int authenticated, partial;

	if (authctxt == NULL)
		fatal("%s: missing context", __func__);

	/* unknown method handling -- must elicit userauth failure msg */
	if (authctxt->method == NULL) {
		authenticated = 0;
		partial = 0;
		goto done_checking;
	}

#ifndef USE_PAM
	/* Special handling for root (done elsewhere for PAM) */
	if (!use_privsep &&
	    authctxt->method->authenticated &&
	    authctxt->pw != NULL && authctxt->pw->pw_uid == 0 &&
	    !auth_root_allowed(method))
		authctxt->method->authenticated = 0;
#endif /* USE_PAM */

#ifdef _UNICOS
	if (authctxt->method->authenticated &&
	    cray_access_denied(authctxt->user)) {
		authctxt->method->authenticated = 0;
		fatal("Access denied for user %s.",authctxt->user);
	}
#endif /* _UNICOS */

	partial = userauth_check_partial_failure(authctxt);
	authenticated = authctxt->method->authenticated;

#ifdef USE_PAM
	/*
	 * If the userauth method failed to complete PAM work then force
	 * partial failure.
	 */
	if (authenticated && !AUTHPAM_DONE(authctxt))
		partial = 1;
#endif /* USE_PAM */

	/*
	 * To properly support invalid userauth method names we set
	 * authenticated=0, partial=0 above and know that
	 * authctxt->method == NULL.
	 *
	 * No unguarded reference to authctxt->method allowed from here.
	 * Checking authenticated != 0 is a valid guard; authctxt->method
	 * MUST NOT be NULL if authenticated.
	 */
done_checking:
	if (!authctxt->valid && authenticated) {
		/*
		 * Should never happen -- if it does PAM's at fault
		 * but we need not panic, just treat as a failure.
		 */
		authctxt->method->authenticated = 0;
		authenticated = 0;
		log("Ignoring authenticated invalid user %s",
		    authctxt->user);
		auth_log(authctxt, 0, method, " ssh2");
	}

	/* Log before sending the reply */
	auth_log(authctxt, authenticated, method, " ssh2");

	if (authenticated && !partial) {

		/* turn off userauth */
		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
		packet_start(SSH2_MSG_USERAUTH_SUCCESS);
		packet_send();
		packet_write_wait();
		/* now we can break out */
		authctxt->success = 1;
	} else {
		char *methods;

		if (authctxt->method && authctxt->method->is_initial)
			authctxt->init_failures++;

		authctxt->method = NULL;

#ifdef USE_PAM
		/*
		 * Keep track of last PAM error (or PERM_DENIED) for BSM
		 * login failure auditing, which may run after the PAM
		 * state has been cleaned up.
		 */
		authctxt->pam_retval = AUTHPAM_ERROR(authctxt, PAM_PERM_DENIED);
#endif /* USE_PAM */

		if (authctxt->failures++ > options.max_auth_tries) {
#ifdef HAVE_BSM
			fatal_remove_cleanup(audit_failed_login_cleanup,
				authctxt);
			audit_sshd_login_failure(&ah, PAM_MAXTRIES);
#endif /* HAVE_BSM */
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
		}

#ifdef _UNICOS
		if (strcmp(method, "password") == 0)
			cray_login_failure(authctxt->user, IA_UDBERR);
#endif /* _UNICOS */
		packet_start(SSH2_MSG_USERAUTH_FAILURE);

		/*
		 * If (partial) then authmethods_get() will return only
		 * required methods, likely only "keyboard-interactive;"
		 * (methods == NULL) implies failure, even if (partial == 1)
		 */
		methods = authmethods_get();
		packet_put_cstring(methods);
		packet_put_char((authenticated && partial && methods) ? 1 : 0);
		if (methods)
			xfree(methods);
		packet_send();
		packet_write_wait();
	}
}