summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/common/hexchat.h3
-rw-r--r--src/common/proto-irc.c24
-rw-r--r--src/common/servlist.c47
-rw-r--r--src/common/servlist.h3
-rw-r--r--src/fe-gtk/servlistgui.c117
5 files changed, 99 insertions, 95 deletions
diff --git a/src/common/hexchat.h b/src/common/hexchat.h
index dd30dce6..f3b9ce85 100644
--- a/src/common/hexchat.h
+++ b/src/common/hexchat.h
@@ -528,13 +528,12 @@ typedef struct server
 	char servername[128];			/* what the server says is its name */
 	char password[86];
 	char sasluser[32];				/* this is just a buffer for network->user */
-	char saslpassword[86];			/* we could reuse password but then we couldn't guarantee NickServ doesn't register first */
 	char nick[NICKLEN];
 	char linebuf[2048];				/* RFC says 512 chars including \r\n */
 	char *last_away_reason;
 	int pos;								/* current position in linebuf */
 	int nickcount;
-	int nickservtype;					/* 0=/MSG nickserv 1=/NICKSERV 2=/NS */
+	int loginmethod;					/* see login_types[] */
 
 	char *chantypes;					/* for 005 numeric - free me */
 	char *chanmodes;					/* for 005 numeric - free me */
diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c
index 984f7f20..53225a95 100644
--- a/src/common/proto-irc.c
+++ b/src/common/proto-irc.c
@@ -49,7 +49,7 @@ irc_login (server *serv, char *user, char *realname)
 {
 	tcp_sendf (serv, "CAP LS\r\n");		/* start with CAP LS as Charybdis sasl.txt suggests */
 
-	if (serv->password[0])
+	if (serv->password[0] && serv->loginmethod == 7)
 	{
 		tcp_sendf (serv, "PASS %s\r\n", serv->password);
 	}
@@ -64,21 +64,21 @@ static void
 irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3)
 {
 	/* are all ircd authors idiots? */
-	switch (serv->nickservtype)
+	switch (serv->loginmethod)
 	{
-	case 0:
+	case 1:
 		tcp_sendf (serv, "PRIVMSG NICKSERV :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
 		break;
-	case 1:
+	case 2:
 		tcp_sendf (serv, "NICKSERV %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
 		break;
-	case 2:
+	case 3:
 		tcp_sendf (serv, "NS %s %s%s%s\r\n", cmd, arg1, arg2, arg3);
 		break;
-	case 3:
+	case 4:
 		tcp_sendf (serv, "PRIVMSG NS :%s %s%s%s\r\n", cmd, arg1, arg2, arg3);
 		break;
-	case 4:
+	case 5:
 		/* why couldn't QuakeNet implement one of the existing ones? */
 		tcp_sendf (serv, "AUTH %s %s\r\n", arg1, arg2);
 	}
@@ -87,7 +87,7 @@ irc_nickserv (server *serv, char *cmd, char *arg1, char *arg2, char *arg3)
 static void
 irc_ns_identify (server *serv, char *pass)
 {
-	if (serv->nickservtype == 4)	/* QuakeNet needs to do everything in its own ways... */
+	if (serv->loginmethod == 5)	/* QuakeNet needs to do everything in its own ways... */
 	{
 		irc_nickserv (serv, "", serv->nick, pass, "");
 	}
@@ -100,7 +100,7 @@ irc_ns_identify (server *serv, char *pass)
 static void
 irc_ns_ghost (server *serv, char *usname, char *pass)
 {
-	if (serv->nickservtype != 4)
+	if (serv->loginmethod != 5)
 		irc_nickserv (serv, "GHOST", usname, " ", pass);
 }
 
@@ -1221,7 +1221,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[])
 						EMIT_SIGNAL (XP_TE_SASLAUTH, serv->server_session, sess->server->sasluser, NULL, NULL, NULL, 0);
 						tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20);
 
-						pass = encode_sasl_pass (sess->server->sasluser, sess->server->saslpassword);
+						pass = encode_sasl_pass (sess->server->sasluser, sess->server->password);
 						tcp_sendf (sess->server, "AUTHENTICATE %s\r\n", pass);
 						free (pass);
 					}
@@ -1259,8 +1259,8 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[])
 						strcat (buffer, "extended-join ");
 						want_cap = 1;
 					}
