diff --git a/libpurple/connection.h b/libpurple/connection.h
--- a/libpurple/connection.h
+++ b/libpurple/connection.h
@@ -253,6 +253,20 @@
 	(purple_connection_get_state(gc) == PURPLE_CONNECTION_CONNECTED)
 
 /**
+ * purple_connection_new:
+ * @protocol: The [class@Purple.Protocol] to use to create the connection.
+ * @account: The [class@Purple.Account] to create a connection for.
+ * @password: (nullable): The password for this account.
+ *
+ * Creates a new [class@Purple.Connection] for @account.
+ *
+ * Returns: (transfer full): The new connection.
+ *
+ * Since: 3.0.0
+ */
+PurpleConnection *purple_connection_new(PurpleProtocol *protocol, PurpleAccount *account, const char *password);
+
+/**
  * purple_connection_is_disconnecting:
  * @gc: The connection.
  *
# HG changeset patch
# Node ID 2f5e5c9bfd50
# Parent  5ae15cfc1bee
diff --git a/libpurple/connection.c b/libpurple/connection.c
--- a/libpurple/connection.c
+++ b/libpurple/connection.c
@@ -892,8 +892,6 @@
 _purple_connection_new(PurpleAccount *account, gboolean is_registration,
                        const gchar *password)
 {
-	PurpleConnection *connection = NULL;
-	PurpleConnectionPrivate *priv = NULL;
 	PurpleProtocol *protocol = NULL;
 
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
@@ -934,32 +932,7 @@
 		}
 	}
 
-	connection = g_object_new(
-		PURPLE_TYPE_CONNECTION,
-		"protocol", protocol,
-		"account", account,
-		"password", password,
-		NULL);
-
-	g_return_if_fail(connection != NULL);
-
-	priv = purple_connection_get_instance_private(connection);
-
-	if(is_registration) {
-		purple_debug_info("connection", "Registering.  connection = %p",
-		                  connection);
-
-		/* set this so we don't auto-reconnect after registering */
-		priv->wants_to_die = TRUE;
-
-		purple_protocol_server_register_user(PURPLE_PROTOCOL_SERVER(protocol),
-		                                     account);
-	} else {
-		purple_debug_info("connection", "Connecting. connection = %p",
-		                  connection);
-
-		purple_protocol_login(protocol, account);
-	}
+	purple_protocol_login(protocol, account, password);
 }
 
 void
@@ -1017,6 +990,21 @@
 	                                       account, cb, user_data);
 }
 
+PurpleConnection *
+purple_connection_new(PurpleProtocol *protocol, PurpleAccount *account,
+                      const char *password)
+{
+	g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
+	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
+
+	return g_object_new(
+		PURPLE_TYPE_CONNECTION,
+		"protocol", protocol,
+		"account", account,
+		"password", password,
+		NULL);
+}
+
 /**************************************************************************
  * Connections API
  **************************************************************************/
diff --git a/libpurple/protocols/bonjour/bonjour.c b/libpurple/protocols/bonjour/bonjour.c
--- a/libpurple/protocols/bonjour/bonjour.c
+++ b/libpurple/protocols/bonjour/bonjour.c
@@ -94,19 +94,23 @@
 
 }
 
-static void
-bonjour_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount *account) {
-	PurpleConnection *gc = purple_account_get_connection(account);
+static PurpleConnection *
+bonjour_login(PurpleProtocol *protocol, PurpleAccount *account,
+              const char *password)
+{
+	PurpleConnection *gc = NULL;
 	BonjourData *bd;
 	PurpleStatus *status;
 	PurplePresence *presence;
 
+	gc = purple_connection_new(protocol, account, password);
+
 	if (!mdns_available()) {
 		purple_connection_error(gc,
 				PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 				_("Unable to find Apple's \"Bonjour for Windows\" toolkit, see "
 				  "https://developer.pidgin.im/BonjourWindows for more information."));
-		return;
+		return gc;
 	}
 
 	purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_HTML |
@@ -124,7 +128,7 @@
 		purple_connection_error (gc,
 				PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 				_("Unable to listen for incoming IM connections"));
-		return;
+		return gc;
 	}
 
 	/* Connect to the mDNS daemon looking for buddies in the LAN */
@@ -151,13 +155,15 @@
 		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Unable to establish connection with the local mDNS server.  Is it running?"));
-		return;
+		return gc;
 	}
 
 	bonjour_dns_sd_update_buddy_icon(bd->dns_sd_data);
 
 	/* Show the buddy list by telling Purple we have already connected */
 	purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
