summary refs log tree commit diff stats
AgeCommit message (Expand)Author
2014-06-02fishlim: Fix filename in error messagesTingPing
2014-06-02Handle a special character before "+OK", e.g. identify-msg + or -Samuel Lidén Borell
2014-06-02Use path to HexChat instead of XChat in the test programSamuel Lidén Borell
2014-06-02Add missing include in the test programSamuel Lidén Borell
2014-06-02Fix memory leak in the test programSamuel Lidén Borell
2014-06-02Fix undefined behaviour in left shiftSamuel Lidén Borell
2014-06-02Update translationstomek
2014-06-02Always use GModule for plugin supportTingPing
2014-06-01Add missing files to POTFILES.inTingPing
2014-06-01Bump version to 2.10.0TingPing
2014-06-01Remove dead networkTingPing
2014-06-01Remove some hardcoded version numbersTingPing
2014-05-31Sensitize open dialog button in friends list when selectedTingPing
2014-05-31Add SeionIRC to serverlistLee Watson
2014-05-31Add StormBit to network listYoeri Beumer
2014-05-31Cosmeticsbviktor
2014-05-31osx: Fix loading system's openssl configTingPing
2014-05-31osx: More theme tweaksTingPing
2014-05-31Rework gtk_xtext_selection_draw(), simplify calls to _selection_render()RichardHitt
2014-05-30osx: Use key theme shipped with gtkTingPing
2014-05-30win32: Fix exiting fullscreen to a maximized windowTingPing
2014-05-29Make lawyers happyBerke Viktor
2014-05-29Replace Inno Perl with MSI PerlBerke Viktor
2014-05-28... and update perl description in installerTingPing
2014-05-28win32: Update perl urls in installerTingPing
2014-05-28perl: Update Perl to 5.20tomek
2014-05-28Update translationsTingPing
2014-05-28Use newer format for default keybindingsTingPing
2014-05-27osx: Use applespell enchant backendTingPing
2014-05-27osx: makebundle.sh improvementsTingPing
2014-05-27osx: Properly handle quittingTingPing
2014-05-27osx: Properly use app menuTingPing
2014-05-26osx: Use osx friendly bindings for GtkEntryTingPing
2014-05-26Fix crash with invalid dnd to userlistTingPing
2014-05-26osx: Improve gtk themeTingPing
2014-05-23Update default settingsTingPing
2014-05-23Enable drag and drop on WindowsTingPing
2014-05-22Fixes #959. In xtext.c:find_x() return offset to hidden text if appropriate.RichardHitt
2014-05-21Fix drag and dropTingPing
2014-05-20Show notifications for private actionsTingPing
2014-05-12Default completion to last spokeTingPing
2014-05-12Add global option to suppress nick change eventsBerke Viktor
2014-05-12Properly support notices to prefix'd users on a channelDerp Derpingston
2014-05-12Fixed truncation of the reason when receiving a KILL message.Derp Derpingston
2014-05-12Add missing NULL check in cmd_lastlogcortexcorepl
2014-05-12Default Techman's World IRC to SASLTheTechman
2014-05-11Fix spell check on OSXTingPing
2014-05-11Fix sorting problem when using tabsRiamse
2014-05-11Fix logging incorrect timestamp with server-timeRiamse
2014-05-11Add option to bounce dock icon on OSXTingPing
b4199fd05ece3891bb'>66d8b0ad ^
306b2a87 ^






















2456d0d3 ^

66d8b0ad ^
2456d0d3 ^



44e40483 ^
2456d0d3 ^










66d8b0ad ^

2456d0d3 ^

66d8b0ad ^
2456d0d3 ^










66d8b0ad ^

2456d0d3 ^

66d8b0ad ^
2456d0d3 ^

c979a8a8 ^

2456d0d3 ^



66d8b0ad ^


2456d0d3 ^

66d8b0ad ^
2456d0d3 ^

66d8b0ad ^


2456d0d3 ^

66d8b0ad ^
2456d0d3 ^



66d8b0ad ^
2456d0d3 ^


66d8b0ad ^
2456d0d3 ^




9eae6db3 ^
2456d0d3 ^

















66d8b0ad ^

2456d0d3 ^

66d8b0ad ^
2456d0d3 ^


c979a8a8 ^

2456d0d3 ^



66d8b0ad ^

2456d0d3 ^

66d8b0ad ^
e421c116 ^



66d8b0ad ^
e421c116 ^
2456d0d3 ^
e421c116 ^


















2456d0d3 ^

e421c116 ^


66d8b0ad ^
e421c116 ^




66d8b0ad ^
e421c116 ^










306b2a87 ^




e421c116 ^




2456d0d3 ^
66d8b0ad ^
2456d0d3 ^




9eae6db3 ^
2456d0d3 ^

66d8b0ad ^
2456d0d3 ^

66d8b0ad ^
2456d0d3 ^










e421c116 ^
2456d0d3 ^