-					/* if the SASL password is set, request SASL auth */
-					if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->saslpassword) != 0)
+					/* if the SASL password is set AND auth mode is set to SASL, request SASL auth */
+					if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->password) != 0 && serv->loginmethod == 6)
 					{
 						strcat (buffer, "sasl ");
 						want_cap = 1;
diff --git a/src/common/servlist.c b/src/common/servlist.c
index 4b04820b..d49b603e 100644
--- a/src/common/servlist.c
+++ b/src/common/servlist.c
@@ -43,7 +43,7 @@ struct defaultserver
 	char *host;
 	char *channel;
 	char *charset;
-	int nsmode;		/* default NickServ type */
+	int loginmode;		/* default authentication type */
 };
 
 static const struct defaultserver def[] =
@@ -245,7 +245,7 @@ static const struct defaultserver def[] =
 	{0,			"irc.ggn.net"},
 	{0,			"irc.vendetta.com"},
 
-	{"freenode",	0,	"#hexchat"},
+	{"freenode", 0, "#hexchat", 0, 6},
 #ifdef USE_OPENSSL
 	{0,				"irc.freenode.net/+6697"},
 #endif
@@ -618,18 +618,17 @@ servlist_connect (session *sess, ircnet *net, gboolean join)
 		}
 	}
 
-	if (net->nstype >= 1)	/* once again, make sure gtk_combo_box_get_active() is not bugging us, just in case */
+	if (net->logintype)
 	{
-		serv->nickservtype = net->nstype - 1;	/* ircnet->nstype starts at 1, server->nickservtype starts at 0! */
+		serv->loginmethod = net->logintype;
 	}
 	else
 	{
-		serv->nickservtype = 1;					/* use /NickServ by default */
+		serv->loginmethod = 2;				/* use /NickServ by default */
 	}
 
 	serv->password[0] = 0;
 	serv->sasluser[0] = 0;
-	serv->saslpassword[0] = 0;
 
 	if (net->pass)
 	{
@@ -645,11 +644,6 @@ servlist_connect (session *sess, ircnet *net, gboolean join)
 		safe_strcpy (serv->sasluser, net->user, sizeof (serv->sasluser));
 	}
 
-	if (net->saslpass)
-	{
-		safe_strcpy (serv->saslpassword, net->saslpass, sizeof (serv->saslpassword));
-	}
-
 	if (net->flags & FLAG_USE_GLOBAL)
 	{
 		strcpy (serv->nick, prefs.hex_irc_nick1);
@@ -941,7 +935,6 @@ servlist_cleanup (void)
 	{
 		net = list->data;
 		free_and_clear (net->pass);
-		free_and_clear (net->saslpass);
 		free_and_clear (net->nickserv);
 	}
 }
@@ -964,7 +957,6 @@ servlist_net_remove (ircnet *net)
 	if (net->real)
 		free (net->real);
 	free_and_clear (net->pass);
-	free_and_clear (net->saslpass);
 	if (net->autojoin)
 		free (net->autojoin);
 	if (net->command)
@@ -1029,9 +1021,9 @@ servlist_load_defaults (void)
 				free (net->encoding);
 				net->encoding = strdup (def[i].charset);
 			}