+
+	return gc;
 }
 
 static void
diff --git a/libpurple/protocols/demo/purpledemoprotocol.c b/libpurple/protocols/demo/purpledemoprotocol.c
--- a/libpurple/protocols/demo/purpledemoprotocol.c
+++ b/libpurple/protocols/demo/purpledemoprotocol.c
@@ -35,16 +35,19 @@
 /******************************************************************************
  * PurpleProtocol Implementation
  *****************************************************************************/
-static void
-purple_demo_protocol_login(G_GNUC_UNUSED PurpleProtocol *protocol,
-                           PurpleAccount *account)
+static PurpleConnection *
+purple_demo_protocol_login(PurpleProtocol *protocol, PurpleAccount *account,
+                           const char *password)
 {
 	PurpleConnection *connection = NULL;
 
-	connection = purple_account_get_connection(account);
+	connection = purple_connection_new(protocol, account, password);
+
 	purple_connection_set_state(connection, PURPLE_CONNECTION_CONNECTED);
 
 	purple_demo_contacts_load(account);
+
+	return connection;
 }
 
 static GList *
diff --git a/libpurple/protocols/facebook/facebook.c b/libpurple/protocols/facebook/facebook.c
--- a/libpurple/protocols/facebook/facebook.c
+++ b/libpurple/protocols/facebook/facebook.c
@@ -1007,8 +1007,8 @@
 	return g_list_reverse(opts);
 }
 
-static void
-fb_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount *acct) {
+static PurpleConnection *
+fb_login(PurpleProtocol *protocol, PurpleAccount *acct, const char *password) {
 	const gchar *pass;
 	const gchar *user;
 	FbApi *api;
@@ -1018,14 +1018,14 @@
 	GProxyResolver *resolver;
 	GError *error = NULL;
 
-	gc = purple_account_get_connection(acct);
+	gc = purple_connection_new(protocol, acct, password);
 
 	resolver = purple_proxy_get_proxy_resolver(acct, &error);
 	if (resolver == NULL) {
 		fb_util_debug_error("Unable to get account proxy resolver: %s",
 		                    error->message);
 		purple_connection_take_error(gc, error);
-		return;
+		return gc;
 	}
 
 	fata = fb_data_new(gc, resolver);
@@ -1105,10 +1105,12 @@
 		user = purple_account_get_username(acct);
 		pass = purple_connection_get_password(gc);
 		fb_api_auth(api, user, pass);
-		return;
+		return gc;
 	}
 
 	fb_api_contacts(api);
+
+	return gc;
 }
 
 static void
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -781,9 +781,11 @@
 	}
 }
 
-static void
-ggp_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount *account) {
-	PurpleConnection *gc = purple_account_get_connection(account);
+static PurpleConnection *
+ggp_login(PurpleProtocol *protocol, PurpleAccount *account,
+          const char *password)
+{
+	PurpleConnection *gc = NULL;
 	struct gg_login_params *glp;
 	GGPInfo *info;
 	const char *address;
@@ -791,6 +793,8 @@
 	GProxyResolver *resolver;
 	GError *error = NULL;
 
+	gc = purple_connection_new(protocol, account, password);
+
 	purple_connection_set_flags(gc,
 		PURPLE_CONNECTION_FLAG_HTML |
 		PURPLE_CONNECTION_FLAG_NO_URLDESC);
@@ -800,7 +804,7 @@
 		purple_debug_error("gg", "Unable to get account proxy resolver: %s",
 		                   error->message);
 		purple_connection_take_error(gc, error);
-		return;
+		return gc;
 	}
 
 	glp = g_new0(struct gg_login_params, 1);
@@ -833,7 +837,7 @@
 			_("The username specified is invalid."));
 		purple_str_wipe(glp->password);
 		g_free(glp);