66d8b0ad ^
2456d0d3 ^
66d8b0ad ^

2456d0d3 ^

66d8b0ad ^
2456d0d3 ^
66d8b0ad ^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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






















                                                                                



                                                     






                                                                           






                         
                                              
                                    
                                                                  
                                    
                                                                                                                                                                                                                                                                             


                


                             



                                   
          
                                                                       
 
                         
 
                                                   
                                                              




                              
                                                     

 






















                                                                                            

                               
 



                                                                  
                                                           










                                                  

 

                 
 










                                              

 

                                                           
 

                        

                                                                   



                                                     


  

                                            
 

                                            


  

                                                          
 



                     
 


                                                                                
 




                                              
                                                                                

















                                                                       

 

                                                       
 


                                         

                                                                                                       



                                                                

 

                                                            
 



                                   
 
                                   
         


















                                                                                                                                       

                                     


                                        
 




                                                            
 










                                                                                                                               




                                         




                                                    
 
 




                                         
                                                              

                                                           
 

                              
 










                                                                                                                         
                                                                                     










                                                                                         
 
                 

 

                          
 
                                                        

                 
/* XChat-WDK
 * 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 XChat
 * 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 <string.h>
#include <stdlib.h>
#include <assert.h>
#include <glib/gbase64.h>

#include "xchat-plugin.h"

static xchat_plugin *ph;   /* plugin handle */
static const char name[] = "X-SASL";
static const char desc[] = "SASL authentication plugin for XChat";
static const char version[] = "1.1";
static const char xsasl_help[] = "X-SASL Usage:\n /XSASL ADD <login> <password> <network>, enable/update SASL authentication for given network\n /XSASL DEL <network>, disable SASL authentication for given network\n /XSASL 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 xchat_pluginpref_set_str (ph, network, buffer);
}

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

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

	if (xchat_pluginpref_list (ph, list))
	{
		xchat_printf (ph, "%s\tSASL-enabled networks:", name);
		xchat_printf (ph, "%s\t----------------------", name);
		token = strtok (list, ",");
		while (token != NULL)
		{
			xchat_printf (ph, "%s\t%s", name, token);
			token = strtok (NULL, ",");
		}
	}
	else
	{
		xchat_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 (xchat_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 = xchat_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 */
		xchat_printf (ph, "%s\t%s\n", name, ++word_eol[4]);
		xchat_commandf (ph, "QUOTE CAP END");
	}

	return XCHAT_EAT_ALL;
}

/*
static int
disconnect_cb (char *word[], void *userdata)
{
	xchat_printf (ph, "disconnected\n");
	return XCHAT_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 XCHAT_EAT_NONE;
		}

		xchat_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);

		/* xchat_printf (ph, "AUTHENTICATE %s\}", enc); */
		xchat_commandf (ph, "QUOTE AUTHENTICATE %s", enc);

		free (enc);
		free (buf);

		return XCHAT_EAT_ALL;
	}

	return XCHAT_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 */
		/* xchat_printf (ph, "%s\t%s\n", name, word_eol[1]); */
		xchat_commandf (ph, "QUOTE AUTHENTICATE PLAIN");
	}

	return XCHAT_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 (!stricmp ("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 */
		{
			xchat_printf (ph, "%s", xsasl_help);
			return XCHAT_EAT_ALL;
		}

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

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

		if (!network || !*network)
		{
			xchat_printf (ph, "%s", xsasl_help);
			return XCHAT_EAT_ALL;
		}

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

		return XCHAT_EAT_ALL;
	}
	else if (!stricmp ("LIST", mode))
	{
		print_info ();
		return XCHAT_EAT_ALL;
	}
	else
	{
		xchat_printf (ph, "%s", xsasl_help);
		return XCHAT_EAT_ALL;
	}
}

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

	return XCHAT_EAT_NONE;
}

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

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

	xchat_hook_command (ph, "XSASL", XCHAT_PRI_NORM, sasl_cmd_cb, xsasl_help, 0);
	xchat_hook_print (ph, "Connected", XCHAT_PRI_NORM, connect_cb, NULL);
	/* xchat_hook_print (ph, "Disconnected", XCHAT_PRI_NORM, disconnect_cb, NULL); */
	xchat_hook_server (ph, "CAP", XCHAT_PRI_NORM, cap_cb, NULL);
	xchat_hook_server (ph, "RAW LINE", XCHAT_PRI_NORM, server_cb, NULL);
	xchat_hook_server (ph, "903", XCHAT_PRI_NORM, authend_cb, NULL);
	xchat_hook_server (ph, "904", XCHAT_PRI_NORM, authend_cb, NULL);
	xchat_hook_server (ph, "905", XCHAT_PRI_NORM, authend_cb, NULL);
	xchat_hook_server (ph, "906", XCHAT_PRI_NORM, authend_cb, NULL);
	xchat_hook_server (ph, "907", XCHAT_PRI_NORM, authend_cb, NULL);

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

	return 1;
}

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