Changes in / [0db75ad:dd34575]
- Files:
-
- 3 added
- 2 deleted
- 54 edited
Legend:
- Unmodified
- Added
- Removed
-
account.c
r0db75ad rdd34575 182 182 account_t *a, *l = NULL; 183 183 184 if( acc->ic ) 185 /* Caller should have checked, accounts still in use can't be deleted. */ 186 return; 187 184 188 for( a = irc->accounts; a; a = (l=a)->next ) 185 189 if( a == acc ) 186 190 { 187 if( a->ic ) return; /* Caller should have checked, accounts still in use can't be deleted. */188 189 191 if( l ) 190 {191 192 l->next = a->next; 192 }193 193 else 194 {195 194 irc->accounts = a->next; 196 }197 195 198 196 while( a->set ) … … 203 201 g_free( a->user ); 204 202 g_free( a->pass ); 205 if( a->server )g_free( a->server );203 g_free( a->server ); 206 204 if( a->reconnect ) /* This prevents any reconnect still queued to happen */ 207 205 cancel_auto_reconnect( a ); -
bitlbee.conf
r0db75ad rdd34575 49 49 ## 50 50 ## Password the user should enter when logging into a closed BitlBee server. 51 ## You can also have an MD5-encrypted password here. Format: "md5:", followed 52 ## by a hash as generated for the <user password=""> attribute in a BitlBee 53 ## XML file (for now there's no easier way to generate the hash). 51 54 ## 52 55 # AuthPassword = ItllBeBitlBee ## Heh.. Our slogan. ;-) 56 ## or 57 # AuthPassword = md5:gzkK0Ox/1xh+1XTsQjXxBJ571Vgl 53 58 54 59 ## OperPassword … … 57 62 ## 58 63 # OperPassword = ChangeMe! 64 ## or 65 # OperPassword = md5:I0mnZbn1t4R731zzRdDN2/pK7lRX 59 66 60 67 ## HostName -
bitlbee.h
r0db75ad rdd34575 30 30 31 31 #define PACKAGE "BitlBee" 32 #define BITLBEE_VERSION "1. 1.1dev"32 #define BITLBEE_VERSION "1.2" 33 33 #define VERSION BITLBEE_VERSION 34 34 35 #define MAX_STRING 12835 #define MAX_STRING 511 36 36 37 37 #if HAVE_CONFIG_H -
conf.c
r0db75ad rdd34575 252 252 { 253 253 g_strfreev( conf->migrate_storage ); 254 conf->migrate_storage = g_strsplit ( ini->value, " \t,;", -1 );254 conf->migrate_storage = g_strsplit_set( ini->value, " \t,;", -1 ); 255 255 } 256 256 else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 ) -
debian/README.Debian
r0db75ad rdd34575 1 *** NEWS (Version 1. 1and later) ***1 *** NEWS (Version 1.2 and later) *** 2 2 3 Starting from version 1. 1, BitlBee has a forking daemon mode. The Debian3 Starting from version 1.2, BitlBee has a forking daemon mode. The Debian 4 4 package now uses this mode by default, instead of inetd mode. If you don't 5 5 want to use this, you can disable the init scripts (best way to do this is … … 7 7 should be necessary only once, it won't be touched during upgrades. 8 8 9 -------------------------------------------------------------------------- 9 Another important change in BitlBee 1.2 is the file format used for your 10 personal settings. Everything's now saved in a single .xml (per account, 11 of course) file instead of $nick.accounts and $nick.nicks. One advantage 12 of this new format is that the passwords are actually encrypted instead of 13 just vaguely obfuscated. BitlBee can still read the old files, and will 14 save things in the new format when you save/disconnect. After that, you 15 can safely remove the old-style files (this is recommended). 16 17 I tried making this transition (the new file format but especially, in this 18 case, the inetd->forkdaemon mode change) as smooth as possible, but I'm 19 aware that many BitlBee users will have their own hacks already to run the 20 program. I hope the package won't break any of this for anyone. 1.2-2 21 should fix at least some of the issues. 22 23 --------------------------------------------------------------------------- 10 24 11 25 Debconf should have asked you on what port you want BitlBee to run. If it -
debian/bitlbee.init
r0db75ad rdd34575 1 1 #! /bin/sh 2 ### BEGIN INIT INFO 3 # Provides: bitlbee 4 # Required-Start: $remote_fs $syslog 5 # Required-Stop: $remote_fs $syslog 6 # Default-Start: 2 3 4 5 7 # Default-Stop: 1 8 ### END INIT INFO 2 9 # 3 10 # Init script for BitlBee Debian package. Based on skeleton init script: … … 18 25 # Default value 19 26 BITLBEE_PORT=6667 20 DAEMON_OPT=-F27 BITLBEE_OPTS=-F 21 28 22 29 # Read config file if it is present. … … 37 44 38 45 start-stop-daemon --start --quiet --pidfile $PIDFILE \ 39 -c bitlbee -g nogroup\40 --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $ DAEMON_OPT46 -c bitlbee: \ 47 --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $BITLBEE_OPTS 41 48 } 42 49 -
debian/changelog
r0db75ad rdd34575 1 bitlbee (1.1.1dev-0pre) unstable; urgency=low 2 1 bitlbee (1.2-4) unstable; urgency=low 2 3 * Not a real release, just a placeholder for the changelog. 4 * Fixed init script to use the BITLBEE_OPTS variable, not an undefined 5 DAEMON_OPT. 6 * Added dependency information to the init script. (Closes: #472567) 7 8 -- Wilmer van der Gaast <wilmer@gaast.net> Sat, 29 Mar 2008 21:10:33 +0000 9 10 bitlbee (1.2-3) unstable; urgency=low 11 12 * Removed DEB_BUILD_OPTIONS again (forgot to apply that change to the 1.2 13 branch when I finished 1.0.4-2, things diverged too much anyway.) 14 Closes: #472540. 15 16 -- Wilmer van der Gaast <wilmer@gaast.net> Mon, 24 Mar 2008 21:10:14 +0000 17 18 bitlbee (1.2-2) unstable; urgency=low 19 20 * Fixed some packaging issues reported by IRC and e-mail. (Closes: #472373) 21 * Fixed proxy support. (Closes: #472395) 22 * Added a BitlBee group so only root can edit the configs and BitlBee can 23 just *read* it. 24 * Manually deleting /var/lib/bitlbee/ when purging, deluser doesn't want to 25 do it. 26 27 -- Wilmer van der Gaast <wilmer@gaast.net> Mon, 24 Mar 2008 19:48:24 +0000 28 29 bitlbee (1.2-1) unstable; urgency=low 30 31 * New upstream release. (Closes: #325017, #386914, #437515) 32 * With hopefully completely sane charset handling (Closes: #296145) 3 33 * Switched to the new forking daemon mode. Added /etc/default/bitlbee 4 34 file, an init script. People who want to stick with inetd can do so, see 5 35 the defaults file. 36 (Closes: #460741, #466171, #294585, #345038, #306452, #392682) 6 37 * Got rid of debconf Woody compatibility stuff. 7 38 * No more MPL code in BitlBee, thanks to the Jabber module rewrite! 8 9 -- Wilmer van der Gaast <wilmer@gaast.net> Fri, 06 Jul 2007 09:09:36 +0100 39 * Added Italian translation, sorry for taking so long! (Closes: #448238) 40 * Added libevent dependency (more reliable event handling). 41 * Removed GLib 1.x dependency because BitlBee really requires GLib >=2.4. 42 43 -- Wilmer van der Gaast <wilmer@gaast.net> Tue, 18 Mar 2008 23:44:19 +0000 44 45 bitlbee (1.0.4-2) unstable; urgency=low 46 47 * Removed $DEB_BUILD_OPTIONS because apparently buildds fill it with crap. 48 (Closes: #458717) 49 50 -- Wilmer van der Gaast <wilmer@gaast.net> Mon, 11 Feb 2008 19:15:33 +0000 51 52 bitlbee (1.0.4-1) unstable; urgency=low 53 54 * New upstream release. 55 * Changed libnss-dev dependency. (Closes: #370442) 56 * Added build-indep rule to debian/rules. (Closes: #395673) 57 58 -- Wilmer van der Gaast <wilmer@gaast.net> Wed, 29 Aug 2007 20:24:28 +0100 10 59 11 60 bitlbee (1.0.3-1.3) unstable; urgency=low -
debian/conffiles
r0db75ad rdd34575 1 1 /etc/bitlbee/motd.txt 2 2 /etc/bitlbee/bitlbee.conf 3 /etc/init.d/bitlbee -
debian/control
r0db75ad rdd34575 4 4 Maintainer: Wilmer van der Gaast <wilmer@gaast.net> 5 5 Standards-Version: 3.5.9 6 Build-Depends: libglib2.0-dev | libglib-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf6 Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf 7 7 8 8 Package: bitlbee -
debian/postinst
r0db75ad rdd34575 14 14 BITLBEE_DISABLED=0 15 15 BITLBEE_UPGRADE_DONT_RESTART=0 16 [ -r /etc/default/bitlbee ] && source/etc/default/bitlbee16 [ -r /etc/default/bitlbee ] && . /etc/default/bitlbee 17 17 18 if [ "$BITLBEE_DISABLED" = "0" ]; then 19 ## In case it's still there (if we're upgrading right now) 18 if [ "$BITLBEE_DISABLED" = "0" ] && type update-inetd > /dev/null 2> /dev/null && 19 ( expr "$2" : '0\..*' > /dev/null || expr "$2" : '1\.0\..*' > /dev/null ); then 20 ## Make sure the inetd entry is gone (can still be there from a 21 ## previous version. 20 22 update-inetd --remove '.*/usr/sbin/bitlbee' 23 if grep -q /usr/sbin/bitlbee /etc/inetd.conf 2> /dev/null; then 24 # Thanks for breaking update-inetd! (bugs.debian.org/311111) 25 # I hope that it works at least with xinetd, because this 26 # emergency hack doesn't: 27 perl -pi -e 's:^[^#].*/usr/sbin/bitlbee$:## Now using daemon mode\: # $&:' /etc/inetd.conf 28 killall -HUP inetd || true 29 fi 21 30 fi 22 31 … … 65 74 fi 66 75 67 adduser --system -- home /var/lib/bitlbee/ --disabled-login --disabled-passwordbitlbee76 adduser --system --group --disabled-login --disabled-password --home /var/lib/bitlbee/ bitlbee 68 77 chmod 700 /var/lib/bitlbee/ 69 78 70 79 ## Can't do this in packaging phase: Don't know the UID yet. Access to 71 ## the file should be limited, now that it stores passwords. 72 chmod 600 /etc/bitlbee/bitlbee.conf 73 chown bitlbee /etc/bitlbee/bitlbee.conf 80 ## the file should be limited, now that it stores passwords. Added 81 ## --group later for a little more security, but have to see if I can 82 ## apply this change to existing installations on upgrades. Will think 83 ## about that later. 84 if getent group bitlbee > /dev/null; then 85 chmod 640 /etc/bitlbee/bitlbee.conf 86 chown root:bitlbee /etc/bitlbee/bitlbee.conf 87 else 88 chmod 600 /etc/bitlbee/bitlbee.conf 89 chown bitlbee /etc/bitlbee/bitlbee.conf 90 fi 74 91 75 92 if [ -z "$2" ]; then -
debian/postrm
r0db75ad rdd34575 9 9 10 10 update-rc.d bitlbee remove > /dev/null 2>&1 || true 11 deluser --remove-home bitlbee || true 11 rm -f /etc/default/bitlbee 12 13 deluser --system --remove-home bitlbee || true 14 rm -rf /var/lib/bitlbee ## deluser doesn't seem to do this for homedirs in /var -
debian/rules
r0db75ad rdd34575 3 3 DEBUG ?= 0 4 4 5 ifdef BITLBEE_VERSION 6 BITLBEE_FORCE_VERSION=1 7 else 5 8 # Want to use the full package version number instead of just the release. 6 9 BITLBEE_VERSION ?= "$(shell dpkg-parsechangelog | grep ^Version: | awk '{print $$2}')" 7 10 export BITLBEE_VERSION 8 11 endif 9 12 10 13 build-arch: build-arch-stamp 11 14 build-arch-stamp: 12 15 if [ ! -d debian ]; then exit 1; fi 13 ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee $(DEB_BUILD_OPTIONS)16 ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent 14 17 $(MAKE) 15 18 # $(MAKE) -C doc/ all … … 66 69 find usr -type f -exec md5sum {} \; > DEBIAN/md5sums 67 70 dpkg-shlibdeps -Tdebian/bitlbee.substvars -dDepends debian/bitlbee/usr/sbin/bitlbee 68 ifdef BITLBEE_ VERSION71 ifdef BITLBEE_FORCE_VERSION 69 72 dpkg-gencontrol -ldebian/changelog -isp -pbitlbee -Tdebian/bitlbee.substvars -Pdebian/bitlbee -v1:$(BITLBEE_VERSION)-0 -V'debconf-depends=debconf (>= 1.2.0) | debconf-2.0' 70 73 else -
doc/CHANGES
r0db75ad rdd34575 1 Version 1.2.1: 2 - Fixed proxy support. 3 - Fixed stalling issues while connecting to Jabber when using the OpenSSL 4 module. 5 - Fixed problem with GLib and ForkDaemon where processes didn't die when 6 the client disconnects. 7 - Fixed handling of "set charset none". (Which pretty much breaks the account 8 completely in 1.2.) 9 - You can now automatically identify yourself to BitlBee by setting a server 10 password in your IRC client. 11 - Compatible with all crazy kinds of line endings that clients can send. 12 13 Finished ... 14 1 15 Version 1.2: 2 - First BitlBee development/testing RELEASE. This should be quite stable3 though (and for most people more stable than 1.0.x). It just has a couple4 of rough edges and needs a bit more testing.5 16 - Added ForkDaemon mode next to the existing Daemon- and inetd modes. With 6 17 ForkDaemon you can run BitlBee as a stand-alone daemon and every connection … … 21 32 1.x is so old that supporting it really isn't necessary anymore. 22 33 - Many, many, MANY little changes, improvements, fixes. Using non-blocking 23 I/O as much as possible, fixed lots of little bugs (including bugs that 24 affected daemon mode stability). See the bzr logs for more information. 25 - Added units tests, will have to add some more before the real release. 34 I/O as much as possible, replaced the Gaim (0.59, IOW heavily outdated) 35 API, fixed lots of little bugs (including bugs that affected daemon mode 36 stability). See the bzr logs for more information. 37 - One of the user-visible changes from the API change: You can finally see 38 all away states/messages properly. 39 - Added units tests. Test coverage is very minimal for now. 40 - Better charset handling: Everything is just converted from/to UTF-8 right 41 in the IRC core, and charset mismatches are detected (if possible) and the 42 user is asked to resolve this before continuing. Also, UTF-8 is the default 43 setting now, since that's how the world seems to work these days. 44 - One can now keep hashed passwords in bitlbee.conf instead of the cleartext 45 version. 26 46 - Most important change: New file format for user data (accounts, nicks and 27 47 settings). Migration to the new format should happen transparently, … … 69 89 * An XML console (add xmlconsole to your contact list or see "help set 70 90 xmlconsole" if you want it permanently). 71 72 Finished ??? 91 - The Yahoo! module now says it supports YMSG protocol version 12, which will 92 hopefully keep the Yahoo module working after 2008-04-02 (when Yahoo! is 93 dropping support for version 6.x of their client). 94 - MSN switchboard handling changes. Hopefully less messages will get lost now, 95 although things are still not perfect. 96 97 Finished 17 Mar 2008 73 98 74 99 Version 1.0.4: -
doc/README
r0db75ad rdd34575 41 41 by default) and chown it to the UID BitlBee is running as. Make sure this 42 42 directory is read-/writable by this user only. 43 44 --- (Fork)Daemon mode 45 46 If you don't want to run any inetd daemon, you can run BitlBee in Daemon 47 mode. Right now, daemon mode may be a bad idea on servers with multiple 48 users, since possible fatal BitlBee bugs will crash the BitlBee process and 49 disconnect all connected users at once. Instead, you can use ForkDaemon 50 mode, which serves every user from a separate process, without depending on 51 an inetd daemon. 52 53 To use BitlBee in daemon mode, just start it with the right flags or enable 54 it in bitlbee.conf. You probably want to write an init script to start 55 BitlBee automatically after a reboot. (This is where you realise using 56 a package from your distro would've been a better idea. :-P) 43 57 44 58 -
doc/user-guide/Support.xml
r0db75ad rdd34575 4 4 5 5 <sect1> 6 <title> BitlBee is beta software</title>6 <title>Disclaimer</title> 7 7 8 8 <para> 9 Although BitlBee has quite some functionality it is still beta. That means it 10 can crash at any time, corrupt your data or whatever. Don't use it in 11 any production environment and don't rely on it. 9 BitlBee doesn't come with a warranty and is still (and will probably always 10 be) under development. That means it can crash at any time, corrupt your 11 data or whatever. Don't use it in any production environment and don't rely 12 on it, or at least don't blame us if things blow up. :-) 12 13 </para> 13 14 -
doc/user-guide/commands.xml
r0db75ad rdd34575 163 163 164 164 <para> 165 If you want, you can also tell BitlBee what nick to give the new contact. Of course you can also use the <emphasis>rename</emphasis> command for that, but sometimes this might be more convenient. 166 </para> 167 168 <para> 169 Adding -tmp adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list. 165 If you want, you can also tell BitlBee what nick to give the new contact. The -tmp option adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list. This normally won't show you any presence notifications. 170 166 </para> 171 167 </description> … … 383 379 384 380 <bitlbee-setting name="charset" type="string" scope="global"> 385 <default> iso8859-1</default>381 <default>utf-8</default> 386 382 <possible-values>you can get a list of all possible values by doing 'iconv -l' in a shell</possible-values> 387 383 388 384 <description> 389 385 <para> 390 Th e charset setting enables you to use different character sets in BitlBee. These get converted to UTF-8 before sending and from UTF-8 when receiving.391 </para> 392 393 <para> 394 If you don't know what's the best value for this, at least iso8859-1 is the best choice for most Western countries. You can try to find what works best for you on http://czyborra.com/charsets/iso8859.html386 This setting tells BitlBee what your IRC client sends and expects. It should be equal to the charset setting of your IRC client if you want to be able to send and receive non-ASCII text properly. 387 </para> 388 389 <para> 390 Most systems use UTF-8 these days. On older systems, an iso8859 charset may work better. For example, iso8859-1 is the best choice for most Western countries. You can try to find what works best for you on http://www.unicodecharacter.com/charsets/iso8859.html 395 391 </para> 396 392 </description> … … 677 673 <description> 678 674 <para> 679 Sends you a /notice when a user starts typing a message (if the protocol supports it, MSN for example). This is a bug, not a feature. (But please don't report it.. ;-) You don't want to use it. Really. In fact the typing-notification is just one of the least useful 'innovations' ever. It's just there because some guy will probably ask me about it anyway. ;-)675 Sends you a /notice when a user starts typing a message (if supported by the IM protocol and the user's client). To use this, you most likely want to use a script in your IRC client to show this information in a more sensible way. 680 676 </para> 681 677 </description> … … 830 826 <short-description>Change friendly name, nick</short-description> 831 827 <syntax>nick <connection> [<new nick>]</syntax> 832 <syntax>nick</syntax> 833 834 <description> 835 <para> 836 This command allows to set the friendly name of an im account. If no new name is specified the command will report the current name. When the name contains spaces, don't forget to quote the whole nick in double quotes. Currently this command is only supported by the MSN protocol. 837 </para> 838 839 <para> 840 It is recommended to use the per-account <emphasis>display_name</emphasis> setting to read and change this information. The <emphasis>nick</emphasis> command is deprecated. 828 <syntax>nick <connection></syntax> 829 830 <description> 831 <para> 832 Deprecated: Use the per-account <emphasis>display_name</emphasis> setting to read and change this information. 841 833 </para> 842 834 </description> 843 835 844 836 <ircexample> 845 <ircline nick="wouter"> nick 1 "Wouter Paesen"</ircline>846 <ircline nick="root"> Setting your name on connection 1 to `Wouter Paesen'</ircline>837 <ircline nick="wouter">account set 1/display_name "The majestik møøse"</ircline> 838 <ircline nick="root">display_name = `The majestik møøse'</ircline> 847 839 </ircexample> 848 840 -
doc/user-guide/misc.xml
r0db75ad rdd34575 47 47 </variablelist> 48 48 49 <para>50 This list was extracted from <ulink url="http://help.msn.com/!data/en_us/data/messengerv50.its51/$content$/EMOTICONS.HTM?H_APP=">http://help.msn.com/!data/en_us/data/messengerv50.its51/$content$/EMOTICONS.HTM?H_APP=</ulink>.51 </para>52 53 49 </sect1> 54 50 … … 56 52 <title>Groupchats</title> 57 53 <para> 58 Since version 0.8x, BitlBee supports groupchats on the MSN and Yahoo!networks. This text will try to explain you how they work.54 BitlBee now supports groupchats on all IM networks. This text will try to explain you how they work. 59 55 </para> 60 56 … … 73 69 74 70 <para> 75 If you want to start a groupchat with the person <emphasis> jim_msn</emphasis> in it, just join the channel <emphasis>#jim_msn</emphasis>. BitlBee will refuse to join you to the channel with that name, but it will create a new virtual channel with root, you and jim_msn in it.71 If you want to start a groupchat with the person <emphasis>lisa_msn</emphasis> in it, just join the channel <emphasis>#lisa_msn</emphasis>. BitlBee will refuse to join you to the channel with that name, but it will create a new virtual channel with root, you and lisa_msn in it. 76 72 </para> 77 73 … … 82 78 <para> 83 79 Some protocols (like Jabber) also support named groupchats. BitlBee now supports these too. You can use the <emphasis>join_chat</emphasis> command to join them. See <emphasis>help join_chat</emphasis> for more information. 84 </para>85 86 <para>87 This is all you'll probably need to know. If you have any problems, please read <emphasis>help groupchats3</emphasis>.88 </para>89 90 </sect1>91 92 <sect1 id="groupchats3">93 <title>Groupchat channel names</title>94 95 <para>96 Obviously the (numbered) channel names don't make a lot of sense. Problem is that groupchats usually don't have names at all in the IM-world, while IRC insists on a name. So BitlBee just generates something random, just don't pay attention to it. :-)97 </para>98 99 <para>100 Please also note that BitlBee doesn't support groupchats for all protocols yet. BitlBee will tell you so. Support for other protocols will hopefully come later.101 80 </para> 102 81 … … 121 100 <member>On the phone, Phone, On phone</member> 122 101 <member>Out to lunch, Lunch, Food</member> 102 <member>Invisible, Hidden</member> 123 103 </simplelist> 124 104 … … 128 108 129 109 <para> 130 You can also add more information to your away message. Setting it to "Busy - Fixing BitlBee bugs" will set your IM-away-states to Busy, but your away message will be more descriptive for people on IRC. Protocols like Yahoo! and Jabber will also show this complete away messageto your buddies.110 You can also add more information to your away message. Setting it to "Busy - Fixing BitlBee bugs" will set your IM-away-states to Busy, but your away message will be more descriptive for people on IRC. Most IM-protocols can also show this additional information to your buddies. 131 111 </para> 132 112 -
doc/user-guide/quickstart.xml
r0db75ad rdd34575 61 61 62 62 <para> 63 For most protocols (currently MSN, Jabber, Yahoo and AOL) BitlBee can download the contact list automatically from the IM server and all the on-line users should appear in the control channel when you log in.63 Now BitlBee logs in and downloads the contact list from the IM server. In a few seconds, all your on-line buddies should show up in the control channel. 64 64 </para> 65 65 66 66 <para> 67 BitlBee will convert names into irc-friendly form (for instance: tux@example.com will be given the nickname tux). If you have more than one person who would have the same name by this logic (for instance: tux@example.com and tux@bitlbee.org) the second one to log on will be tux_. The same is true if you have a tux log on to AOL and a tux log on from Yahoo.67 BitlBee will convert names into IRC-friendly form (for instance: tux@example.com will be given the nickname tux). If you have more than one person who would have the same name by this logic (for instance: tux@example.com and tux@bitlbee.org) the second one to log on will be tux_. The same is true if you have a tux log on to AOL and a tux log on from Yahoo. 68 68 </para> 69 69 … … 127 127 <ircexample> 128 128 <ircline nick="you">tux: hey, how's the weather down there?</ircline> 129 <ircline nick="tux"> 129 <ircline nick="tux">you: a bit chilly!</ircline> 130 130 </ircexample> 131 131 132 132 <para> 133 If you'd rather chat with them in a separate window use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like you would for a private message in IRC. If you want to have messages automatically come up in private messages rather than in the &bitlbee channel, use the <emphasis>set private</emphasis> command: <emphasis>set private true</emphasis> (<emphasis>set private false</emphasis> to change back). 133 Note that, although all contacts are in the &bitlbee channel, only tux will actually receive this message. The &bitlbee channel shouldn't be confused with a real IRC channel. 134 </para> 135 136 <para> 137 If you prefer chatting in a separate window, use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like on real IRC. BitlBee will remember how you talk to someone and show his/her responses the same way. If you want to change the default behaviour (for people you haven't talked to yet), see <emphasis>help set private</emphasis>. 134 138 </para> 135 139 -
ipc.c
r0db75ad rdd34575 258 258 else 259 259 { 260 ipc_master_free_fd( source ); 261 } 262 263 return TRUE; 264 } 265 266 gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond ) 267 { 268 char *buf, **cmd; 269 270 if( ( buf = ipc_readline( source ) ) ) 271 { 272 cmd = irc_parse_line( buf ); 273 if( cmd ) 274 ipc_command_exec( data, cmd, ipc_child_commands ); 275 } 276 else 277 { 278 ipc_child_disable(); 279 } 280 281 return TRUE; 282 } 283 284 void ipc_to_master( char **cmd ) 285 { 286 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 287 { 288 char *s = irc_build_line( cmd ); 289 ipc_to_master_str( "%s", s ); 290 g_free( s ); 291 } 292 else if( global.conf->runmode == RUNMODE_DAEMON ) 293 { 294 ipc_command_exec( NULL, cmd, ipc_master_commands ); 295 } 296 } 297 298 void ipc_to_master_str( char *format, ... ) 299 { 300 char *msg_buf; 301 va_list params; 302 303 va_start( params, format ); 304 msg_buf = g_strdup_vprintf( format, params ); 305 va_end( params ); 306 307 if( strlen( msg_buf ) > 512 ) 308 { 309 /* Don't send it, it's too long... */ 310 } 311 else if( global.conf->runmode == RUNMODE_FORKDAEMON ) 312 { 313 if( global.listen_socket >= 0 ) 314 if( write( global.listen_socket, msg_buf, strlen( msg_buf ) ) <= 0 ) 315 ipc_child_disable(); 316 } 317 else if( global.conf->runmode == RUNMODE_DAEMON ) 318 { 319 char **cmd, *s; 320 321 if( ( s = strchr( msg_buf, '\r' ) ) ) 322 *s = 0; 323 324 cmd = irc_parse_line( msg_buf ); 325 ipc_command_exec( NULL, cmd, ipc_master_commands ); 326 g_free( cmd ); 327 } 328 329 g_free( msg_buf ); 330 } 331 332 void ipc_to_children( char **cmd ) 333 { 334 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 335 { 336 char *msg_buf = irc_build_line( cmd ); 337 ipc_to_children_str( "%s", msg_buf ); 338 g_free( msg_buf ); 339 } 340 else if( global.conf->runmode == RUNMODE_DAEMON ) 341 { 260 342 GSList *l; 261 struct bitlbee_child *c; 262 263 for( l = child_list; l; l = l->next ) 343 344 for( l = irc_connection_list; l; l = l->next ) 345 ipc_command_exec( l->data, cmd, ipc_child_commands ); 346 } 347 } 348 349 void ipc_to_children_str( char *format, ... ) 350 { 351 char *msg_buf; 352 va_list params; 353 354 va_start( params, format ); 355 msg_buf = g_strdup_vprintf( format, params ); 356 va_end( params ); 357 358 if( strlen( msg_buf ) > 512 ) 359 { 360 /* Don't send it, it's too long... */ 361 } 362 else if( global.conf->runmode == RUNMODE_FORKDAEMON ) 363 { 364 int msg_len = strlen( msg_buf ); 365 GSList *l, *next; 366 367 for( l = child_list; l; l = next ) 264 368 { 265 c = l->data; 266 if( c->ipc_fd == source ) 369 struct bitlbee_child *c = l->data; 370 371 next = l->next; 372 if( write( c->ipc_fd, msg_buf, msg_len ) <= 0 ) 267 373 { 268 374 ipc_master_free_one( c ); 269 375 child_list = g_slist_remove( child_list, c ); 270 break;271 376 } 272 }273 }274 275 return TRUE;276 }277 278 gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond )279 {280 char *buf, **cmd;281 282 if( ( buf = ipc_readline( source ) ) )283 {284 cmd = irc_parse_line( buf );285 if( cmd )286 ipc_command_exec( data, cmd, ipc_child_commands );287 }288 else289 {290 b_event_remove( global.listen_watch_source_id );291 close( global.listen_socket );292 293 global.listen_socket = -1;294 }295 296 return TRUE;297 }298 299 void ipc_to_master( char **cmd )300 {301 if( global.conf->runmode == RUNMODE_FORKDAEMON )302 {303 char *s = irc_build_line( cmd );304 ipc_to_master_str( "%s", s );305 g_free( s );306 }307 else if( global.conf->runmode == RUNMODE_DAEMON )308 {309 ipc_command_exec( NULL, cmd, ipc_master_commands );310 }311 }312 313 void ipc_to_master_str( char *format, ... )314 {315 char *msg_buf;316 va_list params;317 318 va_start( params, format );319 msg_buf = g_strdup_vprintf( format, params );320 va_end( params );321 322 if( strlen( msg_buf ) > 512 )323 {324 /* Don't send it, it's too long... */325 }326 else if( global.conf->runmode == RUNMODE_FORKDAEMON )327 {328 write( global.listen_socket, msg_buf, strlen( msg_buf ) );329 }330 else if( global.conf->runmode == RUNMODE_DAEMON )331 {332 char **cmd, *s;333 334 if( ( s = strchr( msg_buf, '\r' ) ) )335 *s = 0;336 337 cmd = irc_parse_line( msg_buf );338 ipc_command_exec( NULL, cmd, ipc_master_commands );339 g_free( cmd );340 }341 342 g_free( msg_buf );343 }344 345 void ipc_to_children( char **cmd )346 {347 if( global.conf->runmode == RUNMODE_FORKDAEMON )348 {349 char *msg_buf = irc_build_line( cmd );350 ipc_to_children_str( "%s", msg_buf );351 g_free( msg_buf );352 }353 else if( global.conf->runmode == RUNMODE_DAEMON )354 {355 GSList *l;356 357 for( l = irc_connection_list; l; l = l->next )358 ipc_command_exec( l->data, cmd, ipc_child_commands );359 }360 }361 362 void ipc_to_children_str( char *format, ... )363 {364 char *msg_buf;365 va_list params;366 367 va_start( params, format );368 msg_buf = g_strdup_vprintf( format, params );369 va_end( params );370 371 if( strlen( msg_buf ) > 512 )372 {373 /* Don't send it, it's too long... */374 }375 else if( global.conf->runmode == RUNMODE_FORKDAEMON )376 {377 int msg_len = strlen( msg_buf );378 GSList *l;379 380 for( l = child_list; l; l = l->next )381 {382 struct bitlbee_child *c = l->data;383 write( c->ipc_fd, msg_buf, msg_len );384 377 } 385 378 } … … 410 403 } 411 404 405 void ipc_master_free_fd( int fd ) 406 { 407 GSList *l; 408 struct bitlbee_child *c; 409 410 for( l = child_list; l; l = l->next ) 411 { 412 c = l->data; 413 if( c->ipc_fd == fd ) 414 { 415 ipc_master_free_one( c ); 416 child_list = g_slist_remove( child_list, c ); 417 break; 418 } 419 } 420 } 421 412 422 void ipc_master_free_all() 413 423 { … … 419 429 g_slist_free( child_list ); 420 430 child_list = NULL; 431 } 432 433 void ipc_child_disable() 434 { 435 b_event_remove( global.listen_watch_source_id ); 436 close( global.listen_socket ); 437 438 global.listen_socket = -1; 421 439 } 422 440 -
ipc.h
r0db75ad rdd34575 44 44 45 45 void ipc_master_free_one( struct bitlbee_child *child ); 46 void ipc_master_free_fd( int fd ); 46 47 void ipc_master_free_all(); 48 49 void ipc_child_disable(); 47 50 48 51 void ipc_to_master( char **cmd ); -
irc.c
r0db75ad rdd34575 42 42 } 43 43 44 static char *set_eval_charset( set_t *set, char *value ) 45 { 46 irc_t *irc = set->data; 47 GIConv ic, oc; 48 49 if( g_strcasecmp( value, "none" ) == 0 ) 50 value = g_strdup( "utf-8" ); 51 52 if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) 53 { 54 return NULL; 55 } 56 if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) 57 { 58 g_iconv_close( ic ); 59 return NULL; 60 } 61 62 if( irc->iconv != (GIConv) -1 ) 63 g_iconv_close( irc->iconv ); 64 if( irc->oconv != (GIConv) -1 ) 65 g_iconv_close( irc->oconv ); 66 67 irc->iconv = ic; 68 irc->oconv = oc; 69 70 return value; 71 } 72 44 73 irc_t *irc_new( int fd ) 45 74 { … … 64 93 irc->mynick = g_strdup( ROOT_NICK ); 65 94 irc->channel = g_strdup( ROOT_CHAN ); 95 96 irc->iconv = (GIConv) -1; 97 irc->oconv = (GIConv) -1; 66 98 67 99 if( global.conf->hostname ) … … 127 159 conf_loaddefaults( irc ); 128 160 161 /* Evaluator sets the iconv/oconv structures. */ 162 set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); 163 129 164 return( irc ); 130 165 } … … 185 220 186 221 /* Because we have no garbage collection, this is quite annoying */ 187 void irc_free(irc_t * irc) 188 { 189 account_t *account; 222 void irc_free( irc_t * irc ) 223 { 190 224 user_t *user, *usertmp; 191 225 … … 196 230 irc_usermsg( irc, "Error while saving settings!" ); 197 231 198 closesocket( irc->fd ); 232 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 233 234 while( irc->accounts ) 235 { 236 if( irc->accounts->ic ) 237 imc_logout( irc->accounts->ic, FALSE ); 238 else if( irc->accounts->reconnect ) 239 cancel_auto_reconnect( irc->accounts ); 240 241 if( irc->accounts->ic == NULL ) 242 account_del( irc, irc->accounts ); 243 else 244 /* Nasty hack, but account_del() doesn't work in this 245 case and we don't want infinite loops, do we? ;-) */ 246 irc->accounts = irc->accounts->next; 247 } 248 249 while( irc->queries != NULL ) 250 query_del( irc, irc->queries ); 251 252 while( irc->set ) 253 set_del( &irc->set, irc->set->key ); 254 255 if (irc->users != NULL) 256 { 257 user = irc->users; 258 while( user != NULL ) 259 { 260 g_free( user->nick ); 261 g_free( user->away ); 262 g_free( user->handle ); 263 if( user->user != user->nick ) g_free( user->user ); 264 if( user->host != user->nick ) g_free( user->host ); 265 if( user->realname != user->nick ) g_free( user->realname ); 266 b_event_remove( user->sendbuf_timer ); 267 268 usertmp = user; 269 user = user->next; 270 g_free( usertmp ); 271 } 272 } 199 273 200 274 if( irc->ping_source_id > 0 ) … … 204 278 b_event_remove( irc->w_watch_source_id ); 205 279 206 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 207 208 for (account = irc->accounts; account; account = account->next) { 209 if (account->ic) { 210 imc_logout(account->ic, TRUE); 211 } else if (account->reconnect) { 212 cancel_auto_reconnect(account); 213 } 214 } 215 216 g_free(irc->sendbuffer); 217 g_free(irc->readbuffer); 218 219 g_free(irc->nick); 220 g_free(irc->user); 221 g_free(irc->host); 222 g_free(irc->realname); 223 g_free(irc->password); 224 225 g_free(irc->myhost); 226 g_free(irc->mynick); 227 228 g_free(irc->channel); 229 230 while (irc->queries != NULL) 231 query_del(irc, irc->queries); 232 233 while (irc->accounts) 234 if (irc->accounts->ic == NULL) 235 account_del(irc, irc->accounts); 236 else 237 /* Nasty hack, but account_del() doesn't work in this 238 case and we don't want infinite loops, do we? ;-) */ 239 irc->accounts = irc->accounts->next; 240 241 while (irc->set) 242 set_del(&irc->set, irc->set->key); 243 244 if (irc->users != NULL) { 245 user = irc->users; 246 while (user != NULL) { 247 g_free(user->nick); 248 g_free(user->away); 249 g_free(user->handle); 250 if(user->user!=user->nick) g_free(user->user); 251 if(user->host!=user->nick) g_free(user->host); 252 if(user->realname!=user->nick) g_free(user->realname); 253 b_event_remove(user->sendbuf_timer); 254 255 usertmp = user; 256 user = user->next; 257 g_free(usertmp); 258 } 259 } 260 261 g_hash_table_foreach_remove(irc->userhash, irc_free_hashkey, NULL); 262 g_hash_table_destroy(irc->userhash); 263 264 g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL); 265 g_hash_table_destroy(irc->watches); 266 267 g_free(irc); 280 closesocket( irc->fd ); 281 irc->fd = -1; 282 283 g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL ); 284 g_hash_table_destroy( irc->userhash ); 285 286 g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL ); 287 g_hash_table_destroy( irc->watches ); 288 289 if( irc->iconv != (GIConv) -1 ) 290 g_iconv_close( irc->iconv ); 291 if( irc->oconv != (GIConv) -1 ) 292 g_iconv_close( irc->oconv ); 293 294 g_free( irc->sendbuffer ); 295 g_free( irc->readbuffer ); 296 297 g_free( irc->nick ); 298 g_free( irc->user ); 299 g_free( irc->host ); 300 g_free( irc->realname ); 301 g_free( irc->password ); 302 303 g_free( irc->myhost ); 304 g_free( irc->mynick ); 305 306 g_free( irc->channel ); 307 308 g_free( irc->last_target ); 309 310 g_free( irc ); 268 311 269 312 if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) … … 286 329 void irc_process( irc_t *irc ) 287 330 { 288 char **lines, *temp, **cmd , *cs;331 char **lines, *temp, **cmd; 289 332 int i; 290 333 … … 295 338 for( i = 0; *lines[i] != '\0'; i ++ ) 296 339 { 297 char conv[IRC_MAX_LINE+1];340 char *conv = NULL; 298 341 299 /* [WvG] Because irc_tokenize splits at every newline, the lines[] list 300 should end with an empty string. This is why this actually works. 301 Took me a while to figure out, Maurits. :-P */ 342 /* [WvG] If the last line isn't empty, it's an incomplete line and we 343 should wait for the rest to come in before processing it. */ 302 344 if( lines[i+1] == NULL ) 303 345 { … … 309 351 } 310 352 311 if( ( cs = set_getstr( &irc->set, "charset" ) ) ) 312 { 313 conv[IRC_MAX_LINE] = 0; 314 if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 ) 353 if( irc->iconv != (GIConv) -1 ) 354 { 355 gsize bytes_read, bytes_written; 356 357 conv = g_convert_with_iconv( lines[i], -1, irc->iconv, 358 &bytes_read, &bytes_written, NULL ); 359 360 if( conv == NULL || bytes_read != strlen( lines[i] ) ) 315 361 { 316 362 /* GLib can do strange things if things are not in the expected charset, … … 324 370 "expect by changing the charset setting. See " 325 371 "`help set charset' for more information. Your " 326 "message was ignored.", cs ); 327 *conv = 0; 372 "message was ignored.", 373 set_getstr( &irc->set, "charset" ) ); 374 375 g_free( conv ); 376 conv = NULL; 328 377 } 329 378 else 330 379 { 331 380 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, 332 "Warning: invalid (non-UTF8)characters received at login time." );381 "Warning: invalid characters received at login time." ); 333 382 334 strncpy( conv, lines[i], IRC_MAX_LINE);383 conv = g_strdup( lines[i] ); 335 384 for( temp = conv; *temp; temp ++ ) 336 385 if( *temp & 0x80 ) … … 341 390 } 342 391 343 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 344 continue; 345 irc_exec( irc, cmd ); 392 if( lines[i] ) 393 { 394 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 395 continue; 396 irc_exec( irc, cmd ); 397 g_free( cmd ); 398 } 346 399 347 g_free( c md);400 g_free( conv ); 348 401 349 402 /* Shouldn't really happen, but just in case... */ … … 369 422 char **irc_tokenize( char *buffer ) 370 423 { 371 int i, j ;424 int i, j, n = 3; 372 425 char **lines; 373 426 374 /* Count the number of elements we're gonna need. */ 375 for( i = 0, j = 1; buffer[i] != '\0'; i ++ ) 376 { 377 if( buffer[i] == '\n' ) 378 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 379 j ++; 380 } 381 382 /* Allocate j+1 elements. */ 383 lines = g_new( char *, j + 1 ); 427 /* Allocate n+1 elements. */ 428 lines = g_new( char *, n + 1 ); 429 430 lines[0] = buffer; 431 432 /* Split the buffer in several strings, and accept any kind of line endings, 433 * knowing that ERC on Windows may send something interesting like \r\r\n, 434 * and surely there must be clients that think just \n is enough... */ 435 for( i = 0, j = 0; buffer[i] != '\0'; i ++ ) 436 { 437 if( buffer[i] == '\r' || buffer[i] == '\n' ) 438 { 439 while( buffer[i] == '\r' || buffer[i] == '\n' ) 440 buffer[i++] = '\0'; 441 442 lines[++j] = buffer + i; 443 444 if( j >= n ) 445 { 446 n *= 2; 447 lines = g_renew( char *, lines, n + 1 ); 448 } 449 450 if( buffer[i] == '\0' ) 451 break; 452 } 453 } 384 454 385 455 /* NULL terminate our list. */ 386 lines[j] = NULL; 387 388 lines[0] = buffer; 389 390 /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional. 391 * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too. 392 */ 393 for( i = 0, j = 0; buffer[i] != '\0'; i ++) 394 { 395 if( buffer[i] == '\n' ) 396 { 397 buffer[i] = '\0'; 398 399 if( i > 0 && buffer[i-1] == '\r' ) 400 buffer[i-1] = '\0'; 401 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 402 lines[++j] = buffer + i + 1; 403 } 404 } 405 406 return( lines ); 456 lines[++j] = NULL; 457 458 return lines; 407 459 } 408 460 … … 538 590 539 591 return; 540 541 592 } 542 593 … … 544 595 { 545 596 int size; 546 char line[IRC_MAX_LINE+1] , *cs;597 char line[IRC_MAX_LINE+1]; 547 598 548 599 /* Don't try to write anything new anymore when shutting down. */ … … 550 601 return; 551 602 552 line[IRC_MAX_LINE] = 0;603 memset( line, 0, sizeof( line ) ); 553 604 g_vsnprintf( line, IRC_MAX_LINE - 2, format, params ); 554 555 605 strip_newlines( line ); 556 if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) 557 { 558 char conv[IRC_MAX_LINE+1]; 559 560 conv[IRC_MAX_LINE] = 0; 561 if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 ) 562 strcpy( line, conv ); 563 } 564 strcat( line, "\r\n" ); 606 607 if( irc->oconv != (GIConv) -1 ) 608 { 609 gsize bytes_read, bytes_written; 610 char *conv; 611 612 conv = g_convert_with_iconv( line, -1, irc->oconv, 613 &bytes_read, &bytes_written, NULL ); 614 615 if( bytes_read == strlen( line ) ) 616 strncpy( line, conv, IRC_MAX_LINE - 2 ); 617 618 g_free( conv ); 619 } 620 g_strlcat( line, "\r\n", IRC_MAX_LINE + 1 ); 565 621 566 622 if( irc->sendbuffer != NULL ) … … 735 791 irc_spawn( irc, u ); 736 792 737 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQs are answered there." ); 793 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n" 794 "If you've never used BitlBee before, please do read the help " 795 "information using the \x02help\x02 command. Lots of FAQs are " 796 "answered there.\n" 797 "If you already have an account on this server, just use the " 798 "\x02identify\x02 command to identify yourself." ); 738 799 739 800 if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) … … 741 802 742 803 irc->status |= USTATUS_LOGGED_IN; 804 805 /* This is for bug #209 (use PASS to identify to NickServ). */ 806 if( irc->password != NULL ) 807 { 808 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; 809 810 irc_setpass( irc, NULL ); 811 root_command( irc, send_cmd ); 812 g_free( send_cmd[1] ); 813 } 743 814 } 744 815 -
irc.h
r0db75ad rdd34575 61 61 char *sendbuffer; 62 62 char *readbuffer; 63 GIConv iconv, oconv; 63 64 64 65 int sentbytes; … … 69 70 char *host; 70 71 char *realname; 71 char *password; 72 char *password; /* HACK: Used to save the user's password, but before 73 logging in, this may contain a password we should 74 send to identify after USER/NICK are received. */ 72 75 73 76 char umode[8]; -
irc_commands.c
r0db75ad rdd34575 30 30 static void irc_cmd_pass( irc_t *irc, char **cmd ) 31 31 { 32 if( global.conf->auth_pass && strcmp( cmd[1], global.conf->auth_pass ) == 0 ) 32 if( irc->status & USTATUS_LOGGED_IN ) 33 { 34 char *send_cmd[] = { "identify", cmd[1], NULL }; 35 36 /* We're already logged in, this client seems to send the PASS 37 command last. (Possibly it won't send it at all if it turns 38 out we don't require it, which will break this feature.) 39 Try to identify using the given password. */ 40 return root_command( irc, send_cmd ); 41 } 42 /* Handling in pre-logged-in state, first see if this server is 43 password-protected: */ 44 else if( global.conf->auth_pass && 45 ( strncmp( global.conf->auth_pass, "md5:", 4 ) == 0 ? 46 md5_verify_password( cmd[1], global.conf->auth_pass + 4 ) == 0 : 47 strcmp( cmd[1], global.conf->auth_pass ) == 0 ) ) 33 48 { 34 49 irc->status |= USTATUS_AUTHORIZED; 35 50 irc_check_login( irc ); 36 51 } 37 else 52 else if( global.conf->auth_pass ) 38 53 { 39 54 irc_reply( irc, 464, ":Incorrect password" ); 55 } 56 else 57 { 58 /* Remember the password and try to identify after USER/NICK. */ 59 irc_setpass( irc, cmd[1] ); 60 irc_check_login( irc ); 40 61 } 41 62 } … … 88 109 static void irc_cmd_oper( irc_t *irc, char **cmd ) 89 110 { 90 if( global.conf->oper_pass && strcmp( cmd[2], global.conf->oper_pass ) == 0 ) 111 if( global.conf->oper_pass && 112 ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ? 113 md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 : 114 strcmp( cmd[2], global.conf->oper_pass ) == 0 ) ) 91 115 { 92 116 irc_umode_set( irc, "+o", 1 ); … … 254 278 if( cmd[1] != irc->last_target ) 255 279 { 256 if( irc->last_target ) 257 g_free( irc->last_target ); 280 g_free( irc->last_target ); 258 281 irc->last_target = g_strdup( cmd[1] ); 259 282 } … … 575 598 576 599 static const command_t irc_commands[] = { 577 { "pass", 1, irc_cmd_pass, IRC_CMD_PRE_LOGIN},600 { "pass", 1, irc_cmd_pass, 0 }, 578 601 { "user", 4, irc_cmd_user, IRC_CMD_PRE_LOGIN }, 579 602 { "nick", 1, irc_cmd_nick, 0 }, -
lib/Makefile
r0db75ad rdd34575 10 10 11 11 # [SH] Program variables 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o 13 13 14 14 CFLAGS += -Wall -
lib/arc.c
r0db75ad rdd34575 131 131 132 132 Both functions return the number of bytes in the result string. 133 134 Note that if you use the pad_to argument, you will need zero-termi- 135 nation to find back the original string length after decryption. So 136 it shouldn't be used if your string contains \0s by itself! 133 137 */ 134 138 135 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password )139 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to ) 136 140 { 137 141 struct arc_state *st; 138 142 unsigned char *key; 139 int key_len, i; 143 char *padded = NULL; 144 int key_len, i, padded_len; 140 145 141 146 key_len = strlen( password ) + ARC_IV_LEN; 142 147 if( clear_len <= 0 ) 143 148 clear_len = strlen( clear ); 149 150 /* Pad the string to the closest multiple of pad_to. This makes it 151 impossible to see the exact length of the password. */ 152 if( pad_to > 0 && ( clear_len % pad_to ) > 0 ) 153 { 154 padded_len = clear_len + pad_to - ( clear_len % pad_to ); 155 padded = g_malloc( padded_len ); 156 memcpy( padded, clear, clear_len ); 157 158 /* First a \0 and then random data, so we don't have to do 159 anything special when decrypting. */ 160 padded[clear_len] = 0; 161 random_bytes( (unsigned char*) padded + clear_len + 1, padded_len - clear_len - 1 ); 162 163 clear = padded; 164 clear_len = padded_len; 165 } 144 166 145 167 /* Prepare buffers and the key + IV */ … … 161 183 162 184 g_free( st ); 185 g_free( padded ); 163 186 164 187 return clear_len + ARC_IV_LEN; -
lib/arc.h
r0db75ad rdd34575 31 31 }; 32 32 33 struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles );33 G_GNUC_MALLOC struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles ); 34 34 unsigned char arc_getbyte( struct arc_state *st ); 35 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password );35 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to ); 36 36 int arc_decode( unsigned char *crypt, int crypt_len, char **clear, char *password ); -
lib/base64.c
r0db75ad rdd34575 118 118 int i, outlen = 0; 119 119 120 for( i = 0; in[i] ; i += 4 )120 for( i = 0; in[i] && in[i+1] && in[i+2] && in[i+3]; i += 4 ) 121 121 { 122 122 int sx; -
lib/events_glib.c
r0db75ad rdd34575 51 51 } GaimIOClosure; 52 52 53 static GMainLoop *loop ;53 static GMainLoop *loop = NULL; 54 54 55 55 void b_main_init() 56 56 { 57 loop = g_main_new( FALSE ); 57 if( loop == NULL ) 58 loop = g_main_new( FALSE ); 58 59 } 59 60 -
lib/misc.c
r0db75ad rdd34575 33 33 #define BITLBEE_CORE 34 34 #include "nogaim.h" 35 #include "base64.h" 35 36 #include <stdio.h> 36 37 #include <stdlib.h> … … 597 598 return sockerr_again(); 598 599 } 600 601 /* Returns values: -1 == Failure (base64-decoded to something unexpected) 602 0 == Okay 603 1 == Password doesn't match the hash. */ 604 int md5_verify_password( char *password, char *hash ) 605 { 606 md5_byte_t *pass_dec = NULL; 607 md5_byte_t pass_md5[16]; 608 md5_state_t md5_state; 609 int ret, i; 610 611 if( base64_decode( hash, &pass_dec ) != 21 ) 612 { 613 ret = -1; 614 } 615 else 616 { 617 md5_init( &md5_state ); 618 md5_append( &md5_state, (md5_byte_t*) password, strlen( password ) ); 619 md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */ 620 md5_finish( &md5_state, pass_md5 ); 621 622 for( i = 0; i < 16; i ++ ) 623 { 624 if( pass_dec[i] != pass_md5[i] ) 625 { 626 ret = 1; 627 break; 628 } 629 } 630 631 /* If we reached the end of the loop, it was a match! */ 632 if( i == 16 ) 633 ret = 0; 634 } 635 636 g_free( pass_dec ); 637 638 return ret; 639 } -
lib/misc.h
r0db75ad rdd34575 67 67 G_MODULE_EXPORT gboolean ssl_sockerr_again( void *ssl ); 68 68 69 G_MODULE_EXPORT int md5_verify_password( char *password, char *hash ); 70 69 71 #endif -
lib/proxy.c
r0db75ad rdd34575 530 530 struct PHB *phb; 531 531 532 if (!host || !port || (port == -1)|| !func || strlen(host) > 128) {532 if (!host || port <= 0 || !func || strlen(host) > 128) { 533 533 return -1; 534 534 } … … 538 538 phb->data = data; 539 539 540 if ( (proxytype == PROXY_NONE) || strlen(proxyhost) > 0 || !proxyport || (proxyport == -1))540 if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0) 541 541 return proxy_connect_none(host, port, phb); 542 542 else if (proxytype == PROXY_HTTP) -
lib/ssl_client.h
r0db75ad rdd34575 60 60 G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len ); 61 61 62 /* See ssl_openssl.c for an explanation. */ 63 G_MODULE_EXPORT int ssl_pending( void *conn ); 64 62 65 /* Abort the SSL connection and disconnect the socket. Do not use close() 63 66 directly, both the SSL library and the peer will be unhappy! */ -
lib/ssl_gnutls.c
r0db75ad rdd34575 211 211 } 212 212 213 /* See ssl_openssl.c for an explanation. */ 214 int ssl_pending( void *conn ) 215 { 216 return 0; 217 } 218 213 219 void ssl_disconnect( void *conn_ ) 214 220 { -
lib/ssl_nss.c
r0db75ad rdd34575 169 169 } 170 170 171 /* See ssl_openssl.c for an explanation. */ 172 int ssl_pending( void *conn ) 173 { 174 return 0; 175 } 176 171 177 void ssl_disconnect( void *conn_ ) 172 178 { -
lib/ssl_openssl.c
r0db75ad rdd34575 62 62 63 63 conn->fd = proxy_connect( host, port, ssl_connected, conn ); 64 if( conn->fd < 0 ) 65 { 66 g_free( conn ); 67 return NULL; 68 } 69 64 70 conn->func = func; 65 71 conn->data = data; 66 72 conn->inpa = -1; 67 68 if( conn->fd < 0 )69 {70 g_free( conn );71 return NULL;72 }73 73 74 74 return conn; … … 231 231 } 232 232 233 /* Only OpenSSL *really* needs this (and well, maybe NSS). See for more info: 234 http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209 235 http://www.openssl.org/docs/ssl/SSL_pending.html 236 237 Required because OpenSSL empties the TCP buffer completely but doesn't 238 necessarily give us all the unencrypted data. 239 240 Returns 0 if there's nothing left or if we don't have to care (GnuTLS), 241 1 if there's more data. */ 242 int ssl_pending( void *conn ) 243 { 244 return ( ((struct scd*)conn) && ((struct scd*)conn)->established ) ? 245 SSL_pending( ((struct scd*)conn)->ssl ) > 0 : 0; 246 } 247 233 248 void ssl_disconnect( void *conn_ ) 234 249 { -
lib/url.c
r0db75ad rdd34575 26 26 #include "url.h" 27 27 28 /* Convert an URL to a url_t structure 28 /* Convert an URL to a url_t structure */ 29 29 int url_set( url_t *url, char *set_url ) 30 30 { 31 char s[MAX_STRING ];31 char s[MAX_STRING+1]; 32 32 char *i; 33 33 34 /* protocol:// */ 34 memset( url, 0, sizeof( url_t ) ); 35 memset( s, 0, sizeof( s ) ); 36 37 /* protocol:// */ 35 38 if( ( i = strstr( set_url, "://" ) ) == NULL ) 36 39 { … … 49 52 url->proto = PROTO_SOCKS5; 50 53 else 51 { 52 return( 0 ); 53 } 54 return 0; 55 54 56 strncpy( s, i + 3, MAX_STRING ); 55 57 } 56 58 57 /* Split 59 /* Split */ 58 60 if( ( i = strchr( s, '/' ) ) == NULL ) 59 61 { … … 67 69 strncpy( url->host, s, MAX_STRING ); 68 70 69 /* Check for username in host field 71 /* Check for username in host field */ 70 72 if( strrchr( url->host, '@' ) != NULL ) 71 73 { … … 76 78 *url->pass = 0; 77 79 } 78 /* If not: Fill in defaults 80 /* If not: Fill in defaults */ 79 81 else 80 82 { … … 82 84 } 83 85 84 /* Password? 86 /* Password? */ 85 87 if( ( i = strchr( url->user, ':' ) ) != NULL ) 86 88 { … … 88 90 strcpy( url->pass, i + 1 ); 89 91 } 90 /* Port number? 92 /* Port number? */ 91 93 if( ( i = strchr( url->host, ':' ) ) != NULL ) 92 94 { -
lib/url.h
r0db75ad rdd34575 26 26 #include "bitlbee.h" 27 27 28 #define PROTO_HTTP 29 #define PROTO_HTTPS 30 #define PROTO_SOCKS4 31 #define PROTO_SOCKS5 32 #define PROTO_DEFAULT 28 #define PROTO_HTTP 2 29 #define PROTO_HTTPS 5 30 #define PROTO_SOCKS4 3 31 #define PROTO_SOCKS5 4 32 #define PROTO_DEFAULT PROTO_HTTP 33 33 34 34 typedef struct url … … 36 36 int proto; 37 37 int port; 38 char host[MAX_STRING ];39 char file[MAX_STRING ];40 char user[MAX_STRING ];41 char pass[MAX_STRING ];38 char host[MAX_STRING+1]; 39 char file[MAX_STRING+1]; 40 char user[MAX_STRING+1]; 41 char pass[MAX_STRING+1]; 42 42 } url_t; 43 43 -
protocols/jabber/Makefile
r0db75ad rdd34575 10 10 11 11 # [SH] Program variables 12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o 13 13 14 14 CFLAGS += -Wall -
protocols/jabber/io.c
r0db75ad rdd34575 241 241 } 242 242 243 /* EAGAIN/etc or a successful read. */ 244 return TRUE; 243 if( ssl_pending( jd->ssl ) ) 244 /* OpenSSL empties the TCP buffers completely but may keep some 245 data in its internap buffers. select() won't see that, but 246 ssl_pending() does. */ 247 return jabber_read_callback( data, fd, cond ); 248 else 249 return TRUE; 245 250 } 246 251 … … 521 526 from the server too. */ 522 527 xt_free( jd->xt ); /* In case we're RE-starting. */ 523 jd->xt = xt_new( ic ); 524 jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers; 528 jd->xt = xt_new( jabber_handlers, ic ); 525 529 526 530 if( jd->r_inpa <= 0 ) -
protocols/jabber/jabber.c
r0db75ad rdd34575 267 267 xt_free( jd->xt ); 268 268 269 g_free( jd->cached_id_prefix ); 269 270 g_free( jd->away_message ); 270 271 g_free( jd->username ); -
protocols/msn/ns.c
r0db75ad rdd34575 34 34 static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts ); 35 35 36 static void msn_auth_got_passport_ id( struct passport_reply *rep);36 static void msn_auth_got_passport_token( struct msn_auth_data *mad ); 37 37 38 38 gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ) … … 214 214 { 215 215 /* Time for some Passport black magic... */ 216 if( !passport_get_ id( msn_auth_got_passport_id, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )216 if( !passport_get_token( msn_auth_got_passport_token, ic, ic->acc->user, ic->acc->pass, cmd[4] ) ) 217 217 { 218 218 imcb_error( ic, "Error while contacting Passport server" ); … … 674 674 } 675 675 676 static void msn_auth_got_passport_ id( struct passport_reply *rep)676 static void msn_auth_got_passport_token( struct msn_auth_data *mad ) 677 677 { 678 struct im_connection *ic = rep->data; 679 struct msn_data *md = ic->proto_data; 680 char *key = rep->result; 681 char buf[1024]; 682 683 if( key == NULL ) 684 { 685 imcb_error( ic, "Error during Passport authentication (%s)", 686 rep->error_string ? rep->error_string : "Unknown error" ); 678 struct im_connection *ic = mad->data; 679 struct msn_data *md; 680 681 /* Dead connection? */ 682 if( g_slist_find( msn_connections, ic ) == NULL ) 683 return; 684 685 md = ic->proto_data; 686 if( mad->token ) 687 { 688 char buf[1024]; 689 690 g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, mad->token ); 691 msn_write( ic, buf, strlen( buf ) ); 692 } 693 else 694 { 695 imcb_error( ic, "Error during Passport authentication: %s", mad->error ); 687 696 imc_logout( ic, TRUE ); 688 697 } 689 else690 {691 g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, key );692 msn_write( ic, buf, strlen( buf ) );693 }694 698 } -
protocols/msn/passport.c
r0db75ad rdd34575 1 /* passport.c1 /** passport.c 2 2 * 3 * Functions to login to microsoft passport service for Messenger 4 * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be> 5 * Copyright (C) 2004 Wilmer van der Gaast <wilmer@gaast.net> 3 * Functions to login to Microsoft Passport service for Messenger 4 * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net> 6 5 * 7 6 * This program is free software; you can redistribute it and/or modify … … 24 23 #include "msn.h" 25 24 #include "bitlbee.h" 25 #include "url.h" 26 #include "misc.h" 27 #include "xmltree.h" 26 28 #include <ctype.h> 27 29 #include <errno.h> 28 30 29 #define MSN_BUF_LEN 8192 31 static int passport_get_token_real( struct msn_auth_data *mad ); 32 static void passport_get_token_ready( struct http_request *req ); 30 33 31 static char *prd_cached = NULL; 32 33 static int passport_get_id_real( gpointer func, gpointer data, char *header ); 34 static void passport_get_id_ready( struct http_request *req ); 35 36 static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header ); 37 static void passport_retrieve_dalogin_ready( struct http_request *req ); 38 39 static char *passport_create_header( char *cookie, char *email, char *pwd ); 40 static void destroy_reply( struct passport_reply *rep ); 41 42 int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie ) 34 int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie ) 43 35 { 44 char *header = passport_create_header( cookie, username, password ); 36 struct msn_auth_data *mad = g_new0( struct msn_auth_data, 1 ); 37 int i; 45 38 46 if( prd_cached == NULL ) 47 return passport_retrieve_dalogin( func, data, header ); 48 else 49 return passport_get_id_real( func, data, header ); 39 mad->username = g_strdup( username ); 40 mad->password = g_strdup( password ); 41 mad->cookie = g_strdup( cookie ); 42 43 mad->callback = func; 44 mad->data = data; 45 46 mad->url = g_strdup( SOAP_AUTHENTICATION_URL ); 47 mad->ttl = 3; /* Max. # of redirects. */ 48 49 /* HTTP-escape stuff and s/,/&/ */ 50 http_decode( mad->cookie ); 51 for( i = 0; mad->cookie[i]; i ++ ) 52 if( mad->cookie[i] == ',' ) 53 mad->cookie[i] = '&'; 54 55 /* Microsoft doesn't allow password longer than 16 chars and silently 56 fails authentication if you give the "full version" of your passwd. */ 57 if( strlen( mad->password ) > MAX_PASSPORT_PWLEN ) 58 mad->password[MAX_PASSPORT_PWLEN] = 0; 59 60 return passport_get_token_real( mad ); 50 61 } 51 62 52 static int passport_get_ id_real( gpointer func, gpointer data, char *header)63 static int passport_get_token_real( struct msn_auth_data *mad ) 53 64 { 54 struct passport_reply *rep; 55 char *server, *dummy, *reqs; 65 char *post_payload, *post_request; 56 66 struct http_request *req; 67 url_t url; 57 68 58 rep = g_new0( struct passport_reply, 1 ); 59 rep->data = data; 60 rep->func = func; 61 rep->header = header; 69 url_set( &url, mad->url ); 62 70 63 server = g_strdup( prd_cached ); 64 dummy = strchr( server, '/' ); 71 post_payload = g_markup_printf_escaped( SOAP_AUTHENTICATION_PAYLOAD, 72 mad->username, 73 mad->password, 74 mad->cookie ); 65 75 66 if( dummy == NULL ) 67 { 68 destroy_reply( rep ); 69 return( 0 ); 70 } 76 post_request = g_strdup_printf( SOAP_AUTHENTICATION_REQUEST, 77 url.file, url.host, 78 (int) strlen( post_payload ), 79 post_payload ); 80 81 req = http_dorequest( url.host, url.port, 1, post_request, 82 passport_get_token_ready, mad ); 71 83 72 reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header ); 84 g_free( post_request ); 85 g_free( post_payload ); 73 86 74 *dummy = 0; 75 req = http_dorequest( server, 443, 1, reqs, passport_get_id_ready, rep ); 76 77 g_free( server ); 78 g_free( reqs ); 79 80 if( req == NULL ) 81 destroy_reply( rep ); 82 83 return( req != NULL ); 87 return req != NULL; 84 88 } 85 89 86 static void passport_get_id_ready( struct http_request *req ) 90 static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data ); 91 static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data ); 92 93 static const struct xt_handler_entry passport_xt_handlers[] = { 94 { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", passport_xt_extract_token }, 95 { "S:Fault", "S:Envelope", passport_xt_handle_fault }, 96 { NULL, NULL, NULL } 97 }; 98 99 static void passport_get_token_ready( struct http_request *req ) 87 100 { 88 struct passport_reply *rep = req->data; 101 struct msn_auth_data *mad = req->data; 102 struct xt_parser *parser; 89 103 90 if( !g_slist_find( msn_connections, rep->data ) ) 104 g_free( mad->url ); 105 g_free( mad->error ); 106 mad->url = mad->error = NULL; 107 108 if( req->status_code == 200 ) 91 109 { 92 destroy_reply( rep ); 93 return; 94 } 95 96 if( req->finished && req->reply_headers && req->status_code == 200 ) 97 { 98 char *dummy; 99 100 if( ( dummy = strstr( req->reply_headers, "from-PP='" ) ) ) 101 { 102 char *responseend; 103 104 dummy += strlen( "from-PP='" ); 105 responseend = strchr( dummy, '\'' ); 106 if( responseend ) 107 *responseend = 0; 108 109 rep->result = g_strdup( dummy ); 110 } 111 else 112 { 113 rep->error_string = g_strdup( "Could not parse Passport server response" ); 114 } 110 parser = xt_new( passport_xt_handlers, mad ); 111 xt_feed( parser, req->reply_body, req->body_size ); 112 xt_handle( parser, NULL, -1 ); 113 xt_free( parser ); 115 114 } 116 115 else 117 116 { 118 rep->error_string = g_strdup_printf( "HTTP error: %s",119 req->status_string ? req->status_string : "Unknown error" );117 mad->error = g_strdup_printf( "HTTP error %d (%s)", req->status_code, 118 req->status_string ? req->status_string : "unknown" ); 120 119 } 121 120 122 rep->func( rep ); 123 destroy_reply( rep ); 121 if( mad->error == NULL && mad->token == NULL ) 122 mad->error = g_strdup( "Could not parse Passport server response" ); 123 124 if( mad->url && mad->token == NULL ) 125 { 126 passport_get_token_real( mad ); 127 } 128 else 129 { 130 mad->callback( mad ); 131 132 g_free( mad->url ); 133 g_free( mad->username ); 134 g_free( mad->password ); 135 g_free( mad->cookie ); 136 g_free( mad->token ); 137 g_free( mad->error ); 138 g_free( mad ); 139 } 124 140 } 125 141 126 static char *passport_create_header( char *cookie, char *email, char *pwd)142 static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data ) 127 143 { 128 char *buffer; 129 char *currenttoken; 130 char *email_enc, *pwd_enc; 144 struct msn_auth_data *mad = data; 145 char *s; 131 146 132 currenttoken = strstr( cookie, "lc=" ); 133 if( currenttoken == NULL ) 134 return NULL; 147 if( ( s = xt_find_attr( node, "Id" ) ) && strcmp( s, "PPToken1" ) == 0 ) 148 mad->token = g_memdup( node->text, node->text_len + 1 ); 135 149 136 email_enc = g_new0( char, strlen( email ) * 3 + 1 ); 137 strcpy( email_enc, email ); 138 http_encode( email_enc ); 139 140 pwd_enc = g_new0( char, strlen( pwd ) * 3 + 1 ); 141 strcpy( pwd_enc, pwd ); 142 http_encode( pwd_enc ); 143 144 buffer = g_strdup_printf( "Authorization: Passport1.4 OrgVerb=GET," 145 "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom," 146 "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc, 147 currenttoken ); 148 149 g_free( email_enc ); 150 g_free( pwd_enc ); 151 152 return buffer; 150 return XT_HANDLED; 153 151 } 154 152 155 static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header)153 static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data ) 156 154 { 157 struct passport_reply *rep = g_new0( struct passport_reply, 1 ); 158 struct http_request *req; 155 struct msn_auth_data *mad = data; 156 struct xt_node *code = xt_find_node( node->children, "faultcode" ); 157 struct xt_node *string = xt_find_node( node->children, "faultstring" ); 158 struct xt_node *redirect = xt_find_node( node->children, "psf:redirectUrl" ); 159 159 160 rep->data = data; 161 rep->func = func; 162 rep->header = header; 160 if( redirect && redirect->text_len && mad->ttl-- > 0 ) 161 mad->url = g_memdup( redirect->text, redirect->text_len + 1 ); 163 162 164 req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep ); 163 if( code == NULL || code->text_len == 0 ) 164 mad->error = g_strdup( "Unknown error" ); 165 else 166 mad->error = g_strdup_printf( "%s (%s)", code->text, string && string->text_len ? 167 string->text : "no description available" ); 165 168 166 if( !req ) 167 destroy_reply( rep ); 168 169 return( req != NULL ); 169 return XT_HANDLED; 170 170 } 171 172 static void passport_retrieve_dalogin_ready( struct http_request *req )173 {174 struct passport_reply *rep = req->data;175 char *dalogin;176 char *urlend;177 178 if( !g_slist_find( msn_connections, rep->data ) )179 {180 destroy_reply( rep );181 return;182 }183 184 if( !req->finished || !req->reply_headers || req->status_code != 200 )185 {186 rep->error_string = g_strdup_printf( "HTTP error while fetching DALogin: %s",187 req->status_string ? req->status_string : "Unknown error" );188 goto failure;189 }190 191 dalogin = strstr( req->reply_headers, "DALogin=" );192 193 if( !dalogin )194 {195 rep->error_string = g_strdup( "Parse error while fetching DALogin" );196 goto failure;197 }198 199 dalogin += strlen( "DALogin=" );200 urlend = strchr( dalogin, ',' );201 if( urlend )202 *urlend = 0;203 204 /* strip the http(s):// part from the url */205 urlend = strstr( urlend, "://" );206 if( urlend )207 dalogin = urlend + strlen( "://" );208 209 if( prd_cached == NULL )210 prd_cached = g_strdup( dalogin );211 212 if( passport_get_id_real( rep->func, rep->data, rep->header ) )213 {214 rep->header = NULL;215 destroy_reply( rep );216 return;217 }218 219 failure:220 rep->func( rep );221 destroy_reply( rep );222 }223 224 static void destroy_reply( struct passport_reply *rep )225 {226 g_free( rep->result );227 g_free( rep->header );228 g_free( rep->error_string );229 g_free( rep );230 } -
protocols/msn/passport.h
r0db75ad rdd34575 1 #ifndef __PASSPORT_H__2 #define __PASSPORT_H__3 1 /* passport.h 4 2 * 5 * Functions to login to Microsoft Passport Service for Messenger 6 * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be>, 7 * Wilmer van der Gaast <wilmer@gaast.net> 3 * Functions to login to Microsoft Passport service for Messenger 4 * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net> 8 5 * 9 6 * This program is free software; you can redistribute it and/or modify … … 18 15 * You should have received a copy of the GNU General Public License 19 16 * along with this program; if not, write to the Free Software 20 * 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 18 */ 19 20 /* Thanks to http://msnpiki.msnfanatic.com/index.php/MSNP13:SOAPTweener 21 for the specs! */ 22 23 #ifndef __PASSPORT_H__ 24 #define __PASSPORT_H__ 22 25 23 26 #include <stdio.h> … … 33 36 #include "nogaim.h" 34 37 35 struct passport_reply 38 #define MAX_PASSPORT_PWLEN 16 39 40 struct msn_auth_data 36 41 { 37 void (*func)( struct passport_reply * ); 38 void *data; 39 char *result; 40 char *header; 41 char *error_string; 42 char *url; 43 int ttl; 44 45 char *username; 46 char *password; 47 char *cookie; 48 49 /* The end result, the only thing we'll really be interested in 50 once finished. */ 51 char *token; 52 char *error; /* Yeah, or that... */ 53 54 void (*callback)( struct msn_auth_data *mad ); 55 gpointer data; 42 56 }; 43 57 44 int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie ); 58 #define SOAP_AUTHENTICATION_URL "https://loginnet.passport.com/RST.srf" 59 60 #define SOAP_AUTHENTICATION_REQUEST \ 61 "POST %s HTTP/1.0\r\n" \ 62 "Accept: text/*\r\n" \ 63 "User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \ 64 "Host: %s\r\n" \ 65 "Content-Length: %d\r\n" \ 66 "Cache-Control: no-cache\r\n" \ 67 "\r\n" \ 68 "%s" 69 70 #define SOAP_AUTHENTICATION_PAYLOAD \ 71 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \ 72 "<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\" xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2004/04/sc\" xmlns:wst=\"http://schemas.xmlsoap.org/ws/2004/04/trust\">" \ 73 "<Header>" \ 74 "<ps:AuthInfo xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"PPAuthInfo\">" \ 75 "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>" \ 76 "<ps:BinaryVersion>4</ps:BinaryVersion>" \ 77 "<ps:UIVersion>1</ps:UIVersion>" \ 78 "<ps:Cookies></ps:Cookies>" \ 79 "<ps:RequestParams>AQAAAAIAAABsYwQAAAAzMDg0</ps:RequestParams>" \ 80 "</ps:AuthInfo>" \ 81 "<wsse:Security>" \ 82 "<wsse:UsernameToken Id=\"user\">" \ 83 "<wsse:Username>%s</wsse:Username>" \ 84 "<wsse:Password>%s</wsse:Password>" \ 85 "</wsse:UsernameToken>" \ 86 "</wsse:Security>" \ 87 "</Header>" \ 88 "<Body>" \ 89 "<ps:RequestMultipleSecurityTokens xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"RSTS\">" \ 90 "<wst:RequestSecurityToken Id=\"RST0\">" \ 91 "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ 92 "<wsp:AppliesTo>" \ 93 "<wsa:EndpointReference>" \ 94 "<wsa:Address>http://Passport.NET/tb</wsa:Address>" \ 95 "</wsa:EndpointReference>" \ 96 "</wsp:AppliesTo>" \ 97 "</wst:RequestSecurityToken>" \ 98 "<wst:RequestSecurityToken Id=\"RST1\">" \ 99 "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ 100 "<wsp:AppliesTo>" \ 101 "<wsa:EndpointReference>" \ 102 "<wsa:Address>messenger.msn.com</wsa:Address>" \ 103 "</wsa:EndpointReference>" \ 104 "</wsp:AppliesTo>" \ 105 "<wsse:PolicyReference URI=\"?%s\"></wsse:PolicyReference>" \ 106 "</wst:RequestSecurityToken>" \ 107 "</ps:RequestMultipleSecurityTokens>" \ 108 "</Body>" \ 109 "</Envelope>" 110 111 int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie ); 45 112 46 113 #endif /* __PASSPORT_H__ */ -
protocols/yahoo/libyahoo2.c
r0db75ad rdd34575 737 737 738 738 memcpy(data + pos, "YMSG", 4); pos += 4; 739 pos += yahoo_put16(data + pos, 0x0 a00);739 pos += yahoo_put16(data + pos, 0x000c); 740 740 pos += yahoo_put16(data + pos, 0x0000); 741 741 pos += yahoo_put16(data + pos, pktlen + extra_pad); … … 3351 3351 break; 3352 3352 case 5: 3353 if( cp != "\005")3353 if(strcmp(cp, "5") != 0) 3354 3354 yct->location = cp; 3355 3355 k = 0; -
protocols/yahoo/yahoo.c
r0db75ad rdd34575 315 315 struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data; 316 316 317 yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );317 yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" ); 318 318 } 319 319 -
query.c
r0db75ad rdd34575 140 140 if( ans ) 141 141 { 142 imcb_log( q->ic, "Accepted: %s", q->question ); 142 if( q->ic ) 143 imcb_log( q->ic, "Accepted: %s", q->question ); 144 else 145 irc_usermsg( irc, "Accepted: %s", q->question ); 143 146 q->yes( NULL, q->data ); 144 147 } 145 148 else 146 149 { 147 imcb_log( q->ic, "Rejected: %s", q->question ); 150 if( q->ic ) 151 imcb_log( q->ic, "Rejected: %s", q->question ); 152 else 153 irc_usermsg( irc, "Rejected: %s", q->question ); 148 154 q->no( NULL, q->data ); 149 155 } -
root_commands.c
r0db75ad rdd34575 204 204 } 205 205 206 void cmd_account_del_yes( gpointer w, void *data ) 207 { 208 account_t *a = data; 209 irc_t *irc = a->irc; 210 211 if( a->ic ) 212 { 213 irc_usermsg( irc, "Account is still logged in, can't delete" ); 214 } 215 else 216 { 217 account_del( irc, a ); 218 irc_usermsg( irc, "Account deleted" ); 219 } 220 } 221 222 void cmd_account_del_no( gpointer w, void *data ) 223 { 224 } 225 206 226 static void cmd_account( irc_t *irc, char **cmd ) 207 227 { … … 258 278 else 259 279 { 260 account_del( irc, a ); 261 irc_usermsg( irc, "Account deleted" ); 280 char *msg; 281 282 msg = g_strdup_printf( "If you remove this account (%s(%s)), BitlBee will " 283 "also forget all your saved nicknames. If you want " 284 "to change your username/password, use the `account " 285 "set' command. Are you sure you want to delete this " 286 "account?", a->prpl->name, a->user ); 287 query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, a ); 288 g_free( msg ); 262 289 } 263 290 } … … 769 796 else 770 797 irc_usermsg( irc, "%s is empty", set_name ); 798 799 if( strchr( set_name, '/' ) ) 800 irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." ); 771 801 } 772 802 else -
set.c
r0db75ad rdd34575 230 230 return value; 231 231 } 232 233 char *set_eval_charset( set_t *set, char *value )234 {235 GIConv cd;236 237 if ( g_strncasecmp( value, "none", 4 ) == 0 )238 return value;239 240 cd = g_iconv_open( "UTF-8", value );241 if( cd == (GIConv) -1 )242 return NULL;243 244 g_iconv_close( cd );245 return value;246 } -
set.h
r0db75ad rdd34575 97 97 char *set_eval_to_char( set_t *set, char *value ); 98 98 char *set_eval_ops( set_t *set, char *value ); 99 char *set_eval_charset( set_t *set, char *value );100 99 101 100 #endif /* __SET_H__ */ -
storage_xml.c
r0db75ad rdd34575 80 80 char *nick = xml_attr( attr_names, attr_values, "nick" ); 81 81 char *pass = xml_attr( attr_names, attr_values, "password" ); 82 md5_byte_t *pass_dec = NULL;82 int st; 83 83 84 84 if( !nick || !pass ) … … 87 87 "Missing attributes for %s element", element_name ); 88 88 } 89 else if( base64_decode( pass, &pass_dec ) != 21 ) 90 { 89 else if( ( st = md5_verify_password( xd->given_pass, pass ) ) == -1 ) 90 { 91 xd->pass_st = XML_PASS_WRONG; 91 92 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 92 93 "Error while decoding password attribute" ); 93 94 } 95 else if( st == 0 ) 96 { 97 if( xd->pass_st != XML_PASS_CHECK_ONLY ) 98 xd->pass_st = XML_PASS_OK; 99 } 94 100 else 95 101 { 96 md5_byte_t pass_md5[16]; 97 md5_state_t md5_state; 98 int i; 99 100 md5_init( &md5_state ); 101 md5_append( &md5_state, (md5_byte_t*) xd->given_pass, strlen( xd->given_pass ) ); 102 md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */ 103 md5_finish( &md5_state, pass_md5 ); 104 105 for( i = 0; i < 16; i ++ ) 106 { 107 if( pass_dec[i] != pass_md5[i] ) 108 { 109 xd->pass_st = XML_PASS_WRONG; 110 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 111 "Password mismatch" ); 112 break; 113 } 114 } 115 116 /* If we reached the end of the loop, it was a match! */ 117 if( i == 16 ) 118 { 119 if( xd->pass_st != XML_PASS_CHECK_ONLY ) 120 xd->pass_st = XML_PASS_OK; 121 } 122 } 123 124 g_free( pass_dec ); 102 xd->pass_st = XML_PASS_WRONG; 103 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 104 "Password mismatch" ); 105 } 125 106 } 126 107 else if( xd->pass_st < XML_PASS_OK ) … … 428 409 int pass_len; 429 410 430 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password );411 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 ); 431 412 pass_b64 = base64_encode( pass_cr, pass_len ); 432 413 g_free( pass_cr ); -
tests/check_arc.c
r0db75ad rdd34575 7 7 #include "arc.h" 8 8 9 char *password = " TotT";9 char *password = "ArcVier"; 10 10 11 11 char *clear_tests[] = … … 14 14 "ItllBeBitlBee", 15 15 "One more boring password", 16 "Hoi hoi", 16 17 NULL 17 18 }; … … 28 29 int len; 29 30 30 len = arc_encode( clear_tests[i], 0, &crypted, password );31 len = arc_encode( clear_tests[i], 0, &crypted, password, 12 ); 31 32 len = arc_decode( crypted, len, &decrypted, password ); 32 33 … … 41 42 struct 42 43 { 43 unsigned char crypted[ 24];44 unsigned char crypted[30]; 44 45 int len; 45 46 char *decrypted; 46 47 } decrypt_tests[] = { 48 /* One block with padding. */ 47 49 { 48 50 { 49 0x c3, 0x0d, 0x43, 0xc3, 0xee, 0x80, 0xe2, 0x8c, 0x0b, 0x29, 0x32, 0x7e,50 0x 38, 0x05, 0x82, 0x10, 0x21, 0x1c, 0x4a, 0x00, 0x2c51 }, 21, "Debugging sucks"51 0x3f, 0x79, 0xb0, 0xf5, 0x91, 0x56, 0xd2, 0x1b, 0xd1, 0x4b, 0x67, 0xac, 52 0xb1, 0x31, 0xc9, 0xdb, 0xf9, 0xaa 53 }, 18, "short pass" 52 54 }, 55 56 /* Two blocks with padding. */ 53 57 { 54 58 { 55 0xb0, 0x00, 0x57, 0x0d, 0x0d, 0x0d, 0x70, 0xe1, 0xc0, 0x00, 0xa4, 0x25, 56 0x7d, 0xbe, 0x03, 0xcc, 0x24, 0xd1, 0x0c 57 }, 19, "Testing rocks" 59 0xf9, 0xa6, 0xec, 0x5d, 0xc7, 0x06, 0xb8, 0x6b, 0x63, 0x9f, 0x2d, 0xb5, 60 0x7d, 0xaa, 0x32, 0xbb, 0xd8, 0x08, 0xfd, 0x81, 0x2e, 0xca, 0xb4, 0xd7, 61 0x2f, 0x36, 0x9c, 0xac, 0xa0, 0xbc 62 }, 30, "longer password" 58 63 }, 64 65 /* This string is exactly two "blocks" long, to make sure unpadded strings also decrypt 66 properly. */ 59 67 { 60 68 { 61 0xb6, 0x92, 0x59, 0xe4, 0xf9, 0xc1, 0x7a, 0xf6, 0xf3, 0x18, 0xea, 0x28, 62 0x73, 0x6d, 0xb3, 0x0a, 0x6f, 0x0a, 0x2b, 0x43, 0x57, 0xe9, 0x3e, 0x63 63 }, 24, "OSCAR is creepy..." 69 0x95, 0x4d, 0xcf, 0x4d, 0x5e, 0x6c, 0xcf, 0xef, 0xb9, 0x80, 0x00, 0xef, 70 0x25, 0xe9, 0x17, 0xf6, 0x29, 0x6a, 0x82, 0x79, 0x1c, 0xca, 0x68, 0xb5, 71 0x4e, 0xd0, 0xc1, 0x41, 0x8e, 0xe6 72 }, 30, "OSCAR is really creepy.." 64 73 }, 65 74 { "", 0, NULL } … … 80 89 81 90 fail_if( strcmp( decrypt_tests[i].decrypted, decrypted ) != 0, 82 " %s didn't decrypt properly", clear_tests[i]);91 "`%s' didn't decrypt properly", decrypt_tests[i].decrypted ); 83 92 84 93 g_free( decrypted ); -
tests/check_help.c
r0db75ad rdd34575 7 7 #include "help.h" 8 8 9 START_TEST(test_help_ none)9 START_TEST(test_help_initfree) 10 10 help_t *h, *r; 11 11 r = help_init(&h, "/dev/null"); 12 12 fail_if(r == NULL); 13 13 fail_if(r != h); 14 15 help_free(&h); 16 fail_if(h != NULL); 14 17 END_TEST 15 18 … … 25 28 TCase *tc_core = tcase_create("Core"); 26 29 suite_add_tcase (s, tc_core); 27 tcase_add_test (tc_core, test_help_ none);30 tcase_add_test (tc_core, test_help_initfree); 28 31 tcase_add_test (tc_core, test_help_nonexistent); 29 32 return s; -
tests/check_irc.c
r0db75ad rdd34575 37 37 irc = irc_new(g_io_channel_unix_get_fd(ch1)); 38 38 39 fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\ n"40 "USER a a a a\ r\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL);39 fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\r\n" 40 "USER a a a a\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL); 41 41 fail_unless(g_io_channel_flush(ch2, NULL) == G_IO_STATUS_NORMAL); 42 42 -
tests/check_jabber_sasl.c
r0db75ad rdd34575 18 18 struct 19 19 { 20 c onst char *challenge;20 char *challenge; 21 21 char *key; 22 22 char *value;
Note: See TracChangeset
for help on using the changeset viewer.