-		return;
+		return gc;
 	}
 
 	glp->image_size = 255;
@@ -864,7 +868,7 @@
 				_("SSL support unavailable"));
 			purple_str_wipe(glp->password);
 			g_free(glp);
-			return;
+			return gc;
 		}
 	}
 	else /* encryption_type == "none" */
@@ -896,13 +900,15 @@
 		purple_connection_error (gc,
 			PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
 			_("Connection failed"));
-		return;
+		return gc;
 	}
 
 	if (info->session->fd > 0) {
 		info->inpa = purple_input_add(info->session->fd,
 			PURPLE_INPUT_READ, ggp_async_login_handler, gc);
 	}
+
+	return gc;
 }
 
 static void
diff --git a/libpurple/protocols/irc/irc.c b/libpurple/protocols/irc/irc.c
--- a/libpurple/protocols/irc/irc.c
+++ b/libpurple/protocols/irc/irc.c
@@ -42,7 +42,7 @@
 
 static GList *irc_status_types(PurpleProtocol *protocol, PurpleAccount *account);
 /* static GList *irc_chat_info(PurpleConnection *gc); */
-static void irc_login(PurpleProtocol *protocol, PurpleAccount *account);
+static PurpleConnection *irc_login(PurpleProtocol *protocol, PurpleAccount *account, const char *password);
 static void irc_login_cb(GObject *source, GAsyncResult *res, gpointer user_data);
 static void irc_close(PurpleProtocol *protocol, PurpleConnection *gc);
 static int irc_im_send(PurpleProtocolIM *im, PurpleConnection *gc, PurpleMessage *msg);
@@ -524,8 +524,10 @@
 	return defaults;
 }
 
-static void
-irc_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount *account) {
+static PurpleConnection *
+irc_login(PurpleProtocol *protocol, PurpleAccount *account,
+          const char *password)
+{
 	PurpleConnection *gc;
 	struct irc_conn *irc;
 	char **userparts;
@@ -533,7 +535,7 @@
 	GSocketClient *client;
 	GError *error = NULL;
 
-	gc = purple_account_get_connection(account);
+	gc = purple_connection_new(protocol, account, password);
 	purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_NO_NEWLINES |
 		PURPLE_CONNECTION_FLAG_NO_IMAGES);
 
@@ -542,7 +544,7 @@
 			PURPLE_CONNECTION_ERROR,
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("IRC nick and server may not contain whitespace")));
-		return;
+		return gc;
 	}
 
 	irc = g_new0(struct irc_conn, 1);
@@ -566,7 +568,7 @@
 
 	if (client == NULL) {
 		purple_connection_take_error(gc, error);
-		return;
+		return gc;
 	}
 
 	/* Optionally use TLS if it's set in the account settings */
@@ -580,6 +582,8 @@
 							IRC_DEFAULT_PORT),
 			irc->cancellable, irc_login_cb, gc);
 	g_object_unref(client);
+
+	return gc;
 }
 
 static gboolean do_login(PurpleConnection *gc) {
diff --git a/libpurple/protocols/ircv3/purpleircv3protocol.c b/libpurple/protocols/ircv3/purpleircv3protocol.c
--- a/libpurple/protocols/ircv3/purpleircv3protocol.c
+++ b/libpurple/protocols/ircv3/purpleircv3protocol.c
@@ -84,21 +84,21 @@
 	return options;
 }
 
