Changes in / [bfafb99:e31e5b8]


Ignore:
Files:
44 added
16 deleted
107 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    rbfafb99 re31e5b8  
    5555        rm -f *.o $(OUTFILE) core utils/bitlbeed init/bitlbee*.service
    5656        $(MAKE) -C tests clean
     57ifdef SKYPE_PI
     58        $(MAKE) -C protocols/skype clean
     59endif
    5760
    5861distclean: clean $(subdirs)
     
    167170$(SKYPE_PI): $(_SRCDIR_)protocols/skype/skype.c
    168171        @echo '*' Building plugin skype
    169         @$(CC) $(CFLAGS) -fPIC -shared $< -o $@
     172        @$(CC) $(CFLAGS) $(SKYPEFLAGS) $< -o $@
    170173
    171174$(objects): %.o: $(_SRCDIR_)%.c
    172175        @echo '*' Compiling $<
    173         @$(CC) -c $(CFLAGS) $< -o $@
     176        @$(CC) -c $(CFLAGS) $(CFLAGS_BITLBEE) $< -o $@
    174177
    175178$(objects): Makefile Makefile.settings config.h
     
    177180$(OUTFILE): $(objects) $(subdirs)
    178181        @echo '*' Linking $(OUTFILE)
    179         @$(CC) $(objects) $(subdirobjs) -o $(OUTFILE) $(LFLAGS) $(EFLAGS)
     182        @$(CC) $(objects) $(subdirobjs) -o $(OUTFILE) $(LDFLAGS_BITLBEE) $(LFLAGS) $(EFLAGS)
    180183ifndef DEBUG
    181184        @echo '*' Stripping $(OUTFILE)
  • bitlbee.h

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2013 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    3939
    4040#define PACKAGE "BitlBee"
    41 #define BITLBEE_VERSION "3.0.5"
     41#define BITLBEE_VERSION "3.2"
    4242#define VERSION BITLBEE_VERSION
    4343#define BITLBEE_VER(a,b,c) (((a) << 16) + ((b) << 8) + (c))
    44 #define BITLBEE_VERSION_CODE BITLBEE_VER(3, 0, 5)
     44#define BITLBEE_VERSION_CODE BITLBEE_VER(3, 2, 0)
    4545
    4646#define MAX_STRING 511
  • configure

    rbfafb99 re31e5b8  
    4141ssl=auto
    4242
     43pie=1
     44
    4345arch=`uname -s`
    4446cpu=`uname -m`
     
    7981--debug=0/1     Disable/enable debugging                $debug
    8082--strip=0/1     Disable/enable binary stripping         $strip
     83--pie=0/1       Build position independent executable   $pie
    8184--gcov=0/1      Disable/enable test coverage reporting  $gcov
    8285--plugins=0/1   Disable/enable plugins support          $plugins
     
    8790
    8891--events=...    Event handler (glib, libevent)          $events
    89 --ssl=...       SSL library to use (gnutls, nss, openssl, bogus, auto)
     92--ssl=...       SSL library to use (gnutls, nss, openssl, auto)
    9093                                                        $ssl
     94
    9195
    9296--target=...    Cross compilation target                same as host
     
    197201else
    198202        [ -z "$CFLAGS" ] && CFLAGS="-O2 -fno-strict-aliasing"
     203fi
     204
     205if [ "$pie" = "1" ]; then
     206        echo 'CFLAGS_BITLBEE=-fPIE' >> Makefile.settings
     207        echo 'LDFLAGS_BITLBEE=-pie' >> Makefile.settings
    199208fi
    200209
     
    385394        echo
    386395        echo 'No detection code exists for OpenSSL. Make sure that you have a complete'
    387         echo 'install of OpenSSL (including devel/header files) before reporting'
     396        echo 'installation of OpenSSL (including devel/header files) before reporting'
    388397        echo 'compilation problems.'
    389398        echo
    390399        echo 'Also, keep in mind that the OpenSSL is, according to some people, not'
    391         echo 'completely GPL-compatible. Using GnuTLS or NSS is recommended and better'
    392         echo 'supported by us. However, on many BSD machines, OpenSSL can be considered'
    393         echo 'part of the operating system, which makes it GPL-compatible.'
     400        echo 'completely GPL-compatible. Using GnuTLS is recommended and better supported'
     401        echo 'by us. However, on many BSD machines, OpenSSL can be considered part of the'
     402        echo 'operating system, which makes it GPL-compatible.'
    394403        echo
    395404        echo 'For more info, see: http://www.openssl.org/support/faq.html#LEGAL2'
     
    398407        echo 'Please note that distributing a BitlBee binary which links to OpenSSL is'
    399408        echo 'probably illegal. If you want to create and distribute a binary BitlBee'
    400         echo 'package, you really should use GnuTLS or NSS instead.'
     409        echo 'package, you really should use GnuTLS instead.'
    401410        echo
    402411        echo 'Also, the OpenSSL license requires us to say this:'
     
    407416       
    408417        ret=1
    409 elif [ "$ssl" = "bogus" ]; then
    410         echo
    411         echo 'Using bogus SSL code. This means some features will not work properly.'
    412        
    413         ## Yes, you, at the console! How can you authenticate if you don't have any SSL!?
    414         if [ "$msn" = "1" -o "$yahoo" = "1" ]; then
    415                 echo
    416                 echo 'WARNING: The MSN and Yahoo! modules will not work without SSL. Disabling.'
    417                 msn=0
    418                 yahoo=0
    419         fi
    420        
    421         ret=1
    422418else
    423419        echo
     
    430426        echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).'
    431427        echo '       Please note that this script doesn'\''t have detection code for OpenSSL,'
    432         echo '       so if you want to use that, you have to select it by hand. If you don'\''t'
    433         echo '       need SSL support, you can select the "bogus" SSL library. (--ssl=bogus)'
     428        echo '       so if you want to use that, you have to select it by hand.'
    434429       
    435430        exit 1
    436431fi;
    437 
    438 if [ "$msn" = "1" -a "$ssl" != "openssl" -a "$ssl" != "gnutls" ]; then
    439         # Needed for MSN only. OpenSSL exports nice cipher functions already,
    440         # in case of GnuTLS we should be able to use gcrypt. Otherwise, use
    441         # built-in stuff. (Since right now those are the only two supported
    442         # SSL modules anyway, this is mostly unnecessary.)
    443         echo 'DES=des.o' >> Makefile.settings
    444 fi
    445432
    446433echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings
     
    527514
    528515if [ "$skype" = "1" -o "$skype" = "plugin" ]; then
     516        if [ "$arch" = "Darwin" ]; then
     517                echo "SKYPEFLAGS=-dynamiclib -undefined dynamic_lookup" >> Makefile.settings
     518        else
     519                echo "SKYPEFLAGS=-fPIC -shared" >> Makefile.settings
     520        fi
    529521        echo 'SKYPE_PI=skype.so' >> Makefile.settings
    530522        protocols_mods="$protocol_mods skype(plugin)"
     
    624616*gcc* )
    625617        echo CFLAGS+=-MMD -MF .depend/\$@.d >> Makefile.settings
    626         for i in . lib protocols protocols/*/; do
     618        for i in . lib tests protocols protocols/*/; do
    627619                mkdir -p $i/.depend
    628620        done
     
    720712else
    721713        echo '  Debugging disabled.'
     714fi
     715
     716if [ "$pie" = "1" ]; then
     717        echo '  Building PIE executable'
     718else
     719        echo '  Building non-PIE executable'
    722720fi
    723721
  • debian/bitlbee-common.postrm

    rbfafb99 re31e5b8  
    1313rm -f /etc/default/bitlbee
    1414
    15 deluser --system --remove-home bitlbee || true
     15deluser --system bitlbee || true
    1616rm -rf /var/lib/bitlbee ## deluser doesn't seem to do this for homedirs in /var
  • debian/changelog

    rbfafb99 re31e5b8  
     1bitlbee (3.2-1) unstable; urgency=high
     2
     3  * New upstream release.
     4  * Depend on gnutls-dev instead of libgnutls-dev. (Closes: #691766)
     5  * Also, drop nss dependency. GnuTLS is supported officially, the rest is
     6    use-at-your-own-risk (so compile it yourself).
     7
     8 -- Wilmer van der Gaast <wilmer@gaast.net>  Mon, 14 Jan 2013 22:34:06 +0000
     9
     10bitlbee (3.0.6-1) unstable; urgency=low
     11
     12  * New upstream release.
     13
     14 -- Wilmer van der Gaast <wilmer@gaast.net>  Sun, 28 Oct 2012 19:58:33 +0000
     15
     16bitlbee (3.0.5-1.2) unstable; urgency=low
     17
     18  * Non-maintainer upload.
     19  * debian/bitlbee{,-dev}.postinst: Fix directory to symlink upgrade in
     20    postinst. (Closes: #687865)
     21
     22 -- David Prévot <taffit@debian.org>  Wed, 26 Sep 2012 23:20:41 -0400
     23
     24bitlbee (3.0.5-1.1) unstable; urgency=low
     25
     26  * Non-maintainer upload.
     27  * Fix "fails to install, purge, and install again":
     28    remove --remove-home option from deluser call in bitlbee-common.postrm.
     29    The option needs perl-modules which is not guaranteed to be there, and the
     30    directory gets removed manually anyway.
     31    (Closes: #681146)
     32
     33 -- gregor herrmann <gregoa@debian.org>  Thu, 26 Jul 2012 18:44:36 +0200
     34
    135bitlbee (3.0.5-1) unstable; urgency=low
    236
  • debian/control

    rbfafb99 re31e5b8  
    55Uploaders: Jelmer Vernooij <jelmer@samba.org>
    66Standards-Version: 3.9.1
    7 Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), po-debconf, libpurple-dev, libotr2-dev, debhelper (>= 6.0.7~), asciidoc
     7Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, gnutls-dev | libgnutls-dev, po-debconf, libpurple-dev, libotr2-dev, debhelper (>= 6.0.7~), asciidoc
    88Homepage: http://www.bitlbee.org/
    99Vcs-Bzr: http://code.bitlbee.org/bitlbee/
  • debian/copyright

    rbfafb99 re31e5b8  
    55
    66Authors: Wilmer van der Gaast, Sjoerd Hemminga, Jelmer Vernooij,
    7          Maurits Dijkstra and others.
     7         Maurits Dijkstra, Geert Mulders, Miklos Vajna and others.
    88
    9 Mainly Copyright 2002-2004 Wilmer van der Gaast.
    10 Some parts are borrowed from Gaim (version 0.58) <http://gaim.sf.net/>.
    11 For the copyrights on those parts, please read the Gaim source code.
     9Mainly Copyright 2002-2012 Wilmer van der Gaast.
     10
     11
     12Bits of third party code, also GPLed:
     13* Some parts (mostly protocols/oscar/) are borrowed from Gaim (version
     14  0.58), now known as Pidgin <http://www.pidgin.im/>.
     15* protocols/yahoo/ is libyahoo2 <http://libyahoo2.sf.net/>.
     16
     17Other license (but GPL-compatible):
     18* lib/json.[ch] is from <https://github.com/udp/json-parser> and licensed
     19  under the modified BSD license.
     20
    1221
    1322BitlBee License:
     
    3342
    3443The SGML-formatted documentation is written by Jelmer Vernooij
    35 <jelmer@nl.linux.org> under the GNU Free Documentation License:
     44<jelmer@samba.org> under the GNU Free Documentation License:
    3645
    3746============================================================================
    38                 GNU Free Documentation License
    39                    Version 1.1, March 2000
     47Copyright (c)  2002-2012 Jelmer Vernooij, Wilmer van der Gaast.
    4048
    41  Copyright (C) 2000  Free Software Foundation, Inc.
    42         51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
    43  Everyone is permitted to copy and distribute verbatim copies
    44  of this license document, but changing it is not allowed.
    45 
    46 
    47 0. PREAMBLE
    48 
    49 The purpose of this License is to make a manual, textbook, or other
    50 written document "free" in the sense of freedom: to assure everyone
    51 the effective freedom to copy and redistribute it, with or without
    52 modifying it, either commercially or noncommercially.  Secondarily,
    53 this License preserves for the author and publisher a way to get
    54 credit for their work, while not being considered responsible for
    55 modifications made by others.
    56 
    57 This License is a kind of "copyleft", which means that derivative
    58 works of the document must themselves be free in the same sense.  It
    59 complements the GNU General Public License, which is a copyleft
    60 license designed for free software.
    61 
    62 We have designed this License in order to use it for manuals for free
    63 software, because free software needs free documentation: a free
    64 program should come with manuals providing the same freedoms that the
    65 software does.  But this License is not limited to software manuals;
    66 it can be used for any textual work, regardless of subject matter or
    67 whether it is published as a printed book.  We recommend this License
    68 principally for works whose purpose is instruction or reference.
    69 
    70 
    71 1. APPLICABILITY AND DEFINITIONS
    72 
    73 This License applies to any manual or other work that contains a
    74 notice placed by the copyright holder saying it can be distributed
    75 under the terms of this License.  The "Document", below, refers to any
    76 such manual or work.  Any member of the public is a licensee, and is
    77 addressed as "you".
    78 
    79 A "Modified Version" of the Document means any work containing the
    80 Document or a portion of it, either copied verbatim, or with
    81 modifications and/or translated into another language.
    82 
    83 A "Secondary Section" is a named appendix or a front-matter section of
    84 the Document that deals exclusively with the relationship of the
    85 publishers or authors of the Document to the Document's overall subject
    86 (or to related matters) and contains nothing that could fall directly
    87 within that overall subject.  (For example, if the Document is in part a
    88 textbook of mathematics, a Secondary Section may not explain any
    89 mathematics.)  The relationship could be a matter of historical
    90 connection with the subject or with related matters, or of legal,
    91 commercial, philosophical, ethical or political position regarding
    92 them.
    93 
    94 The "Invariant Sections" are certain Secondary Sections whose titles
    95 are designated, as being those of Invariant Sections, in the notice
    96 that says that the Document is released under this License.
    97 
    98 The "Cover Texts" are certain short passages of text that are listed,
    99 as Front-Cover Texts or Back-Cover Texts, in the notice that says that
    100 the Document is released under this License.
    101 
    102 A "Transparent" copy of the Document means a machine-readable copy,
    103 represented in a format whose specification is available to the
    104 general public, whose contents can be viewed and edited directly and
    105 straightforwardly with generic text editors or (for images composed of
    106 pixels) generic paint programs or (for drawings) some widely available
    107 drawing editor, and that is suitable for input to text formatters or
    108 for automatic translation to a variety of formats suitable for input
    109 to text formatters.  A copy made in an otherwise Transparent file
    110 format whose markup has been designed to thwart or discourage
    111 subsequent modification by readers is not Transparent.  A copy that is
    112 not "Transparent" is called "Opaque".
    113 
    114 Examples of suitable formats for Transparent copies include plain
    115 ASCII without markup, Texinfo input format, LaTeX input format, SGML
    116 or XML using a publicly available DTD, and standard-conforming simple
    117 HTML designed for human modification.  Opaque formats include
    118 PostScript, PDF, proprietary formats that can be read and edited only
    119 by proprietary word processors, SGML or XML for which the DTD and/or
    120 processing tools are not generally available, and the
    121 machine-generated HTML produced by some word processors for output
    122 purposes only.
    123 
    124 The "Title Page" means, for a printed book, the title page itself,
    125 plus such following pages as are needed to hold, legibly, the material
    126 this License requires to appear in the title page.  For works in
    127 formats which do not have any title page as such, "Title Page" means
    128 the text near the most prominent appearance of the work's title,
    129 preceding the beginning of the body of the text.
    130 
    131 
    132 2. VERBATIM COPYING
    133 
    134 You may copy and distribute the Document in any medium, either
    135 commercially or noncommercially, provided that this License, the
    136 copyright notices, and the license notice saying this License applies
    137 to the Document are reproduced in all copies, and that you add no other
    138 conditions whatsoever to those of this License.  You may not use
    139 technical measures to obstruct or control the reading or further
    140 copying of the copies you make or distribute.  However, you may accept
    141 compensation in exchange for copies.  If you distribute a large enough
    142 number of copies you must also follow the conditions in section 3.
    143 
    144 You may also lend copies, under the same conditions stated above, and
    145 you may publicly display copies.
    146 
    147 
    148 3. COPYING IN QUANTITY
    149 
    150 If you publish printed copies of the Document numbering more than 100,
    151 and the Document's license notice requires Cover Texts, you must enclose
    152 the copies in covers that carry, clearly and legibly, all these Cover
    153 Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
    154 the back cover.  Both covers must also clearly and legibly identify
    155 you as the publisher of these copies.  The front cover must present
    156 the full title with all words of the title equally prominent and
    157 visible.  You may add other material on the covers in addition.
    158 Copying with changes limited to the covers, as long as they preserve
    159 the title of the Document and satisfy these conditions, can be treated
    160 as verbatim copying in other respects.
    161 
    162 If the required texts for either cover are too voluminous to fit
    163 legibly, you should put the first ones listed (as many as fit
    164 reasonably) on the actual cover, and continue the rest onto adjacent
    165 pages.
    166 
    167 If you publish or distribute Opaque copies of the Document numbering
    168 more than 100, you must either include a machine-readable Transparent
    169 copy along with each Opaque copy, or state in or with each Opaque copy
    170 a publicly-accessible computer-network location containing a complete
    171 Transparent copy of the Document, free of added material, which the
    172 general network-using public has access to download anonymously at no
    173 charge using public-standard network protocols.  If you use the latter
    174 option, you must take reasonably prudent steps, when you begin
    175 distribution of Opaque copies in quantity, to ensure that this
    176 Transparent copy will remain thus accessible at the stated location
    177 until at least one year after the last time you distribute an Opaque
    178 copy (directly or through your agents or retailers) of that edition to
    179 the public.
    180 
    181 It is requested, but not required, that you contact the authors of the
    182 Document well before redistributing any large number of copies, to give
    183 them a chance to provide you with an updated version of the Document.
    184 
    185 
    186 4. MODIFICATIONS
    187 
    188 You may copy and distribute a Modified Version of the Document under
    189 the conditions of sections 2 and 3 above, provided that you release
    190 the Modified Version under precisely this License, with the Modified
    191 Version filling the role of the Document, thus licensing distribution
    192 and modification of the Modified Version to whoever possesses a copy
    193 of it.  In addition, you must do these things in the Modified Version:
    194 
    195 A. Use in the Title Page (and on the covers, if any) a title distinct
    196    from that of the Document, and from those of previous versions
    197    (which should, if there were any, be listed in the History section
    198    of the Document).  You may use the same title as a previous version
    199    if the original publisher of that version gives permission.
    200 B. List on the Title Page, as authors, one or more persons or entities
    201    responsible for authorship of the modifications in the Modified
    202    Version, together with at least five of the principal authors of the
    203    Document (all of its principal authors, if it has less than five).
    204 C. State on the Title page the name of the publisher of the
    205    Modified Version, as the publisher.
    206 D. Preserve all the copyright notices of the Document.
    207 E. Add an appropriate copyright notice for your modifications
    208    adjacent to the other copyright notices.
    209 F. Include, immediately after the copyright notices, a license notice
    210    giving the public permission to use the Modified Version under the
    211    terms of this License, in the form shown in the Addendum below.
    212 G. Preserve in that license notice the full lists of Invariant Sections
    213    and required Cover Texts given in the Document's license notice.
    214 H. Include an unaltered copy of this License.
    215 I. Preserve the section entitled "History", and its title, and add to
    216    it an item stating at least the title, year, new authors, and
    217    publisher of the Modified Version as given on the Title Page.  If
    218    there is no section entitled "History" in the Document, create one
    219    stating the title, year, authors, and publisher of the Document as
    220    given on its Title Page, then add an item describing the Modified
    221    Version as stated in the previous sentence.
    222 J. Preserve the network location, if any, given in the Document for
    223    public access to a Transparent copy of the Document, and likewise
    224    the network locations given in the Document for previous versions
    225    it was based on.  These may be placed in the "History" section.
    226    You may omit a network location for a work that was published at
    227    least four years before the Document itself, or if the original
    228    publisher of the version it refers to gives permission.
    229 K. In any section entitled "Acknowledgements" or "Dedications",
    230    preserve the section's title, and preserve in the section all the
    231    substance and tone of each of the contributor acknowledgements
    232    and/or dedications given therein.
    233 L. Preserve all the Invariant Sections of the Document,
    234    unaltered in their text and in their titles.  Section numbers
    235    or the equivalent are not considered part of the section titles.
    236 M. Delete any section entitled "Endorsements".  Such a section
    237    may not be included in the Modified Version.
    238 N. Do not retitle any existing section as "Endorsements"
    239    or to conflict in title with any Invariant Section.
    240 
    241 If the Modified Version includes new front-matter sections or
    242 appendices that qualify as Secondary Sections and contain no material
    243 copied from the Document, you may at your option designate some or all
    244 of these sections as invariant.  To do this, add their titles to the
    245 list of Invariant Sections in the Modified Version's license notice.
    246 These titles must be distinct from any other section titles.
    247 
    248 You may add a section entitled "Endorsements", provided it contains
    249 nothing but endorsements of your Modified Version by various
    250 parties--for example, statements of peer review or that the text has
    251 been approved by an organization as the authoritative definition of a
    252 standard.
    253 
    254 You may add a passage of up to five words as a Front-Cover Text, and a
    255 passage of up to 25 words as a Back-Cover Text, to the end of the list
    256 of Cover Texts in the Modified Version.  Only one passage of
    257 Front-Cover Text and one of Back-Cover Text may be added by (or
    258 through arrangements made by) any one entity.  If the Document already
    259 includes a cover text for the same cover, previously added by you or
    260 by arrangement made by the same entity you are acting on behalf of,
    261 you may not add another; but you may replace the old one, on explicit
    262 permission from the previous publisher that added the old one.
    263 
    264 The author(s) and publisher(s) of the Document do not by this License
    265 give permission to use their names for publicity for or to assert or
    266 imply endorsement of any Modified Version.
    267 
    268 
    269 5. COMBINING DOCUMENTS
    270 
    271 You may combine the Document with other documents released under this
    272 License, under the terms defined in section 4 above for modified
    273 versions, provided that you include in the combination all of the
    274 Invariant Sections of all of the original documents, unmodified, and
    275 list them all as Invariant Sections of your combined work in its
    276 license notice.
    277 
    278 The combined work need only contain one copy of this License, and
    279 multiple identical Invariant Sections may be replaced with a single
    280 copy.  If there are multiple Invariant Sections with the same name but
    281 different contents, make the title of each such section unique by
    282 adding at the end of it, in parentheses, the name of the original
    283 author or publisher of that section if known, or else a unique number.
    284 Make the same adjustment to the section titles in the list of
    285 Invariant Sections in the license notice of the combined work.
    286 
    287 In the combination, you must combine any sections entitled "History"
    288 in the various original documents, forming one section entitled
    289 "History"; likewise combine any sections entitled "Acknowledgements",
    290 and any sections entitled "Dedications".  You must delete all sections
    291 entitled "Endorsements."
    292 
    293 
    294 6. COLLECTIONS OF DOCUMENTS
    295 
    296 You may make a collection consisting of the Document and other documents
    297 released under this License, and replace the individual copies of this
    298 License in the various documents with a single copy that is included in
    299 the collection, provided that you follow the rules of this License for
    300 verbatim copying of each of the documents in all other respects.
    301 
    302 You may extract a single document from such a collection, and distribute
    303 it individually under this License, provided you insert a copy of this
    304 License into the extracted document, and follow this License in all
    305 other respects regarding verbatim copying of that document.
    306 
    307 
    308 7. AGGREGATION WITH INDEPENDENT WORKS
    309 
    310 A compilation of the Document or its derivatives with other separate
    311 and independent documents or works, in or on a volume of a storage or
    312 distribution medium, does not as a whole count as a Modified Version
    313 of the Document, provided no compilation copyright is claimed for the
    314 compilation.  Such a compilation is called an "aggregate", and this
    315 License does not apply to the other self-contained works thus compiled
    316 with the Document, on account of their being thus compiled, if they
    317 are not themselves derivative works of the Document.
    318 
    319 If the Cover Text requirement of section 3 is applicable to these
    320 copies of the Document, then if the Document is less than one quarter
    321 of the entire aggregate, the Document's Cover Texts may be placed on
    322 covers that surround only the Document within the aggregate.
    323 Otherwise they must appear on covers around the whole aggregate.
    324 
    325 
    326 8. TRANSLATION
    327 
    328 Translation is considered a kind of modification, so you may
    329 distribute translations of the Document under the terms of section 4.
    330 Replacing Invariant Sections with translations requires special
    331 permission from their copyright holders, but you may include
    332 translations of some or all Invariant Sections in addition to the
    333 original versions of these Invariant Sections.  You may include a
    334 translation of this License provided that you also include the
    335 original English version of this License.  In case of a disagreement
    336 between the translation and the original English version of this
    337 License, the original English version will prevail.
    338 
    339 
    340 9. TERMINATION
    341 
    342 You may not copy, modify, sublicense, or distribute the Document except
    343 as expressly provided for under this License.  Any other attempt to
    344 copy, modify, sublicense or distribute the Document is void, and will
    345 automatically terminate your rights under this License.  However,
    346 parties who have received copies, or rights, from you under this
    347 License will not have their licenses terminated so long as such
    348 parties remain in full compliance.
    349 
    350 
    351 10. FUTURE REVISIONS OF THIS LICENSE
    352 
    353 The Free Software Foundation may publish new, revised versions
    354 of the GNU Free Documentation License from time to time.  Such new
    355 versions will be similar in spirit to the present version, but may
    356 differ in detail to address new problems or concerns.  See
    357 http://www.gnu.org/copyleft/.
    358 
    359 Each version of the License is given a distinguishing version number.
    360 If the Document specifies that a particular numbered version of this
    361 License "or any later version" applies to it, you have the option of
    362 following the terms and conditions either of that specified version or
    363 of any later version that has been published (not as a draft) by the
    364 Free Software Foundation.  If the Document does not specify a version
    365 number of this License, you may choose any version ever published (not
    366 as a draft) by the Free Software Foundation.
    367 
    368 
    369 ADDENDUM: How to use this License for your documents
    370 
    371 To use this License in a document you have written, include a copy of
    372 the License in the document and put the following copyright and
    373 license notices just after the title page:
    374 
    375       Copyright (c)  YEAR  YOUR NAME.
    376       Permission is granted to copy, distribute and/or modify this document
    377       under the terms of the GNU Free Documentation License, Version 1.1
    378       or any later version published by the Free Software Foundation;
    379       with the Invariant Sections being LIST THEIR TITLES, with the
    380       Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
    381       A copy of the license is included in the section entitled "GNU
    382       Free Documentation License".
    383 
    384 If you have no Invariant Sections, write "with no Invariant Sections"
    385 instead of saying which ones are invariant.  If you have no
    386 Front-Cover Texts, write "no Front-Cover Texts" instead of
    387 "Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
    388 
    389 If your document contains nontrivial examples of program code, we
    390 recommend releasing these examples in parallel under your choice of
    391 free software license, such as the GNU General Public License,
    392 to permit their use in free software.
     49Permission is granted to copy, distribute and/or modify this document
     50under the terms of the GNU Free Documentation License, Version 1.1 or
     51any later version published by the Free Software Foundation; with no
     52Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
     53Texts.  A copy of the license is included in the section entitled `GNU
     54Free Documentation License''.
    39355============================================================================
  • doc/AUTHORS

    rbfafb99 re31e5b8  
    1 Current developers:
     1Core team:
    22
    33Wilmer van der Gaast <wilmer@gaast.net>
    44        Main developer
     5
     6
     7Other contributors:
     8
     9Miklos Vajna <vmiklos@vmiklos.hu>
     10        Skype module
     11
     12pesco <pesco@khjk.org>
     13        OTR support
     14
     15
     16Retired developers:
     17
     18Sjoerd 'lucumo' Hemminga <sjoerd@hemminga-online.nl>
     19        NickServ, documentation
    520
    621Jelmer 'ctrlsoft' Vernooij <jelmer@samba.org>
     
    1025        Daemon dude, plus some other stuff
    1126
     27Geert Mulders <g.c.w.m.mulders@gmail.com>
     28        Initial version of the Twitter module
    1229
    13 Retired developer:
    14 
    15 Sjoerd 'lucumo' Hemminga <sjoerd@hemminga-online.nl>
    16         NickServ, documentation
    17 
    18 The development team wishes to thank Sjoerd for his contributions to the
    19 Bee.
     30ulim <a.sporto+bee@gmail.com>
     31Marijn Kruisselbrink
     32        File transfer support
  • doc/CHANGES

    rbfafb99 re31e5b8  
    33
    44http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on
     5
     6Version 3.2:
     7- By far the most important change, a thorough update to the Twitter
     8  module:
     9  * Now using Twitter API 1.1,
     10  * which means it's now using JSON instead of XML,
     11  * which means access to the streaming API (Twitter only, other Twitter
     12    API services don't seem to have it). No more 60-second polls, #twitter
     13    looks even more like real IRC now!
     14  * Also, the streaming API means nice things like receiving DMs.
     15  * show_ids, already enabled by default for a while, now uses hexa-
     16    decimal numbers, which means a 256-entry backlog instead of just 100.
     17  * Added a mode=strict setting which requires everything to be a command.
     18    The "post" command should then be used to post a Tweet.
     19- Jabber module bugfix that fixes connection issues with at least Google
     20  Talk but reportedly some other servers (OpenFire?) as well.
     21- SSL modules improved a little bit. GnuTLS module now supports SNI and
     22  session caching. Shouldn't change much, but hopefully reduces latency
     23  and bandwidth usage a little bit. 
     24- A bunch of other fixes/improvements here and there.
     25
     26Finished 6 Jan 2013
     27
     28Version 3.0.6:
     29- Updated MSN module to speak MSNP18:
     30  * Biggest change is that this brings MPOP support (you can sign in to
     31    one account from multiple locations).
     32  * Restored support for *sending* offline messages.
     33  * Some support for federated (i.e. Yahoo!) contacts. (Only messages
     34    might work, you won't see them online.)
     35- Twitter:
     36  * Work-around for stalls that are still happening sometimes.
     37  * Added "favourite" command.
     38  * "show_ids" enabled by default.
     39- Handle see-other-host Jabber messages which should fix support for
     40  MSN-XMPP.
     41- Misc. fixes and improvements.
     42
     43Finished 14 Oct 2012
    544
    645Version 3.0.5:
  • doc/bitlbee.8

    rbfafb99 re31e5b8  
    1313.\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    1414.\"
    15 .TH bitlbee 8 "07 March 2004"
     15.TH bitlbee 8 "19 May 2010"
    1616.SH NAME
    1717BitlBee \- IRC gateway to IM chat networks
     
    114114.PP
    115115 Wilmer van der Gaast <wilmer@gaast.net>
    116 .BR
    117  Jelmer Vernooij <jelmer@vernstok.nl>
    118 .BR
    119  Maurits Dijkstra <mauritsd@xs4all.nl>
  • doc/user-guide/commands.xml

    rbfafb99 re31e5b8  
    6969                       
    7070                        <bitlbee-command name="twitter">
    71                                 <syntax>account add twitter &lt;handle&gt; [&lt;password&gt;]</syntax>
     71                                <syntax>account add twitter &lt;handle&gt;</syntax>
    7272
    7373                                <description>
     
    9595                       
    9696                        <bitlbee-command name="identica">
    97                                 <syntax>account add identica &lt;handle&gt; [&lt;password&gt;]</syntax>
     97                                <syntax>account add identica &lt;handle&gt;</syntax>
    9898
    9999                                <description>
    100100                                        <para>
    101                                                 Same protocol as <emphasis>twitter</emphasis>, but defaults to a <emphasis>base_url</emphasis> pointing at identi.ca, and with OAuth disabled.
     101                                                Same protocol as <emphasis>twitter</emphasis>, but defaults to a <emphasis>base_url</emphasis> pointing at identi.ca. It also works with OAuth (so don't specify your password).
    102102                                        </para>
    103103                                </description>
     
    835835        <bitlbee-setting name="commands" type="boolean" scope="account">
    836836                <default>true</default>
     837                <possible-values>true, false, strict</possible-values>
    837838
    838839                <description>
     
    848849                                <varlistentry><term>follow &lt;screenname&gt;</term><listitem><para>Start following a person</para></listitem></varlistentry>
    849850                                <varlistentry><term>unfollow &lt;screenname&gt;</term><listitem><para>Stop following a person</para></listitem></varlistentry>
     851                                <varlistentry><term>favourite &lt;screenname|#id&gt;</term><listitem><para>Favo<emphasis>u</emphasis>rite the given user's most recent tweet, or the given tweet ID.</para></listitem></varlistentry>
    850852                                <varlistentry><term>post &lt;message&gt;</term><listitem><para>Post a tweet</para></listitem></varlistentry>
    851853                        </variablelist>
    852854
    853855                        <para>
    854                                 Anything that doesn't look like a command will be treated as a tweet. Watch out for typos! :-)
     856                                Anything that doesn't look like a command will be treated as a tweet. Watch out for typos, or to avoid this behaviour, you can set this setting to <emphasis>strict</emphasis>, which causes the <emphasis>post</emphasis> command to become mandatory for posting a tweet.
    855857                        </para>
    856858                </description>
     
    928930                       
    929931                        <para>
     932                                With a ! prefix an inverted channel can be created, for example with this setting set to <emphasis>!group</emphasis> you can create a channel with all users <emphasis>not</emphasis> in that group.
     933                        </para>
     934                       
     935                        <para>
    930936                                Note that, when creating a new channel, BitlBee will try to preconfigure the channel for you, based on the channel name. See <emphasis>help channels</emphasis>.
    931937                        </para>
     
    10221028
    10231029        </bitlbee-setting>
     1030
     1031        <bitlbee-setting name="stream" type="boolean" scope="account">
     1032                <default>true</default>
     1033
     1034                <description>
     1035                        <para>
     1036                                For Twitter accounts, this setting enables use of the Streaming API. This automatically gives you incoming DMs as well.
     1037                        </para>
     1038                       
     1039                        <para>
     1040                                For other Twitter-like services, this setting is not supported.
     1041                        </para>
     1042                </description>
     1043
     1044        </bitlbee-setting>
    10241045       
    10251046        <bitlbee-setting name="target_url_length" type="integer" scope="account">
     
    13371358
    13381359        <bitlbee-setting name="show_ids" type="boolean" scope="account">
    1339                 <default>false</default>
     1360                <default>true</default>
    13401361
    13411362                <description>
     
    15011522
    15021523        <bitlbee-setting name="tls" type="boolean" scope="account">
    1503                 <default>try</default>
    1504 
    1505                 <description>
    1506                         <para>
    1507                                 Newer Jabber servers allow clients to convert a plain-text session to a TLS/SSL-encrypted session. Normally (with this setting set to <emphasis>try</emphasis>) BitlBee will do this, if possible.
    1508                         </para>
    1509 
    1510                         <para>
    1511                                 If you want to force BitlBee to use TLS sessions only (and to give up if that doesn't seem to be possible) you can set this setting to <emphasis>true</emphasis>. Set it to <emphasis>false</emphasis> if you want the session to remain plain-text.
     1524                <default>true</default>
     1525
     1526                <description>
     1527                        <para>
     1528                                By default (with this setting enabled), BitlBee will require Jabber servers to offer encryption via StartTLS and refuse to connect if they don't.
     1529                        </para>
     1530
     1531                        <para>
     1532                                If you set this to "try", BitlBee will use StartTLS only if it's offered. With the setting disabled, StartTLS support will be ignored and avoided entirely.
    15121533                        </para>
    15131534                </description>
     
    17671788        <bitlbee-command name="group">
    17681789                <short-description>Contact group management</short-description>
    1769                 <syntax>group list</syntax>
    1770 
    1771                 <description>
    1772                         <para>
    1773                                 Only the <emphasis>group list</emphasis> command is supported at the moment, which shows a list of all groups defined so far.
     1790                <syntax>group [ list | info &lt;group&gt; ]</syntax>
     1791
     1792                <description>
     1793                        <para>
     1794                                The <emphasis>group list</emphasis> command shows a list of all groups defined so far.
     1795                        </para>
     1796                       
     1797                        <para>
     1798                                The <emphasis>group info</emphasis> command shows a list of all members of a the group &lt;group&gt;.
    17741799                        </para>
    17751800                       
  • doc/user-guide/help.xml

    rbfafb99 re31e5b8  
    2626
    2727<para>
    28 BitlBee is written by Wilmer van der Gaast together with Jelmer Vernooij, Maurits Dijkstra and others. Bugs can be reported at <ulink link="http://bugs.bitlbee.org/">http://bugs.bitlbee.org/</ulink>.
     28Some more help can be found on <ulink link="http://wiki.bitlbee.org/">http://wiki.bitlbee.org/</ulink>. Bugs can be reported at <ulink link="http://bugs.bitlbee.org/">http://bugs.bitlbee.org/</ulink>.
    2929</para>
    3030
  • doc/user-guide/misc.xml

    rbfafb99 re31e5b8  
    386386</sect1>
    387387
     388<sect1 id="whatsnew030200">
     389<title>New stuff in BitlBee 3.2</title>
     390
     391<para>
     392Upgradeed to Twitter API version 1.1. This is necessary because previous
     393versions will stop working from March 2013. At the same time, BitlBee now
     394supports the streaming API and incoming direct messages.
     395</para>
     396</sect1>
     397
    388398</chapter>
  • ipc.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
  • irc.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
  • irc.h

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2013 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    207207typedef enum
    208208{
    209         IRC_CC_TYPE_DEFAULT,
    210         IRC_CC_TYPE_REST,
    211         IRC_CC_TYPE_GROUP,
    212         IRC_CC_TYPE_ACCOUNT,
    213         IRC_CC_TYPE_PROTOCOL,
     209        IRC_CC_TYPE_DEFAULT  = 0x00001,
     210        IRC_CC_TYPE_REST     = 0x00002, /* Still not implemented. */
     211        IRC_CC_TYPE_GROUP    = 0x00004,
     212        IRC_CC_TYPE_ACCOUNT  = 0x00008,
     213        IRC_CC_TYPE_PROTOCOL = 0x00010,
     214        IRC_CC_TYPE_MASK     = 0x000ff,
     215        IRC_CC_TYPE_INVERT   = 0x00100,
    214216} irc_control_channel_type_t;
    215217
  • irc_channel.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2013 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    670670       
    671671        icc->account = acc;
    672         if( icc->type == IRC_CC_TYPE_ACCOUNT )
     672        if( ( icc->type & IRC_CC_TYPE_MASK ) == IRC_CC_TYPE_ACCOUNT )
    673673                bee_irc_channel_update( ic->irc, ic, NULL );
    674674       
     
    680680        struct irc_channel *ic = set->data;
    681681        struct irc_control_channel *icc = ic->data;
    682        
    683         if( strcmp( value, "all" ) == 0 )
    684                 icc->type = IRC_CC_TYPE_DEFAULT;
    685         else if( strcmp( value, "rest" ) == 0 )
    686                 icc->type = IRC_CC_TYPE_REST;
    687         else if( strcmp( value, "group" ) == 0 )
    688                 icc->type = IRC_CC_TYPE_GROUP;
    689         else if( strcmp( value, "account" ) == 0 )
    690                 icc->type = IRC_CC_TYPE_ACCOUNT;
    691         else if( strcmp( value, "protocol" ) == 0 )
    692                 icc->type = IRC_CC_TYPE_PROTOCOL;
     682        char *s;
     683       
     684        icc->type &= ~( IRC_CC_TYPE_MASK | IRC_CC_TYPE_INVERT );
     685       
     686        s = value;
     687        if( s[0] == '!' )
     688        {
     689                icc->type |= IRC_CC_TYPE_INVERT;
     690                s ++;
     691        }
     692       
     693        if( strcmp( s, "all" ) == 0 )
     694                icc->type |= IRC_CC_TYPE_DEFAULT;
     695        else if( strcmp( s, "rest" ) == 0 )
     696                icc->type |= IRC_CC_TYPE_REST;
     697        else if( strcmp( s, "group" ) == 0 )
     698                icc->type |= IRC_CC_TYPE_GROUP;
     699        else if( strcmp( s, "account" ) == 0 )
     700                icc->type |= IRC_CC_TYPE_ACCOUNT;
     701        else if( strcmp( s, "protocol" ) == 0 )
     702                icc->type |= IRC_CC_TYPE_PROTOCOL;
    693703        else
    694704                return SET_INVALID;
     
    704714       
    705715        icc->group = bee_group_by_name( ic->irc->b, value, TRUE );
    706         if( icc->type == IRC_CC_TYPE_GROUP )
     716        if( ( icc->type & IRC_CC_TYPE_MASK ) == IRC_CC_TYPE_GROUP )
    707717                bee_irc_channel_update( ic->irc, ic, NULL );
    708718       
     
    720730       
    721731        icc->protocol = prpl;
    722         if( icc->type == IRC_CC_TYPE_PROTOCOL )
     732        if( ( icc->type & IRC_CC_TYPE_MASK ) == IRC_CC_TYPE_PROTOCOL )
    723733                bee_irc_channel_update( ic->irc, ic, NULL );
    724734       
     
    776786{
    777787        struct irc_control_channel *icc = ic->data;
     788        gboolean ret = FALSE;
    778789       
    779790        if( iu->bu == NULL )
    780791                return FALSE;
    781792       
    782         switch( icc->type )
     793        switch( icc->type & IRC_CC_TYPE_MASK )
    783794        {
    784795        case IRC_CC_TYPE_GROUP:
    785                 return iu->bu->group == icc->group;
     796                ret = iu->bu->group == icc->group;
     797                break;
    786798        case IRC_CC_TYPE_ACCOUNT:
    787                 return iu->bu->ic->acc == icc->account;
     799                ret = iu->bu->ic->acc == icc->account;
     800                break;
    788801        case IRC_CC_TYPE_PROTOCOL:
    789                 return iu->bu->ic->acc->prpl == icc->protocol;
     802                ret = iu->bu->ic->acc->prpl == icc->protocol;
     803                break;
    790804        case IRC_CC_TYPE_DEFAULT:
    791805        default:
    792                 return TRUE;
    793         }
     806                ret = TRUE;
     807                break;
     808        }
     809       
     810        if( icc->type & IRC_CC_TYPE_INVERT )
     811                ret = !ret;
     812       
     813        return ret;
    794814}
    795815
  • irc_commands.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    382382static void irc_cmd_notice( irc_t *irc, char **cmd )
    383383{
     384        irc_user_t *iu;
     385       
    384386        if( !cmd[2] )
    385387        {
     
    392394        if( nick_cmp( cmd[1], irc->user->nick ) == 0 )
    393395                irc_send_msg( irc->user, "NOTICE", irc->user->nick, cmd[2], NULL );
     396        else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) )
     397                iu->f->privmsg( iu, cmd[2] );
    394398}
    395399
  • irc_im.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
  • irc_send.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
  • irc_user.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
  • lib/Makefile

    rbfafb99 re31e5b8  
    1313
    1414# [SH] Program variables
    15 objects = arc.o base64.o $(DES) $(EVENT_HANDLER) ftutil.o http_client.o ini.o md5.o misc.o oauth.o oauth2.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
     15objects = arc.o base64.o $(EVENT_HANDLER) ftutil.o http_client.o ini.o json.o json_util.o md5.o misc.o oauth.o oauth2.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o
    1616
    1717LFLAGS += -r
     
    4242$(objects): %.o: $(_SRCDIR_)%.c
    4343        @echo '*' Compiling $<
    44         @$(CC) -c $(CFLAGS) $< -o $@
     44        @$(CC) -c $(CFLAGS) $(CFLAGS_BITLBEE) $< -o $@
    4545
    4646-include .depend/*.d
  • lib/http_client.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2011 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    7373                printf( "About to send HTTP request:\n%s\n", req->request );
    7474       
    75         return( req );
     75        return req;
    7676}
    7777
     
    193193}
    194194
     195static gboolean http_handle_headers( struct http_request *req );
     196
    195197static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond )
    196198{
    197199        struct http_request *req = data;
    198         int evil_server = 0;
    199         char buffer[2048];
    200         char *end1, *end2;
     200        char buffer[4096];
     201        char *s;
     202        size_t content_length;
    201203        int st;
    202204       
     
    217219                                   packets that abort connections! \o/ */
    218220                               
    219                                 goto got_reply;
     221                                goto eof;
    220222                        }
    221223                }
    222224                else if( st == 0 )
    223225                {
    224                         goto got_reply;
     226                        goto eof;
    225227                }
    226228        }
     
    238240                else if( st == 0 )
    239241                {
    240                         goto got_reply;
    241                 }
    242         }
    243        
    244         if( st > 0 )
     242                        goto eof;
     243                }
     244        }
     245       
     246        if( st > 0 && !req->sbuf )
    245247        {
    246248                req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + st + 1 );
    247249                memcpy( req->reply_headers + req->bytes_read, buffer, st );
    248250                req->bytes_read += st;
    249         }
     251               
     252                st = 0;
     253        }
     254       
     255        if( st >= 0 && ( req->flags & HTTPC_STREAMING ) )
     256        {
     257                if( !req->reply_body &&
     258                    ( strstr( req->reply_headers, "\r\n\r\n" ) ||
     259                      strstr( req->reply_headers, "\n\n" ) ) )
     260                {
     261                        size_t hlen;
     262                       
     263                        /* We've now received all headers, so process them once
     264                           before we start feeding back data. */
     265                        if( !http_handle_headers( req ) )
     266                                return FALSE;
     267                       
     268                        hlen = req->reply_body - req->reply_headers;
     269                       
     270                        req->sblen = req->bytes_read - hlen;
     271                        req->sbuf = g_memdup( req->reply_body, req->sblen + 1 );
     272                        req->reply_headers = g_realloc( req->reply_headers, hlen + 1 );
     273                       
     274                        req->reply_body = req->sbuf;
     275                }
     276               
     277                if( st > 0 )
     278                {
     279                        int pos = req->reply_body - req->sbuf;
     280                        req->sbuf = g_realloc( req->sbuf, req->sblen + st + 1 );
     281                        memcpy( req->sbuf + req->sblen, buffer, st );
     282                        req->bytes_read += st;
     283                        req->sblen += st;
     284                        req->sbuf[req->sblen] = '\0';
     285                        req->reply_body = req->sbuf + pos;
     286                        req->body_size = req->sblen - pos;
     287                }
     288               
     289                if( req->reply_body )
     290                        req->func( req );
     291        }
     292       
     293        if( ssl_pending( req->ssl ) )
     294                return http_incoming_data( data, source, cond );
    250295       
    251296        /* There will be more! */
     
    254299                                 http_incoming_data, req );
    255300       
    256         if( ssl_pending( req->ssl ) )
    257                 return http_incoming_data( data, source, cond );
    258         else
    259                 return FALSE;
    260 
    261 got_reply:
     301        return FALSE;
     302
     303eof:
     304        req->flags |= HTTPC_EOF;
     305       
    262306        /* Maybe if the webserver is overloaded, or when there's bad SSL
    263307           support... */
     
    268312        }
    269313       
     314        if( !( req->flags & HTTPC_STREAMING ) )
     315        {
     316                /* Returns FALSE if we were redirected, in which case we should abort
     317                   and not run any callback yet. */
     318                if( !http_handle_headers( req ) )
     319                        return FALSE;
     320        }
     321
     322cleanup:
     323        if( req->ssl )
     324                ssl_disconnect( req->ssl );
     325        else
     326                closesocket( req->fd );
     327       
     328        if( ( s = get_rfc822_header( req->reply_headers, "Content-Length", 0 ) ) &&
     329            sscanf( s, "%zd", &content_length ) == 1 )
     330        {
     331                if( content_length < req->body_size )
     332                {
     333                        req->status_code = -1;
     334                        g_free( req->status_string );
     335                        req->status_string = g_strdup( "Response truncated" );
     336                }
     337        }
     338        g_free( s );
     339       
     340        if( getenv( "BITLBEE_DEBUG" ) && req )
     341                printf( "Finishing HTTP request with status: %s\n",
     342                        req->status_string ? req->status_string : "NULL" );
     343       
     344        req->func( req );
     345        http_free( req );
     346        return FALSE;
     347}
     348
     349/* Splits headers and body. Checks result code, in case of 300s it'll handle
     350   redirects. If this returns FALSE, don't call any callbacks! */
     351static gboolean http_handle_headers( struct http_request *req )
     352{
     353        char *end1, *end2;
     354        int evil_server = 0;
     355       
    270356        /* Zero termination is very convenient. */
    271         req->reply_headers[req->bytes_read] = 0;
     357        req->reply_headers[req->bytes_read] = '\0';
    272358       
    273359        /* Find the separation between headers and body, and keep stupid
     
    288374        {
    289375                req->status_string = g_strdup( "Malformed HTTP reply" );
    290                 goto cleanup;
     376                return TRUE;
    291377        }
    292378       
     
    305391        if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL )
    306392        {
    307                 if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 )
     393                if( sscanf( end1 + 1, "%hd", &req->status_code ) != 1 )
    308394                {
    309395                        req->status_string = g_strdup( "Can't parse status code" );
     
    348434                {
    349435                        req->status_string = g_strdup( "Can't locate Location: header" );
    350                         goto cleanup;
     436                        return TRUE;
    351437                }
    352438               
     
    368454                        req->status_string = g_strdup( "Can't handle recursive redirects" );
    369455                       
    370                         goto cleanup;
     456                        return TRUE;
    371457                }
    372458                else
     
    379465                        s = strstr( loc, "\r\n" );
    380466                        if( s == NULL )
    381                                 goto cleanup;
     467                                return TRUE;
    382468                       
    383469                        url = g_new0( url_t, 1 );
     
    388474                                req->status_string = g_strdup( "Malformed redirect URL" );
    389475                                g_free( url );
    390                                 goto cleanup;
     476                                return TRUE;
    391477                        }
    392478                       
     
    400486                                req->status_string = g_strdup( "Error while rebuilding request string" );
    401487                                g_free( url );
    402                                 goto cleanup;
     488                                return TRUE;
    403489                        }
    404490                       
     
    466552                        req->status_string = g_strdup( "Connection problem during redirect" );
    467553                        g_free( new_request );
    468                         goto cleanup;
     554                        return TRUE;
    469555                }
    470556               
     
    479565        }
    480566       
    481         /* Assume that a closed connection means we're finished, this indeed
    482            breaks with keep-alive connections and faulty connections. */
    483         req->finished = 1;
    484 
    485 cleanup:
     567        return TRUE;
     568}
     569
     570void http_flush_bytes( struct http_request *req, size_t len )
     571{
     572        if( len <= 0 || len > req->body_size || !( req->flags & HTTPC_STREAMING ) )
     573                return;
     574       
     575        req->reply_body += len;
     576        req->body_size -= len;
     577       
     578        if( req->reply_body - req->sbuf >= 512 )
     579        {
     580                char *new = g_memdup( req->reply_body, req->body_size + 1 );
     581                g_free( req->sbuf );
     582                req->reply_body = req->sbuf = new;
     583                req->sblen = req->body_size;
     584        }
     585}
     586
     587void http_close( struct http_request *req )
     588{
     589        if( !req )
     590                return;
     591       
     592        if( req->inpa > 0 )
     593                b_event_remove( req->inpa );
     594       
    486595        if( req->ssl )
    487596                ssl_disconnect( req->ssl );
     
    489598                closesocket( req->fd );
    490599       
    491         if( getenv( "BITLBEE_DEBUG" ) && req )
    492                 printf( "Finishing HTTP request with status: %s\n",
    493                         req->status_string ? req->status_string : "NULL" );
    494        
    495         req->func( req );
    496600        http_free( req );
    497         return FALSE;
    498601}
    499602
     
    503606        g_free( req->reply_headers );
    504607        g_free( req->status_string );
     608        g_free( req->sbuf );
    505609        g_free( req );
    506610}
    507 
  • lib/http_client.h

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2005 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2626/* http_client allows you to talk (asynchronously, again) to HTTP servers.
    2727   In the "background" it will send the whole query and wait for a complete
    28    response to come back. Right now it's only used by the MSN Passport
    29    authentication code, but it might be useful for other things too (for
    30    example the AIM usericon patch uses this so icons can be stored on
    31    webservers instead of the local filesystem).
     28   response to come back. Initially written for MS Passport authentication,
     29   but used for many other things now like OAuth and Twitter.
    3230   
    33    Didn't test this too much, but it seems to work well. Just don't look
    34    at the code that handles HTTP 30x redirects. ;-) The function is
    35    probably not very useful for downloading lots of data since it keeps
    36    everything in a memory buffer until the download is completed (and
    37    can't pass any data or whatever before then). It's very useful for
    38    doing quick requests without blocking the whole program, though. */
     31   It's very useful for doing quick requests without blocking the whole
     32   program. Unfortunately it doesn't support fancy stuff like HTTP keep-
     33   alives. */
    3934
    4035#include <glib.h>
     
    4237
    4338struct http_request;
     39
     40typedef enum http_client_flags
     41{
     42        HTTPC_STREAMING = 1,
     43        HTTPC_EOF = 2,
     44       
     45        /* Let's reserve 0x1000000+ for lib users. */
     46} http_client_flags_t;
    4447
    4548/* Your callback function should look like this: */
     
    5356        char *request;          /* The request to send to the server. */
    5457        int request_length;     /* Its size. */
    55         int status_code;        /* The numeric HTTP status code. (Or -1
     58        short status_code;      /* The numeric HTTP status code. (Or -1
    5659                                   if something really went wrong) */
    5760        char *status_string;    /* The error text. */
     
    5962        char *reply_body;
    6063        int body_size;          /* The number of bytes in reply_body. */
    61         int finished;           /* Set to non-0 if the request was completed
    62                                    successfully. */
    63         int redir_ttl;          /* You can set it to 0 if you don't want
     64        short redir_ttl;        /* You can set it to 0 if you don't want
    6465                                   http_client to follow them. */
     66       
     67        http_client_flags_t flags;
    6568       
    6669        http_input_function func;
     
    6871       
    6972        /* Please don't touch the things down here, you shouldn't need them. */
    70        
    7173        void *ssl;
    7274        int fd;
     
    7577        int bytes_written;
    7678        int bytes_read;
     79       
     80        /* Used in streaming mode. Caller should read from reply_body. */
     81        char *sbuf;
     82        size_t sblen;
    7783};
    7884
     
    8389struct http_request *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data );
    8490struct http_request *http_dorequest_url( char *url_string, http_input_function func, gpointer data );
     91
     92/* For streaming connections only; flushes len bytes at the start of the buffer. */
     93void http_flush_bytes( struct http_request *req, size_t len );
     94void http_close( struct http_request *req );
  • lib/misc.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2006 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    1111 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
    1212 *                          (and possibly other members of the Gaim team)
    13  * Copyright 2002-2006 Wilmer van der Gaast <wilmer@gaast.net>
     13 * Copyright 2002-2012 Wilmer van der Gaast <wilmer@gaast.net>
    1414 */
    1515
     
    730730}
    731731
    732 char *get_rfc822_header( char *text, char *header, int len )
     732char *get_rfc822_header( const char *text, const char *header, int len )
    733733{
    734734        int hlen = strlen( header ), i;
    735         char *ret;
     735        const char *ret;
    736736       
    737737        if( text == NULL )
  • lib/misc.h

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    6868G_MODULE_EXPORT int md5_verify_password( char *password, char *hash );
    6969G_MODULE_EXPORT char **split_command_parts( char *command );
    70 G_MODULE_EXPORT char *get_rfc822_header( char *text, char *header, int len );
     70G_MODULE_EXPORT char *get_rfc822_header( const char *text, const char *header, int len );
    7171
    7272#endif
  • lib/oauth2.c

    rbfafb99 re31e5b8  
    44*  Simple OAuth client (consumer) implementation.                           *
    55*                                                                           *
    6 *  Copyright 2010-2011 Wilmer van der Gaast <wilmer@gaast.net>              *
     6*  Copyright 2010-2012 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    2626#include "oauth2.h"
    2727#include "oauth.h"
     28#include "json.h"
    2829#include "url.h"
    2930
     
    4445};
    4546
    46 static char *oauth2_json_dumb_get( const char *json, const char *key );
    4747static void oauth2_access_token_done( struct http_request *req );
    4848
     
    103103        struct oauth2_access_token_data *cb_data = req->data;
    104104        char *atoken = NULL, *rtoken = NULL;
    105         const char *content_type;
     105        char *content_type;
    106106       
    107107        if( getenv( "BITLBEE_DEBUG" ) && req->reply_body )
     
    115115        else if( content_type && strstr( content_type, "application/json" ) )
    116116        {
    117                 atoken = oauth2_json_dumb_get( req->reply_body, "access_token" );
    118                 rtoken = oauth2_json_dumb_get( req->reply_body, "refresh_token" );
     117                json_value *js = json_parse( req->reply_body );
     118                if( js && js->type == json_object )
     119                {
     120                        int i;
     121                       
     122                        for( i = 0; i < js->u.object.length; i ++ )
     123                        {
     124                                if( js->u.object.values[i].value->type != json_string )
     125                                        continue;
     126                                if( strcmp( js->u.object.values[i].name, "access_token" ) == 0 )
     127                                        atoken = g_strdup( js->u.object.values[i].value->u.string.ptr );
     128                                if( strcmp( js->u.object.values[i].name, "refresh_token" ) == 0 )
     129                                        rtoken = g_strdup( js->u.object.values[i].value->u.string.ptr );
     130                        }
     131                }
     132                json_value_free( js );
    119133        }
    120134        else
     
    132146       
    133147        cb_data->func( cb_data->data, atoken, rtoken );
     148        g_free( content_type );
    134149        g_free( atoken );
    135150        g_free( rtoken );
    136151        g_free( cb_data );
    137152}
    138 
    139 /* Super dumb. I absolutely refuse to use/add a complete json parser library
    140    (adding a new dependency to BitlBee for the first time in.. 6 years?) just
    141    to parse 100 bytes of data. So I have to do my own parsing because OAuth2
    142    dropped support for XML. (GRRR!) This is very dumb and for example won't
    143    work for integer values, nor will it strip/handle backslashes. */
    144 static char *oauth2_json_dumb_get( const char *json, const char *key )
    145 {
    146         int is_key = 0; /* 1 == reading key, 0 == reading value */
    147         int found_key = 0;
    148                
    149         while( json && *json )
    150         {
    151                 /* Grab strings and see if they're what we're looking for. */
    152                 if( *json == '"' || *json == '\'' )
    153                 {
    154                         char q = *json;
    155                         const char *str_start;
    156                         json ++;
    157                         str_start = json;
    158                        
    159                         while( *json )
    160                         {
    161                                 /* \' and \" are not string terminators. */
    162                                 if( *json == '\\' && json[1] == q )
    163                                         json ++;
    164                                 /* But without a \ it is. */
    165                                 else if( *json == q )
    166                                         break;
    167                                 json ++;
    168                         }
    169                         if( *json == '\0' )
    170                                 return NULL;
    171                        
    172                         if( is_key && strncmp( str_start, key, strlen( key ) ) == 0 )
    173                         {
    174                                 found_key = 1;
    175                         }
    176                         else if( !is_key && found_key )
    177                         {
    178                                 char *ret = g_memdup( str_start, json - str_start + 1 );
    179                                 ret[json-str_start] = '\0';
    180                                 return ret;
    181                         }
    182                        
    183                 }
    184                 else if( *json == '{' || *json == ',' )
    185                 {
    186                         found_key = 0;
    187                         is_key = 1;
    188                 }
    189                 else if( *json == ':' )
    190                         is_key = 0;
    191                
    192                 json ++;
    193         }
    194        
    195         return NULL;
    196 }
  • lib/ssl_gnutls.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2011 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    3838
    3939static gboolean initialized = FALSE;
    40 gnutls_certificate_credentials xcred;
     40gnutls_certificate_credentials_t xcred;
    4141
    4242#include <limits.h>
     
    6060        gboolean verify;
    6161       
    62         gnutls_session session;
     62        gnutls_session_t session;
    6363};
     64
     65static GHashTable *session_cache;
    6466
    6567static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
     
    8587                gnutls_certificate_set_x509_trust_file( xcred, global.conf->cafile, GNUTLS_X509_FMT_PEM );
    8688               
    87                 /* Not needed in GnuTLS 2.11+ but we support older versions for now. */
    88                 gnutls_certificate_set_verify_flags( xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT );
     89                /* Not needed in GnuTLS 2.11+ (enabled by default there) so
     90                   don't do it (resets possible other defaults). */
     91                if( !gnutls_check_version( "2.11" ) )
     92                        gnutls_certificate_set_verify_flags( xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT );
    8993        }
    9094        initialized = TRUE;
     
    9599        */
    96100       
     101        session_cache = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free );
     102       
    97103        atexit( ssl_deinit );
    98104}
     
    102108        gnutls_global_deinit();
    103109        gnutls_certificate_free_credentials( xcred );
     110        g_hash_table_destroy( session_cache );
     111        session_cache = NULL;
    104112}
    105113
     
    108116        struct scd *conn = g_new0( struct scd, 1 );
    109117       
    110         conn->fd = proxy_connect( host, port, ssl_connected, conn );
    111118        conn->func = func;
    112119        conn->data = data;
     
    114121        conn->hostname = g_strdup( host );
    115122        conn->verify = verify && global.conf->cafile;
     123        conn->fd = proxy_connect( host, port, ssl_connected, conn );
    116124       
    117125        if( conn->fd < 0 )
     
    132140        conn->data = data;
    133141        conn->inpa = -1;
    134         conn->hostname = hostname;
     142        conn->hostname = g_strdup( hostname );
    135143       
    136144        /* For now, SSL verification is globally enabled by setting the cafile
     
    169177        int verifyret = 0;
    170178        gnutls_x509_crt_t cert;
    171         const char *hostname;
    172        
    173         hostname = gnutls_session_get_ptr( session );
     179        struct scd *conn;
     180       
     181        conn = gnutls_session_get_ptr( session );
    174182
    175183        gnutlsret = gnutls_certificate_verify_peers2( session, &status );
     
    209217                return VERIFY_CERT_ERROR;
    210218
    211         if( !gnutls_x509_crt_check_hostname( cert, hostname ) )
     219        if( !gnutls_x509_crt_check_hostname( cert, conn->hostname ) )
    212220        {
    213221                verifyret |= VERIFY_CERT_INVALID;
     
    218226
    219227        return verifyret;
     228}
     229
     230struct ssl_session
     231{
     232        size_t size;
     233        char data[];
     234};
     235
     236static void ssl_cache_add( struct scd *conn )
     237{
     238        size_t data_size;
     239        struct ssl_session *data;
     240        char *hostname;
     241       
     242        if( !conn->hostname ||
     243            gnutls_session_get_data( conn->session, NULL, &data_size ) != 0 )
     244                return;
     245       
     246        data = g_malloc( sizeof( struct ssl_session ) + data_size );
     247        if( gnutls_session_get_data( conn->session, data->data, &data->size ) != 0 )
     248        {
     249                g_free( data );
     250                return;
     251        }
     252       
     253        hostname = g_strdup( conn->hostname );
     254        g_hash_table_insert( session_cache, hostname, data );
     255}
     256
     257static void ssl_cache_resume( struct scd *conn )
     258{
     259        struct ssl_session *data;
     260       
     261        if( conn->hostname &&
     262            ( data = g_hash_table_lookup( session_cache, conn->hostname ) ) )
     263        {
     264                gnutls_session_set_data( conn->session, data->data, data->size );
     265                g_hash_table_remove( session_cache, conn->hostname );
     266        }
    220267}
    221268
     
    265312       
    266313        gnutls_init( &conn->session, GNUTLS_CLIENT );
    267         if( conn->verify )
    268                 gnutls_session_set_ptr( conn->session, (void *) conn->hostname );
     314        gnutls_session_set_ptr( conn->session, (void *) conn );
    269315#if GNUTLS_VERSION_NUMBER < 0x020c00
    270316        gnutls_transport_set_lowat( conn->session, 0 );
     
    272318        gnutls_set_default_priority( conn->session );
    273319        gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, xcred );
     320        if( conn->hostname && !isdigit( conn->hostname[0] ) )
     321                gnutls_server_name_set( conn->session, GNUTLS_NAME_DNS,
     322                                        conn->hostname, strlen( conn->hostname ) );
    274323       
    275324        sock_make_nonblocking( conn->fd );
    276         gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr) GNUTLS_STUPID_CAST conn->fd );
     325        gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr_t) GNUTLS_STUPID_CAST conn->fd );
     326       
     327        ssl_cache_resume( conn );
    277328       
    278329        return ssl_handshake( data, source, cond );
     
    316367                        /* For now we can't handle non-blocking perfectly everywhere... */
    317368                        sock_make_blocking( conn->fd );
    318                
     369                       
     370                        ssl_cache_add( conn );
    319371                        conn->established = TRUE;
    320372                        conn->func( conn->data, 0, conn, cond );
     
    400452        if( conn->session )
    401453                gnutls_deinit( conn->session );
     454        g_free( conn->hostname );
    402455        g_free( conn );
    403456}
  • lib/ssl_nss.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2005 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    4040#include <secerr.h>
    4141#include <sslerr.h>
     42#include <assert.h>
     43#include <unistd.h>
    4244
    4345int ssl_errno = 0;
     
    4547static gboolean initialized = FALSE;
    4648
    47 struct scd
    48 {
     49#define SSLDEBUG 0
     50
     51struct scd {
    4952        ssl_input_function func;
    5053        gpointer data;
    5154        int fd;
     55        char *hostname;
    5256        PRFileDesc *prfd;
    5357        gboolean established;
     
    5559};
    5660
    57 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
    58 static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond );
    59 
    60 
    61 static SECStatus nss_auth_cert (void *arg, PRFileDesc *socket, PRBool checksig, PRBool isserver)
     61static gboolean ssl_connected(gpointer data, gint source,
     62                              b_input_condition cond);
     63static gboolean ssl_starttls_real(gpointer data, gint source,
     64                                  b_input_condition cond);
     65
     66static SECStatus nss_auth_cert(void *arg, PRFileDesc * socket, PRBool checksig,
     67                               PRBool isserver)
    6268{
    6369        return SECSuccess;
    6470}
    6571
    66 static SECStatus nss_bad_cert (void *arg, PRFileDesc *socket)
     72static SECStatus nss_bad_cert(void *arg, PRFileDesc * socket)
    6773{
    6874        PRErrorCode err;
    6975
    70         if(!arg) return SECFailure;
    71 
    72         *(PRErrorCode *)arg = err = PORT_GetError();
    73 
    74         switch(err) {
     76        if (!arg)
     77                return SECFailure;
     78
     79        *(PRErrorCode *) arg = err = PORT_GetError();
     80
     81        switch (err) {
    7582        case SEC_ERROR_INVALID_AVA:
    7683        case SEC_ERROR_INVALID_TIME:
     
    94101}
    95102
    96 
    97 void ssl_init( void )
    98 {
    99         PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
     103void ssl_init(void)
     104{
     105        PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
     106        // https://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslfnc.html#1234224
     107        // This NSS function is not intended for use with SSL, which
     108        // requires that the certificate and key database files be
     109        // opened. Relates to whole non-verification of servers for now.
    100110        NSS_NoDB_Init(NULL);
    101111        NSS_SetDomesticPolicy();
     
    103113}
    104114
    105 void *ssl_connect( char *host, int port, gboolean verify, ssl_input_function func, gpointer data )
    106 {
    107         struct scd *conn = g_new0( struct scd, 1 );
    108        
    109         conn->fd = proxy_connect( host, port, ssl_connected, conn );
     115void *ssl_connect(char *host, int port, gboolean verify,
     116                  ssl_input_function func, gpointer data)
     117{
     118        struct scd *conn = g_new0(struct scd, 1);
     119
     120        conn->fd = proxy_connect(host, port, ssl_connected, conn);
    110121        conn->func = func;
    111122        conn->data = data;
    112        
    113         if( conn->fd < 0 )
    114         {
    115                 g_free( conn );
    116                 return( NULL );
    117         }
    118        
    119         if( !initialized )
    120         {
     123        conn->hostname = g_strdup(host);
     124
     125        if (conn->fd < 0) {
     126                g_free(conn->hostname);
     127                g_free(conn);
     128                return (NULL);
     129        }
     130
     131        if (!initialized) {
    121132                ssl_init();
    122133        }
    123134
    124        
    125         return( conn );
    126 }
    127 
    128 static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond )
     135        return (conn);
     136}
     137
     138static gboolean ssl_starttls_real(gpointer data, gint source,
     139                                  b_input_condition cond)
    129140{
    130141        struct scd *conn = data;
    131142
    132         return ssl_connected( conn, conn->fd, B_EV_IO_WRITE );
    133 }
    134 
    135 void *ssl_starttls( int fd, char *hostname, gboolean verify, ssl_input_function func, gpointer data )
    136 {
    137         struct scd *conn = g_new0( struct scd, 1 );
     143        return ssl_connected(conn, conn->fd, B_EV_IO_WRITE);
     144}
     145
     146void *ssl_starttls(int fd, char *hostname, gboolean verify,
     147                   ssl_input_function func, gpointer data)
     148{
     149        struct scd *conn = g_new0(struct scd, 1);
    138150
    139151        conn->fd = fd;
    140152        conn->func = func;
    141153        conn->data = data;
     154        conn->hostname = hostname;
     155
     156        /* For now, SSL verification is globally enabled by setting the cafile
     157           setting in bitlbee.conf. Commented out by default because probably
     158           not everyone has this file in the same place and plenty of folks
     159           may not have the cert of their private Jabber server in it. */
    142160        conn->verify = verify && global.conf->cafile;
    143161
     
    151169           simpler. */
    152170
    153         b_timeout_add( 1, ssl_starttls_real, conn );
     171        b_timeout_add(1, ssl_starttls_real, conn);
    154172
    155173        return conn;
    156174}
    157175
    158 static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
     176static gboolean ssl_connected(gpointer data, gint source,
     177                              b_input_condition cond)
    159178{
    160179        struct scd *conn = data;
    161        
     180
    162181        /* Right now we don't have any verification functionality for NSS. */
    163182
    164         if( conn->verify )
    165         {
    166                 conn->func( conn->data, 1, NULL, cond );
    167                 if( source >= 0 ) closesocket( source );
    168                 g_free( conn );
     183        if (conn->verify) {
     184                conn->func(conn->data, 1, NULL, cond);
     185                if (source >= 0)
     186                        closesocket(source);
     187                g_free(conn->hostname);
     188                g_free(conn);
    169189
    170190                return FALSE;
    171191        }
    172        
    173         if( source == -1 )
     192
     193        if (source == -1)
    174194                goto ssl_connected_failure;
    175        
     195
    176196        /* Until we find out how to handle non-blocking I/O with NSS... */
    177         sock_make_blocking( conn->fd );
    178        
     197        sock_make_blocking(conn->fd);
     198
    179199        conn->prfd = SSL_ImportFD(NULL, PR_ImportTCPSocket(source));
     200        if (!conn->prfd)
     201                goto ssl_connected_failure;
    180202        SSL_OptionSet(conn->prfd, SSL_SECURITY, PR_TRUE);
    181203        SSL_OptionSet(conn->prfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
    182         SSL_BadCertHook(conn->prfd, (SSLBadCertHandler)nss_bad_cert, NULL);
    183         SSL_AuthCertificateHook(conn->prfd, (SSLAuthCertificate)nss_auth_cert, (void *)CERT_GetDefaultCertDB());
     204        SSL_BadCertHook(conn->prfd, (SSLBadCertHandler) nss_bad_cert, NULL);
     205        SSL_AuthCertificateHook(conn->prfd, (SSLAuthCertificate) nss_auth_cert,
     206                                (void *)CERT_GetDefaultCertDB());
     207        SSL_SetURL(conn->prfd, conn->hostname);
    184208        SSL_ResetHandshake(conn->prfd, PR_FALSE);
    185209
     
    187211                goto ssl_connected_failure;
    188212        }
    189        
    190        
     213
    191214        conn->established = TRUE;
    192         conn->func( conn->data, 0, conn, cond );
     215        conn->func(conn->data, 0, conn, cond);
    193216        return FALSE;
    194        
    195         ssl_connected_failure:
    196        
    197         conn->func( conn->data, 0, NULL, cond );
    198        
    199         PR_Close( conn -> prfd );
    200         if( source >= 0 ) closesocket( source );
    201         g_free( conn );
    202        
     217
     218 ssl_connected_failure:
     219
     220        conn->func(conn->data, 0, NULL, cond);
     221
     222        if (conn->prfd)
     223                PR_Close(conn->prfd);
     224        if (source >= 0)
     225                closesocket(source);
     226        g_free(conn->hostname);
     227        g_free(conn);
     228
    203229        return FALSE;
    204230}
    205231
    206 int ssl_read( void *conn, char *buf, int len )
    207 {
    208         if( !((struct scd*)conn)->established )
    209                 return( 0 );
    210        
    211         return( PR_Read( ((struct scd*)conn)->prfd, buf, len ) );
    212 }
    213 
    214 int ssl_write( void *conn, const char *buf, int len )
    215 {
    216         if( !((struct scd*)conn)->established )
    217                 return( 0 );
    218        
    219         return( PR_Write ( ((struct scd*)conn)->prfd, buf, len ) );
    220 }
    221 
    222 int ssl_pending( void *conn )
    223 {
    224         struct scd *c = (struct scd *) conn;
    225 
    226         if( c == NULL ) {
     232int ssl_read(void *conn, char *buf, int len)
     233{
     234        int st;
     235        PRErrorCode PR_err;
     236
     237        if (!((struct scd *)conn)->established) {
     238                ssl_errno = SSL_NOHANDSHAKE;
     239                return -1;
     240        }
     241
     242        st = PR_Read(((struct scd *)conn)->prfd, buf, len);
     243        PR_err = PR_GetError();
     244
     245        ssl_errno = SSL_OK;
     246        if (PR_err == PR_WOULD_BLOCK_ERROR)
     247                ssl_errno = SSL_AGAIN;
     248
     249        if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0)
     250                len = write(STDERR_FILENO, buf, st);
     251
     252        return st;
     253}
     254
     255int ssl_write(void *conn, const char *buf, int len)
     256{
     257        int st;
     258        PRErrorCode PR_err;
     259
     260        if (!((struct scd *)conn)->established) {
     261                ssl_errno = SSL_NOHANDSHAKE;
     262                return -1;
     263        }
     264        st = PR_Write(((struct scd *)conn)->prfd, buf, len);
     265        PR_err = PR_GetError();
     266
     267        ssl_errno = SSL_OK;
     268        if (PR_err == PR_WOULD_BLOCK_ERROR)
     269                ssl_errno = SSL_AGAIN;
     270
     271        if (SSLDEBUG && getenv("BITLBEE_DEBUG") && st > 0)
     272                len = write(2, buf, st);
     273
     274        return st;
     275}
     276
     277int ssl_pending(void *conn)
     278{
     279        struct scd *c = (struct scd *)conn;
     280
     281        if (c == NULL) {
    227282                return 0;
    228283        }
    229284
    230         return ( c->established && SSL_DataPending( c->prfd ) > 0 );
    231 }
    232 
    233 void ssl_disconnect( void *conn_ )
     285        return (c->established && SSL_DataPending(c->prfd) > 0);
     286}
     287
     288void ssl_disconnect(void *conn_)
    234289{
    235290        struct scd *conn = conn_;
    236        
    237         PR_Close( conn->prfd );
    238         closesocket( conn->fd );
    239        
    240         g_free( conn );
    241 }
    242 
    243 int ssl_getfd( void *conn )
    244 {
    245         return( ((struct scd*)conn)->fd );
    246 }
    247 
    248 b_input_condition ssl_getdirection( void *conn )
     291
     292        // When we swich to NSS_Init, we should have here
     293        // NSS_Shutdown();
     294
     295        if (conn->prfd)
     296                PR_Close(conn->prfd);
     297
     298        g_free(conn->hostname);
     299        g_free(conn);
     300}
     301
     302int ssl_getfd(void *conn)
     303{
     304        return (((struct scd *)conn)->fd);
     305}
     306
     307b_input_condition ssl_getdirection(void *conn)
    249308{
    250309        /* Just in case someone calls us, let's return the most likely case: */
     
    252311}
    253312
    254 char *ssl_verify_strerror( int code )
    255 {
    256         return g_strdup( "SSL certificate verification not supported by BitlBee NSS code." );
    257 }
     313char *ssl_verify_strerror(int code)
     314{
     315        return
     316            g_strdup
     317            ("SSL certificate verification not supported by BitlBee NSS code.");
     318}
     319
     320size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len,
     321                        const unsigned char *input, size_t input_len,
     322                        const unsigned char *iv, unsigned char **res)
     323{
     324#define CIPHER_MECH CKM_DES3_CBC
     325#define MAX_OUTPUT_LEN 72
     326
     327        int len1;
     328        unsigned int len2;
     329
     330        PK11Context *ctx = NULL;
     331        PK11SlotInfo *slot = NULL;
     332        SECItem keyItem;
     333        SECItem ivItem;
     334        SECItem *secParam = NULL;
     335        PK11SymKey *symKey = NULL;
     336
     337        size_t rc;
     338        SECStatus rv;
     339
     340        if (!initialized) {
     341                ssl_init();
     342        }
     343
     344        keyItem.data = (unsigned char *)key;
     345        keyItem.len = key_len;
     346
     347        slot = PK11_GetBestSlot(CIPHER_MECH, NULL);
     348        if (slot == NULL) {
     349                fprintf(stderr, "PK11_GetBestSlot failed (err %d)\n",
     350                        PR_GetError());
     351                rc = 0;
     352                goto out;
     353        }
     354
     355        symKey =
     356            PK11_ImportSymKey(slot, CIPHER_MECH, PK11_OriginUnwrap, CKA_ENCRYPT,
     357                              &keyItem, NULL);
     358        if (symKey == NULL) {
     359                fprintf(stderr, "PK11_ImportSymKey failed (err %d)\n",
     360                        PR_GetError());
     361                rc = 0;
     362                goto out;
     363        }
     364
     365        ivItem.data = (unsigned char *)iv;
     366        /* See msn_soap_passport_sso_handle_response in protocols/msn/soap.c */
     367        ivItem.len = 8;
     368
     369        secParam = PK11_ParamFromIV(CIPHER_MECH, &ivItem);
     370        if (secParam == NULL) {
     371                fprintf(stderr, "PK11_ParamFromIV failed (err %d)\n",
     372                        PR_GetError());
     373                rc = 0;
     374                goto out;
     375        }
     376
     377        ctx =
     378            PK11_CreateContextBySymKey(CIPHER_MECH, CKA_ENCRYPT, symKey,
     379                                       secParam);
     380        if (ctx == NULL) {
     381                fprintf(stderr, "PK11_CreateContextBySymKey failed (err %d)\n",
     382                        PR_GetError());
     383                rc = 0;
     384                goto out;
     385        }
     386
     387        *res = g_new0(unsigned char, MAX_OUTPUT_LEN);
     388
     389        rv = PK11_CipherOp(ctx, *res, &len1, MAX_OUTPUT_LEN,
     390                           (unsigned char *)input, input_len);
     391        if (rv != SECSuccess) {
     392                fprintf(stderr, "PK11_CipherOp failed (err %d)\n",
     393                        PR_GetError());
     394                rc = 0;
     395                goto out;
     396        }
     397
     398        assert(len1 <= MAX_OUTPUT_LEN);
     399
     400        rv = PK11_DigestFinal(ctx, *res + len1, &len2,
     401                              (unsigned int)MAX_OUTPUT_LEN - len1);
     402        if (rv != SECSuccess) {
     403                fprintf(stderr, "PK11_DigestFinal failed (err %d)\n",
     404                        PR_GetError());
     405                rc = 0;
     406                goto out;
     407        }
     408
     409        rc = len1 + len2;
     410
     411 out:
     412        if (ctx)
     413                PK11_DestroyContext(ctx, PR_TRUE);
     414        if (symKey)
     415                PK11_FreeSymKey(symKey);
     416        if (secParam)
     417                SECITEM_FreeItem(secParam, PR_TRUE);
     418        if (slot)
     419                PK11_FreeSlot(slot);
     420
     421        return rc;
     422}
  • lib/ssl_openssl.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    4747        gboolean established;
    4848        gboolean verify;
     49        char *hostname;
    4950       
    5051        int inpa;
    5152        int lasterr;            /* Necessary for SSL_get_error */
    5253        SSL *ssl;
    53         SSL_CTX *ssl_ctx;
    5454};
    5555
     56static SSL_CTX *ssl_ctx;
     57
     58static void ssl_conn_free( struct scd *conn );
    5659static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
    5760static gboolean ssl_starttls_real( gpointer data, gint source, b_input_condition cond );
     
    6164void ssl_init( void )
    6265{
     66        const SSL_METHOD *meth;
     67       
     68        SSL_library_init();
     69       
     70        meth = TLSv1_client_method();
     71        ssl_ctx = SSL_CTX_new( meth );
     72       
    6373        initialized = TRUE;
    64         SSL_library_init();
    65         // SSLeay_add_ssl_algorithms();
    6674}
    6775
     
    7381        if( conn->fd < 0 )
    7482        {
    75                 g_free( conn );
     83                ssl_conn_free( conn );
    7684                return NULL;
    7785        }
     
    8088        conn->data = data;
    8189        conn->inpa = -1;
     90        conn->hostname = g_strdup( host );
    8291       
    8392        return conn;
     
    93102        conn->inpa = -1;
    94103        conn->verify = verify && global.conf->cafile;
     104        conn->hostname = g_strdup( hostname );
    95105       
    96106        /* This function should be called via a (short) timeout instead of
     
    118128{
    119129        struct scd *conn = data;
    120         const SSL_METHOD *meth;
    121        
    122         /* Right now we don't have any verification functionality for OpenSSL. */
    123 
     130       
    124131        if( conn->verify )
    125132        {
     133                /* Right now we don't have any verification functionality for OpenSSL. */
    126134                conn->func( conn->data, 1, NULL, cond );
    127135                if( source >= 0 ) closesocket( source );
    128                 g_free( conn );
     136                ssl_conn_free( conn );
    129137
    130138                return FALSE;
     
    139147        }
    140148       
    141         meth = TLSv1_client_method();
    142         conn->ssl_ctx = SSL_CTX_new( meth );
    143         if( conn->ssl_ctx == NULL )
     149       
     150        if( ssl_ctx == NULL )
    144151                goto ssl_connected_failure;
    145152       
    146         conn->ssl = SSL_new( conn->ssl_ctx );
     153        conn->ssl = SSL_new( ssl_ctx );
    147154        if( conn->ssl == NULL )
    148155                goto ssl_connected_failure;
     
    152159        SSL_set_fd( conn->ssl, conn->fd );
    153160       
     161        if( conn->hostname && !isdigit( conn->hostname[0] ) )
     162                SSL_set_tlsext_host_name( conn->ssl, conn->hostname );
     163       
    154164        return ssl_handshake( data, source, cond );
    155165
    156166ssl_connected_failure:
    157167        conn->func( conn->data, 0, NULL, cond );
    158        
    159         if( conn->ssl )
    160         {
    161                 SSL_shutdown( conn->ssl );
    162                 SSL_free( conn->ssl );
    163         }
    164         if( conn->ssl_ctx )
    165         {
    166                 SSL_CTX_free( conn->ssl_ctx );
    167         }
    168         if( source >= 0 ) closesocket( source );
    169         g_free( conn );
    170        
     168        ssl_disconnect( conn );
    171169        return FALSE;
    172170
     
    184182                {
    185183                        conn->func( conn->data, 0, NULL, cond );
    186                        
    187                         SSL_shutdown( conn->ssl );
    188                         SSL_free( conn->ssl );
    189                         SSL_CTX_free( conn->ssl_ctx );
    190                        
    191                         if( source >= 0 ) closesocket( source );
    192                         g_free( conn );
    193                        
     184                        ssl_disconnect( conn );
    194185                        return FALSE;
    195186                }
     
    261252}
    262253
     254static void ssl_conn_free( struct scd *conn )
     255{
     256        SSL_free( conn->ssl );
     257        g_free( conn->hostname );
     258        g_free( conn );
     259       
     260}
     261
    263262void ssl_disconnect( void *conn_ )
    264263{
     
    273272        closesocket( conn->fd );
    274273       
    275         SSL_free( conn->ssl );
    276         SSL_CTX_free( conn->ssl_ctx );
    277         g_free( conn );
     274        ssl_conn_free( conn );
    278275}
    279276
  • lib/xmltree.c

    rbfafb99 re31e5b8  
    44*  Simple XML (stream) parse tree handling code (Jabber/XMPP, mainly)       *
    55*                                                                           *
    6 *  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2006-2012 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This library is free software; you can redistribute it and/or            *
     
    163163        int i;
    164164       
    165         /* Just in case someone likes infinite loops... */
    166165        if( xt->root == NULL )
    167                 return 0;
     166                return 1;
    168167       
    169168        if( node == NULL )
     
    263262}
    264263
    265 struct xt_node *xt_from_string( const char *in )
     264struct xt_node *xt_from_string( const char *in, int len )
    266265{
    267266        struct xt_parser *parser;
    268         struct xt_node *ret;
     267        struct xt_node *ret = NULL;
     268       
     269        if( len == 0 )
     270                len = strlen( in );
    269271       
    270272        parser = xt_new( NULL, NULL );
    271         xt_feed( parser, in, strlen( in ) );
    272         ret = parser->root;
    273         parser->root = NULL;
     273        xt_feed( parser, in, len );
     274        if( parser->cur == NULL )
     275        {
     276                ret = parser->root;
     277                parser->root = NULL;
     278        }
    274279        xt_free( parser );
    275280       
  • lib/xmltree.h

    rbfafb99 re31e5b8  
    44*  Simple XML (stream) parse tree handling code (Jabber/XMPP, mainly)       *
    55*                                                                           *
    6 *  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2006-2012 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This library is free software; you can redistribute it and/or            *
     
    8282int xt_handle( struct xt_parser *xt, struct xt_node *node, int depth );
    8383void xt_cleanup( struct xt_parser *xt, struct xt_node *node, int depth );
    84 struct xt_node *xt_from_string( const char *in );
     84struct xt_node *xt_from_string( const char *in, int text_len );
    8585char *xt_to_string( struct xt_node *node );
    8686char *xt_to_string_i( struct xt_node *node );
  • motd.txt

    rbfafb99 re31e5b8  
    1414The developers of the Bee hope you have a buzzing time.
    1515
    16 * BitlBee development team: wilmer, jelmer, Maurits
     16* BitlBee development team.
    1717 
    1818... Buzzing, haha, get it?
  • nick.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    134134                                chop = fmt[1];
    135135                                if( chop == '\0' )
     136                                {
     137                                        g_string_free( ret, TRUE );
    136138                                        return NULL;
     139                                }
    137140                                fmt += 2;
    138141                        }
     
    187190                        else
    188191                        {
     192                                g_string_free( ret, TRUE );
    189193                                return NULL;
    190194                        }
  • otr.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    237237        s = set_add( &irc->b->set, "otr_color_encrypted", "true", set_eval_bool, irc );
    238238       
    239         s = set_add( &irc->b->set, "otr_policy", "oppurtunistic", set_eval_list, irc );
     239        s = set_add( &irc->b->set, "otr_policy", "opportunistic", set_eval_list, irc );
    240240        l = g_slist_prepend( NULL, "never" );
    241241        l = g_slist_prepend( l, "opportunistic" );
  • protocols/Makefile

    rbfafb99 re31e5b8  
    5555$(objects): %.o: $(_SRCDIR_)%.c
    5656        @echo '*' Compiling $<
    57         @$(CC) -c $(CFLAGS) $< -o $@
     57        @$(CC) -c $(CFLAGS) $(CFLAGS_BITLBEE) $< -o $@
    5858
    5959-include .depend/*.d
  • protocols/account.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2013 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    154154        else if( strcmp( set->key, "password" ) == 0 )
    155155        {
    156                 if( value )
    157                 {
    158                         g_free( acc->pass );
    159                         acc->pass = g_strdup( value );
    160                         return NULL;    /* password shouldn't be visible in plaintext! */
    161                 }
    162                 else
    163                 {
    164                         /* NULL can (should) be stored in the set_t
    165                            variable, but is otherwise not correct. */
    166                         return SET_INVALID;
    167                 }
     156                /* set -del should be allowed now, but I don't want to have any
     157                   NULL pointers to have to deal with. */
     158                if( !value )
     159                        value = "";
     160               
     161                g_free( acc->pass );
     162                acc->pass = g_strdup( value );
     163                return NULL;    /* password shouldn't be visible in plaintext! */
    168164        }
    169165        else if( strcmp( set->key, "tag" ) == 0 )
     
    354350        a->prpl->login( a );
    355351       
    356         if( a->ic && !( a->ic->flags & OPT_SLOW_LOGIN ) )
     352        if( a->ic && !( a->ic->flags & ( OPT_SLOW_LOGIN | OPT_LOGGED_IN ) ) )
    357353                a->ic->keepalive = b_timeout_add( 120000, account_on_timeout, a->ic );
    358354}
     
    373369        struct im_connection *ic = d;
    374370       
    375         imcb_error( ic, "Connection timeout" );
    376         imc_logout( ic, TRUE );
     371        if( !( ic->flags & ( OPT_SLOW_LOGIN | OPT_LOGGED_IN ) ) )
     372        {
     373                imcb_error( ic, "Connection timeout" );
     374                imc_logout( ic, TRUE );
     375        }
    377376       
    378377        return FALSE;
  • protocols/account.h

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2013 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    6969        ACC_FLAG_AWAY_MESSAGE = 0x01,   /* Supports away messages instead of just states. */
    7070        ACC_FLAG_STATUS_MESSAGE = 0x02, /* Supports status messages (without being away). */
     71        ACC_FLAG_HANDLE_DOMAINS = 0x04, /* Contact handles need a domain portion. */
    7172} account_flag_t;
    7273
  • protocols/jabber/Makefile

    rbfafb99 re31e5b8  
    3838$(objects): %.o: $(_SRCDIR_)%.c
    3939        @echo '*' Compiling $<
    40         @$(CC) -c $(CFLAGS) $< -o $@
     40        @$(CC) -c $(CFLAGS) $(CFLAGS_BITLBEE) $< -o $@
    4141
    4242jabber_mod.o: $(objects)
  • protocols/jabber/conference.c

    rbfafb99 re31e5b8  
    44*  Jabber module - Conference rooms                                         *
    55*                                                                           *
    6 *  Copyright 2007 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2007-2012 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
  • protocols/jabber/io.c

    rbfafb99 re31e5b8  
    44*  Jabber module - I/O stuff (plain, SSL), queues, etc                      *
    55*                                                                           *
    6 *  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2006-2012 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    453453{
    454454        struct im_connection *ic = data;
     455        struct jabber_data *jd = ic->proto_data;
    455456        int allow_reconnect = TRUE;
    456457        struct jabber_error *err;
     458        struct xt_node *host;
     459       
     460        if( !( ic->flags & OPT_LOGGED_IN ) &&
     461            ( host = xt_find_node( node->children, "see-other-host" ) ) &&
     462            host->text )
     463        {
     464                char *s;
     465                int port = set_getint( &ic->acc->set, "port" );
     466               
     467                /* Let's try to obey this request, if we're not logged
     468                   in yet (i.e. not have too much state yet). */
     469                if( jd->ssl )
     470                        ssl_disconnect( jd->ssl );
     471                closesocket( jd->fd );
     472                b_event_remove( jd->r_inpa );
     473                b_event_remove( jd->w_inpa );
     474               
     475                jd->ssl = NULL;
     476                jd->r_inpa = jd->w_inpa = 0;
     477                jd->flags &= JFLAG_XMLCONSOLE;
     478               
     479                s = strchr( host->text, ':' );
     480                if( s != NULL )
     481                        sscanf( s + 1, "%d", &port );
     482               
     483                imcb_log( ic, "Redirected to %s", host->text );
     484                jd->fd = proxy_connect( host->text, port, jabber_connected_plain, ic );
     485               
     486                return XT_ABORT;
     487        }
    457488       
    458489        err = jabber_error_parse( node, XMLNS_STREAM_ERROR );
  • protocols/jabber/iq.c

    rbfafb99 re31e5b8  
    44*  Jabber module - IQ packets                                               *
    55*                                                                           *
    6 *  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2006-2012 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    128128                                                   XMLNS_MUC,
    129129                                                   XMLNS_PING,
     130                                                   XMLNS_RECEIPTS,
    130131                                                   XMLNS_SI,
    131132                                                   XMLNS_BYTESTREAMS,
  • protocols/jabber/jabber.c

    rbfafb99 re31e5b8  
    44*  Jabber module - Main file                                                *
    55*                                                                           *
    6 *  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2006-2013 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    8585        s->flags |= ACC_SET_OFFLINE_ONLY;
    8686       
    87         s = set_add( &acc->set, "tls", "try", set_eval_tls, acc );
     87        s = set_add( &acc->set, "tls", "true", set_eval_tls, acc );
    8888        s->flags |= ACC_SET_OFFLINE_ONLY;
    8989       
     
    9696        s->flags |= ACC_SET_OFFLINE_ONLY;
    9797       
    98         acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE;
     98        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
     99                      ACC_FLAG_HANDLE_DOMAINS;
    99100}
    100101
     
    231232        if( set_getbool( &acc->set, "ssl" ) )
    232233        {
    233                 jd->ssl = ssl_connect( connect_to, set_getint( &acc->set, "port" ), FALSE, jabber_connected_ssl, ic );
     234                jd->ssl = ssl_connect( connect_to, set_getint( &acc->set, "port" ), set_getbool( &acc->set, "tls_verify" ), jabber_connected_ssl, ic );
    234235                jd->fd = jd->ssl ? ssl_getfd( jd->ssl ) : -1;
    235236        }
  • protocols/jabber/jabber.h

    rbfafb99 re31e5b8  
    44*  Jabber module - Main file                                                *
    55*                                                                           *
    6 *  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2006-2013 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    196196};
    197197
    198 #define JABBER_XMLCONSOLE_HANDLE "xmlconsole"
     198#define JABBER_XMLCONSOLE_HANDLE "_xmlconsole"
    199199#define JABBER_OAUTH_HANDLE "jabber_oauth"
    200200
     
    227227#define XMLNS_TIME         "urn:xmpp:time"                                       /* XEP-0202 */
    228228#define XMLNS_PING         "urn:xmpp:ping"                                       /* XEP-0199 */
     229#define XMLNS_RECEIPTS     "urn:xmpp:receipts"                                   /* XEP-0184 */
    229230#define XMLNS_VCARD        "vcard-temp"                                          /* XEP-0054 */
    230231#define XMLNS_DELAY        "jabber:x:delay"                                      /* XEP-0091 */
  • protocols/jabber/message.c

    rbfafb99 re31e5b8  
    44*  Jabber module - Handling of message(s) (tags), etc                       *
    55*                                                                           *
    6 *  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2006-2012 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    2929        char *from = xt_find_attr( node, "from" );
    3030        char *type = xt_find_attr( node, "type" );
     31        char *id = xt_find_attr( node, "id" );
    3132        struct xt_node *body = xt_find_node( node->children, "body" ), *c;
     33        struct xt_node *request = xt_find_node( node->children, "request" );
    3234        struct jabber_buddy *bud = NULL;
    3335        char *s, *room = NULL, *reason = NULL;
     
    3537        if( !from )
    3638                return XT_HANDLED; /* Consider this packet corrupted. */
     39
     40        if( request && id )
     41        {
     42                /* Send a message receipt (XEP-0184), looking like this:
     43                 * <message
     44                 *  from='kingrichard@royalty.england.lit/throne'
     45                 *  id='bi29sg183b4v'
     46                 *  to='northumberland@shakespeare.lit/westminster'>
     47                 *  <received xmlns='urn:xmpp:receipts' id='richard2-4.1.247'/>
     48                 * </message> */
     49                struct xt_node *received, *receipt;
     50               
     51                received = xt_new_node( "received", NULL, NULL );
     52                xt_add_attr( received, "xmlns", XMLNS_RECEIPTS );
     53                xt_add_attr( received, "id", id );
     54                receipt = jabber_make_packet( "message", NULL, from, received );
     55
     56                jabber_write_packet( ic, receipt );
     57                xt_free_node( receipt );
     58        }
    3759       
    3860        bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT );
  • protocols/jabber/sasl.c

    rbfafb99 re31e5b8  
    44*  Jabber module - SASL authentication                                      *
    55*                                                                           *
    6 *  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
     6*  Copyright 2006-2012 Wilmer van der Gaast <wilmer@gaast.net>              *
    77*                                                                           *
    88*  This program is free software; you can redistribute it and/or modify     *
     
    387387        {
    388388                /* We found rspauth, but don't really care... */
     389                g_free( s );
    389390        }
    390391       
  • protocols/jabber/si.c

    rbfafb99 re31e5b8  
    293293                }
    294294
    295                 *s = '/';
    296         }
    297         else
     295                if( s )
     296                        *s = '/';
     297        }
     298       
     299        if( !requestok )
    298300        {
    299301                reply = jabber_make_error_packet( node, "item-not-found", "cancel", NULL );
  • protocols/msn/Makefile

    rbfafb99 re31e5b8  
    3838$(objects): %.o: $(_SRCDIR_)%.c
    3939        @echo '*' Compiling $<
    40         @$(CC) -c $(CFLAGS) $< -o $@
     40        @$(CC) -c $(CFLAGS) $(CFLAGS_BITLBEE) $< -o $@
    4141
    4242msn_mod.o: $(objects)
  • protocols/msn/msn.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2013 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    4444        set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc );
    4545       
    46         acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE;
     46        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
     47                      ACC_FLAG_HANDLE_DOMAINS;
    4748}
    4849
     
    5354       
    5455        ic->proto_data = md;
     56        ic->flags |= OPT_PONGS | OPT_PONGED;
    5557       
    5658        if( strchr( acc->user, '@' ) == NULL )
     
    98100                g_free( md->lock_key );
    99101                g_free( md->pp_policy );
     102                g_free( md->uuid );
    100103               
    101104                while( md->groups )
     
    139142static int msn_buddy_msg( struct im_connection *ic, char *who, char *message, int away )
    140143{
     144        struct bee_user *bu = bee_user_by_handle( ic->bee, ic, who );
     145        struct msn_buddy_data *bd = bu ? bu->data : NULL;
    141146        struct msn_switchboard *sb;
    142147       
     
    148153        else
    149154#endif
    150         if( ( sb = msn_sb_by_handle( ic, who ) ) )
     155        if( bd && bd->flags & MSN_BUDDY_FED )
     156        {
     157                msn_ns_sendmessage( ic, bu, message );
     158        }
     159        else if( ( sb = msn_sb_by_handle( ic, who ) ) )
    151160        {
    152161                return( msn_sb_sendmessage( sb, message ) );
     
    190199                md->away_state = msn_away_state_list + 1;
    191200       
    192         if( !msn_ns_write( ic, -1, "CHG %d %s\r\n", ++md->trId, md->away_state->code ) )
     201        if( !msn_ns_write( ic, -1, "CHG %d %s %d:%02d\r\n", ++md->trId, md->away_state->code, MSN_CAP1, MSN_CAP2 ) )
    193202                return;
    194203       
    195         uux = g_markup_printf_escaped( "<Data><PSM>%s</PSM><CurrentMedia></CurrentMedia>"
    196                                        "</Data>", message ? message : "" );
     204        uux = g_markup_printf_escaped( "<EndpointData><Capabilities>%d:%02d"
     205                                       "</Capabilities></EndpointData>",
     206                                       MSN_CAP1, MSN_CAP2 );
     207        msn_ns_write( ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux );
     208        g_free( uux );
     209       
     210        uux = g_markup_printf_escaped( "<PrivateEndpointData><EpName>%s</EpName>"
     211                                       "<Idle>%s</Idle><ClientType>%d</ClientType>"
     212                                       "<State>%s</State></PrivateEndpointData>",
     213                                       md->uuid,
     214                                       strcmp( md->away_state->code, "IDL" ) ? "false" : "true",
     215                                       1, /* ? */
     216                                       md->away_state->code );
     217        msn_ns_write( ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux );
     218        g_free( uux );
     219       
     220        uux = g_markup_printf_escaped( "<Data><DDP></DDP><PSM>%s</PSM>"
     221                                       "<CurrentMedia></CurrentMedia>"
     222                                       "<MachineGuid>%s</MachineGuid></Data>",
     223                                       message ? message : "", md->uuid );
    197224        msn_ns_write( ic, -1, "UUX %d %zd\r\n%s", ++md->trId, strlen( uux ), uux );
    198225        g_free( uux );
     
    232259{
    233260        struct msn_switchboard *sb = msn_sb_by_chat( c );
    234         char buf[1024];
    235261       
    236262        if( sb )
    237         {
    238                 g_snprintf( buf, sizeof( buf ), "CAL %d %s\r\n", ++sb->trId, who );
    239                 msn_sb_write( sb, buf, strlen( buf ) );
    240         }
     263                msn_sb_write( sb, "CAL %d %s\r\n", ++sb->trId, who );
    241264}
    242265
     
    246269       
    247270        if( sb )
    248                 msn_sb_write( sb, "OUT\r\n", 5 );
     271                msn_sb_write( sb, "OUT\r\n" );
    249272}
    250273
     
    340363{
    341364        struct msn_data *md = bu->ic->proto_data;
    342         bu->data = g_new0( struct msn_buddy_data, 1 );
     365        struct msn_buddy_data *bd;
     366        char *handle;
     367       
     368        bd = bu->data = g_new0( struct msn_buddy_data, 1 );
    343369        g_tree_insert( md->domaintree, bu->handle, bu );
     370       
     371        for( handle = bu->handle; isdigit( *handle ); handle ++ );
     372        if( *handle == ':' )
     373        {
     374                /* Pass a nick hint so hopefully the stupid numeric prefix
     375                   won't show up to the user.  */
     376                char *s = strchr( ++handle, '@' );
     377                if( s )
     378                {
     379                        handle = g_strndup( handle, s - handle );
     380                        imcb_buddy_nick_hint( bu->ic, bu->handle, handle );
     381                        g_free( handle );
     382                }
     383               
     384                bd->flags |= MSN_BUDDY_FED;
     385        }
    344386}
    345387
  • protocols/msn/msn.h

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    5353*/
    5454
     55/* <= BitlBee 3.0.5
    5556#define MSNP11_PROD_KEY "ILTXC!4IXB5FB*PX"
    5657#define MSNP11_PROD_ID  "PROD0119GSJUC$18"
    57 #define MSNP_VER        "MSNP15"
    58 #define MSNP_BUILD      "8.5.1288"
     58*/
     59
     60#define MSNP11_PROD_KEY "C1BX{V4W}Q3*10SM"
     61#define MSNP11_PROD_ID  "PROD0120PW!CCV9@"
     62#define MSNP_VER        "MSNP18"
     63#define MSNP_BUILD      "14.0.8117.416"
    5964
    6065#define MSN_SB_NEW         -24062002
     66
     67#define MSN_CAP1        0xC000
     68#define MSN_CAP2        0x0000
    6169
    6270#define MSN_MESSAGE_HEADERS "MIME-Version: 1.0\r\n" \
     
    118126        char *tokens[4];
    119127        char *lock_key, *pp_policy;
     128        char *uuid;
    120129       
    121130        GSList *msgq, *grpq, *soapq;
     
    189198        MSN_BUDDY_PL = 16,
    190199        MSN_BUDDY_ADL_SYNCED = 256,
     200        MSN_BUDDY_FED = 512,
    191201} msn_buddy_flags_t;
    192202
     
    222232
    223233/* ns.c */
    224 int msn_ns_write( struct im_connection *ic, int fd, const char *fmt, ... );
     234int msn_ns_write( struct im_connection *ic, int fd, const char *fmt, ... ) G_GNUC_PRINTF( 3, 4 );
    225235gboolean msn_ns_connect( struct im_connection *ic, struct msn_handler_data *handler, const char *host, int port );
    226236void msn_ns_close( struct msn_handler_data *handler );
     
    228238void msn_auth_got_contact_list( struct im_connection *ic );
    229239int msn_ns_finish_login( struct im_connection *ic );
     240int msn_ns_sendmessage( struct im_connection *ic, struct bee_user *bu, const char *text );
     241void msn_ns_oim_send_queue( struct im_connection *ic, GSList **msgq );
    230242
    231243/* msn_util.c */
    232 int msn_logged_in( struct im_connection *ic );
    233244int msn_buddy_list_add( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *realname_, const char *group );
    234245int msn_buddy_list_remove( struct im_connection *ic, msn_buddy_flags_t list, const char *who, const char *group );
     
    242253struct msn_group *msn_group_by_id( struct im_connection *ic, const char *id );
    243254int msn_ns_set_display_name( struct im_connection *ic, const char *value );
     255const char *msn_normalize_handle( const char *handle );
    244256
    245257/* tables.c */
     
    250262
    251263/* sb.c */
    252 int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... );
     264int msn_sb_write( struct msn_switchboard *sb, const char *fmt, ... ) G_GNUC_PRINTF( 2, 3 );;
    253265struct msn_switchboard *msn_sb_create( struct im_connection *ic, char *host, int port, char *key, int session );
    254 struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, char *handle );
     266struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, const char *handle );
    255267struct msn_switchboard *msn_sb_by_chat( struct groupchat *c );
    256268struct msn_switchboard *msn_sb_spare( struct im_connection *ic );
  • protocols/msn/msn_util.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2929#include "soap.h"
    3030#include <ctype.h>
    31 
    32 int msn_logged_in( struct im_connection *ic )
    33 {
    34         imcb_connected( ic );
    35        
    36         return( 0 );
    37 }
    3831
    3932static char *adlrml_entry( const char *handle_, msn_buddy_flags_t list )
     
    537530        return msn_ns_write( ic, -1, "PRP %d MFN %s\r\n", ++md->trId, fn );
    538531}
     532
     533const char *msn_normalize_handle( const char *handle )
     534{
     535        if( strncmp( handle, "1:", 2 ) == 0 )
     536                return handle + 2;
     537        else
     538                return handle;
     539}
  • protocols/msn/ns.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    2525
    2626#include <ctype.h>
     27#include <sys/utsname.h>
    2728#include "nogaim.h"
    2829#include "msn.h"
    2930#include "md5.h"
     31#include "sha1.h"
    3032#include "soap.h"
    3133#include "xmltree.h"
     
    110112        handler->rxlen = 0;
    111113        handler->rxq = g_new0( char, 1 );
     114       
     115        if( md->uuid == NULL )
     116        {
     117                struct utsname name;
     118                sha1_state_t sha[1];
     119               
     120                /* UUID == SHA1("BitlBee" + my hostname + MSN username) */
     121                sha1_init( sha );
     122                sha1_append( sha, (void*) "BitlBee", 7 );
     123                if( uname( &name ) == 0 )
     124                {
     125                        sha1_append( sha, (void*) name.nodename, strlen( name.nodename ) );
     126                }
     127                sha1_append( sha, (void*) ic->acc->user, strlen( ic->acc->user ) );
     128                md->uuid = sha1_random_uuid( sha );
     129                memcpy( md->uuid, "b171be3e", 8 ); /* :-P */
     130        }
    112131       
    113132        if( msn_ns_write( ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER ) )
     
    353372                return st;
    354373        }
    355         else if( strcmp( cmd[0], "ILN" ) == 0 )
     374        else if( strcmp( cmd[0], "ILN" ) == 0 || strcmp( cmd[0], "NLN" ) == 0 )
    356375        {
    357376                const struct msn_away_state *st;
     377                const char *handle;
     378                int cap = 0;
    358379               
    359380                if( num_parts < 6 )
     
    363384                        return( 0 );
    364385                }
    365                
    366                 http_decode( cmd[5] );
    367                 imcb_rename_buddy( ic, cmd[3], cmd[5] );
    368                
    369                 st = msn_away_state_by_code( cmd[2] );
     386                /* ILN and NLN are more or less the same, except ILN has a trId
     387                   at the start, and NLN has a capability field at the end.
     388                   Does ILN still exist BTW? */
     389                if( cmd[0][1] == 'I' )
     390                        cmd ++;
     391                else
     392                        cap = atoi( cmd[4] );
     393
     394                handle = msn_normalize_handle( cmd[2] );
     395                if( strcmp( handle, ic->acc->user ) == 0 )
     396                        return 1; /* That's me! */
     397               
     398                http_decode( cmd[3] );
     399                imcb_rename_buddy( ic, handle, cmd[3] );
     400               
     401                st = msn_away_state_by_code( cmd[1] );
    370402                if( !st )
    371403                {
     
    374406                }
    375407               
    376                 imcb_buddy_status( ic, cmd[3], OPT_LOGGED_IN |
    377                                    ( st != msn_away_state_list ? OPT_AWAY : 0 ),
    378                                    st->name, NULL );
    379         }
    380         else if( strcmp( cmd[0], "FLN" ) == 0 )
    381         {
    382                 if( cmd[1] == NULL )
    383                         return 1;
    384                
    385                 imcb_buddy_status( ic, cmd[1], 0, NULL, NULL );
    386                
    387                 msn_sb_start_keepalives( msn_sb_by_handle( ic, cmd[1] ), TRUE );
    388         }
    389         else if( strcmp( cmd[0], "NLN" ) == 0 )
    390         {
    391                 const struct msn_away_state *st;
    392                 int cap;
    393                
    394                 if( num_parts < 6 )
    395                 {
    396                         imcb_error( ic, "Syntax error" );
    397                         imc_logout( ic, TRUE );
    398                         return( 0 );
    399                 }
    400                
    401                 http_decode( cmd[4] );
    402                 cap = atoi( cmd[5] );
    403                 imcb_rename_buddy( ic, cmd[2], cmd[4] );
    404                
    405                 st = msn_away_state_by_code( cmd[1] );
    406                 if( !st )
    407                 {
    408                         /* FIXME: Warn/Bomb about unknown away state? */
    409                         st = msn_away_state_list + 1;
    410                 }
    411                
    412                 imcb_buddy_status( ic, cmd[2], OPT_LOGGED_IN |
     408                imcb_buddy_status( ic, handle, OPT_LOGGED_IN |
    413409                                   ( st != msn_away_state_list ? OPT_AWAY : 0 ) |
    414410                                   ( cap & 1 ? OPT_MOBILE : 0 ),
    415411                                   st->name, NULL );
    416412               
    417                 msn_sb_stop_keepalives( msn_sb_by_handle( ic, cmd[2] ) );
     413                msn_sb_stop_keepalives( msn_sb_by_handle( ic, handle ) );
     414        }
     415        else if( strcmp( cmd[0], "FLN" ) == 0 )
     416        {
     417                const char *handle;
     418               
     419                if( cmd[1] == NULL )
     420                        return 1;
     421               
     422                handle = msn_normalize_handle( cmd[1] );
     423                imcb_buddy_status( ic, handle, 0, NULL, NULL );
     424                msn_sb_start_keepalives( msn_sb_by_handle( ic, handle ), TRUE );
    418425        }
    419426        else if( strcmp( cmd[0], "RNG" ) == 0 )
     
    462469                else
    463470                {
    464                         sb->who = g_strdup( cmd[5] );
     471                        sb->who = g_strdup( msn_normalize_handle( cmd[5] ) );
    465472                }
    466473        }
     
    555562        {
    556563                /* Status message. */
    557                 if( num_parts >= 4 )
    558                         handler->msglen = atoi( cmd[3] );
     564                if( num_parts >= 3 )
     565                        handler->msglen = atoi( cmd[2] );
    559566        }
    560567        else if( strcmp( cmd[0], "NOT" ) == 0 )
     
    564571                if( num_parts >= 2 )
    565572                        handler->msglen = atoi( cmd[1] );
     573        }
     574        else if( strcmp( cmd[0], "UBM" ) == 0 )
     575        {
     576                if( num_parts >= 7 )
     577                        handler->msglen = atoi( cmd[6] );
     578        }
     579        else if( strcmp( cmd[0], "QNG" ) == 0 )
     580        {
     581                ic->flags |= OPT_PONGED;
    566582        }
    567583        else if( isdigit( cmd[0][0] ) )
     
    668684                        else if( g_strncasecmp( ct, "text/x-msmsgsactivemailnotification", 35 ) == 0 )
    669685                        {
    670                                 /* Sorry, but this one really is *USELESS* */
     686                        }
     687                        else if( g_strncasecmp( ct, "text/x-msmsgsinitialmdatanotification", 37 ) == 0 ||
     688                                 g_strncasecmp( ct, "text/x-msmsgsoimnotification", 28 ) == 0 )
     689                        {
     690                                /* We received an offline message. Or at least notification
     691                                   that there is one waiting for us. Fetching the message(s)
     692                                   and purging them from the server is a lot of SOAPy work
     693                                   not worth doing IMHO. Also I thought it was possible to
     694                                   have the notification server send them directly, I was
     695                                   pretty sure I saw Pidgin do it..
     696                                   
     697                                   At least give a notification for now, seems like a
     698                                   reasonable thing to do. Only problem is, they'll keep
     699                                   coming back at login time until you read them using a
     700                                   different client. :-( */
     701                               
     702                                char *xml = get_rfc822_header( body, "Mail-Data:", blen );
     703                                struct xt_node *md, *m;
     704                               
     705                                if( !xml )
     706                                        return 1;
     707                                md = xt_from_string( xml, 0 );
     708                                if( !md )
     709                                        return 1;
     710                               
     711                                for( m = md->children; ( m = xt_find_node( m, "M" ) ); m = m->next )
     712                                {
     713                                        struct xt_node *e = xt_find_node( m->children, "E" );
     714                                        struct xt_node *rt = xt_find_node( m->children, "RT" );
     715                                        struct tm tp;
     716                                        time_t msgtime = 0;
     717                                       
     718                                        if( !e || !e->text )
     719                                                continue;
     720                                       
     721                                        memset( &tp, 0, sizeof( tp ) );
     722                                        if( rt && rt->text &&
     723                                            sscanf( rt->text, "%4d-%2d-%2dT%2d:%2d:%2d.",
     724                                                    &tp.tm_year, &tp.tm_mon, &tp.tm_mday,
     725                                                    &tp.tm_hour, &tp.tm_min, &tp.tm_sec ) == 6 )
     726                                        {
     727                                                tp.tm_year -= 1900;
     728                                                tp.tm_mon --;
     729                                                msgtime = mktime_utc( &tp );
     730                                               
     731                                        }
     732                                        imcb_buddy_msg( ic, e->text, "<< \002BitlBee\002 - Received offline message. BitlBee can't show these. >>", 0, msgtime );
     733                                }
     734                               
     735                                g_free( xml );
     736                                xt_free_node( md );
    671737                        }
    672738                        else
     
    683749                char *psm_text = NULL;
    684750               
    685                 ubx = xt_from_string( msg );
     751                ubx = xt_from_string( msg, msglen );
    686752                if( ubx && strcmp( ubx->name, "Data" ) == 0 &&
    687753                    ( psm = xt_find_node( ubx->children, "PSM" ) ) )
    688754                        psm_text = psm->text;
    689755               
    690                 imcb_buddy_status_msg( ic, cmd[1], psm_text );
     756                imcb_buddy_status_msg( ic, msn_normalize_handle( cmd[1] ), psm_text );
    691757                xt_free_node( ubx );
    692758        }
     
    695761                struct xt_node *adl, *d, *c;
    696762               
    697                 if( !( adl = xt_from_string( msg ) ) )
     763                if( !( adl = xt_from_string( msg, msglen ) ) )
    698764                        return 1;
    699765               
     
    716782                                        continue;
    717783                               
     784                                /* FIXME: Use "t" here, guess I should just add it
     785                                   as a prefix like elsewhere in the protocol. */
    718786                                handle = g_strdup_printf( "%s@%s", cn, dn );
    719787                                if( !( ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) ||
     
    741809                }
    742810        }
    743        
    744         return( 1 );
     811        else if( strcmp( cmd[0], "UBM" ) == 0 )
     812        {
     813                /* This one will give us msgs from federated networks. Technically
     814                   it should also get us offline messages, but I don't know how
     815                   I can signal MSN servers to use it. */
     816                char *ct, *handle;
     817               
     818                if( strcmp( cmd[1], ic->acc->user ) == 0 )
     819                {
     820                        /* With MPOP, you'll get copies of your own msgs from other
     821                           sessions. Discard those at least for now. */
     822                        return 1;
     823                }
     824               
     825                ct = get_rfc822_header( msg, "Content-Type", msglen );
     826                if( strncmp( ct, "text/plain", 10 ) != 0 )
     827                {
     828                        /* Typing notification or something? */
     829                        g_free( ct );
     830                        return 1;
     831                }
     832                if( strcmp( cmd[2], "1" ) != 0 )
     833                        handle = g_strdup_printf( "%s:%s", cmd[2], cmd[1] );
     834                else
     835                        handle = g_strdup( cmd[1] );
     836               
     837                imcb_buddy_msg( ic, handle, body, 0, 0 );
     838                g_free( handle );
     839        }
     840       
     841        return 1;
    745842}
    746843
     
    757854        if( token )
    758855        {
    759                 msn_ns_write( ic, -1, "USR %d SSO S %s %s\r\n", ++md->trId, md->tokens[0], token );
     856                msn_ns_write( ic, -1, "USR %d SSO S %s %s {%s}\r\n", ++md->trId, md->tokens[0], token, md->uuid );
    760857        }
    761858        else
     
    809906        xt_add_attr( c, "n", handle );
    810907        xt_add_attr( c, "l", l );
    811         xt_add_attr( c, "t", "1" ); /* 1 means normal, 4 means mobile? */
     908        xt_add_attr( c, "t", "1" ); /* FIXME: Network type, i.e. 32 for Y!MSG */
    812909        xt_insert_child( d, c );
    813910       
     
    886983        return 1;
    887984}
     985
     986int msn_ns_sendmessage( struct im_connection *ic, bee_user_t *bu, const char *text )
     987{
     988        struct msn_data *md = ic->proto_data;
     989        int type = 0;
     990        char *buf, *handle;
     991       
     992        if( strncmp( text, "\r\r\r", 3 ) == 0 )
     993                /* Err. Shouldn't happen but I guess it can. Don't send others
     994                   any of the "SHAKE THAT THING" messages. :-D */
     995                return 1;
     996       
     997        /* This might be a federated contact. Get its network number,
     998           prefixed to bu->handle with a colon. Default is 1. */
     999        for( handle = bu->handle; isdigit( *handle ); handle ++ )
     1000                type = type * 10 + *handle - '0';
     1001        if( *handle == ':' )
     1002                handle ++;
     1003        else
     1004                type = 1;
     1005       
     1006        buf = g_strdup_printf( "%s%s", MSN_MESSAGE_HEADERS, text );
     1007       
     1008        if( msn_ns_write( ic, -1, "UUM %d %s %d %d %zd\r\n%s",
     1009                                  ++md->trId, handle, type,
     1010                                  1, /* type == IM (not nudge/typing) */
     1011                                  strlen( buf ), buf ) )
     1012                return 1;
     1013        else
     1014                return 0;
     1015}
     1016
     1017void msn_ns_oim_send_queue( struct im_connection *ic, GSList **msgq )
     1018{
     1019        GSList *l;
     1020       
     1021        for( l = *msgq; l; l = l->next )
     1022        {
     1023                struct msn_message *m = l->data;
     1024                bee_user_t *bu = bee_user_by_handle( ic->bee, ic, m->who );
     1025               
     1026                if( bu )
     1027                        if( !msn_ns_sendmessage( ic, bu, m->text ) )
     1028                                return;
     1029        }
     1030       
     1031        while( *msgq != NULL )
     1032        {
     1033                struct msn_message *m = (*msgq)->data;
     1034               
     1035                g_free( m->who );
     1036                g_free( m->text );
     1037                g_free( m );
     1038               
     1039                *msgq = g_slist_remove( *msgq, m );
     1040        }
     1041}
  • protocols/msn/sb.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    122122}
    123123
    124 struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, char *handle )
     124struct msn_switchboard *msn_sb_by_handle( struct im_connection *ic, const char *handle )
    125125{
    126126        struct msn_data *md = ic->proto_data;
     
    308308        struct msn_switchboard *sb = data;
    309309        struct im_connection *ic;
     310        struct msn_data *md;
    310311        char buf[1024];
    311312       
     
    315316       
    316317        ic = sb->ic;
     318        md = ic->proto_data;
    317319       
    318320        if( source != sb->fd )
     
    332334       
    333335        if( sb->session == MSN_SB_NEW )
    334                 g_snprintf( buf, sizeof( buf ), "USR %d %s %s\r\n", ++sb->trId, ic->acc->user, sb->key );
     336                g_snprintf( buf, sizeof( buf ), "USR %d %s;{%s} %s\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key );
    335337        else
    336                 g_snprintf( buf, sizeof( buf ), "ANS %d %s %s %d\r\n", ++sb->trId, ic->acc->user, sb->key, sb->session );
     338                g_snprintf( buf, sizeof( buf ), "ANS %d %s;{%s} %s %d\r\n", ++sb->trId, ic->acc->user, md->uuid, sb->key, sb->session );
    337339       
    338340        if( msn_sb_write( sb, "%s", buf ) )
     
    453455                        char buf[1024];
    454456                       
    455                         if( num == 1 )
     457                        /* For as much as I understand this MPOP stuff now, a
     458                           switchboard has two (or more) roster entries per
     459                           participant. One "bare JID" and one JID;UUID. Ignore
     460                           the latter. */
     461                        if( !strchr( cmd[4], ';' ) )
    456462                        {
    457                                 g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session );
    458                                 sb->chat = imcb_chat_new( ic, buf );
     463                                /* HACK: Since even 1:1 chats now have >2 participants
     464                                   (ourselves included) it gets hard to tell them apart
     465                                   from rooms. Let's hope this is enough: */
     466                                if( sb->chat == NULL && num != tot )
     467                                {
     468                                        g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session );
     469                                        sb->chat = imcb_chat_new( ic, buf );
     470                                       
     471                                        g_free( sb->who );
     472                                        sb->who = NULL;
     473                                }
    459474                               
    460                                 g_free( sb->who );
    461                                 sb->who = NULL;
    462                         }
    463                        
    464                         imcb_chat_add_buddy( sb->chat, cmd[4] );
    465                        
    466                         if( num == tot )
     475                                if( sb->chat )
     476                                        imcb_chat_add_buddy( sb->chat, cmd[4] );
     477                        }
     478                       
     479                        /* We have the full roster, start showing the channel to
     480                           the user. */
     481                        if( num == tot && sb->chat )
    467482                        {
    468483                                imcb_chat_add_buddy( sb->chat, ic->acc->user );
     
    506521                        return( 0 );
    507522                }
     523               
     524                /* See IRO above. Handle "bare JIDs" only. */
     525                if( strchr( cmd[1], ';' ) )
     526                        return 1;
    508527               
    509528                if( sb->who && g_strcasecmp( cmd[1], sb->who ) == 0 )
     
    541560                        return( st );
    542561                }
     562                else if( strcmp( cmd[1], ic->acc->user ) == 0 )
     563                {
     564                        /* Well, gee thanks. Thanks for letting me know I've arrived.. */
     565                }
    543566                else if( sb->who )
    544567                {
     
    613636                           The server will clean it up when it's idle for too long. */
    614637                }
    615                 else if( sb->chat )
     638                else if( sb->chat && !strchr( cmd[1], ';' ) )
    616639                {
    617640                        imcb_chat_remove_buddy( sb->chat, cmd[1], "" );
     
    629652                /* If the person is offline, send an offline message instead,
    630653                   and don't report an error. */
    631                 /* TODO: Support for OIMs that works. (#874) */
    632                 /*
    633654                if( num == 217 )
    634                         msn_soap_oim_send_queue( ic, &sb->msgq );
     655                        msn_ns_oim_send_queue( ic, &sb->msgq );
    635656                else
    636                 */
    637657                        imcb_error( ic, "Error reported by switchboard server: %s", err->text );
    638658               
  • protocols/msn/soap.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    229229        if( payload )
    230230        {
    231                 struct xt_node *xt = xt_from_string( payload );
     231                struct xt_node *xt = xt_from_string( payload, 0 );
    232232                if( xt )
    233233                        xt_print( xt );
  • protocols/msn/soap.h

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
  • protocols/nogaim.c

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    261261        struct im_connection *ic = d;
    262262       
     263        if( ( ic->flags & OPT_PONGS ) && !( ic->flags & OPT_PONGED ) )
     264        {
     265                /* This protocol is expected to ack keepalives and hasn't
     266                   since the last time we were here. */
     267                imcb_error( ic, "Connection timeout" );
     268                imc_logout( ic, TRUE );
     269                return FALSE;
     270        }
     271        ic->flags &= ~OPT_PONGED;
     272       
    263273        if( ic->acc->prpl->keepalive )
    264274                ic->acc->prpl->keepalive( ic );
    265275       
    266276        return TRUE;
     277}
     278
     279void start_keepalives( struct im_connection *ic, int interval )
     280{
     281        b_event_remove( ic->keepalive );
     282        ic->keepalive = b_timeout_add( interval, send_keepalive, ic );
     283       
     284        /* Connecting successfully counts as a first successful pong. */
     285        if( ic->flags & OPT_PONGS )
     286                ic->flags |= OPT_PONGED;
    267287}
    268288
     
    277297        imcb_log( ic, "Logged in" );
    278298       
    279         b_event_remove( ic->keepalive );
    280         ic->keepalive = b_timeout_add( 60000, send_keepalive, ic );
    281299        ic->flags |= OPT_LOGGED_IN;
     300        start_keepalives( ic, 60000 );
    282301       
    283302        /* Necessary to send initial presence status, even if we're not away. */
  • protocols/nogaim.h

    rbfafb99 re31e5b8  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2010 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    1616 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
    1717 *                          (and possibly other members of the Gaim team)
    18  * Copyright 2002-2007 Wilmer van der Gaast <wilmer@gaast.net>
     18 * Copyright 2002-2012 Wilmer van der Gaast <wilmer@gaast.net>
    1919 */
    2020
     
    6868#define OPT_THINKING    0x00000200 /* about these values... Stupid me! */
    6969#define OPT_NOOTR       0x00001000 /* protocol not suitable for OTR */
     70#define OPT_PONGS       0x00010000 /* Service sends us keep-alives */
     71#define OPT_PONGED      0x00020000 /* Received a keep-alive during last interval */
    7072
    7173/* ok. now the fun begins. first we create a connection structure */
     
    8890        int permdeny;
    8991       
    90         char displayname[128];
    9192        char *away;
    92        
    93         int evil;
    9493       
    9594        /* BitlBee */
     
    127126        char show[BUDDY_ALIAS_MAXLEN];
    128127        int present;
    129         int evil;
    130128        time_t signon;
    131129        time_t idle;
     
    198196        void (* rem_permit)     (struct im_connection *, char *who);
    199197        void (* rem_deny)       (struct im_connection *, char *who);
    200         /* Doesn't actually have UI hooks. */
     198        /* Doesn't actually have UI hooks. Not used at all, can be removed. */
    201199        void (* set_permit_deny)(struct im_connection *);
    202200       
  • protocols/oscar/Makefile

    rbfafb99 re31e5b8  
    3939$(objects): %.o: $(_SRCDIR_)%.c
    4040        @echo '*' Compiling $<
    41         @$(CC) -c $(CFLAGS) $< -o $@
     41        @$(CC) -c $(CFLAGS) $(CFLAGS_BITLBEE) $< -o $@
    4242
    4343oscar_mod.o: $(objects)
  • protocols/oscar/aim.h

    rbfafb99 re31e5b8  
    410410#define AIM_USERINFO_PRESENT_SESSIONLEN   0x00000100
    411411
    412 const char *aim_userinfo_sn(aim_userinfo_t *ui);
    413 guint16 aim_userinfo_flags(aim_userinfo_t *ui);
    414 guint16 aim_userinfo_idle(aim_userinfo_t *ui);
    415 float aim_userinfo_warnlevel(aim_userinfo_t *ui);
    416 time_t aim_userinfo_membersince(aim_userinfo_t *ui);
    417 time_t aim_userinfo_onlinesince(aim_userinfo_t *ui);
    418 guint32 aim_userinfo_sessionlen(aim_userinfo_t *ui);
    419 int aim_userinfo_hascap(aim_userinfo_t *ui, guint32 cap);
    420 
    421412#define AIM_FLAG_UNCONFIRMED    0x0001 /* "damned transients" */
    422413#define AIM_FLAG_ADMINISTRATOR  0x0002
     
    474465int aim_addtlvtochain16(aim_tlvlist_t **list, const guint16 t, const guint16 v);
    475466int aim_addtlvtochain32(aim_tlvlist_t **list, const guint16 type, const guint32 v);
    476 int aim_addtlvtochain_availmsg(aim_tlvlist_t **list, const guint16 type, const char *msg);
    477467int aim_addtlvtochain_raw(aim_tlvlist_t **list, const guint16 t, const guint16 l, const guint8 *v);
    478468int aim_addtlvtochain_caps(aim_tlvlist_t **list, const guint16 t, const guint32 caps);
     
    601591#define AIM_WARN_ANON                     0x01
    602592
    603 int aim_sendpauseack(aim_session_t *sess, aim_conn_t *conn);
    604 int aim_send_warning(aim_session_t *sess, aim_conn_t *conn, const char *destsn, guint32 flags);
    605 int aim_nop(aim_session_t *, aim_conn_t *);
    606593int aim_flap_nop(aim_session_t *sess, aim_conn_t *conn);
    607 int aim_bos_setidle(aim_session_t *, aim_conn_t *, guint32);
    608 int aim_bos_changevisibility(aim_session_t *, aim_conn_t *, int, const char *);
    609 int aim_bos_setbuddylist(aim_session_t *, aim_conn_t *, const char *);
    610594int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile, const char *awaymsg, guint32 caps);
    611595int aim_bos_setgroupperm(aim_session_t *, aim_conn_t *, guint32 mask);
     
    616600int aim_bos_reqbuddyrights(aim_session_t *, aim_conn_t *);
    617601int aim_bos_reqlocaterights(aim_session_t *, aim_conn_t *);
    618 int aim_setdirectoryinfo(aim_session_t *sess, aim_conn_t *conn, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, guint16 privacy);
    619 int aim_setuserinterests(aim_session_t *sess, aim_conn_t *conn, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, guint16 privacy);
    620602int aim_setextstatus(aim_session_t *sess, aim_conn_t *conn, guint32 status);
    621603
     
    627609#define AIM_CLIENTTYPE_WINAIM41 0x0003
    628610#define AIM_CLIENTTYPE_AOL_TOC  0x0004
    629 unsigned short aim_fingerprintclient(unsigned char *msghdr, int len);
    630611
    631612#define AIM_RATE_CODE_CHANGE     0x0001
     
    646627#define AIM_SENDMEMBLOCK_FLAG_ISREQUEST  0
    647628#define AIM_SENDMEMBLOCK_FLAG_ISHASH     1
    648 
    649 int aim_sendmemblock(aim_session_t *sess, aim_conn_t *conn, guint32 offset, guint32 len, const guint8 *buf, guint8 flag);
    650629
    651630#define AIM_GETINFO_GENERALINFO 0x00001
     
    674653#define AIM_TRANSFER_DENY_DECLINE 0x0001
    675654#define AIM_TRANSFER_DENY_NOTACCEPTING 0x0002
    676 int aim_denytransfer(aim_session_t *sess, const char *sender, const guint8 *cookie, unsigned short code);
    677655aim_conn_t *aim_accepttransfer(aim_session_t *sess, aim_conn_t *conn, const char *sn, const guint8 *cookie, const guint8 *ip, guint16 listingfiles, guint16 listingtotsize, guint16 listingsize, guint32 listingchecksum, guint16 rendid);
    678656
    679657int aim_getinfo(aim_session_t *, aim_conn_t *, const char *, unsigned short);
    680 int aim_sendbuddyoncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info);
    681 int aim_sendbuddyoffgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn);
    682658
    683659#define AIM_IMPARAM_FLAG_CHANMSGS_ALLOWED       0x00000001
     
    747723int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, guint16 flags, const char *msg, int msglen);
    748724int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance);
    749 int aim_chat_attachname(aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance);
    750 char *aim_chat_getname(aim_conn_t *conn);
    751 aim_conn_t *aim_chat_getconn(aim_session_t *, const char *name);
    752725
    753726int aim_chatnav_reqrights(aim_session_t *sess, aim_conn_t *conn);
     
    756729
    757730int aim_chatnav_createroom(aim_session_t *sess, aim_conn_t *conn, const char *name, guint16 exchange);
    758 int aim_chat_leaveroom(aim_session_t *sess, const char *name);
    759731
    760732/* aim_util.c */
     
    812784
    813785
    814 int aimutil_putstr(u_char *, const char *, int);
    815 int aimutil_tokslen(char *toSearch, int index, char dl);
    816 int aimutil_itemcnt(char *toSearch, char dl);
    817 char *aimutil_itemidx(char *toSearch, int index, char dl);
    818786int aim_sncmp(const char *a, const char *b);
    819787
  • protocols/oscar/aim_internal.h

    rbfafb99 re31e5b8  
    112112int aim_putsnac(aim_bstream_t *, guint16 family, guint16 type, guint16 flags, aim_snacid_t id);
    113113
    114 aim_conn_t *aim_cloneconn(aim_session_t *sess, aim_conn_t *src);
    115 void aim_clonehandlers(aim_session_t *sess, aim_conn_t *dest, aim_conn_t *src);
    116 
    117114int aim_oft_buildheader(unsigned char *,struct aim_fileheader_t *);
    118115
     
    195192
    196193int aim_extractuserinfo(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *);
    197 int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info);
    198194
    199195int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo);
    200196
    201 int aim_request_directim(aim_session_t *sess, const char *destsn, guint8 *ip, guint16 port, guint8 *ckret);
    202 int aim_request_sendfile(aim_session_t *sess, const char *sn, const char *filename, guint16 numfiles, guint32 totsize, guint8 *ip, guint16 port, guint8 *ckret);
    203197void aim_conn_close_rend(aim_session_t *sess, aim_conn_t *conn);
    204198void aim_conn_kill_rend(aim_session_t *sess, aim_conn_t *conn);
     
    210204int aim_reqrates(aim_session_t *, aim_conn_t *);
    211205int aim_rates_addparam(aim_session_t *, aim_conn_t *);
    212 int aim_rates_delparam(aim_session_t *, aim_conn_t *);
    213206
    214207#endif /* __AIM_INTERNAL_H__ */
  • protocols/oscar/bos.c

    rbfafb99 re31e5b8  
    5656}
    5757
    58 /*
    59  * Modify permit/deny lists (group 9, types 5, 6, 7, and 8)
    60  *
    61  * Changes your visibility depending on changetype:
    62  *
    63  *  AIM_VISIBILITYCHANGE_PERMITADD: Lets provided list of names see you
    64  *  AIM_VISIBILITYCHANGE_PERMIDREMOVE: Removes listed names from permit list
    65  *  AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names
    66  *  AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again
    67  *
    68  * list should be a list of
    69  * screen names in the form "Screen Name One&ScreenNameTwo&" etc.
    70  *
    71  * Equivelents to options in WinAIM:
    72  *   - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD
    73  *      with only your name on it.
    74  *   - Allow only users on my Buddy List: Send an
    75  *      AIM_VISIBILITYCHANGE_PERMITADD with the list the same as your
    76  *      buddy list
    77  *   - Allow only the uesrs below: Send an AIM_VISIBILITYCHANGE_PERMITADD
    78  *      with everyone listed that you want to see you.
    79  *   - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only
    80  *      yourself in the list
    81  *   - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with
    82  *      the list of users to be blocked
    83  *
    84  * XXX ye gods.
    85  */
    86 int aim_bos_changevisibility(aim_session_t *sess, aim_conn_t *conn, int changetype, const char *denylist)
    87 {
    88         aim_frame_t *fr;
    89         int packlen = 0;
    90         guint16 subtype;
    91         char *localcpy = NULL, *tmpptr = NULL;
    92         int i;
    93         int listcount;
    94         aim_snacid_t snacid;
    95 
    96         if (!denylist)
    97                 return -EINVAL;
    98 
    99         if (changetype == AIM_VISIBILITYCHANGE_PERMITADD)
    100                 subtype = 0x05;
    101         else if (changetype == AIM_VISIBILITYCHANGE_PERMITREMOVE)
    102                 subtype = 0x06;
    103         else if (changetype == AIM_VISIBILITYCHANGE_DENYADD)
    104                 subtype = 0x07;
    105         else if (changetype == AIM_VISIBILITYCHANGE_DENYREMOVE)
    106                 subtype = 0x08;
    107         else
    108                 return -EINVAL;
    109 
    110         localcpy = g_strdup(denylist);
    111 
    112         listcount = aimutil_itemcnt(localcpy, '&');
    113         packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;
    114 
    115         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, packlen))) {
    116                 g_free(localcpy);
    117                 return -ENOMEM;
    118         }
    119 
    120         snacid = aim_cachesnac(sess, 0x0009, subtype, 0x0000, NULL, 0);
    121         aim_putsnac(&fr->data, 0x0009, subtype, 0x00, snacid);
    122 
    123         for (i = 0; (i < (listcount - 1)) && (i < 99); i++) {
    124                 tmpptr = aimutil_itemidx(localcpy, i, '&');
    125 
    126                 aimbs_put8(&fr->data, strlen(tmpptr));
    127                 aimbs_putraw(&fr->data, (guint8 *)tmpptr, strlen(tmpptr));
    128 
    129                 g_free(tmpptr);
    130         }
    131         g_free(localcpy);
    132 
    133         aim_tx_enqueue(sess, fr);
    134 
    135         return 0;
    136 }
    137 
    13858static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
    13959{
  • protocols/oscar/buddylist.c

    rbfafb99 re31e5b8  
    9191        return 0;
    9292}
    93 
    94 /*
    95  * aim_add_buddy()
    96  *
    97  * Adds a single buddy to your buddy list after login.
    98  *
    99  * XXX this should just be an extension of setbuddylist()
    100  *
    101  */
    102 int aim_add_buddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
    103 {
    104         aim_frame_t *fr;
    105         aim_snacid_t snacid;
    106 
    107         if (!sn || !strlen(sn))
    108                 return -EINVAL;
    109 
    110         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
    111                 return -ENOMEM;
    112 
    113         snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1);
    114         aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
    115 
    116         aimbs_put8(&fr->data, strlen(sn));
    117         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    118 
    119         aim_tx_enqueue(sess, fr);
    120 
    121         return 0;
    122 }
    123 
    124 /*
    125  * XXX generalise to support removing multiple buddies (basically, its
    126  * the same as setbuddylist() but with a different snac subtype).
    127  *
    128  */
    129 int aim_remove_buddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
    130 {
    131         aim_frame_t *fr;
    132         aim_snacid_t snacid;
    133 
    134         if (!sn || !strlen(sn))
    135                 return -EINVAL;
    136 
    137         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
    138                 return -ENOMEM;
    139 
    140         snacid = aim_cachesnac(sess, 0x0003, 0x0005, 0x0000, sn, strlen(sn)+1);
    141         aim_putsnac(&fr->data, 0x0003, 0x0005, 0x0000, snacid);
    142 
    143         aimbs_put8(&fr->data, strlen(sn));
    144         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    145 
    146         aim_tx_enqueue(sess, fr);
    147 
    148         return 0;
    149 }
    150 
  • protocols/oscar/buddylist.h

    rbfafb99 re31e5b8  
    1717#define AIM_CB_BUD_DEFAULT 0xffff
    1818
    19 /* aim_buddylist.c */
    20 int aim_add_buddy(aim_session_t *, aim_conn_t *, const char *);
    21 int aim_remove_buddy(aim_session_t *, aim_conn_t *, const char *);
    22 
    2319#endif /* __OSCAR_BUDDYLIST_H__ */
  • protocols/oscar/chat.c

    rbfafb99 re31e5b8  
    2626
    2727        return;
    28 }
    29 
    30 char *aim_chat_getname(aim_conn_t *conn)
    31 {
    32         struct chatconnpriv *ccp;
    33 
    34         if (!conn)
    35                 return NULL;
    36 
    37         if (conn->type != AIM_CONN_TYPE_CHAT)
    38                 return NULL;
    39 
    40         ccp = (struct chatconnpriv *)conn->priv;
    41 
    42         return ccp->name;
    43 }
    44 
    45 /* XXX get this into conn.c -- evil!! */
    46 aim_conn_t *aim_chat_getconn(aim_session_t *sess, const char *name)
    47 {
    48         aim_conn_t *cur;
    49 
    50         for (cur = sess->connlist; cur; cur = cur->next) {
    51                 struct chatconnpriv *ccp = (struct chatconnpriv *)cur->priv;
    52 
    53                 if (cur->type != AIM_CONN_TYPE_CHAT)
    54                         continue;
    55                 if (!cur->priv) {
    56                         imcb_error(sess->aux_data, "chat connection with no name!");
    57                         continue;
    58                 }
    59 
    60                 if (strcmp(ccp->name, name) == 0)
    61                         break;
    62         }
    63 
    64         return cur;
    65 }
    66 
    67 int aim_chat_attachname(aim_conn_t *conn, guint16 exchange, const char *roomname, guint16 instance)
    68 {
    69         struct chatconnpriv *ccp;
    70 
    71         if (!conn || !roomname)
    72                 return -EINVAL;
    73 
    74         if (conn->priv)
    75                 g_free(conn->priv);
    76 
    77         if (!(ccp = g_malloc(sizeof(struct chatconnpriv))))
    78                 return -ENOMEM;
    79 
    80         ccp->exchange = exchange;
    81         ccp->name = g_strdup(roomname);
    82         ccp->instance = instance;
    83 
    84         conn->priv = (void *)ccp;
    85 
    86         return 0;
    8728}
    8829
     
    250191        outinfo->name = aimbs_getstr(bs, namelen);
    251192        outinfo->instance = aimbs_get16(bs);
    252 
    253         return 0;
    254 }
    255 
    256 int aim_chat_leaveroom(aim_session_t *sess, const char *name)
    257 {
    258         aim_conn_t *conn;
    259 
    260         if (!(conn = aim_chat_getconn(sess, name)))
    261                 return -ENOENT;
    262 
    263         aim_conn_close(conn);
    264193
    265194        return 0;
  • protocols/oscar/conn.c

    rbfafb99 re31e5b8  
    351351
    352352        return cur;
    353 }
    354 
    355 /**
    356  * aim_cloneconn - clone an aim_conn_t
    357  * @sess: session containing parent
    358  * @src: connection to clone
    359  *
    360  * A new connection is allocated, and the values are filled in
    361  * appropriately. Note that this function sets the new connnection's
    362  * ->priv pointer to be equal to that of its parent: only the pointer
    363  * is copied, not the data it points to.
    364  *
    365  * This function returns a pointer to the new aim_conn_t, or %NULL on
    366  * error
    367  */
    368 aim_conn_t *aim_cloneconn(aim_session_t *sess, aim_conn_t *src)
    369 {
    370         aim_conn_t *conn;
    371 
    372         if (!(conn = aim_conn_getnext(sess)))
    373                 return NULL;
    374 
    375         conn->fd = src->fd;
    376         conn->type = src->type;
    377         conn->subtype = src->subtype;
    378         conn->seqnum = src->seqnum;
    379         conn->priv = src->priv;
    380         conn->internal = src->internal;
    381         conn->lastactivity = src->lastactivity;
    382         conn->forcedlatency = src->forcedlatency;
    383         conn->sessv = src->sessv;
    384         aim_clonehandlers(sess, conn, src);
    385 
    386         if (src->inside) {
    387                 /*
    388                  * XXX should clone this section as well, but since currently
    389                  * this function only gets called for some of that rendezvous
    390                  * crap, and not on SNAC connections, its probably okay for
    391                  * now.
    392                  *
    393                  */
    394         }
    395 
    396         return conn;
    397353}
    398354
  • protocols/oscar/icq.c

    rbfafb99 re31e5b8  
    6565        aimbs_putle16(&fr->data, 0x003e); /* I command thee. */
    6666        aimbs_putle16(&fr->data, snacid); /* eh. */
    67 
    68         aim_tx_enqueue(sess, fr);
    69 
    70         return 0;
    71 }
    72 
    73 int aim_icq_sendxmlreq(aim_session_t *sess, const char *xml)
    74 {
    75         aim_conn_t *conn;
    76         aim_frame_t *fr;
    77         aim_snacid_t snacid;
    78         int bslen;
    79 
    80         if (!xml || !strlen(xml))
    81                 return -EINVAL;
    82 
    83         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
    84                 return -EINVAL;
    85 
    86         bslen = 2 + 10 + 2 + strlen(xml) + 1;
    87 
    88         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
    89                 return -ENOMEM;
    90 
    91         snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
    92         aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
    93 
    94         /* For simplicity, don't bother using a tlvlist */
    95         aimbs_put16(&fr->data, 0x0001);
    96         aimbs_put16(&fr->data, bslen);
    97 
    98         aimbs_putle16(&fr->data, bslen - 2);
    99         aimbs_putle32(&fr->data, atoi(sess->sn));
    100         aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
    101         aimbs_putle16(&fr->data, snacid); /* eh. */
    102         aimbs_putle16(&fr->data, 0x0998); /* shrug. */
    103         aimbs_putle16(&fr->data, strlen(xml) + 1);
    104         aimbs_putraw(&fr->data, (guint8 *)xml, strlen(xml) + 1);
    10567
    10668        aim_tx_enqueue(sess, fr);
     
    152114
    153115        return 0;
    154 }
    155 
    156 int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin)
    157 {
    158         aim_conn_t *conn;
    159         aim_frame_t *fr;
    160         aim_snacid_t snacid;
    161         int bslen;
    162 
    163         if (!uin || uin[0] < '0' || uin[0] > '9')
    164                 return -EINVAL;
    165 
    166         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
    167                 return -EINVAL;
    168 
    169         bslen = 2 + 4 + 2 + 2 + 2 + 4;
    170 
    171         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
    172                 return -ENOMEM;
    173 
    174         snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
    175         aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
    176 
    177         /* For simplicity, don't bother using a tlvlist */
    178         aimbs_put16(&fr->data, 0x0001);
    179         aimbs_put16(&fr->data, bslen);
    180 
    181         aimbs_putle16(&fr->data, bslen - 2);
    182         aimbs_putle32(&fr->data, atoi(sess->sn));
    183         aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
    184         aimbs_putle16(&fr->data, snacid); /* eh. */
    185         aimbs_putle16(&fr->data, 0x051f); /* shrug. */
    186         aimbs_putle32(&fr->data, atoi(uin));
    187 
    188         aim_tx_enqueue(sess, fr);
    189 
    190         return 0;
    191116}
    192117
  • protocols/oscar/icq.h

    rbfafb99 re31e5b8  
    9494int aim_icq_ackofflinemsgs(aim_session_t *sess);
    9595int aim_icq_getallinfo(aim_session_t *sess, const char *uin);
    96 int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin);
    9796
    9897#endif /* __OSCAR_ICQ_H__ */
  • protocols/oscar/im.c

    rbfafb99 re31e5b8  
    2323#include "im.h"
    2424#include "info.h"
    25 
    26 /*
    27  * Takes a msghdr (and a length) and returns a client type
    28  * code.  Note that this is *only a guess* and has a low likelihood
    29  * of actually being accurate.
    30  *
    31  * Its based on experimental data, with the help of Eric Warmenhoven
    32  * who seems to have collected a wide variety of different AIM clients.
    33  *
    34  *
    35  * Heres the current collection:
    36  *  0501 0003 0101 0101 01       AOL Mobile Communicator, WinAIM 1.0.414
    37  *  0501 0003 0101 0201 01       WinAIM 2.0.847, 2.1.1187, 3.0.1464,
    38  *                                      4.3.2229, 4.4.2286
    39  *  0501 0004 0101 0102 0101     WinAIM 4.1.2010, libfaim (right here)
    40  *  0501 0001 0101 01            AOL v6.0, CompuServe 2000 v6.0, any
    41  *                                      TOC client
    42  *
    43  * Note that in this function, only the feature bytes are tested, since
    44  * the rest will always be the same.
    45  *
    46  */
    47 guint16 aim_fingerprintclient(guint8 *msghdr, int len)
    48 {
    49         static const struct {
    50                 guint16 clientid;
    51                 int len;
    52                 guint8 data[10];
    53         } fingerprints[] = {
    54                 /* AOL Mobile Communicator, WinAIM 1.0.414 */
    55                 { AIM_CLIENTTYPE_MC,
    56                   3, {0x01, 0x01, 0x01}},
    57 
    58                 /* WinAIM 2.0.847, 2.1.1187, 3.0.1464, 4.3.2229, 4.4.2286 */
    59                 { AIM_CLIENTTYPE_WINAIM,
    60                   3, {0x01, 0x01, 0x02}},
    61 
    62                 /* WinAIM 4.1.2010, libfaim */
    63                 { AIM_CLIENTTYPE_WINAIM41,
    64                   4, {0x01, 0x01, 0x01, 0x02}},
    65 
    66                 /* AOL v6.0, CompuServe 2000 v6.0, any TOC client */
    67                 { AIM_CLIENTTYPE_AOL_TOC,
    68                   1, {0x01}},
    69 
    70                 { 0, 0}
    71         };
    72         int i;
    73 
    74         if (!msghdr || (len <= 0))
    75                 return AIM_CLIENTTYPE_UNKNOWN;
    76 
    77         for (i = 0; fingerprints[i].len; i++) {
    78                 if (fingerprints[i].len != len)
    79                         continue;
    80                 if (memcmp(fingerprints[i].data, msghdr, fingerprints[i].len) == 0)
    81                         return fingerprints[i].clientid;
    82         }
    83 
    84         return AIM_CLIENTTYPE_UNKNOWN;
    85 }
    86 
    87 /* This should be endian-safe now... but who knows... */
    88 guint16 aim_iconsum(const guint8 *buf, int buflen)
    89 {
    90         guint32 sum;
    91         int i;
    92 
    93         for (i = 0, sum = 0; i + 1 < buflen; i += 2)
    94                 sum += (buf[i+1] << 8) + buf[i];
    95         if (i < buflen)
    96                 sum += buf[i];
    97 
    98         sum = ((sum & 0xffff0000) >> 16) + (sum & 0x0000ffff);
    99 
    100         return (guint16)sum;
    101 }
    10225
    10326/*
     
    367290}
    368291
    369 /*
    370  * This is also performance sensitive. (If you can believe it...)
    371  *
    372  */
    373 int aim_send_icon(aim_session_t *sess, const char *sn, const guint8 *icon, int iconlen, time_t stamp, guint16 iconsum)
    374 {
    375         aim_conn_t *conn;
    376         int i;
    377         guint8 ck[8];
    378         aim_frame_t *fr;
    379         aim_snacid_t snacid;
    380 
    381         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
    382                 return -EINVAL;
    383 
    384         if (!sn || !icon || (iconlen <= 0) || (iconlen >= MAXICONLEN))
    385                 return -EINVAL;
    386 
    387         for (i = 0; i < 8; i++)
    388                 aimutil_put8(ck+i, (guint8) rand());
    389 
    390         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2)))
    391                 return -ENOMEM;
    392 
    393         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    394         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    395 
    396         /*
    397          * Cookie
    398          */
    399         aimbs_putraw(&fr->data, ck, 8);
    400 
    401         /*
    402          * Channel (2)
    403          */
    404         aimbs_put16(&fr->data, 0x0002);
    405 
    406         /*
    407          * Dest sn
    408          */
    409         aimbs_put8(&fr->data, strlen(sn));
    410         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    411 
    412         /*
    413          * TLV t(0005)
    414          *
    415          * Encompasses everything below.
    416          */
    417         aimbs_put16(&fr->data, 0x0005);
    418         aimbs_put16(&fr->data, 2+8+16+6+4+4+iconlen+4+4+4+strlen(AIM_ICONIDENT));
    419 
    420         aimbs_put16(&fr->data, 0x0000);
    421         aimbs_putraw(&fr->data, ck, 8);
    422         aim_putcap(&fr->data, AIM_CAPS_BUDDYICON);
    423 
    424         /* TLV t(000a) */
    425         aimbs_put16(&fr->data, 0x000a);
    426         aimbs_put16(&fr->data, 0x0002);
    427         aimbs_put16(&fr->data, 0x0001);
    428 
    429         /* TLV t(000f) */
    430         aimbs_put16(&fr->data, 0x000f);
    431         aimbs_put16(&fr->data, 0x0000);
    432 
    433         /* TLV t(2711) */
    434         aimbs_put16(&fr->data, 0x2711);
    435         aimbs_put16(&fr->data, 4+4+4+iconlen+strlen(AIM_ICONIDENT));
    436         aimbs_put16(&fr->data, 0x0000);
    437         aimbs_put16(&fr->data, iconsum);
    438         aimbs_put32(&fr->data, iconlen);
    439         aimbs_put32(&fr->data, stamp);
    440         aimbs_putraw(&fr->data, icon, iconlen);
    441         aimbs_putraw(&fr->data, (guint8 *)AIM_ICONIDENT, strlen(AIM_ICONIDENT));
    442 
    443         /* TLV t(0003) */
    444         aimbs_put16(&fr->data, 0x0003);
    445         aimbs_put16(&fr->data, 0x0000);
    446 
    447         aim_tx_enqueue(sess, fr);
    448 
    449         return 0;
    450 }
    451 
    452 /*
    453  * This only works for ICQ 2001b (thats 2001 not 2000).  Better, only
    454  * send it to clients advertising the RTF capability.  In fact, if you send
    455  * it to a client that doesn't support that capability, the server will gladly
    456  * bounce it back to you.
    457  *
    458  * You'd think this would be in icq.c, but, well, I'm trying to stick with
    459  * the one-group-per-file scheme as much as possible.  This could easily
    460  * be an exception, since Rendezvous IMs are external of the Oscar core,
    461  * and therefore are undefined.  Really I just need to think of a good way to
    462  * make an interface similar to what AOL actually uses.  But I'm not using COM.
    463  *
    464  */
    465 int aim_send_rtfmsg(aim_session_t *sess, struct aim_sendrtfmsg_args *args)
    466 {
    467         const char rtfcap[] = {"{97B12751-243C-4334-AD22-D6ABF73F1492}"}; /* AIM_CAPS_ICQRTF capability in string form */
    468         aim_conn_t *conn;
    469         int i;
    470         guint8 ck[8];
    471         aim_frame_t *fr;
    472         aim_snacid_t snacid;
    473         int servdatalen;
    474 
    475         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
    476                 return -EINVAL;
    477 
    478         if (!args || !args->destsn || !args->rtfmsg)
    479                 return -EINVAL;
    480 
    481         servdatalen = 2+2+16+2+4+1+2  +  2+2+4+4+4  +  2+4+2+strlen(args->rtfmsg)+1  +  4+4+4+strlen(rtfcap)+1;
    482 
    483         for (i = 0; i < 8; i++)
    484                 aimutil_put8(ck+i, (guint8) rand());
    485 
    486         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+128+servdatalen)))
    487                 return -ENOMEM;
    488 
    489         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    490         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    491 
    492         /*
    493          * Cookie
    494          */
    495         aimbs_putraw(&fr->data, ck, 8);
    496 
    497         /*
    498          * Channel (2)
    499          */
    500         aimbs_put16(&fr->data, 0x0002);
    501 
    502         /*
    503          * Dest sn
    504          */
    505         aimbs_put8(&fr->data, strlen(args->destsn));
    506         aimbs_putraw(&fr->data, (guint8 *)args->destsn, strlen(args->destsn));
    507 
    508         /*
    509          * TLV t(0005)
    510          *
    511          * Encompasses everything below.
    512          */
    513         aimbs_put16(&fr->data, 0x0005);
    514         aimbs_put16(&fr->data, 2+8+16  +  2+2+2  +  2+2  +  2+2+servdatalen);
    515 
    516         aimbs_put16(&fr->data, 0x0000);
    517         aimbs_putraw(&fr->data, ck, 8);
    518         aim_putcap(&fr->data, AIM_CAPS_ICQSERVERRELAY);
    519 
    520         /*
    521          * t(000a) l(0002) v(0001)
    522          */
    523         aimbs_put16(&fr->data, 0x000a);
    524         aimbs_put16(&fr->data, 0x0002);
    525         aimbs_put16(&fr->data, 0x0001);
    526 
    527         /*
    528          * t(000f) l(0000) v()
    529          */
    530         aimbs_put16(&fr->data, 0x000f);
    531         aimbs_put16(&fr->data, 0x0000);
    532 
    533         /*
    534          * Service Data TLV
    535          */
    536         aimbs_put16(&fr->data, 0x2711);
    537         aimbs_put16(&fr->data, servdatalen);
    538 
    539         aimbs_putle16(&fr->data, 11 + 16 /* 11 + (sizeof CLSID) */);
    540         aimbs_putle16(&fr->data, 9);
    541         aim_putcap(&fr->data, AIM_CAPS_EMPTY);
    542         aimbs_putle16(&fr->data, 0);
    543         aimbs_putle32(&fr->data, 0);
    544         aimbs_putle8(&fr->data, 0);
    545         aimbs_putle16(&fr->data, 0x03ea); /* trid1 */
    546 
    547         aimbs_putle16(&fr->data, 14);
    548         aimbs_putle16(&fr->data, 0x03eb); /* trid2 */
    549         aimbs_putle32(&fr->data, 0);
    550         aimbs_putle32(&fr->data, 0);
    551         aimbs_putle32(&fr->data, 0);
    552 
    553         aimbs_putle16(&fr->data, 0x0001);
    554         aimbs_putle32(&fr->data, 0);
    555         aimbs_putle16(&fr->data, strlen(args->rtfmsg)+1);
    556         aimbs_putraw(&fr->data, (guint8 *)args->rtfmsg, strlen(args->rtfmsg)+1);
    557 
    558         aimbs_putle32(&fr->data, args->fgcolor);
    559         aimbs_putle32(&fr->data, args->bgcolor);
    560         aimbs_putle32(&fr->data, strlen(rtfcap)+1);
    561         aimbs_putraw(&fr->data, (guint8 *)rtfcap, strlen(rtfcap)+1);
    562 
    563         aim_tx_enqueue(sess, fr);
    564 
    565         return 0;
    566 }
    567 
    568 int aim_request_directim(aim_session_t *sess, const char *destsn, guint8 *ip, guint16 port, guint8 *ckret)
    569 {
    570         aim_conn_t *conn;
    571         guint8 ck[8];
    572         aim_frame_t *fr;
    573         aim_snacid_t snacid;
    574         aim_tlvlist_t *tl = NULL, *itl = NULL;
    575         int hdrlen, i;
    576         guint8 *hdr;
    577         aim_bstream_t hdrbs;
    578 
    579         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
    580                 return -EINVAL;
    581 
    582         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 256+strlen(destsn))))
    583                 return -ENOMEM;
    584 
    585         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    586         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    587 
    588         /*
    589          * Generate a random message cookie
    590          *
    591          * This cookie needs to be alphanumeric and NULL-terminated to be
    592          * TOC-compatible.
    593          *
    594          * XXX have I mentioned these should be generated in msgcookie.c?
    595          *
    596          */
    597         for (i = 0; i < 7; i++)
    598                 ck[i] = 0x30 + ((guint8) rand() % 10);
    599         ck[7] = '\0';
    600 
    601         if (ckret)
    602                 memcpy(ckret, ck, 8);
    603 
    604         /* Cookie */
    605         aimbs_putraw(&fr->data, ck, 8);
    606 
    607         /* Channel */
    608         aimbs_put16(&fr->data, 0x0002);
    609 
    610         /* Destination SN */
    611         aimbs_put8(&fr->data, strlen(destsn));
    612         aimbs_putraw(&fr->data, (guint8 *)destsn, strlen(destsn));
    613 
    614         aim_addtlvtochain_noval(&tl, 0x0003);
    615 
    616         hdrlen = 2+8+16+6+8+6+4;
    617         hdr = g_malloc(hdrlen);
    618         aim_bstream_init(&hdrbs, hdr, hdrlen);
    619 
    620         aimbs_put16(&hdrbs, 0x0000);
    621         aimbs_putraw(&hdrbs, ck, 8);
    622         aim_putcap(&hdrbs, AIM_CAPS_IMIMAGE);
    623 
    624         aim_addtlvtochain16(&itl, 0x000a, 0x0001);
    625         aim_addtlvtochain_raw(&itl, 0x0003, 4, ip);
    626         aim_addtlvtochain16(&itl, 0x0005, port);
    627         aim_addtlvtochain_noval(&itl, 0x000f);
    628        
    629         aim_writetlvchain(&hdrbs, &itl);
    630 
    631         aim_addtlvtochain_raw(&tl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);
    632 
    633         aim_writetlvchain(&fr->data, &tl);
    634 
    635         g_free(hdr);
    636         aim_freetlvchain(&itl);
    637         aim_freetlvchain(&tl);
    638 
    639         aim_tx_enqueue(sess, fr);
    640 
    641         return 0;
    642 }
    643 
    644 int aim_request_sendfile(aim_session_t *sess, const char *sn, const char *filename, guint16 numfiles, guint32 totsize, guint8 *ip, guint16 port, guint8 *ckret)
    645 {
    646         aim_conn_t *conn;
    647         int i;
    648         guint8 ck[8];
    649         aim_frame_t *fr;
    650         aim_snacid_t snacid;
    651 
    652         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
    653                 return -EINVAL;
    654 
    655         if (!sn || !filename)
    656                 return -EINVAL;
    657 
    658         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn)+2+2+2+8+16+6+8+6+4+2+2+2+2+4+strlen(filename)+4)))
    659                 return -ENOMEM;
    660 
    661         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    662         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    663 
    664         for (i = 0; i < 7; i++)
    665                 aimutil_put8(ck+i, 0x30 + ((guint8) rand() % 10));
    666         ck[7] = '\0';
    667 
    668         if (ckret)
    669                 memcpy(ckret, ck, 8);
    670 
    671         /*
    672          * Cookie
    673          */
    674         aimbs_putraw(&fr->data, ck, 8);
    675 
    676         /*
    677          * Channel (2)
    678          */
    679         aimbs_put16(&fr->data, 0x0002);
    680 
    681         /*
    682          * Dest sn
    683          */
    684         aimbs_put8(&fr->data, strlen(sn));
    685         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    686 
    687         /*
    688          * TLV t(0005)
    689          *
    690          * Encompasses everything below. Gee.
    691          */
    692         aimbs_put16(&fr->data, 0x0005);
    693         aimbs_put16(&fr->data, 2+8+16+6+8+6+4+2+2+2+2+4+strlen(filename)+4);
    694 
    695         aimbs_put16(&fr->data, 0x0000);
    696         aimbs_putraw(&fr->data, ck, 8);
    697         aim_putcap(&fr->data, AIM_CAPS_SENDFILE);
    698 
    699         /* TLV t(000a) */
    700         aimbs_put16(&fr->data, 0x000a);
    701         aimbs_put16(&fr->data, 0x0002);
    702         aimbs_put16(&fr->data, 0x0001);
    703 
    704         /* TLV t(0003) (IP) */
    705         aimbs_put16(&fr->data, 0x0003);
    706         aimbs_put16(&fr->data, 0x0004);
    707         aimbs_putraw(&fr->data, ip, 4);
    708 
    709         /* TLV t(0005) (port) */
    710         aimbs_put16(&fr->data, 0x0005);
    711         aimbs_put16(&fr->data, 0x0002);
    712         aimbs_put16(&fr->data, port);
    713 
    714         /* TLV t(000f) */
    715         aimbs_put16(&fr->data, 0x000f);
    716         aimbs_put16(&fr->data, 0x0000);
    717 
    718         /* TLV t(2711) */
    719         aimbs_put16(&fr->data, 0x2711);
    720         aimbs_put16(&fr->data, 2+2+4+strlen(filename)+4);
    721 
    722         /* ? */
    723         aimbs_put16(&fr->data, 0x0001);
    724         aimbs_put16(&fr->data, numfiles);
    725         aimbs_put32(&fr->data, totsize);
    726         aimbs_putraw(&fr->data, (guint8 *)filename, strlen(filename));
    727 
    728         /* ? */
    729         aimbs_put32(&fr->data, 0x00000000);
    730 
    731         aim_tx_enqueue(sess, fr);
    732 
    733         return 0;
    734 }
    735 
    736 /**
    737  * Request the status message of the given ICQ user.
    738  *
    739  * @param sess The oscar session.
    740  * @param sn The UIN of the user of whom you wish to request info.
    741  * @param type The type of info you wish to request.  This should be the current
    742  *        state of the user, as one of the AIM_ICQ_STATE_* defines.
    743  * @return Return 0 if no errors, otherwise return the error number.
    744  */
    745 int aim_send_im_ch2_geticqmessage(aim_session_t *sess, const char *sn, int type)
    746 {
    747         aim_conn_t *conn;
    748         int i;
    749         guint8 ck[8];
    750         aim_frame_t *fr;
    751         aim_snacid_t snacid;
    752 
    753         if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)) || !sn)
    754                 return -EINVAL;
    755 
    756         for (i = 0; i < 8; i++)
    757                 aimutil_put8(ck+i, (guint8) rand());
    758 
    759         if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn) + 4+0x5e + 4)))
    760                 return -ENOMEM;
    761 
    762         snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
    763         aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
    764 
    765         /* Cookie */
    766         aimbs_putraw(&fr->data, ck, 8);
    767 
    768         /* Channel (2) */
    769         aimbs_put16(&fr->data, 0x0002);
    770 
    771         /* Dest sn */
    772         aimbs_put8(&fr->data, strlen(sn));
    773         aimbs_putraw(&fr->data, (guint8 *)sn, strlen(sn));
    774 
    775         /* TLV t(0005) - Encompasses almost everything below. */
    776         aimbs_put16(&fr->data, 0x0005); /* T */
    777         aimbs_put16(&fr->data, 0x005e); /* L */
    778         { /* V */
    779                 aimbs_put16(&fr->data, 0x0000);
    780 
    781                 /* Cookie */
    782                 aimbs_putraw(&fr->data, ck, 8);
    783 
    784                 /* Put the 16 byte server relay capability */
    785                 aim_putcap(&fr->data, AIM_CAPS_ICQSERVERRELAY);
    786 
    787                 /* TLV t(000a) */
    788                 aimbs_put16(&fr->data, 0x000a);
    789                 aimbs_put16(&fr->data, 0x0002);
    790                 aimbs_put16(&fr->data, 0x0001);
    791 
    792                 /* TLV t(000f) */
    793                 aimbs_put16(&fr->data, 0x000f);
    794                 aimbs_put16(&fr->data, 0x0000);
    795 
    796                 /* TLV t(2711) */
    797                 aimbs_put16(&fr->data, 0x2711);
    798                 aimbs_put16(&fr->data, 0x0036);
    799                 { /* V */
    800                         aimbs_putle16(&fr->data, 0x001b); /* L */
    801                         aimbs_putle16(&fr->data, 0x0008); /* AAA - Protocol version */
    802                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    803                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    804                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    805                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    806                         aimbs_putle16(&fr->data, 0x0000); /* Unknown */
    807                         aimbs_putle16(&fr->data, 0x0003); /* Client features? */
    808                         aimbs_putle16(&fr->data, 0x0000); /* Unknown */
    809                         aimbs_putle8(&fr->data, 0x00); /* Unkizown */
    810                         aimbs_putle16(&fr->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
    811 
    812                         aimbs_putle16(&fr->data, 0x000e); /* L */
    813                         aimbs_putle16(&fr->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
    814                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    815                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    816                         aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    817 
    818                         /* The type of status message being requested */
    819                         if (type & AIM_ICQ_STATE_CHAT)
    820                                 aimbs_putle16(&fr->data, 0x03ec);
    821                         else if(type & AIM_ICQ_STATE_DND)
    822                                 aimbs_putle16(&fr->data, 0x03eb);
    823                         else if(type & AIM_ICQ_STATE_OUT)
    824                                 aimbs_putle16(&fr->data, 0x03ea);
    825                         else if(type & AIM_ICQ_STATE_BUSY)
    826                                 aimbs_putle16(&fr->data, 0x03e9);
    827                         else if(type & AIM_ICQ_STATE_AWAY)
    828                                 aimbs_putle16(&fr->data, 0x03e8);
    829 
    830                         aimbs_putle16(&fr->data, 0x0000); /* Status? */
    831                         aimbs_putle16(&fr->data, 0x0001); /* Priority of this message? */
    832                         aimbs_putle16(&fr->data, 0x0001); /* L? */
    833                         aimbs_putle8(&fr->data, 0x00); /* Null termination? */
    834                 } /* End TLV t(2711) */
    835         } /* End TLV t(0005) */
    836 
    837         /* TLV t(0003) */
    838         aimbs_put16(&fr->data, 0x0003);
    839         aimbs_put16(&fr->data, 0x0000);
    840 
    841         aim_tx_enqueue(sess, fr);
    842 
    843         return 0;
    844 }
    845 
    846292/**
    847293 * answers status message requests