summary refs log tree commit diff stats
path: root/win32/copy/share/download.png
blob: 43253432082aa6795ce8e39442b7ebeadb053f43 (plain)
ofshex dumpascii
0000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 10 00 00 00 10 08 06 00 00 00 1f f3 ff .PNG........IHDR................
0020 61 00 00 02 86 49 44 41 54 38 8d 95 93 cb 4b 94 51 18 c6 7f 67 be 99 b1 69 d0 2e e6 58 91 95 89 a....IDAT8....K.Q...g...i...X...
0040 97 ca 4b 4a 50 a1 63 b4 89 68 23 14 6e 5a b4 30 23 ea 4f 88 5a 45 20 46 ab 12 0c 71 e5 22 21 08 ..KJP.c..h#.nZ.0#.O.ZE.F...q."!.
0060 0a c1 34 a9 20 0b 8c 72 63 17 29 95 28 a3 b2 1a 4d c7 f9 2e e7 7c e7 b4 18 ef b9 a8 77 f7 9e f3 ..4....rc.).(...M....|......w...
0080 9e 1f cf f3 70 5e 61 8c e1 5f ab af a7 7b d9 70 64 6d 26 c1 95 43 17 6f 9e 2d 1e 0c 76 ed 88 c5 ....p^a.._...{.pdm&..C.o.-..v...
00a0 62 1b 4f 47 9b 6e 2f bd 2b d9 5b 36 38 fc 66 a8 0a a0 f0 c0 91 07 e3 43 2f 8f fd 05 50 6b 18 ae b.OG.n/.+.[68.f........C/...Pk..
00c0 ac 29 9b 15 21 2f da fb f8 2e cd 8d 6d 4b 15 54 95 c6 8f 11 0e 0a 52 ae 02 20 b0 9a d4 bc fc ad .)..!/......mK.T......R.........
00e0 d1 d0 ba c5 5e 6b 4d 5f 4f 37 5b ca 6b d1 01 81 ad c0 56 69 ef ab 02 72 33 f2 28 0e c6 17 7a cf ....^kM_O7[.k.....Vi...r3.(...z.
0100 73 01 90 3e d8 12 1c 69 70 d2 02 d2 19 34 b4 d6 85 3d e1 44 a6 92 93 6a cf ba 0a 1c 92 38 5a 03 s..>...ip....4...=.D...j.....8Z.
0120 e0 38 2e 49 3b 39 07 d0 38 0a b4 f2 71 95 5e 04 88 10 b9 5b cd f6 4f bb f3 cb 27 77 96 e4 7a 23 .8.I;9..8...q.^....[..O...'w..z#
0140 13 bd e1 44 f4 03 59 75 3b b9 3c 11 47 f4 56 70 34 ef 04 9e d2 04 3c 1f ad 24 b6 34 58 f3 16 da ...D..Yu;.<.G.Vp4.....<..$.4X...
0160 cf dc fb fc d5 1f 3f f8 3b 31 b5 e1 c5 8e 96 70 22 fa 81 91 b1 8f bc 4c 3c 41 f4 56 70 e5 54 4b ......?.;1.....p"......L<A.Vp.TK
0180 5a 81 d2 cc da 1e 9e f4 f9 36 2d 97 87 d8 71 ae 7b e0 93 1c dd ff ba 29 f8 6b 64 ec 23 00 65 4f Z........6-...q.{......).kd.#.eO
01a0 1b 69 6e 68 43 93 36 6c 3b 1e 8e 2b 99 4a 29 12 49 6f d1 c2 7c 75 9e 7f f4 aa af a7 3b fb c6 fd .inhC.6l;..+.J).Io..|u......;...
01c0 4b 00 34 5f 6c c3 18 83 54 69 80 56 0e 29 27 c4 cf a4 c4 95 1a ac 39 c0 ee a2 22 01 08 27 e5 9a K.4_l...Ti.V.)'.......9..."..'..
01e0 b6 f6 56 6e 5d e8 22 3b 33 07 29 25 52 49 8c 31 14 14 14 30 3a fa 96 e1 40 19 30 f7 21 ad 45 0b ..Vn].";3.)%RI.1...0:...@.0.!.E.
0200 16 b0 c9 0a 89 9c e6 6b d7 eb b2 c2 eb 91 ae 87 ed d8 28 a5 b0 2c 0b 2b 98 16 eb b8 12 ed fb e0 .......k..........(..,.+........
0220 ab d0 42 06 ef de bf 57 c0 2c 88 5c 20 26 95 87 af fd 05 6b c6 18 32 32 32 d2 41 7a d2 fc 9c f6 ..B....W.,.\.&.....k..222.Az....
0240 66 df 7c 49 8d ad cc c0 9e eb 37 47 22 11 5c d7 c5 18 83 10 82 81 e7 fd fc 98 f8 7e e7 e1 e0 f8 f.|I......7G".\............~....
0260 b7 57 99 b1 9c 99 99 e9 a1 8e 13 a1 ab d5 f1 1a 21 96 6e 63 49 61 61 20 10 08 94 9e ac af af 3f .W..............!.ncIaa........?
0280 1c af be 34 7f 5e 50 58 1c ca df b5 4b e5 ed 3b 5e 4b e5 e9 43 9d 0d db 9a aa e3 35 02 40 fc cf ...4.^PX....K..;^K..C......5.@..
02a0 3a 3f 7b da 6f 00 e6 1f 03 fc 01 db 74 2e c3 1e ff c1 14 00 00 00 00 49 45 4e 44 ae 42 60 82 :?{.o.......t..........IEND.B`.
'#n163'>163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
/* HexChat
 * Copyright (c) 2010 <ygrek@autistici.org>
 * Copyright (c) 2012 Berke Viktor.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/*
 * SASL authentication plugin for HexChat
 * Extremely primitive: only PLAIN, no error checking
 *
 * http://ygrek.org.ua/p/cap_sasl.html
 *
 * Docs:
 *  http://hg.atheme.org/charybdis/charybdis/file/6144f52a119b/doc/sasl.txt
 *  http://tools.ietf.org/html/rfc4422
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <glib.h>

#include "hexchat-plugin.h"

static hexchat_plugin *ph;   /* plugin handle */
static char name[] = "SASL";
static char desc[] = "SASL authentication plugin for HexChat";
static char version[] = "1.2";
static const char sasl_help[] = "SASL Usage:\n /SASL ADD <login> <password> <network>, enable/update SASL authentication for given network\n /SASL DEL <network>, disable SASL authentication for given network\n /SASL LIST, get the list of SASL-enabled networks\n";

struct sasl_info
{
	char const* login;
	char const* password;
	char const* network;
};

typedef struct sasl_info sasl_info;

static int
add_info (char const* login, char const* password, char const* network)
{
	char buffer[512];

	sprintf (buffer, "%s:%s", login, password);
	return hexchat_pluginpref_set_str (ph, network, buffer);
}

static int
del_info (char const* network)
{
	return hexchat_pluginpref_delete (ph, network);
}

static void
print_info ()
{
	char list[512];
	char* token;

	if (hexchat_pluginpref_list (ph, list))
	{
		hexchat_printf (ph, "%s\tSASL-enabled networks:", name);
		hexchat_printf (ph, "%s\t----------------------", name);
		token = strtok (list, ",");
		while (token != NULL)
		{
			hexchat_printf (ph, "%s\t%s", name, token);
			token = strtok (NULL, ",");
		}
	}
	else
	{
		hexchat_printf (ph, "%s\tThere are no SASL-enabled networks currently", name);
	}
}

static sasl_info*
find_info (char const* network)
{
	char buffer[512];
	char* token;
	sasl_info* cur = (sasl_info*) malloc (sizeof (sasl_info));

	if (hexchat_pluginpref_get_str (ph, network, buffer))
	{
		token = strtok (buffer, ":");
		cur->login = g_strdup (token);
		token = strtok (NULL, ":");
		cur->password = g_strdup (token);
		cur->network = g_strdup (network);

		return cur;
	}

	return NULL;
}

static sasl_info*
get_info (void)
{
	const char* name;
	name = hexchat_get_info (ph, "network");

	if (name)
	{
		return find_info (name);
	}
	else
	{
		return NULL;
	}
}

static int
authend_cb (char *word[], char *word_eol[], void *userdata)
{
	if (get_info ())
	{
		/* omit cryptic server message parts */
		hexchat_printf (ph, "%s\t%s\n", name, ++word_eol[4]);
		hexchat_commandf (ph, "QUOTE CAP END");
	}

	return HEXCHAT_EAT_ALL;
}

/*
static int
disconnect_cb (char *word[], void *userdata)
{
	hexchat_printf (ph, "disconnected\n");
	return HEXCHAT_EAT_NONE;
}
*/

static int
server_cb (char *word[], char *word_eol[], void *userdata)
{
	size_t len;
	char* buf;
	char* enc;
	sasl_info* p;

	if (strcmp ("AUTHENTICATE", word[1]) == 0 && strcmp ("+", word[2]) == 0)
	{
		p = get_info ();

		if (!p)
		{
			return HEXCHAT_EAT_NONE;
		}

		hexchat_printf (ph, "%s\tAuthenticating as %s\n", name, p->login);

		len = strlen (p->login) * 2 + 2 + strlen (p->password);
		buf = (char*) malloc (len + 1);
		strcpy (buf, p->login);
		strcpy (buf + strlen (p->login) + 1, p->login);
		strcpy (buf + strlen (p->login) * 2 + 2, p->password);
		enc = g_base64_encode ((unsigned char*) buf, len);

		/* hexchat_printf (ph, "AUTHENTICATE %s\}", enc); */
		hexchat_commandf (ph, "QUOTE AUTHENTICATE %s", enc);

		free (enc);
		free (buf);

		return HEXCHAT_EAT_ALL;
	}

	return HEXCHAT_EAT_NONE;
}

static int
cap_cb (char *word[], char *word_eol[], void *userdata)
{
	if (get_info ())
	{
		/* FIXME test sasl cap */
		/* this is visible in the rawlog in case someone needs it, otherwise it's just noise */
		/* hexchat_printf (ph, "%s\t%s\n", name, word_eol[1]); */
		hexchat_commandf (ph, "QUOTE AUTHENTICATE PLAIN");
	}

	return HEXCHAT_EAT_ALL;
}

static int
sasl_cmd_cb (char *word[], char *word_eol[], void *userdata)
{
	const char* login;
	const char* password;
	const char* network;
	const char* mode = word[2];

	if (!g_ascii_strcasecmp ("ADD", mode))
	{
		login = word[3];
		password = word[4];
		network = word_eol[5];

		if (!network || !*network)	/* only check for the last word, if it's there, the previous ones will be there, too */
		{
			hexchat_printf (ph, "%s", sasl_help);
			return HEXCHAT_EAT_ALL;
		}

		if (add_info (login, password, network))
		{
			hexchat_printf (ph, "%s\tEnabled SASL authentication for the \"%s\" network\n", name, network);
		}
		else
		{
			hexchat_printf (ph, "%s\tFailed to enable SASL authentication for the \"%s\" network\n", name, network);
		}

		return HEXCHAT_EAT_ALL;
	}
	else if (!g_ascii_strcasecmp ("DEL", mode))
	{
		network = word_eol[3];

		if (!network || !*network)
		{
			hexchat_printf (ph, "%s", sasl_help);
			return HEXCHAT_EAT_ALL;
		}

		if (del_info (network))
		{
			hexchat_printf (ph, "%s\tDisabled SASL authentication for the \"%s\" network\n", name, network);
		}
		else
		{
			hexchat_printf (ph, "%s\tFailed to disable SASL authentication for the \"%s\" network\n", name, network);
		}

		return HEXCHAT_EAT_ALL;
	}
	else if (!g_ascii_strcasecmp ("LIST", mode))
	{
		print_info ();
		return HEXCHAT_EAT_ALL;
	}
	else
	{
		hexchat_printf (ph, "%s", sasl_help);
		return HEXCHAT_EAT_ALL;
	}
}

static int
connect_cb (char *word[], void *userdata)
{
	if (get_info ())
	{
		hexchat_printf (ph, "%s\tSASL enabled\n", name);
		hexchat_commandf (ph, "QUOTE CAP REQ :sasl");
	}

	return HEXCHAT_EAT_NONE;
}

int
hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg)
{
	/* we need to save this for use with any hexchat_* functions */
	ph = plugin_handle;

	/* tell HexChat our info */
	*plugin_name = name;
	*plugin_desc = desc;
	*plugin_version = version;

	hexchat_hook_command (ph, "SASL", HEXCHAT_PRI_NORM, sasl_cmd_cb, sasl_help, 0);
	hexchat_hook_print (ph, "Connected", HEXCHAT_PRI_NORM, connect_cb, NULL);
	/* hexchat_hook_print (ph, "Disconnected", HEXCHAT_PRI_NORM, disconnect_cb, NULL); */
	hexchat_hook_server (ph, "CAP", HEXCHAT_PRI_NORM, cap_cb, NULL);
	hexchat_hook_server (ph, "RAW LINE", HEXCHAT_PRI_NORM, server_cb, NULL);
	hexchat_hook_server (ph, "903", HEXCHAT_PRI_NORM, authend_cb, NULL);
	hexchat_hook_server (ph, "904", HEXCHAT_PRI_NORM, authend_cb, NULL);
	hexchat_hook_server (ph, "905", HEXCHAT_PRI_NORM, authend_cb, NULL);
	hexchat_hook_server (ph, "906", HEXCHAT_PRI_NORM, authend_cb, NULL);
	hexchat_hook_server (ph, "907", HEXCHAT_PRI_NORM, authend_cb, NULL);

	hexchat_printf (ph, "%s plugin loaded\n", name);

	return 1;
}

int
hexchat_plugin_deinit (void)
{
	hexchat_printf (ph, "%s plugin unloaded\n", name);
	return 1;
}