-static void
-purple_ircv3_protocol_login(G_GNUC_UNUSED PurpleProtocol *protocol,
-                            PurpleAccount *account)
+static PurpleConnection *
+purple_ircv3_protocol_login(PurpleProtocol *protocol, PurpleAccount *account,
+                            const char *password)
 {
 	PurpleIRCv3Connection *connection = NULL;
 	PurpleConnection *purple_connection = NULL;
 	GError *error = NULL;
 
-	purple_connection = purple_account_get_connection(account);
+	purple_connection = purple_connection_new(protocol, account, password);
 
 	connection = purple_ircv3_connection_new(account);
 	if(!purple_ircv3_connection_valid(connection, &error)) {
 		purple_connection_take_error(purple_connection, error);
 
-		return;
+		return purple_connection;
 	}
 
 	g_object_set_data_full(G_OBJECT(purple_connection),
@@ -106,6 +106,8 @@
 	                       connection, g_object_unref);
 
 	purple_ircv3_connection_connect(connection);
+
+	return purple_connection;
 }
 
 static void
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -1003,17 +1003,21 @@
 	}
 }
 
-static void
-jabber_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount *account) {
-	PurpleConnection *gc = purple_account_get_connection(account);
+static PurpleConnection *
+jabber_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount *account,
+             const char *password)
+{
+	PurpleConnection *gc = NULL;
 	JabberStream *js;
 	PurpleImage *image;
 
+	gc = purple_connection_new(protocol, account, password);
+
 	purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_HTML |
 		PURPLE_CONNECTION_FLAG_NO_IMAGES);
 	js = jabber_stream_new(account);
 	if (js == NULL)
-		return;
+		return gc;
 
 	/* replace old default proxies with the new default: NULL
 	 * TODO: these can eventually be removed */
@@ -1037,6 +1041,8 @@
 	}
 
 	jabber_stream_connect(js);
+
+	return gc;
 }
 
 
@@ -1493,9 +1499,12 @@
 	JabberStream *js;
 
 	if (purple_connection_get_state(gc) != PURPLE_CONNECTION_CONNECTED) {
+		#warning fix registration and unregistration
+		#if 0
 		if (purple_connection_get_state(gc) != PURPLE_CONNECTION_CONNECTING) {
 			jabber_login(PURPLE_PROTOCOL(protocol_server), account);
 		}
+		#endif
 
 		js = purple_connection_get_protocol_data(gc);
 		js->unregistration = TRUE;
diff --git a/libpurple/protocols/novell/novell.c b/libpurple/protocols/novell/novell.c
--- a/libpurple/protocols/novell/novell.c
+++ b/libpurple/protocols/novell/novell.c
@@ -2184,8 +2184,10 @@
  * Protocol Ops
  ******************************************************************************/
 
-static void
-novell_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount * account) {
+static PurpleConnection *
+novell_login(PurpleProtocol *protocol, PurpleAccount *account,
+             const char *password)
+{
 	PurpleConnection *gc;
 	NMUser *user = NULL;
 	const char *server;
@@ -2193,12 +2195,7 @@
 	int port;
 	GError *error = NULL;
 
-	if (account == NULL)
-		return;
-
-	gc = purple_account_get_connection(account);
-	if (gc == NULL)
-		return;
+	gc = purple_connection_new(protocol, account, password);
 
 	purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_NO_IMAGES);
 
@@ -2214,7 +2211,7 @@
 			PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
 			_("Unable to connect to server. Please enter the "
 			  "address of the server to which you wish to connect."));
-		return;
+		return gc;
 	}
 
 	port = purple_account_get_int(account, "port", DEFAULT_PORT);
@@ -2229,7 +2226,7 @@
 		user->conn->client = purple_gio_socket_client_new(account, &error);
 		if (user->conn->client == NULL) {
 			purple_connection_take_error(gc, error);
-			return;
+			return gc;
 		}
 
 		g_socket_client_set_tls(user->conn->client, TRUE);
@@ -2237,6 +2234,8 @@
 		        user->conn->client, user->conn->addr, user->conn->port,
 		        user->cancellable, novell_login_callback, gc);
 	}
+
+	return gc;
 }
 
 static void
diff --git a/libpurple/protocols/sametime/sametime.c b/libpurple/protocols/sametime/sametime.c
--- a/libpurple/protocols/sametime/sametime.c
+++ b/libpurple/protocols/sametime/sametime.c
@@ -3523,8 +3523,8 @@
 
 
 static void
