Index: wp-login.php
===================================================================
--- wp-login.php	(revision 21203)
+++ wp-login.php	(working copy)
@@ -86,9 +86,16 @@
 	if ( $interim_login )
 		$login_header_url = '#';
 
+	$login_body_class = str_replace( 'login', '', _get_login_action() );
+
+	if ( is_rtl() )
+		$login_body_class .= ' rtl';
+
+	if ( wp_is_mobile() )
+		$login_body_class .= ' mobile';
 	?>
 	</head>
-	<body class="login<?php if ( wp_is_mobile() ) echo ' mobile'; ?>">
+	<body class="login <?php echo apply_filters( 'login_body_class', '' ) . " $login_body_class"; ?>">
 	<div id="login">
 		<h1><a href="<?php echo esc_url( $login_header_url ); ?>" title="<?php echo esc_attr( $login_header_title ); ?>"><?php bloginfo( 'name' ); ?></a></h1>
 	<?php
@@ -343,20 +350,33 @@
 	return $user_id;
 }
 
+/**
+ * Retrieves current action.
+ *
+ * @since 3.5.0
+ *
+ * @return string Requested action.
+ */
+function _get_login_action() {
+	$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'login';
+
+	if ( isset( $_GET['key'] ) )
+		$action = 'resetpass';
+
+	// validate action so as to default to the login screen
+	if ( ! in_array( $action, array( 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login' ), true ) && false === has_filter( 'login_form_' . $action ) )
+		$action = 'login';
+
+	return $action;
+}
+
 //
 // Main
 //
 
-$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'login';
+$action = _get_login_action();
 $errors = new WP_Error();
 
-if ( isset($_GET['key']) )
-	$action = 'resetpass';
-
-// validate action so as to default to the login screen
-if ( !in_array( $action, array( 'postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login' ), true ) && false === has_filter( 'login_form_' . $action ) )
-	$action = 'login';
-
 nocache_headers();
 
 header('Content-Type: '.get_bloginfo('html_type').'; charset='.get_bloginfo('charset'));