-			if (def[i].nsmode)
+			if (def[i].loginmode)
 			{
-				net->nstype = def[i].nsmode;
+				net->logintype = def[i].loginmode;
 			}
 			if (g_str_hash (def[i].network) == def_hash)
 			{
@@ -1100,9 +1092,6 @@ servlist_load (void)
 			case 'P':
 				net->pass = strdup (buf + 2);
 				break;
-			case 'A':
-				net->saslpass = strdup (buf + 2);
-				break;
 			case 'J':
 				net->autojoin = strdup (buf + 2);
 				break;
@@ -1134,8 +1123,8 @@ servlist_load (void)
 			case 'B':
 				net->nickserv = strdup (buf + 2);
 				break;
-			case 'T':
-				net->nstype = atoi (buf + 2);
+			case 'L':
+				net->logintype = atoi (buf + 2);
 				break;
 			}
 		}
@@ -1244,26 +1233,12 @@ servlist_save (void)
 			fprintf (fp, "R=%s\n", net->real);
 		if (net->pass)
 			fprintf (fp, "P=%s\n", net->pass);
-		if (net->saslpass)
-			fprintf (fp, "A=%s\n", net->saslpass);
 		if (net->autojoin)
 			fprintf (fp, "J=%s\n", net->autojoin);
 		if (net->nickserv)
 			fprintf (fp, "B=%s\n", net->nickserv);
-		if (net->nstype)
-		{
-			if (net->nstype == -1)		/* gtk_combo_box_get_active() returns -1 for invalid indices */
-			{
-				net->nstype = 0; 		/* avoid further crashes for the current session */
-				buf = g_strdup_printf (_("Warning: invalid NickServ type. Falling back to default type for network %s."), net->name);
-				fe_message (buf, FE_MSG_WARN);
-				g_free (buf);
-			}
-			else						/* the selection was fine, save it */
-			{
-				fprintf (fp, "T=%d\n", net->nstype);
-			}
-		}
+		if (net->logintype)
+			fprintf (fp, "L=%d\n", net->logintype);
 		if (net->encoding && g_ascii_strcasecmp (net->encoding, "System") &&
 			 g_ascii_strcasecmp (net->encoding, "System default"))
 		{
diff --git a/src/common/servlist.h b/src/common/servlist.h
index b652f463..c70c3871 100644
--- a/src/common/servlist.h
+++ b/src/common/servlist.h
@@ -33,11 +33,10 @@ typedef struct ircnet
 	char *user;
 	char *real;
 	char *pass;
-	char *saslpass;
 	char *autojoin;
 	char *command;
 	char *nickserv;
-	int nstype;
+	int logintype;
 	char *comment;
 	char *encoding;
 	GSList *servlist;
diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c
index 8d480dc4..4af648ca 100644
--- a/src/fe-gtk/servlistgui.c
+++ b/src/fe-gtk/servlistgui.c
@@ -64,7 +64,6 @@ static GtkWidget *edit_entry_user;
 static GtkWidget *edit_entry_real;
 static GtkWidget *edit_entry_join;
 static GtkWidget *edit_entry_pass;
-static GtkWidget *edit_entry_saslpass;
 static GtkWidget *edit_entry_cmd;
 static GtkWidget *edit_entry_nickserv;
 static GtkWidget *edit_label_nick;
@@ -103,24 +102,53 @@ static const char *pages[]=
 	NULL
 };
 