-mw_protocol_login(G_GNUC_UNUSED PurpleProtocol *protocol,
-                  PurpleAccount *account)
+mw_protocol_login(PurpleProtocol *protocol, PurpleAccount *account,
+                  const char *password)
 {
   PurpleConnection *gc;
   struct mwPurpleProtocolData *pd;
@@ -3534,7 +3534,7 @@
 
   GError *error = NULL;
 
-  gc = purple_account_get_connection(account);
+  gc = purple_connection_new(protocol, account, password);
   pd = mwPurpleProtocolData_new(gc);
 
   /* while we do support images, the default is to not offer it */
@@ -3561,7 +3561,7 @@
     purple_connection_error(gc,
             PURPLE_CONNECTION_ERROR_INVALID_SETTINGS,
             _("A server is required to connect this account"));
-    return;
+    return gc;
   }
 
   pass = g_strdup(purple_connection_get_password(gc));
@@ -3603,13 +3603,15 @@
   pd->client = purple_gio_socket_client_new(account, &error);
   if (pd->client == NULL) {
     purple_connection_take_error(gc, error);
-    return;
+    return gc;
   }
 
   g_socket_client_connect_to_host_async(
           pd->client, host,
           port, pd->cancellable,
           connect_cb, pd);
+
+  return gc;
 }
 
 
diff --git a/libpurple/protocols/silc/silc.c b/libpurple/protocols/silc/silc.c
--- a/libpurple/protocols/silc/silc.c
+++ b/libpurple/protocols/silc/silc.c
@@ -575,9 +575,9 @@
 	silcpurple_continue_running(sg);
 }
 
-static void
-silcpurple_login(G_GNUC_UNUSED PurpleProtocol *protocol,
-                 PurpleAccount *account)
+static PurpleConnection *
+silcpurple_login(PurpleProtocol *protocol, PurpleAccount *account,
+                 const char *password)
 {
 	SilcClient client;
 	PurpleConnection *gc;
@@ -587,9 +587,7 @@
 	char *username, *hostname, *realname, **up;
 	int i;
 
-	gc = purple_account_get_connection(account);
-	if (!gc)
-		return;
+	gc = purple_connection_new(protocol, account, password);
 	purple_connection_set_protocol_data(gc, NULL);
 
 	memset(&params, 0, sizeof(params));
@@ -600,7 +598,7 @@
 	if (!client) {
 		purple_connection_error(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
 		                             _("Out of memory"));
-		return;
+		return gc;
 	}
 
 	/* Get username, real name and local hostname for SILC library */
@@ -640,7 +638,7 @@
 
 	sg = silc_calloc(1, sizeof(*sg));
 	if (!sg)
-		return;
+		return gc;
 	sg->cancellable = g_cancellable_new();
 	sg->client = client;
 	sg->gc = gc;
@@ -656,7 +654,7 @@
 		silcpurple_free(sg);
 		silc_free(hostname);
 		g_free(username);
-		return;
+		return gc;
 	}
 	silc_free(hostname);
 	g_free(username);
@@ -667,7 +665,7 @@
 		                             _("Error loading SILC key pair"));
 		purple_connection_set_protocol_data(gc, NULL);
 		silcpurple_free(sg);
-		return;
+		return gc;
 	}
 
 	/* Run SILC scheduler */
@@ -675,6 +673,8 @@
 	silc_schedule_set_notify(client->schedule, silcpurple_scheduler,
 				 client);
 	silc_client_run_one(client);
+
+	return gc;
 }
 
 static int
diff --git a/libpurple/protocols/zephyr/zephyr.c b/libpurple/protocols/zephyr/zephyr.c
--- a/libpurple/protocols/zephyr/zephyr.c
+++ b/libpurple/protocols/zephyr/zephyr.c
@@ -672,15 +672,17 @@
 	return g_strdup(realm);
 }
 