-static const char *nstypes[]=
-{
-	/* This list is the same as in irc_nickserv(), except starting at 1, because
-	 * the 1st row is not used. We can't use index 0 coz then "if (nstype)" would
-	 * not be evaluated, it would give the same result as NULL (i.e. unset) nstype.
-	 * For unset nstype we have a "Default" entry in place of this placeholder, so
-	 * indices will be correct anyway.
-	 */
-	"PLACEHOLDER",			/* nstype = 0 */
-	"/msg NickServ",		/* nstype = 1, nickservtype = 0 */
-	"/NickServ",			/* nstype = 2, nickservtype = 1 */
-	"/NS",					/* ... */
+/* This is our dictionary for authentication types. Keep these in sync with
+ * login_types[]! This allows us to re-order the login type dropdown in the
+ * network list without breaking config compatibility.
+ */
+static int login_types_conf[] =
+{
+	0,	/* default - we don't use this but it makes indexing consistent with login_types[] so it's nice */
+	6,	/* SASL */
+	7,	/* /pass */
+	1,	/* /msg NickServ */
+	2,	/* /NickServ */
+	3,	/* /NS */
+	4,	/* /msg NS */
+	5,	/* /auth */
+};
+
+static const char *login_types[]=
+{
+	"Default",
+	"SASL",
+	"/pass",
+	"/msg NickServ",
+	"/NickServ",
+	"/NS",
 	"/msg NS",
 	"/auth",
 	NULL
-	/* This also means that we need to shift these values for irc_nickserv()! */
 };
 
+/* poor man's IndexOf() - find the dropdown string index that belongs to the given config value */
+static int
+servlist_get_login_desc_index (int conf_value)
+{
+	int i;
+	int length = sizeof (login_types_conf) / sizeof (login_types_conf[0]);		/* the number of elements in the conf array */
+
+	for (i = 0; i < length; i++)
+	{
+		if (login_types_conf[i] == conf_value)
+		{
+			return i;
+		}
+	}
+
+	return 0;	/* make the compiler happy */
+}
+
 static void
 servlist_select_and_show (GtkTreeView *treeview, GtkTreeIter *iter,
 								  GtkListStore *store)
@@ -500,7 +528,6 @@ servlist_edit_update (ircnet *net)
 	servlist_update_from_entry (&net->command, edit_entry_cmd);
 	servlist_update_from_entry (&net->nickserv, edit_entry_nickserv);
 	servlist_update_from_entry (&net->pass, edit_entry_pass);
-	servlist_update_from_entry (&net->saslpass, edit_entry_saslpass);
 }
 
 static void
@@ -1328,9 +1355,12 @@ servlist_combo_cb (GtkEntry *entry, gpointer userdata)
 	}
 }
 
+/* Fills up the network's authentication type so that it's guaranteed to be either NULL or a valid value. */
 static void
-servlist_nscombo_cb (GtkEntry *entry, gpointer userdata)
+servlist_logintypecombo_cb (GtkEntry *entry, gpointer userdata)
 {
+	int index;
+
 	if (!selected_net)
 	{
 		return;
@@ -1338,7 +1368,15 @@ servlist_nscombo_cb (GtkEntry *entry, gpointer userdata)
 
 	if (!ignore_changed)
 	{
-		selected_net->nstype = gtk_combo_box_get_active (GTK_COMBO_BOX (entry));
+		index = gtk_combo_box_get_active (GTK_COMBO_BOX (entry));	/* starts at 0, returns -1 for invalid selections */
+
+		if (index != -1)
+		{
+			/* The selection is valid. It can be 0, which is the default type, but we need to allow
+			 * that so that you can revert from other types. servlist_save() will dump 0 anyway.
+			 */
+			selected_net->logintype = login_types_conf[index];
+		}
 	}
 }
 
@@ -1364,23 +1402,22 @@ servlist_create_charsetcombo (void)
 }
 
 static GtkWidget *
-servlist_create_nstypecombo (void)
+servlist_create_logintypecombo (void)
 {
 	GtkWidget *cb;
 	int i;
 
 	cb = gtk_combo_box_entry_new_text ();
-	gtk_combo_box_append_text (GTK_COMBO_BOX (cb), "Default");
 
-	i = 1;		/* start with the 2nd row, leave the placeholder 0th element alone */
+	i = 0;
 
-	while (nstypes[i])
+	while (login_types[i])
 	{
-		gtk_combo_box_append_text (GTK_COMBO_BOX (cb), (char *)nstypes[i]);
+		gtk_combo_box_append_text (GTK_COMBO_BOX (cb), (char *)login_types[i]);
 		i++;
 	}
 
-	g_signal_connect (G_OBJECT (GTK_BIN (cb)), "changed", G_CALLBACK (servlist_nscombo_cb), NULL);
+	g_signal_connect (G_OBJECT (GTK_BIN (cb)), "changed", G_CALLBACK (servlist_logintypecombo_cb), NULL);
 
 	return cb;
 }