-static void
-zephyr_login(G_GNUC_UNUSED PurpleProtocol *protocol, PurpleAccount * account) {
+static PurpleConnection *
+zephyr_login(PurpleProtocol *protocol, PurpleAccount *account,
+             const char *password)
+{
 	PurpleConnection *gc;
 	zephyr_account *zephyr;
 	ZephyrLoginFunc login;
 	GSourceFunc check_notify;
 	ZSubscription_t sub;
 
-	gc = purple_account_get_connection(account);
+	gc = purple_connection_new(protocol, account, password);
 
 #ifdef WIN32
 	username = purple_account_get_username(account);
@@ -719,7 +721,7 @@
 	zephyr->encoding = (char *)purple_account_get_string(account, "encoding", ZEPHYR_FALLBACK_CHARSET);
 
 	if (!login(zephyr)) {
-		return;
+		return gc;
 	}
 	purple_debug_info("zephyr","does it get here\n");
 	purple_debug_info("zephyr"," realm: %s username:%s\n", zephyr->realm, zephyr->username);
@@ -739,7 +741,7 @@
 		purple_notify_error(gc, NULL,
 			"Unable to subscribe to messages", "Unable to subscribe to initial messages",
 			purple_request_cpar_from_connection(gc));
-		return;
+		return gc;
 	}
 
 	purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED);
@@ -753,6 +755,8 @@
 
 	zephyr->nottimer = g_timeout_add(100, check_notify, gc);
 	zephyr->loctimer = g_timeout_add_seconds(20, check_loc, zephyr);
+
+	return gc;
 }
 
 static void write_zsubs(zephyr_account *zephyr)
diff --git a/libpurple/purpleprotocol.h b/libpurple/purpleprotocol.h
--- a/libpurple/purpleprotocol.h
+++ b/libpurple/purpleprotocol.h
@@ -141,7 +141,7 @@
 	PurpleBuddyIconSpec *(*get_buddy_icon_spec)(PurpleProtocol *protocol);
 	PurpleWhiteboardOps *(*get_whiteboard_ops)(PurpleProtocol *protocol);
 
-	void (*login)(PurpleProtocol *protocol, PurpleAccount *account);
+	PurpleConnection *(*login)(PurpleProtocol *protocol, PurpleAccount *account, const char *password);
 
 	void (*close)(PurpleProtocol *protocol, PurpleConnection *connection);
 
@@ -268,14 +268,20 @@
 
 /**
  * purple_protocol_login:
- * @protocol: The #PurpleProtocol instance.
- * @account: The #PurpleAccount to login.
+ * @protocol: The instance.
+ * @account: The [class@Purple.Account] to login.
+ * @password: The password for this connection.
  *
- * Logs @account in using @protocol.
+ * Logs @account in to @protocol using @password.
+ *
+ * In simple cases, you can just pass the values to
+ * [ctor@Purple.Connection.new] and return that value.
+ *
+ * Returns: (transfer full): The new connection.
  *
  * Since: 3.0.0
  */
-void purple_protocol_login(PurpleProtocol *protocol, PurpleAccount *account);
+PurpleConnection *purple_protocol_login(PurpleProtocol *protocol, PurpleAccount *account, const char *password);
 
 /**
  * purple_protocol_close:
diff --git a/libpurple/purpleprotocol.c b/libpurple/purpleprotocol.c
--- a/libpurple/purpleprotocol.c
+++ b/libpurple/purpleprotocol.c
@@ -522,17 +522,21 @@
 	return NULL;
 }
 
-void
-purple_protocol_login(PurpleProtocol *protocol, PurpleAccount *account) {
+PurpleConnection *
+purple_protocol_login(PurpleProtocol *protocol, PurpleAccount *account,
+                      const char *password)
+{
 	PurpleProtocolClass *klass = NULL;
 
-	g_return_if_fail(PURPLE_IS_PROTOCOL(protocol));
-	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
+	g_return_val_if_fail(PURPLE_IS_PROTOCOL(protocol), NULL);
+	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
 
 	klass = PURPLE_PROTOCOL_GET_CLASS(protocol);
 	if(klass != NULL && klass->login != NULL) {
-		klass->login(protocol, account);
+		return klass->login(protocol, account, password);
 	}
+
+	return NULL;
 }
 
 void