@@ -1430,9 +1467,9 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
 	GtkWidget *label16;
 	GtkWidget *label21;
 	GtkWidget *label34;
-	GtkWidget *label_nstype;
+	GtkWidget *label_logintype;
 	GtkWidget *comboboxentry_charset;
-	GtkWidget *comboboxentry_nstypes;
+	GtkWidget *comboboxentry_logintypes;
 	GtkWidget *hbox1;
 	GtkWidget *scrolledwindow2;
 	GtkWidget *treeview_servers;
@@ -1545,37 +1582,31 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
 					_("If your nickname requires a password, enter it here. Not all IRC networks support this."));
 	gtk_entry_set_visibility (GTK_ENTRY (edit_entry_nickserv), FALSE);
 
-	label_nstype = gtk_label_new (_("NickServ type:"));
-	gtk_widget_show (label_nstype);
-	gtk_table_attach (GTK_TABLE (table3), label_nstype, 1, 2, 18, 19,
+	label_logintype = gtk_label_new (_("Login method:"));
+	gtk_widget_show (label_logintype);
+	gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 18, 19,
 							(GtkAttachOptions) (GTK_FILL),
 							(GtkAttachOptions) (0), 0, 0);
-	gtk_misc_set_alignment (GTK_MISC (label_nstype), 0, 0.5);
+	gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5);
 
-	comboboxentry_nstypes = servlist_create_nstypecombo ();
+	comboboxentry_logintypes = servlist_create_logintypecombo ();
 	ignore_changed = TRUE;
-	gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_nstypes)->child), net->nstype ? nstypes[net->nstype] : "Default");
+	gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_logintypes)->child), net->logintype ? login_types[servlist_get_login_desc_index (net->logintype)] : login_types[0]);
 	ignore_changed = FALSE;
-	gtk_widget_show (comboboxentry_nstypes);
-	gtk_table_attach (GTK_TABLE (table3), comboboxentry_nstypes, 2, 3, 18, 19,
+	gtk_widget_show (comboboxentry_logintypes);
+	gtk_table_attach (GTK_TABLE (table3), comboboxentry_logintypes, 2, 3, 18, 19,
 							(GtkAttachOptions) (GTK_FILL),
 							(GtkAttachOptions) (GTK_FILL), 0, 0);
 
 	edit_entry_pass =
-		servlist_create_entry (table3, _("Server password:"), 20,
+		servlist_create_entry (table3, _("Password:"), 20,
 									  net->pass, 0,
-					_("Password for the server, if in doubt, leave blank."));
+					_("Password used for login. If in doubt, leave blank."));
 	gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE);
 
-	edit_entry_saslpass =
-		servlist_create_entry (table3, _("SASL password:"), 21,
-									  net->saslpass, 0,
-					_("Password for SASL authentication, if in doubt, leave blank."));
-	gtk_entry_set_visibility (GTK_ENTRY (edit_entry_saslpass), FALSE);
-
 	label34 = gtk_label_new (_("Character set:"));
 	gtk_widget_show (label34);
-	gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 22, 23,
+	gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 21, 22,
 							(GtkAttachOptions) (GTK_FILL),
 							(GtkAttachOptions) (0), 0, 0);
 	gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5);
@@ -1585,7 +1616,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net)
 	gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_charset)->child), net->encoding ? net->encoding : "System default");
 	ignore_changed = FALSE;
 	gtk_widget_show (comboboxentry_charset);
-	gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 22, 23,
+	gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 21, 22,
 							(GtkAttachOptions) (GTK_FILL),
 							(GtkAttachOptions) (GTK_FILL), 0, 0);