diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e142a52
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,625 @@
+GNU GENERAL PUBLIC LICENSE
+
+Version 3, 29 June 2007
+
+Copyright © 2007 Free Software Foundation, Inc.
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The GNU General Public License is a free, copyleft license for software and
+other kinds of works.
+
+The licenses for most software and other practical works are designed to take
+away your freedom to share and change the works. By contrast, the GNU General
+Public License is intended to guarantee your freedom to share and change all
+versions of a program--to make sure it remains free software for all its users.
+We, the Free Software Foundation, use the GNU General Public License for most
+of our software; it applies also to any other work released this way by its
+authors. You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for them if you wish), that
+you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs, and that you know you
+can do these things.
+
+To protect your rights, we need to prevent others from denying you these rights
+or asking you to surrender the rights. Therefore, you have certain responsibilities
+if you distribute copies of the software, or if you modify it: responsibilities
+to respect the freedom of others.
+
+For example, if you distribute copies of such a program, whether gratis or
+for a fee, you must pass on to the recipients the same freedoms that you received.
+You must make sure that they, too, receive or can get the source code. And
+you must show them these terms so they know their rights.
+
+Developers that use the GNU GPL protect your rights with two steps: (1) assert
+copyright on the software, and (2) offer you this License giving you legal
+permission to copy, distribute and/or modify it.
+
+For the developers' and authors' protection, the GPL clearly explains that
+there is no warranty for this free software. For both users' and authors'
+sake, the GPL requires that modified versions be marked as changed, so that
+their problems will not be attributed erroneously to authors of previous versions.
+
+Some devices are designed to deny users access to install or run modified
+versions of the software inside them, although the manufacturer can do so.
+This is fundamentally incompatible with the aim of protecting users' freedom
+to change the software. The systematic pattern of such abuse occurs in the
+area of products for individuals to use, which is precisely where it is most
+unacceptable. Therefore, we have designed this version of the GPL to prohibit
+the practice for those products. If such problems arise substantially in other
+domains, we stand ready to extend this provision to those domains in future
+versions of the GPL, as needed to protect the freedom of users.
+
+Finally, every program is threatened constantly by software patents. States
+should not allow patents to restrict development and use of software on general-purpose
+computers, but in those that do, we wish to avoid the special danger that
+patents applied to a free program could make it effectively proprietary. To
+prevent this, the GPL assures that patents cannot be used to render the program
+non-free.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+"Copyright" also means copyright-like laws that apply to other kinds of works,
+such as semiconductor masks.
+
+"The Program" refers to any copyrightable work licensed under this License.
+Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals
+or organizations.
+
+To "modify" a work means to copy from or adapt all or part of the work in
+a fashion requiring copyright permission, other than the making of an exact
+copy. The resulting work is called a "modified version" of the earlier work
+or a work "based on" the earlier work.
+
+A "covered work" means either the unmodified Program or a work based on the
+Program.
+
+To "propagate" a work means to do anything with it that, without permission,
+would make you directly or secondarily liable for infringement under applicable
+copyright law, except executing it on a computer or modifying a private copy.
+Propagation includes copying, distribution (with or without modification),
+making available to the public, and in some countries other activities as
+well.
+
+To "convey" a work means any kind of propagation that enables other parties
+to make or receive copies. Mere interaction with a user through a computer
+network, with no transfer of a copy, is not conveying.
+
+An interactive user interface displays "Appropriate Legal Notices" to the
+extent that it includes a convenient and prominently visible feature that
+(1) displays an appropriate copyright notice, and (2) tells the user that
+there is no warranty for the work (except to the extent that warranties are
+provided), that licensees may convey the work under this License, and how
+to view a copy of this License. If the interface presents a list of user commands
+or options, such as a menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+The "source code" for a work means the preferred form of the work for making
+modifications to it. "Object code" means any non-source form of a work.
+
+A "Standard Interface" means an interface that either is an official standard
+defined by a recognized standards body, or, in the case of interfaces specified
+for a particular programming language, one that is widely used among developers
+working in that language.
+
+The "System Libraries" of an executable work include anything, other than
+the work as a whole, that (a) is included in the normal form of packaging
+a Major Component, but which is not part of that Major Component, and (b)
+serves only to enable use of the work with that Major Component, or to implement
+a Standard Interface for which an implementation is available to the public
+in source code form. A "Major Component", in this context, means a major essential
+component (kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to produce
+the work, or an object code interpreter used to run it.
+
+The "Corresponding Source" for a work in object code form means all the source
+code needed to generate, install, and (for an executable work) run the object
+code and to modify the work, including scripts to control those activities.
+However, it does not include the work's System Libraries, or general-purpose
+tools or generally available free programs which are used unmodified in performing
+those activities but which are not part of the work. For example, Corresponding
+Source includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically linked
+subprograms that the work is specifically designed to require, such as by
+intimate data communication or control flow between those subprograms and
+other parts of the work.
+
+The Corresponding Source need not include anything that users can regenerate
+automatically from other parts of the Corresponding Source.
+
+ The Corresponding Source for a work in source code form is that same work.
+
+ 2. Basic Permissions.
+
+All rights granted under this License are granted for the term of copyright
+on the Program, and are irrevocable provided the stated conditions are met.
+This License explicitly affirms your unlimited permission to run the unmodified
+Program. The output from running a covered work is covered by this License
+only if the output, given its content, constitutes a covered work. This License
+acknowledges your rights of fair use or other equivalent, as provided by copyright
+law.
+
+You may make, run and propagate covered works that you do not convey, without
+conditions so long as your license otherwise remains in force. You may convey
+covered works to others for the sole purpose of having them make modifications
+exclusively for you, or provide you with facilities for running those works,
+provided that you comply with the terms of this License in conveying all material
+for which you do not control copyright. Those thus making or running the covered
+works for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of your copyrighted
+material outside their relationship with you.
+
+Conveying under any other circumstances is permitted solely under the conditions
+stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+No covered work shall be deemed part of an effective technological measure
+under any applicable law fulfilling obligations under article 11 of the WIPO
+copyright treaty adopted on 20 December 1996, or similar laws prohibiting
+or restricting circumvention of such measures.
+
+When you convey a covered work, you waive any legal power to forbid circumvention
+of technological measures to the extent such circumvention is effected by
+exercising rights under this License with respect to the covered work, and
+you disclaim any intention to limit operation or modification of the work
+as a means of enforcing, against the work's users, your or third parties'
+legal rights to forbid circumvention of technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+You may convey verbatim copies of the Program's source code as you receive
+it, in any medium, provided that you conspicuously and appropriately publish
+on each copy an appropriate copyright notice; keep intact all notices stating
+that this License and any non-permissive terms added in accord with section
+7 apply to the code; keep intact all notices of the absence of any warranty;
+and give all recipients a copy of this License along with the Program.
+
+You may charge any price or no price for each copy that you convey, and you
+may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+You may convey a work based on the Program, or the modifications to produce
+it from the Program, in the form of source code under the terms of section
+4, provided that you also meet all of these conditions:
+
+a) The work must carry prominent notices stating that you modified it, and
+giving a relevant date.
+
+b) The work must carry prominent notices stating that it is released under
+this License and any conditions added under section 7. This requirement modifies
+the requirement in section 4 to "keep intact all notices".
+
+c) You must license the entire work, as a whole, under this License to anyone
+who comes into possession of a copy. This License will therefore apply, along
+with any applicable section 7 additional terms, to the whole of the work,
+and all its parts, regardless of how they are packaged. This License gives
+no permission to license the work in any other way, but it does not invalidate
+such permission if you have separately received it.
+
+d) If the work has interactive user interfaces, each must display Appropriate
+Legal Notices; however, if the Program has interactive interfaces that do
+not display Appropriate Legal Notices, your work need not make them do so.
+
+A compilation of a covered work with other separate and independent works,
+which are not by their nature extensions of the covered work, and which are
+not combined with it such as to form a larger program, in or on a volume of
+a storage or distribution medium, is called an "aggregate" if the compilation
+and its resulting copyright are not used to limit the access or legal rights
+of the compilation's users beyond what the individual works permit. Inclusion
+of a covered work in an aggregate does not cause this License to apply to
+the other parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+You may convey a covered work in object code form under the terms of sections
+4 and 5, provided that you also convey the machine-readable Corresponding
+Source under the terms of this License, in one of these ways:
+
+a) Convey the object code in, or embodied in, a physical product (including
+a physical distribution medium), accompanied by the Corresponding Source fixed
+on a durable physical medium customarily used for software interchange.
+
+b) Convey the object code in, or embodied in, a physical product (including
+a physical distribution medium), accompanied by a written offer, valid for
+at least three years and valid for as long as you offer spare parts or customer
+support for that product model, to give anyone who possesses the object code
+either (1) a copy of the Corresponding Source for all the software in the
+product that is covered by this License, on a durable physical medium customarily
+used for software interchange, for a price no more than your reasonable cost
+of physically performing this conveying of source, or (2) access to copy the
+Corresponding Source from a network server at no charge.
+
+c) Convey individual copies of the object code with a copy of the written
+offer to provide the Corresponding Source. This alternative is allowed only
+occasionally and noncommercially, and only if you received the object code
+with such an offer, in accord with subsection 6b.
+
+d) Convey the object code by offering access from a designated place (gratis
+or for a charge), and offer equivalent access to the Corresponding Source
+in the same way through the same place at no further charge. You need not
+require recipients to copy the Corresponding Source along with the object
+code. If the place to copy the object code is a network server, the Corresponding
+Source may be on a different server (operated by you or a third party) that
+supports equivalent copying facilities, provided you maintain clear directions
+next to the object code saying where to find the Corresponding Source. Regardless
+of what server hosts the Corresponding Source, you remain obligated to ensure
+that it is available for as long as needed to satisfy these requirements.
+
+e) Convey the object code using peer-to-peer transmission, provided you inform
+other peers where the object code and Corresponding Source of the work are
+being offered to the general public at no charge under subsection 6d.
+
+A separable portion of the object code, whose source code is excluded from
+the Corresponding Source as a System Library, need not be included in conveying
+the object code work.
+
+A "User Product" is either (1) a "consumer product", which means any tangible
+personal property which is normally used for personal, family, or household
+purposes, or (2) anything designed or sold for incorporation into a dwelling.
+In determining whether a product is a consumer product, doubtful cases shall
+be resolved in favor of coverage. For a particular product received by a particular
+user, "normally used" refers to a typical or common use of that class of product,
+regardless of the status of the particular user or of the way in which the
+particular user actually uses, or expects or is expected to use, the product.
+A product is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent the
+only significant mode of use of the product.
+
+"Installation Information" for a User Product means any methods, procedures,
+authorization keys, or other information required to install and execute modified
+versions of a covered work in that User Product from a modified version of
+its Corresponding Source. The information must suffice to ensure that the
+continued functioning of the modified object code is in no case prevented
+or interfered with solely because modification has been made.
+
+If you convey an object code work under this section in, or with, or specifically
+for use in, a User Product, and the conveying occurs as part of a transaction
+in which the right of possession and use of the User Product is transferred
+to the recipient in perpetuity or for a fixed term (regardless of how the
+transaction is characterized), the Corresponding Source conveyed under this
+section must be accompanied by the Installation Information. But this requirement
+does not apply if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has been installed
+in ROM).
+
+The requirement to provide Installation Information does not include a requirement
+to continue to provide support service, warranty, or updates for a work that
+has been modified or installed by the recipient, or for the User Product in
+which it has been modified or installed. Access to a network may be denied
+when the modification itself materially and adversely affects the operation
+of the network or violates the rules and protocols for communication across
+the network.
+
+Corresponding Source conveyed, and Installation Information provided, in accord
+with this section must be in a format that is publicly documented (and with
+an implementation available to the public in source code form), and must require
+no special password or key for unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+"Additional permissions" are terms that supplement the terms of this License
+by making exceptions from one or more of its conditions. Additional permissions
+that are applicable to the entire Program shall be treated as though they
+were included in this License, to the extent that they are valid under applicable
+law. If additional permissions apply only to part of the Program, that part
+may be used separately under those permissions, but the entire Program remains
+governed by this License without regard to the additional permissions.
+
+When you convey a copy of a covered work, you may at your option remove any
+additional permissions from that copy, or from any part of it. (Additional
+permissions may be written to require their own removal in certain cases when
+you modify the work.) You may place additional permissions on material, added
+by you to a covered work, for which you have or can give appropriate copyright
+permission.
+
+Notwithstanding any other provision of this License, for material you add
+to a covered work, you may (if authorized by the copyright holders of that
+material) supplement the terms of this License with terms:
+
+a) Disclaiming warranty or limiting liability differently from the terms of
+sections 15 and 16 of this License; or
+
+b) Requiring preservation of specified reasonable legal notices or author
+attributions in that material or in the Appropriate Legal Notices displayed
+by works containing it; or
+
+c) Prohibiting misrepresentation of the origin of that material, or requiring
+that modified versions of such material be marked in reasonable ways as different
+from the original version; or
+
+d) Limiting the use for publicity purposes of names of licensors or authors
+of the material; or
+
+e) Declining to grant rights under trademark law for use of some trade names,
+trademarks, or service marks; or
+
+f) Requiring indemnification of licensors and authors of that material by
+anyone who conveys the material (or modified versions of it) with contractual
+assumptions of liability to the recipient, for any liability that these contractual
+assumptions directly impose on those licensors and authors.
+
+All other non-permissive additional terms are considered "further restrictions"
+within the meaning of section 10. If the Program as you received it, or any
+part of it, contains a notice stating that it is governed by this License
+along with a term that is a further restriction, you may remove that term.
+If a license document contains a further restriction but permits relicensing
+or conveying under this License, you may add to a covered work material governed
+by the terms of that license document, provided that the further restriction
+does not survive such relicensing or conveying.
+
+If you add terms to a covered work in accord with this section, you must place,
+in the relevant source files, a statement of the additional terms that apply
+to those files, or a notice indicating where to find the applicable terms.
+
+Additional terms, permissive or non-permissive, may be stated in the form
+of a separately written license, or stated as exceptions; the above requirements
+apply either way.
+
+ 8. Termination.
+
+You may not propagate or modify a covered work except as expressly provided
+under this License. Any attempt otherwise to propagate or modify it is void,
+and will automatically terminate your rights under this License (including
+any patent licenses granted under the third paragraph of section 11).
+
+However, if you cease all violation of this License, then your license from
+a particular copyright holder is reinstated (a) provisionally, unless and
+until the copyright holder explicitly and finally terminates your license,
+and (b) permanently, if the copyright holder fails to notify you of the violation
+by some reasonable means prior to 60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is reinstated permanently
+if the copyright holder notifies you of the violation by some reasonable means,
+this is the first time you have received notice of violation of this License
+(for any work) from that copyright holder, and you cure the violation prior
+to 30 days after your receipt of the notice.
+
+Termination of your rights under this section does not terminate the licenses
+of parties who have received copies or rights from you under this License.
+If your rights have been terminated and not permanently reinstated, you do
+not qualify to receive new licenses for the same material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+You are not required to accept this License in order to receive or run a copy
+of the Program. Ancillary propagation of a covered work occurring solely as
+a consequence of using peer-to-peer transmission to receive a copy likewise
+does not require acceptance. However, nothing other than this License grants
+you permission to propagate or modify any covered work. These actions infringe
+copyright if you do not accept this License. Therefore, by modifying or propagating
+a covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+Each time you convey a covered work, the recipient automatically receives
+a license from the original licensors, to run, modify and propagate that work,
+subject to this License. You are not responsible for enforcing compliance
+by third parties with this License.
+
+An "entity transaction" is a transaction transferring control of an organization,
+or substantially all assets of one, or subdividing an organization, or merging
+organizations. If propagation of a covered work results from an entity transaction,
+each party to that transaction who receives a copy of the work also receives
+whatever licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the Corresponding
+Source of the work from the predecessor in interest, if the predecessor has
+it or can get it with reasonable efforts.
+
+You may not impose any further restrictions on the exercise of the rights
+granted or affirmed under this License. For example, you may not impose a
+license fee, royalty, or other charge for exercise of rights granted under
+this License, and you may not initiate litigation (including a cross-claim
+or counterclaim in a lawsuit) alleging that any patent claim is infringed
+by making, using, selling, offering for sale, or importing the Program or
+any portion of it.
+
+ 11. Patents.
+
+A "contributor" is a copyright holder who authorizes use under this License
+of the Program or a work on which the Program is based. The work thus licensed
+is called the contributor's "contributor version".
+
+A contributor's "essential patent claims" are all patent claims owned or controlled
+by the contributor, whether already acquired or hereafter acquired, that would
+be infringed by some manner, permitted by this License, of making, using,
+or selling its contributor version, but do not include claims that would be
+infringed only as a consequence of further modification of the contributor
+version. For purposes of this definition, "control" includes the right to
+grant patent sublicenses in a manner consistent with the requirements of this
+License.
+
+Each contributor grants you a non-exclusive, worldwide, royalty-free patent
+license under the contributor's essential patent claims, to make, use, sell,
+offer for sale, import and otherwise run, modify and propagate the contents
+of its contributor version.
+
+In the following three paragraphs, a "patent license" is any express agreement
+or commitment, however denominated, not to enforce a patent (such as an express
+permission to practice a patent or covenant not to sue for patent infringement).
+To "grant" such a patent license to a party means to make such an agreement
+or commitment not to enforce a patent against the party.
+
+If you convey a covered work, knowingly relying on a patent license, and the
+Corresponding Source of the work is not available for anyone to copy, free
+of charge and under the terms of this License, through a publicly available
+network server or other readily accessible means, then you must either (1)
+cause the Corresponding Source to be so available, or (2) arrange to deprive
+yourself of the benefit of the patent license for this particular work, or
+(3) arrange, in a manner consistent with the requirements of this License,
+to extend the patent license to downstream recipients. "Knowingly relying"
+means you have actual knowledge that, but for the patent license, your conveying
+the covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that country
+that you have reason to believe are valid.
+
+If, pursuant to or in connection with a single transaction or arrangement,
+you convey, or propagate by procuring conveyance of, a covered work, and grant
+a patent license to some of the parties receiving the covered work authorizing
+them to use, propagate, modify or convey a specific copy of the covered work,
+then the patent license you grant is automatically extended to all recipients
+of the covered work and works based on it.
+
+A patent license is "discriminatory" if it does not include within the scope
+of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
+of one or more of the rights that are specifically granted under this License.
+You may not convey a covered work if you are a party to an arrangement with
+a third party that is in the business of distributing software, under which
+you make payment to the third party based on the extent of your activity of
+conveying the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory patent
+license (a) in connection with copies of the covered work conveyed by you
+(or copies made from those copies), or (b) primarily for and in connection
+with specific products or compilations that contain the covered work, unless
+you entered into that arrangement, or that patent license was granted, prior
+to 28 March 2007.
+
+Nothing in this License shall be construed as excluding or limiting any implied
+license or other defenses to infringement that may otherwise be available
+to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+If conditions are imposed on you (whether by court order, agreement or otherwise)
+that contradict the conditions of this License, they do not excuse you from
+the conditions of this License. If you cannot convey a covered work so as
+to satisfy simultaneously your obligations under this License and any other
+pertinent obligations, then as a consequence you may not convey it at all.
+For example, if you agree to terms that obligate you to collect a royalty
+for further conveying from those to whom you convey the Program, the only
+way you could satisfy both those terms and this License would be to refrain
+entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+Notwithstanding any other provision of this License, you have permission to
+link or combine any covered work with a work licensed under version 3 of the
+GNU Affero General Public License into a single combined work, and to convey
+the resulting work. The terms of this License will continue to apply to the
+part which is the covered work, but the special requirements of the GNU Affero
+General Public License, section 13, concerning interaction through a network
+will apply to the combination as such.
+
+ 14. Revised Versions of this License.
+
+The Free Software Foundation may publish revised and/or new versions of the
+GNU General Public License from time to time. Such new versions will be similar
+in spirit to the present version, but may differ in detail to address new
+problems or concerns.
+
+Each version is given a distinguishing version number. If the Program specifies
+that a certain numbered version of the GNU General Public License "or any
+later version" applies to it, you have the option of following the terms and
+conditions either of that numbered version or of any later version published
+by the Free Software Foundation. If the Program does not specify a version
+number of the GNU General Public License, you may choose any version ever
+published by the Free Software Foundation.
+
+If the Program specifies that a proxy can decide which future versions of
+the GNU General Public License can be used, that proxy's public statement
+of acceptance of a version permanently authorizes you to choose that version
+for the Program.
+
+Later license versions may give you additional or different permissions. However,
+no additional obligations are imposed on any author or copyright holder as
+a result of your choosing to follow a later version.
+
+ 15. Disclaimer of Warranty.
+
+THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
+LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
+PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+ 16. Limitation of Liability.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
+AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
+INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
+USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
+INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
+PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
+PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+If the disclaimer of warranty and limitation of liability provided above cannot
+be given local legal effect according to their terms, reviewing courts shall
+apply local law that most closely approximates an absolute waiver of all civil
+liability in connection with the Program, unless a warranty or assumption
+of liability accompanies a copy of the Program in return for a fee. END OF
+TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to attach
+them to the start of each source file to most effectively state the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+
+
+Copyright (C)
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program does terminal interaction, make it output a short notice like
+this when it starts in an interactive mode:
+
+ Copyright (C)
+
+This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+
+This is free software, and you are welcome to redistribute it under certain
+conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands might
+be different; for a GUI interface, you would use an "about box".
+
+You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary. For
+more information on this, and how to apply and follow the GNU GPL, see .
+
+The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General Public
+License instead of this License. But first, please read .
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..765f068
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,19 @@
+main_source = src/main.c
+
+core_sources = \
+ src/xmppc.h src/xmppc.c \
+ src/mode/omemo.h src/mode/omemo.c \
+ src/mode/roster.h src/mode/roster.c \
+ src/mode/muc.h src/mode/muc.c \
+ src/mode/message.h src/mode/message.c \
+ src/mode/pgp.h src/mode/pgp.c \
+ src/mode/account.h src/mode/account.c \
+ src/mode/monitor.h src/mode/monitor.c \
+ src/mode/openpgp.h src/mode/openpgp.c
+
+AM_CFLAGS = @AM_CFLAGS@ -I$(srcdir)/src
+
+dist_doc_DATA = README.md
+
+bin_PROGRAMS = xmppc
+xmppc_SOURCES = $(core_sources) $(main_source)
diff --git a/README.md b/README.md
index d0da686..d508c5b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,51 @@
# xmppc
+xmppc - command line interface (CLI) XMPP Client.
+
+xmppc is a XMPP command line interface client. It's written in C and is using
+the xmpp library [libstrophe](http://strophe.im/libstrophe/).
+
+## Dependencies
+
+* [libc6-dev](https://packages.debian.org/buster/libc6-dev) (2.28-10)
+* [libglib2.0-dev](https://packages.debian.org/buster/libglib2.0-dev) (2.58.3)
+* [libstrophe-dev](https://packages.debian.org/buster/libstrophe-dev) (0.9.2-2)
+* [libgpgme-dev](https://packages.debian.org/buster/libgpgme-dev) (1.12.0)
+
+## Build
+
+The project is using [GNU Automake](https://www.gnu.org/software/automake/).
+
+```
+aptitude install libstrophe-dev
+./bootstrap.sh
+./configure
+make
+```
+
+## Usage
+
+```
+xmppc --jid user@domain.tld --pwd "password" --mode roster list
+xmppc -j user@domain.tld -p "password" -m roster list
+xmppc -j user@domain.tld -p "password" -m roster export
+xmppc -j user@domain.tld -p "password" -m message chat friend@domain.tld "Message"
+xmppc -j user@domain.tld -p "password" -m pgp chat friend@domain.tld "Message"
+xmppc -j user@domain.tld -p "password" -m openpgp signcrypt friend@domain.tld "Message"
+xmppc -j user@domain.tld -p "password" -m omemo list
+xmppc -j user@domain.tld -p "password" -m monitor stanza
+```
+Use xmppc with [pass](https://packages.debian.org/buster/pass)
+
+```
+xmppc --jid user@domain.tld --pwd $(pass XMPP/domain.tld/user) --mode roster list
+```
+
+## Documentation
+
+* Wiki
+
+## Contact details
+
+* MUC: xmpp-messenger@conference.anoxinon.me
+
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100644
index 0000000..c5a7472
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+autoreconf --install
diff --git a/changelog b/changelog
new file mode 100644
index 0000000..981159e
--- /dev/null
+++ b/changelog
@@ -0,0 +1,11 @@
+2020-04-10 DebXWoody
+
+ Release 0.0.2
+ * message chat
+ * pgp chat
+ * omemo list
+
+2020-04-04 DebXWoody
+
+ Release 0.0.1
+ * roster list command
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..4b6f030
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,72 @@
+AC_INIT([xmppc], [0.0.3], [stefan@debxwoody.de])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_SRCDIR([src/main.c])
+AC_CONFIG_HEADERS([src/config.h])
+AC_CONFIG_FILES([Makefile])
+AM_INIT_AUTOMAKE([foreign subdir-objects])
+
+AC_PROG_CC
+AC_PROG_LIBTOOL
+AC_SYS_LARGEFILE
+
+AC_CANONICAL_HOST
+PLATFORM="unknown"
+AS_CASE([$host_os],
+ [freebsd*], [PLATFORM="freebsd"],
+ [openbsd*], [PLATFORM="openbsd"],
+ [darwin*], [PLATFORM="osx"],
+ [cygwin], [PLATFORM="cygwin"],
+ [PLATFORM="nix"])
+
+#PACKAGE_STATUS="development"
+PACKAGE_STATUS="release"
+
+AM_CFLAGS="-Wall -Wno-deprecated-declarations -pedantic -std=c11"
+AS_IF([test "x$PACKAGE_STATUS" = xdevelopment],
+ [AM_CFLAGS="$AM_CFLAGS -Wunused -Werror -g"])
+
+AS_IF([test "x$PACKAGE_STATUS" = xdevelopment],
+ [AC_DEFINE([XMPPC_DEVELOPMENT], [1], [XMPPC Development])])
+
+# libstrophe
+PKG_CHECK_MODULES([libstrophe], [libstrophe >= 0.9.2],
+ [LIBS="$libstrophe_LIBS $LIBS" CFLAGS="$CFLAGS $libstrophe_CFLAGS" AC_DEFINE([HAVE_LIBSTROPHE], [1], [libstrophe])],
+ [AC_MSG_ERROR([libstrophe in version >= 0.9.2 not found, is required xmppc])])
+
+# glib
+PKG_CHECK_MODULES([glib], [glib-2.0 >= 2.40],
+ [LIBS="$glib_LIBS $LIBS" CFLAGS="$CFLAGS $glib_CFLAGS"],
+ [AC_MSG_ERROR([glib 2.40 or higher is required for xmppc])])
+
+AM_CONDITIONAL([BUILD_PGP], [false])
+if test "x$enable_pgp" != xno; then
+ AC_CHECK_LIB([gpgme], [main],
+ [AM_CONDITIONAL([BUILD_PGP], [true])
+ AC_DEFINE([HAVE_LIBGPGME], [1], [Have libgpgme])
+ AC_PATH_PROG([GPGME_CONFIG], [gpgme-config], ["failed"])
+ AS_IF([test "x$GPGME_CONFIG" = xfailed],
+ [LIBS="-lgpgme $LIBS"],
+ [LIBS="`$GPGME_CONFIG --libs` $LIBS" AM_CPPFLAGS="`$GPGME_CONFIG --cflags` $AM_CPPFLAGS"])],
+ [AS_IF([test "x$enable_pgp" = xyes],
+ [AC_MSG_ERROR([libgpgme is required for pgp support])],
+ [AC_MSG_NOTICE([libgpgme not found, pgp support not enabled])])])
+fi
+
+
+AC_SUBST(AM_LDFLAGS)
+AC_SUBST(AM_CFLAGS)
+AC_SUBST(AM_CPPFLAGS)
+
+AC_CHECK_FUNCS([strdup])
+
+AC_OUTPUT
+
+echo ""
+echo "PLATFORM : $host_os"
+echo "PACKAGE_STATUS : $PACKAGE_STATUS"
+echo "AM_CFLAGS : $AM_CFLAGS"
+echo "AM_CPPFLAGS : $AM_CPPFLAGS"
+echo "AM_LDFLAGS : $AM_LDFLAGS"
+echo "LIBS : $LIBS"
+
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..a08e1ba
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,445 @@
+/*!
+ * @file main.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @authors
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * @copyright
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+/*!
+ * @mainpage xmppc - XMPP command line
+ *
+ * @section whatIsXmppc What is xmppc
+ *
+ * xmppc is a command line program for XMPP (https://xmpp.org/).
+ * The program has been written for the Debian GNU/Linux system (https://www.debian.org/).
+ *
+ * @section build Build
+ *
+ * @subsection dependencies Dependencies
+ *
+ * - The GNU C Library (glibc) - 2.28-10
+ * - GLib - 2.58.3
+ * - XMPP library libstrophe - 0.9.2-2
+ * - GPGME (GnuPG Made Easy) - 1.12.0-6
+ *
+ * @subsection compile Compile
+ *
+ * @code{.bash}
+ * ./bootstrap.sh
+ * ./configure
+ * make
+ * @endcode
+ *
+ * @subsection documentation Documentation
+ * @code{.bash}
+ * cd doc
+ * make
+ * @endcode
+ * @section usage Usage
+ *
+ * @code{.bash}
+ * xmppc --jid --pwd --mode
+ * @endcode
+ *
+ * @code{.bash}
+ * xmppc --jid user@domain.tld --pwd "my secret" --mode pgp chat friend@domain.tld "Hello!"
+ * xmppc --jid user@domain.tld --pwd $(pass XMPP/domain/user) --mode omemo list
+ * @endcode
+ *
+ *
+ * @section development Development
+ *
+ * - \subpage module
+ *
+ */
+
+/*!
+ * \page module Modules
+ *
+ * \section account Account
+ * \section roster Roster
+ * \section message Message
+ * \section muc Multi-User-Chat
+ * \section omemo OMEMO
+ * XEP-0384: OMEMO Encryption (Version 0.3.0 (2018-07-31)). xmppc can use used
+ * to request the users OMEMO Device ID List and displays the Fingerprints of
+ * the keys.
+ *
+ * @code{.bash}
+ * xmppc --jid user@domain.tld --pwd $(pass domain.tld/user) --mode omemo
+ * @endcode
+ *
+ * @code{.bash}
+ * xmppc --jid user@domain.tld --pwd $(pass domain.tld/user) --mode omemo| gpg --clear-sign --sign-with 123ABC_MY_OPENPGP_KEY_1234 > omemo.asc
+ * @endcode
+ *
+ *
+ * \section pgp PGP
+ * XEP-0027: Current Jabber OpenPGP Usage
+ * (https://xmpp.org/extensions/xep-0027.html) is obsolete, but there are still
+ * clients which supports XEP-0027 instead of XEP-0373 / XEP-0374. This module
+ * supports sending of OpenPGP encrypted messages via XMPP's XEP-0027.
+ *
+ * @code{.bash}
+ * xmppc --jid user@domain.tld --pwd "my secret" --mode pgp friend@domain.tld "Hello!"
+ * @endcode
+ *
+ * xmppc use GnuPG's GPGME API use lookup the own key and the key of the
+ * recipient. Those two keys will be used to encrypt the message.
+ *
+ * Details \subpage module-pgp
+ *
+ */
+
+#include "config.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "xmppc.h"
+#include "mode/account.h"
+#include "mode/message.h"
+#include "mode/muc.h"
+#include "mode/omemo.h"
+#include "mode/roster.h"
+#include "mode/pgp.h"
+#include "mode/openpgp.h"
+#include "mode/monitor.h"
+
+/*!
+ * @brief The callback structure.
+ *
+ * This struct is used to call the "execution"-function of the mode module (e.g
+ * account_execute_command, roster_execute_command, ...).
+ *
+ * @authors DebxWoody
+ * @since 0.0.2
+ * @version 1
+ *
+ */
+
+typedef struct {
+ /*! Size of arguments */
+ int argc;
+ /*! Array of C-Strings (arguments) with size of argc */
+ char **argv;
+ /*! Pointer to Execute-Handler */
+ ExecuteHandler callback;
+ /*! XMPPC context object */
+ xmppc_t *xmppc;
+} callback_t;
+
+/*!
+ * @brief Mode Mapping.
+ *
+ * This struct is used to provider the mapping of the mode name (name via
+ * command line interface of the user (e.g. -m account). The technical ID of the
+ * mode which is defined via enum xmppc_mode_t and the pointer of function which
+ * should be used to handle those mode.
+ *
+ * @authors DebxWoody
+ * @since 0.0.2
+ * @version 1
+ */
+
+struct mode_mapping {
+ const char *name;
+ xmppc_mode_t mode;
+ ExecuteHandler callback;
+};
+
+/*!
+ * @brief Mode mapping table.
+ *
+ * Mapping of mode's string, enum and function.
+ *
+ * @authors DebxWoody
+ * @since 0.0.2
+ * @version 1
+ *
+ */
+
+static struct mode_mapping map[] = {
+ /*!
+ * Account Mode Mapping
+ * @since 0.0.2
+ * @version 1
+ */
+ {"account", ACCOUNT, account_execute_command},
+ /*!
+ * roster Mode Mapping
+ * @since 0.0.2
+ * @version 1
+ */
+ {"roster", ROSTER, roster_execute_command},
+ /*!
+ * Message Mode Mapping
+ * @since 0.0.2
+ * @version 1
+ */
+ {"message", MESSAGE, message_execute_command},
+ /*!
+ * MUC Mode Mapping
+ * @since 0.0.2
+ * @version 1
+ */
+ {"muc", MUC, muc_execute_command},
+ /*!
+ * OMEMO Mode Mapping
+ * @since 0.0.2
+ * @version 1
+ */
+ {"omemo", OMEMO, omemo_execute_command},
+ /*!
+ * PGP Mode Mapping
+ * @since 0.0.2
+ * @version 1
+ */
+ {"pgp", PGP, pgp_execute_command},
+ /*!
+ * XEP-0373: OpenPGP for XMPP
+ */
+ {"openpgp", OPENPGP, openpgp_execute_command},
+ /*!
+ * Monitor
+ */
+ {"monitor", MONITOR, monitor_execute_command},
+ // End of Map
+ {NULL, 0}
+};
+
+/*!
+ * \brief Connection Handler Callback of libstrophe.
+ *
+ * This function will be called by libstrophe.
+ *
+ * \param conn See libstrophe documentation
+ * \param status See libstrophe documentation
+ * \param error See libstrophe documentation
+ * \param stream_error See libstrophe documentation
+ *
+ * \param userdata callback_t object for the mode request by user.
+ *
+ * @authors DebxWoody
+ * @since 0.0.2
+ * @version 1
+ *
+ */
+
+void conn_handler(xmpp_conn_t *const conn, const xmpp_conn_event_t status,
+ const int error, xmpp_stream_error_t *const stream_error,
+ void *const userdata) {
+ callback_t *callback = (callback_t *)userdata;
+
+ if (status == XMPP_CONN_CONNECT) {
+ logInfo(callback->xmppc, "Connected\n");
+ callback->callback(callback->xmppc, callback->argc, callback->argv);
+ } else {
+ xmpp_stop(xmpp_conn_get_context(conn));
+ }
+}
+
+static void _show_help();
+
+/*!
+ * \brief C-Main function
+ *
+ * - Parse argv arguments of the command line.
+ * - Checks jid and password for xmpp logging
+ * - Checks mode requested by user
+ * - All other arguments will be used as mode parameters
+ *
+ * \param argc Arguments counter
+ * \param argv Arguments vector
+ * \returns Exit Code
+ *
+ * @authors DebxWoody
+ * @since 0.0.2
+ * @version 2
+ */
+
+int main(int argc, char *argv[]) {
+#if XMPPC_DEVELOPMENT
+ printf("!!! WARNING: XMPPC is running in development mode !!!\n");
+#endif
+
+ INIT_XMPPC(xmppc);
+
+ static int verbose_flag = 0;
+ int c = 0;
+ xmppc_mode_t mode = UNKOWN;
+ char *jid = NULL;
+ char *pwd = NULL;
+
+ static struct option long_options[] = {
+ /* These options set a flag. */
+ {"verbose", no_argument, &verbose_flag, 1},
+ {"help", no_argument, 0, 'h'},
+ {"config", required_argument, 0, 'c'},
+ {"jid", required_argument, 0, 'j'},
+ {"pwd", required_argument, 0, 'p'},
+ {"mode", required_argument, 0, 'm'},
+ {"file", required_argument, 0, 'f'},
+ {0, 0, 0, 0}};
+ while (c > -1) {
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "hvj:p:m:", long_options, &option_index);
+ if (c > -1) {
+ switch (c) {
+ case 'h':
+ _show_help();
+ return EXIT_SUCCESS;
+
+ case 'c':
+ printf("option -c with value `%s'\n", optarg);
+ break;
+
+ case 'f':
+ printf("option -f with value `%s'\n", optarg);
+ break;
+
+ case 'j':
+ jid = malloc(strlen(optarg) + 1);
+ strcpy(jid, optarg);
+ break;
+
+ case 'p':
+ pwd = malloc(strlen(optarg) + 1);
+ strcpy(pwd, optarg);
+ break;
+
+ case 'm':
+ for(int i = 0; map[i].name;i++ ) {
+ if (strcmp(optarg, map[i].name) == 0) {
+ mode = map[i].mode;
+ break;
+ }
+ }
+ break;
+
+ case 'v':
+ verbose_flag++;
+ break;
+
+ case '?':
+ break;
+
+ default:
+ abort();
+ }
+ }
+ }
+
+ int paramc = argc- optind;
+ char* paramv[paramc];
+
+ for (int i = optind; i < argc; i++) {
+ char* x= malloc(strlen(argv[i])+1 *sizeof(char) );
+ strcpy(x,argv[i]);
+ paramv[i-optind] = x;
+ }
+ xmppc_context(&xmppc, verbose_flag);
+
+ logInfo(&xmppc, "Connecting... \n");
+ xmppc_connect(&xmppc, jid, pwd);
+
+ ExecuteHandler handler = NULL;
+ for(int i = 0; map[i].name;i++ ) {
+ if (mode == map[i].mode) {
+ handler = map[i].callback;
+ break;
+ }
+ }
+
+ callback_t callback = {paramc, paramv, handler, &xmppc};
+
+ xmpp_connect_client(xmppc.conn, NULL, 0, conn_handler, &callback);
+
+ xmpp_run(xmppc.ctx);
+ xmpp_conn_release(xmppc.conn);
+ xmpp_ctx_free(xmppc.ctx);
+ xmpp_shutdown();
+
+ return EXIT_SUCCESS;
+}
+
+static void _show_help() {
+#ifdef XMPPC_DEVELOPMENT
+ printf("%s - Development\n", PACKAGE_STRING);
+#else
+ printf("%s\n", PACKAGE_STRING);
+#endif
+ printf("Usage: xmppc --jid --pwd --mode \n");
+ printf("Options:\n");
+ printf(" -h / --help Display this information.\n");
+ printf(" -j / --jid Jabber ID\n");
+ printf(" -p / --pwd Passwort\n");
+ printf(" -m / --mode xmppc mode\n");
+ printf("\n");
+ printf("Modes:\n");
+ printf(" -m --mode roster xmppc roster mode\n");
+ printf(" list List all contacts\n");
+ printf(" export Exports all contacts\n");
+ printf("\n");
+ printf(" -m --mode message xmppc message mode\n");
+ printf(" chat Sending unencrypted message to jid\n");
+ printf("\n");
+ printf(" -m --mode pgp xmppc pgp mode (XEP-0027) \n");
+ printf(" chat Sending pgp encrypted message to jid\n");
+ printf("\n");
+ printf(" -m --mode omemo xmppc omemo mode\n");
+ printf(" list List the device IDs and fingerprints\n");
+ printf("\n");
+ printf(" -m --mode openpgp xmppc openpgp mode (XEP-0373)\n");
+ printf(" signcrypt Sending pgp signed and encrypted message to jid\n");
+ printf("\n");
+ printf(" -m --mode monitor Monitot mode");
+ printf(" stanza Stanza Monitor\n");
+ printf(" monitor microblog Monitor microblog (XEP-0277: Microblogging over XMPP)\n");
+ printf("\n");
+ printf("\n");
+ printf("Examples:\n");
+ printf(" Usage: xmppc --jid user@domain.tld --pwd \"secret\" --mode roster list\n");
+ printf(" Usage: xmppc --jid user@domain.tld --pwd \"secret\" --mode pgp chat friend@domain.tld \"Hello\"\n");
+
+}
diff --git a/src/mode/account.c b/src/mode/account.c
new file mode 100644
index 0000000..00c8912
--- /dev/null
+++ b/src/mode/account.c
@@ -0,0 +1,52 @@
+/*!
+ * @file File: account.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @copyright
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#include "account.h"
+#include "stdio.h"
+#include "string.h"
+
+void account_execute_command(xmppc_t *xmppc, int argc, char *argv[]) {
+ logError(xmppc, "Message command not implemented!\n");
+ xmpp_disconnect(xmppc->conn);
+ xmpp_stop(xmppc->ctx);
+}
+
diff --git a/src/mode/account.h b/src/mode/account.h
new file mode 100644
index 0000000..940d42d
--- /dev/null
+++ b/src/mode/account.h
@@ -0,0 +1,51 @@
+/*!
+ * @file account.h
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @ copyright
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+
+#ifndef XMPPC_ACCOUNT_H__
+#define XMPPC_ACCOUNT_H__
+
+#include "xmppc.h"
+
+void account_execute_command(xmppc_t *xmppc, int agrc, char *argv[]);
+
+#endif // XMPPC_ACCOUNT_H__
diff --git a/src/mode/message.c b/src/mode/message.c
new file mode 100644
index 0000000..51cdd77
--- /dev/null
+++ b/src/mode/message.c
@@ -0,0 +1,68 @@
+/*!
+ * @file message.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @authors
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * @copyright
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#include "message.h"
+#include "string.h"
+
+static void _message_send_text(xmppc_t *xmppc, char* to, char* message);
+
+void message_execute_command(xmppc_t *xmppc, int argc, char *argv[]) {
+ if( argc == 3 && ( strcmp("chat", argv[0] ) == 0)) {
+ _message_send_text(xmppc, argv[1],argv[2]);
+ } else {
+ logError(xmppc, "Befehl unbekannt");
+ }
+ xmpp_disconnect(xmppc->conn);
+}
+
+void _message_send_text(xmppc_t *xmppc, char* to, char* text) {
+ xmpp_conn_t *conn = xmppc->conn;
+ xmpp_stanza_t *message;
+ char* id = xmpp_uuid_gen(xmppc->ctx);
+ message = xmpp_message_new(xmpp_conn_get_context(conn), "chat", to, id);
+ int res = xmpp_message_set_body(message, text);
+ if(res == 0) {
+ xmpp_send(conn, message);
+ }
+}
+
+
diff --git a/src/mode/message.h b/src/mode/message.h
new file mode 100644
index 0000000..bc9d908
--- /dev/null
+++ b/src/mode/message.h
@@ -0,0 +1,49 @@
+/*
+ * @file message.h
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+
+#ifndef XMPPC_MESSAGE_H__
+#define XMPPC_MESSAGE_H__
+
+#include "xmppc.h"
+
+void message_execute_command(xmppc_t *xmppc, int agrc, char *argv[]);
+
+#endif // XMPPC_MESSAGE_H__
diff --git a/src/mode/monitor.c b/src/mode/monitor.c
new file mode 100644
index 0000000..f45541c
--- /dev/null
+++ b/src/mode/monitor.c
@@ -0,0 +1,126 @@
+/*!
+ * @file File: monitor.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @copyright
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#include "monitor.h"
+#include "stdio.h"
+#include "string.h"
+
+
+static int _monitor_log_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
+static int _monitor_show_microblog(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata);
+
+void monitor_execute_command(xmppc_t *xmppc, int argc, char *argv[]) {
+ if(argc > 0 && strcmp("stanza", argv[0]) == 0) {
+ xmpp_handler_add(xmppc->conn, _monitor_log_stanza, NULL, NULL, NULL, NULL);
+#ifdef XMPPC_DEVELOPMENT
+ } else if (argc > 0 && strcmp("microblog", argv[0]) == 0) {
+ xmpp_handler_add(xmppc->conn, _monitor_show_microblog, NULL, NULL, NULL, NULL);
+#endif
+ } else {
+ printf("Command unbekannt!");
+ xmpp_disconnect(xmppc->conn);
+ }
+ // presence
+ xmpp_stanza_t *presence = xmpp_presence_new(xmppc->ctx);
+ char* id = xmpp_uuid_gen(xmppc->ctx);
+ xmpp_stanza_set_id(presence, id);
+ xmpp_send(xmppc->conn, presence);
+ xmpp_stanza_release(presence);
+
+ // XEP-0280: Message Carbons
+ xmpp_stanza_t *carbons = xmpp_iq_new(xmppc->ctx, "set", xmpp_uuid_gen(xmppc->ctx));
+ xmpp_stanza_t* enable = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(enable, "enable");
+ xmpp_stanza_set_ns(enable, "urn:xmpp:carbons:2");
+ xmpp_stanza_add_child(carbons,enable);
+ xmpp_send(xmppc->conn,carbons);
+}
+
+int _monitor_log_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata){
+ char* s;
+ size_t len;
+ xmpp_stanza_to_text(stanza,&s,&len);
+
+ char* color = "\x1b[m";
+ if(strcmp(xmpp_stanza_get_name(stanza), "iq") == 0 ) color = ANSI_COLOR_YELLOW;
+ if(strcmp(xmpp_stanza_get_name(stanza), "message") == 0 ) {
+ color = ANSI_COLOR_BLUE;
+ if(strcmp("headline", xmpp_stanza_get_type(stanza)) == 0) {
+ color = ANSI_COLOR_CYAN;
+ }
+ }
+
+ if(strcmp(xmpp_stanza_get_name(stanza), "presence") == 0 ) color = ANSI_COLOR_GREEN;
+ if(xmpp_stanza_get_type(stanza) != NULL)
+ if(strcmp(xmpp_stanza_get_type(stanza), "error") == 0 ) color = ANSI_COLOR_B_RED;
+
+ printf("%s%s\x1b[m\n", color, s);
+ return 1;
+}
+
+/* XEP-0277: Microblogging over XMPP */
+
+int _monitor_show_microblog(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata){
+
+
+
+ xmpp_stanza_t *log = stanza;
+ if(strcmp(xmpp_stanza_get_name(stanza), "message") == 0 ) {
+ xmpp_stanza_t* event = xmpp_stanza_get_child_by_name(stanza, "event");
+ if(event != NULL &&
+ strcmp(xmpp_stanza_get_ns(event), "http://jabber.org/protocol/pubsub#event") ==0) {
+ char* body_text = xmpp_message_get_body(stanza);
+ printf("Event: %s\n", body_text);
+ xmpp_stanza_t * items = xmpp_stanza_get_child_by_name(event,"items");
+ if( items != NULL && strcmp("urn:xmpp:microblog:0", xmpp_stanza_get_attribute(items, "node" )) == 0) {
+ printf("urn:xmpp:microblog:0 items found!\n");
+ }
+ }
+ }
+
+ if(log) {
+ _monitor_log_stanza(conn, stanza, userdata);
+ }
+
+ return 1;
+}
+
diff --git a/src/mode/monitor.h b/src/mode/monitor.h
new file mode 100644
index 0000000..d34803f
--- /dev/null
+++ b/src/mode/monitor.h
@@ -0,0 +1,51 @@
+/*!
+ * @file monitor.h
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @ copyright
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+
+#ifndef XMPPC_MONITOR_H__
+#define XMPPC_MONITOR_H__
+
+#include "xmppc.h"
+
+void monitor_execute_command(xmppc_t *xmppc, int agrc, char *argv[]);
+
+#endif // XMPPC_MONITOR_H__
diff --git a/src/mode/muc.c b/src/mode/muc.c
new file mode 100644
index 0000000..9f810fe
--- /dev/null
+++ b/src/mode/muc.c
@@ -0,0 +1,48 @@
+/*
+ * @file muc.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#include "account.h"
+#include "stdio.h"
+#include "string.h"
+
+void muc_execute_command(xmppc_t *xmppc, int argc, char *argv[]) {
+ logError(xmppc, "Message command not implemented!\n");
+}
+
diff --git a/src/mode/muc.h b/src/mode/muc.h
new file mode 100644
index 0000000..5d2ddf6
--- /dev/null
+++ b/src/mode/muc.h
@@ -0,0 +1,50 @@
+/*
+ * @file muc.h
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @copyright
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#ifndef XMPPC_MUC_H__
+#define XMPPC_MUC_H__
+
+#include "xmppc.h"
+
+void muc_execute_command(xmppc_t *xmppc, int agrc, char *argv[]);
+
+#endif // XMPPC_MUC_H__
diff --git a/src/mode/omemo.c b/src/mode/omemo.c
new file mode 100644
index 0000000..c974467
--- /dev/null
+++ b/src/mode/omemo.c
@@ -0,0 +1,187 @@
+/*!
+ * @file omemo.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @copyright
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#include "omemo.h"
+
+#include
+#include
+#define DJB_TYPE 0x05
+
+static int response = 0;
+
+static void _omemo_device_list_query(xmppc_t *xmppc);
+static int _omemo_device_list_reply(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
+ void *const userdata);
+
+static void _omemo_bundles_query(xmppc_t *xmppc, const char* deviceid);
+static int _omemo_bundles_reply(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
+ void *const userdata);
+
+void omemo_execute_command(xmppc_t *xmppc, int agrc, char *argv[]) {
+ _omemo_device_list_query(xmppc);
+}
+
+void _omemo_device_list_query(xmppc_t *xmppc) {
+ xmpp_conn_t *conn = xmppc->conn;
+ xmpp_stanza_t *iq, *query, *item;
+ char* id = xmpp_uuid_gen(xmppc->ctx);
+ iq = xmpp_iq_new(xmpp_conn_get_context(conn), "get", id);
+ const char *jid = xmpp_conn_get_jid(conn);
+ xmpp_stanza_set_from(iq, jid);
+ xmpp_stanza_set_to(iq, jid);
+ query = xmpp_stanza_new(xmpp_conn_get_context(conn));
+ xmpp_stanza_set_name(query, "pubsub");
+ xmpp_stanza_set_ns(query, "http://jabber.org/protocol/pubsub");
+ xmpp_stanza_add_child(iq, query);
+ item = xmpp_stanza_new(xmpp_conn_get_context(conn));
+ xmpp_stanza_set_name(item, "items");
+ xmpp_stanza_set_attribute(item, "node",
+ "eu.siacs.conversations.axolotl.devicelist");
+ xmpp_stanza_add_child(query, item);
+ xmpp_stanza_release(query);
+ xmpp_stanza_release(item);
+ xmpp_id_handler_add(conn, _omemo_device_list_reply , id, xmppc);
+ xmpp_send(conn, iq);
+}
+
+static int _omemo_device_list_reply(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
+ void *const userdata) {
+ xmppc_t *xmppc = (xmppc_t *)userdata;
+ xmpp_stanza_t *query, *item;
+ const char *name;
+ printf("Device List\n");
+ query = xmpp_stanza_get_child_by_name(stanza, "pubsub");
+ query = xmpp_stanza_get_child_by_name(query, "items");
+ query = xmpp_stanza_get_child_by_name(query, "item");
+ query = xmpp_stanza_get_child_by_name(query, "list");
+ for (item = xmpp_stanza_get_children(query); item;
+ item = xmpp_stanza_get_next(item))
+ if ((name = xmpp_stanza_get_attribute(item, "id"))) {
+ response++;
+ printf("\t %s\n", name);
+ _omemo_bundles_query(xmppc, name);
+ }
+
+ return 0;
+}
+
+void _omemo_bundles_query(xmppc_t *xmppc, const char* deviceid){
+ xmpp_conn_t *conn = xmppc->conn;
+ xmpp_stanza_t *iq, *query, *item;
+ char* id = xmpp_uuid_gen(xmppc->ctx);
+ iq = xmpp_iq_new(xmpp_conn_get_context(conn), "get", id);
+ const char *jid = xmpp_conn_get_jid(conn);
+ xmpp_stanza_set_from(iq, jid);
+ xmpp_stanza_set_to(iq, jid);
+ query = xmpp_stanza_new(xmpp_conn_get_context(conn));
+ xmpp_stanza_set_name(query, "pubsub");
+ xmpp_stanza_set_ns(query, "http://jabber.org/protocol/pubsub");
+ xmpp_stanza_add_child(iq, query);
+ item = xmpp_stanza_new(xmpp_conn_get_context(conn));
+ xmpp_stanza_set_name(item, "items");
+ char bundle[100] = "";
+ strcat(bundle, "eu.siacs.conversations.axolotl.bundles:");
+ strcat(bundle, deviceid);
+ xmpp_stanza_set_attribute(item, "node",bundle);
+ xmpp_stanza_add_child(query, item);
+ xmpp_stanza_release(query);
+ xmpp_stanza_release(item);
+ xmpp_id_handler_add(conn, _omemo_bundles_reply , id, xmppc);
+ xmpp_send(conn, iq);
+
+}
+
+int _omemo_bundles_reply(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
+ void *const userdata) {
+ xmppc_t *xmppc = (xmppc_t *)userdata;
+
+ if(strcmp(xmpp_stanza_get_type(stanza), "error") == 0) {
+ printf("Fehler\n");
+ return 0;
+ }
+
+ xmpp_stanza_t *query;
+ query = xmpp_stanza_get_child_by_name(stanza, "pubsub");
+ query = xmpp_stanza_get_child_by_name(query, "items");
+ query = xmpp_stanza_get_child_by_name(query, "item");
+ query = xmpp_stanza_get_child_by_name(query, "bundle");
+ query = xmpp_stanza_get_child_by_name(query, "identityKey");
+ char* identityKey = xmpp_stanza_get_text(query);
+
+ size_t identity_public_key_len = 0;
+ unsigned char *x = g_base64_decode(identityKey, &identity_public_key_len);
+ unsigned char *identity_public_key_data = x;
+ if (identity_public_key_data[0] != DJB_TYPE) {
+ printf("Ist kein DJB_TYPE");
+ }
+
+ // Skip first byte corresponding to signal DJB_TYPE
+ identity_public_key_len--;
+ identity_public_key_data = &identity_public_key_data[1];
+
+ char *fingerprint = malloc(identity_public_key_len * 2 + 1);
+ fingerprint[identity_public_key_len*2] = '\0';
+
+ for (int i = 0; i < identity_public_key_len; i++) {
+ fingerprint[i * 2] = (identity_public_key_data[i] & 0xf0) >> 4;
+ fingerprint[i * 2] += '0';
+ if (fingerprint[i * 2] > '9') {
+ fingerprint[i * 2] += 0x27;
+ }
+
+ fingerprint[(i * 2) + 1] = identity_public_key_data[i] & 0x0f;
+ fingerprint[(i * 2) + 1] += '0';
+ if (fingerprint[(i * 2) + 1] > '9') {
+ fingerprint[(i * 2) + 1] += 0x27;
+ }
+ }
+ printf("Fingerprint: %s\n", fingerprint);
+ response--;
+ if(response == 0) {
+ xmpp_disconnect(xmppc->conn);
+ xmpp_stop(xmppc->ctx);
+ }
+
+ return 0;
+}
+
+
diff --git a/src/mode/omemo.h b/src/mode/omemo.h
new file mode 100644
index 0000000..9d8a6c7
--- /dev/null
+++ b/src/mode/omemo.h
@@ -0,0 +1,50 @@
+/*
+ * @file omemo.h
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @copyright
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#ifndef XMPPC_OMEMO_H__
+#define XMPPC_OMEMO_H__
+
+#include "xmppc.h"
+
+void omemo_execute_command(xmppc_t *xmppc, int agrc, char *argv[]);
+
+#endif // XMPPC_OMEMO_H__
diff --git a/src/mode/openpgp.c b/src/mode/openpgp.c
new file mode 100644
index 0000000..ac7ede8
--- /dev/null
+++ b/src/mode/openpgp.c
@@ -0,0 +1,244 @@
+/*!
+ * @file openpgp.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @authors
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * @copyright
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#define _GNU_SOURCE
+
+#include "openpgp.h"
+#include "string.h"
+
+#include
+#include
+#include
+#include
+
+static void _openpgp_send_text(xmppc_t *xmppc, char* to, char* text);
+static xmpp_stanza_t* _openpgp_signcrypt(xmppc_t *xmppc, char* to, char* text);
+static char* _openpgp_gpg_signcrypt(xmppc_t *xmppc, char* recipient, char* message);
+static gpgme_error_t _openpgp_lookup_key(xmppc_t *xmppc, char* name, gpgme_ctx_t* ctx, gpgme_key_t* key);
+
+void openpgp_execute_command(xmppc_t *xmppc, int argc, char *argv[]) {
+ if(argc > 0) {
+ if(strcmp("signcrypt", argv[0]) == 0) {
+ _openpgp_send_text(xmppc, argv[1], argv[2]);
+ } else {
+ logError(xmppc, "Unbekanner Befehl: %s\n", argv[0]);
+ }
+ }
+ xmpp_disconnect(xmppc->conn);
+}
+
+void _openpgp_send_text(xmppc_t *xmppc, char* to, char* text) {
+ xmpp_conn_t *conn = xmppc->conn;
+ xmpp_stanza_t *message;
+ char* id = xmpp_uuid_gen(xmppc->ctx);
+ message = xmpp_message_new(xmpp_conn_get_context(conn), NULL, to, id);
+ xmpp_message_set_body(message, "This message is *encrypted* with OpenPGP (See :XEP:`0373`)");
+ xmpp_stanza_t *openpgp = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(openpgp, "openpgp");
+ xmpp_stanza_set_ns(openpgp, "urn:xmpp:openpgp:0");
+
+ xmpp_stanza_t * signcrypt = _openpgp_signcrypt(xmppc, to, text);
+ char* c;
+ size_t s;
+ xmpp_stanza_to_text(signcrypt, &c,&s);
+ char* signcrypt_e = _openpgp_gpg_signcrypt(xmppc,to, c);
+ // BASE64_OPENPGP_MESSAGE
+ xmpp_stanza_t* base64_openpgp_message = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_text(base64_openpgp_message,signcrypt_e);
+ xmpp_stanza_add_child(openpgp, base64_openpgp_message);
+ xmpp_stanza_add_child(message, openpgp);
+
+ xmpp_stanza_to_text(message, &c,&s);
+
+ xmpp_send(conn, message);
+
+}
+
+xmpp_stanza_t* _openpgp_signcrypt(xmppc_t *xmppc, char* to, char* text) {
+
+ time_t now = time(NULL);
+ struct tm* tm = localtime(&now);
+ char buf[255];
+ strftime(buf, sizeof(buf), "%FT%T%z", tm);
+ printf("%s\n",buf);
+
+ int randnr = rand() % 5;
+ char rpad_data[randnr];
+ for(int i = 0; i < randnr-1; i++) {
+ rpad_data[i] = 'c';
+ }
+ rpad_data[randnr-1] = '\0';
+
+
+ xmpp_stanza_t *signcrypt = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(signcrypt, "signcrypt");
+ xmpp_stanza_set_ns(signcrypt, "urn:xmpp:openpgp:0");
+ xmpp_stanza_t *s_to = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(s_to, "to");
+ xmpp_stanza_set_attribute(s_to, "jid", to);
+ xmpp_stanza_t *time = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(time, "time");
+ xmpp_stanza_set_attribute(time, "stamp", buf);
+ xmpp_stanza_set_name(time, "time");
+ xmpp_stanza_t *rpad = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(rpad, "rpad");
+ xmpp_stanza_t *rpad_text = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_text(rpad_text, rpad_data);
+ xmpp_stanza_t *payload= xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(payload, "payload");
+ xmpp_stanza_t *body = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(body, "body");
+ xmpp_stanza_set_ns(body, "jabber:client");
+ xmpp_stanza_t *body_text = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_text(body_text, text);
+ xmpp_stanza_add_child(signcrypt,s_to);
+ xmpp_stanza_add_child(signcrypt,time);
+ xmpp_stanza_add_child(signcrypt,rpad);
+ xmpp_stanza_add_child(rpad,rpad_text);
+ xmpp_stanza_add_child(signcrypt,payload);
+ xmpp_stanza_add_child(payload, body);
+ xmpp_stanza_add_child(body, body_text);
+ return signcrypt;
+
+}
+
+char* _openpgp_gpg_signcrypt(xmppc_t *xmppc, char* recipient, char* message) {
+ setlocale (LC_ALL, "");
+ gpgme_check_version (NULL);
+ gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
+ gpgme_ctx_t ctx;
+ gpgme_error_t error = gpgme_new (&ctx);
+ if(GPG_ERR_NO_ERROR != error ) {
+ printf("gpgme_new: %d\n", error);
+ return NULL;
+ }
+ error = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OPENPGP);
+ if(error != 0) {
+ logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error));
+ }
+ gpgme_set_armor(ctx,0);
+ gpgme_set_textmode(ctx,0);
+ gpgme_set_offline(ctx,1);
+ gpgme_set_keylist_mode(ctx, GPGME_KEYLIST_MODE_LOCAL);
+ if(error != 0) {
+ logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error));
+ }
+
+ gpgme_key_t recp[3];
+ recp[0] = NULL,
+ recp[1] = NULL;
+ const char *jid = xmpp_conn_get_jid(xmppc->conn);
+
+ char* xmpp_jid_me = alloca( (strlen(jid)+6) * sizeof(char) );
+ char* xmpp_jid_recipient = alloca( (strlen(recipient)+6) * sizeof(char) );
+
+ strcpy(xmpp_jid_me, "xmpp:");
+ strcpy(xmpp_jid_recipient, "xmpp:");
+ strcat(xmpp_jid_me, jid);
+ strcat(xmpp_jid_recipient,recipient);
+
+ error = _openpgp_lookup_key(xmppc,xmpp_jid_me, &ctx, &recp[0]);
+ if(error != 0) {
+ logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error));
+ }
+
+ error = _openpgp_lookup_key(xmppc,xmpp_jid_recipient, &ctx, &recp[1]);
+ if(error != 0) {
+ logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error));
+ }
+ recp[2] = NULL;
+ logInfo(xmppc, "%s <%s>\n", recp[0]->uids->name, recp[0]->uids->email);
+ logInfo(xmppc, "%s <%s>\n", recp[1]->uids->name, recp[1]->uids->email);
+
+#ifdef XMPPC_DEVELOPMENT
+ gpgme_encrypt_flags_t flags = GPGME_ENCRYPT_ALWAYS_TRUST;
+#else
+ gpgme_encrypt_flags_t flags = 0;
+#endif
+
+ gpgme_data_t plain;
+ gpgme_data_t cipher;
+
+ error = gpgme_data_new (&plain);
+ if(error != 0) {
+ logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error));
+ }
+
+ error = gpgme_data_new_from_mem(&plain, message, strlen(message),0);
+ if(error != 0) {
+ logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error));
+ }
+ error = gpgme_data_new (&cipher);
+ if(error != 0) {
+ logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error));
+ }
+
+ error = gpgme_op_encrypt_sign ( ctx, recp, flags, plain, cipher);
+ if(error != 0) {
+ logError(xmppc,"GpgME Error: %s\n", gpgme_strerror(error));
+ }
+
+ size_t len;
+ char *cipher_str = gpgme_data_release_and_get_mem(cipher, &len);
+ char* result = g_base64_encode( (unsigned char*) cipher_str,len);
+ gpgme_key_release (recp[0]);
+ gpgme_key_release (recp[1]);
+ gpgme_release (ctx);
+ return result;
+}
+
+gpgme_error_t _openpgp_lookup_key(xmppc_t *xmppc,char* name, gpgme_ctx_t* ctx, gpgme_key_t* key) {
+ logDebug(xmppc, "Looking for key: %s ...\n", name);
+ gpgme_error_t error = gpgme_op_keylist_start (*ctx, NULL, 0);
+ while (!error) {
+ error = gpgme_op_keylist_next (*ctx, key);
+ if(strcmp((*key)->uids->name, name) == 0) {
+ logDebug(xmppc, "Key found: %s ...\n", (*key)->uids->name);
+ return error;
+ }
+ else {
+ gpgme_key_release((*key));
+ }
+ }
+ return error;
+}
+
diff --git a/src/mode/openpgp.h b/src/mode/openpgp.h
new file mode 100644
index 0000000..854ef67
--- /dev/null
+++ b/src/mode/openpgp.h
@@ -0,0 +1,59 @@
+/*!
+ * @file openpgp.h
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @authors
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * @copyright
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+/*!
+ * \page module-openpgp OpenPGP
+ * \brief xmppc OpenPGP
+ *
+ * Commands
+ * - chat
+ *
+ */
+
+#ifndef XMPPC_OPENPGP_H__
+#define XMPPC_OPENPGP_H__
+
+#include "xmppc.h"
+
+void openpgp_execute_command(xmppc_t *xmppc, int argc, char *argv[]);
+
+#endif // XMPPC_OPENPGP_H__
diff --git a/src/mode/pgp.c b/src/mode/pgp.c
new file mode 100644
index 0000000..aa29bcf
--- /dev/null
+++ b/src/mode/pgp.c
@@ -0,0 +1,153 @@
+/*!
+ * @file pgp.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @authors
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * @copyright
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#define _GNU_SOURCE
+
+#include "pgp.h"
+#include "string.h"
+
+#include
+#include
+#include
+
+
+#define PGP_BEGIN "-----BEGIN PGP MESSAGE-----"
+#define PGP_END "-----END PGP MESSAGE-----"
+
+static char* _pgp_encrypt_message(xmppc_t *xmppc, char* recipient, char* message);
+static char* _pgp_remove_PGP_MESSAGE_comment(const char* message);
+
+static void _pgp_send_text(xmppc_t *xmppc, char* to, char* text);
+
+void pgp_execute_command(xmppc_t *xmppc, int argc, char *argv[]) {
+ if(argc > 0) {
+ if(strcmp("chat", argv[0]) == 0) {
+ _pgp_send_text(xmppc, argv[1], argv[2]);
+ } else {
+ logError(xmppc, "Unbekanner Befehl: %s\n", argv[0]);
+ }
+ }
+ xmpp_disconnect(xmppc->conn);
+}
+
+void _pgp_send_text(xmppc_t *xmppc, char* to, char* text) {
+ xmpp_conn_t *conn = xmppc->conn;
+ xmpp_stanza_t *message;
+ char* id = xmpp_uuid_gen(xmppc->ctx);
+ message = xmpp_message_new(xmpp_conn_get_context(conn), "chat", to, id);
+ int res = xmpp_message_set_body(message, "This message is *encrypted* with PGP (See :XEP:`27`)");
+ if(res == 0) {
+ xmpp_stanza_t *x = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(x, "x");
+ xmpp_stanza_set_ns(x, "jabber:x:encrypted");
+ xmpp_stanza_t *b = xmpp_stanza_new(xmppc->ctx);
+ char* encrypt_text = _pgp_encrypt_message(xmppc, to,text);
+ if(text == NULL) {
+ return;
+ }
+ xmpp_stanza_set_text(b,encrypt_text);
+ xmpp_stanza_add_child(x, b);
+ xmpp_stanza_add_child(message, x);
+ xmpp_stanza_t *e = xmpp_stanza_new(xmppc->ctx);
+ xmpp_stanza_set_name(e, "encryption");
+ xmpp_stanza_set_ns(e, "urn:xmpp:eme:0");
+ xmpp_stanza_set_attribute(e, "namespace", "jabber:x:encrypted");
+ xmpp_stanza_add_child(message, e);
+ xmpp_send(conn, message);
+ }
+}
+
+char* _pgp_encrypt_message(xmppc_t *xmppc, char* recipient, char* message) {
+ setlocale (LC_ALL, "");
+ gpgme_check_version (NULL);
+ gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
+ gpgme_ctx_t ctx;
+ gpgme_error_t error = gpgme_new (&ctx);
+ if(GPG_ERR_NO_ERROR != error ) {
+ printf("gpgme_new: %d\n", error);
+ return NULL;
+ }
+ error = gpgme_set_protocol(ctx, GPGME_PROTOCOL_OPENPGP);
+ gpgme_set_armor(ctx,1);
+ gpgme_set_textmode(ctx,1);
+ gpgme_set_offline(ctx,1);
+ gpgme_set_keylist_mode(ctx, GPGME_KEYLIST_MODE_LOCAL);
+
+ gpgme_key_t recp[3];
+ const char *jid = xmpp_conn_get_jid(xmppc->conn);
+ error = gpgme_get_key(ctx, jid, &(recp[0]), 0);
+ error = gpgme_get_key(ctx, recipient, &(recp[1]), 0);
+ recp[2] = NULL;
+
+ logInfo(xmppc, "%s <%s>\n", recp[0]->uids->name, recp[0]->uids->email);
+ logInfo(xmppc, "%s <%s>\n", recp[1]->uids->name, recp[1]->uids->email);
+
+ gpgme_encrypt_flags_t flags = 0;
+ gpgme_data_t plain;
+ gpgme_data_t cipher;
+
+ error = gpgme_data_new (&plain);
+
+ error = gpgme_data_new_from_mem(&plain, message, strlen(message),0);
+ error = gpgme_data_new (&cipher);
+
+ error = gpgme_op_encrypt ( ctx, recp, flags, plain, cipher);
+ size_t len;
+ char *cipher_str = gpgme_data_release_and_get_mem(cipher, &len);
+ char* result = NULL;
+ if(len > 0 ){
+ result = _pgp_remove_PGP_MESSAGE_comment(cipher_str);
+ }
+
+ gpgme_key_release (recp[0]);
+ gpgme_key_release (recp[1]);
+ gpgme_release (ctx);
+ return result;
+}
+
+static char* _pgp_remove_PGP_MESSAGE_comment(const char* message) {
+ char* tmp = strndupa(message, strlen(message) - (strlen(PGP_END)+1));
+ tmp = tmp+((strlen(PGP_BEGIN) +1) * sizeof(char));
+ char* result = malloc(strlen(tmp)+1);
+ strcpy(result, tmp);
+ return result;
+}
diff --git a/src/mode/pgp.h b/src/mode/pgp.h
new file mode 100644
index 0000000..03d5908
--- /dev/null
+++ b/src/mode/pgp.h
@@ -0,0 +1,59 @@
+/*!
+ * @file pgp.h
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @authors
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * @copyright
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+/*!
+ * \page module-pgp PGP
+ * \brief xmppc PGP Module
+ *
+ * Commands
+ * - chat
+ *
+ */
+
+#ifndef XMPPC_PGP_H__
+#define XMPPC_PGP_H__
+
+#include "xmppc.h"
+
+void pgp_execute_command(xmppc_t *xmppc, int agrc, char *argv[]);
+
+#endif // XMPPC_PGP_H__
diff --git a/src/mode/roster.c b/src/mode/roster.c
new file mode 100644
index 0000000..16da191
--- /dev/null
+++ b/src/mode/roster.c
@@ -0,0 +1,121 @@
+/*
+ * @file roster.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#include "roster.h"
+#include
+#include
+#include
+
+#define COMMAND_LIST "list"
+#define COMMAND_EXPORT "export"
+
+typedef enum commandTyp { C_UNKOWN, LIST, EXPORT } CommandType;
+
+typedef struct command {
+ CommandType type;
+} command_t;
+
+static void _roster_parse_command(command_t *command, int argc, char *argv[]);
+
+static void _roster_send_query(xmppc_t *xmppc,command_t *command);
+
+static int _handle_reply(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
+ void *const userdata);
+
+void roster_execute_command(xmppc_t *xmppc, int argc, char *argv[]) {
+ command_t *command = malloc(sizeof(command_t));
+ command->type = UNKOWN;
+ _roster_parse_command(command, argc, argv);
+ _roster_send_query(xmppc, command);
+}
+
+static void _roster_parse_command(command_t *command, int argc, char *argv[]) {
+ if (strcmp(COMMAND_LIST, argv[0]) == 0) {
+ command->type = LIST;
+ } else if (strcmp(COMMAND_EXPORT, argv[0]) == 0) {
+ command->type = EXPORT;
+ }
+}
+
+static void _roster_send_query(xmppc_t *xmppc, command_t *command ) {
+ logInfo(xmppc, "Send roster query\n");
+ xmpp_ctx_t *ctx = xmppc->ctx;
+ xmpp_conn_t *conn = xmppc->conn;
+ xmpp_stanza_t *iq, *query;
+ iq = xmpp_iq_new(ctx, "get", "roster1");
+ query = xmpp_stanza_new(ctx);
+ xmpp_stanza_set_name(query, "query");
+ xmpp_stanza_set_ns(query, XMPP_NS_ROSTER);
+ xmpp_stanza_add_child(iq, query);
+ xmpp_stanza_release(query);
+ xmpp_id_handler_add(conn, _handle_reply, "roster1",command);
+ xmpp_send(conn, iq);
+ xmpp_stanza_release(iq);
+}
+
+int _handle_reply(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
+ void *const userdata) {
+ command_t* command = (command_t*) userdata;
+ xmpp_stanza_t *query, *item;
+ const char *type, *name;
+ type = xmpp_stanza_get_type(stanza);
+ if (strcmp(type, "error") == 0)
+ printf("query failed\n");
+ else {
+ query = xmpp_stanza_get_child_by_name(stanza, "query");
+ for (item = xmpp_stanza_get_children(query); item;
+ item = xmpp_stanza_get_next(item)) {
+ if(command->type == LIST) {
+ if ((name = xmpp_stanza_get_attribute(item, "name")))
+ printf("\t %s (%s) sub=%s\n", name,
+ xmpp_stanza_get_attribute(item, "jid"),
+ xmpp_stanza_get_attribute(item, "subscription"));
+ else
+ printf("\t %s sub=%s\n", xmpp_stanza_get_attribute(item, "jid"),
+ xmpp_stanza_get_attribute(item, "subscription"));
+ } else if (command->type == EXPORT) {
+ printf("%s\n", xmpp_stanza_get_attribute(item, "jid"));
+ }
+ }
+ }
+ xmpp_disconnect(conn);
+ xmpp_stop(xmpp_conn_get_context(conn));
+ return 0;
+}
diff --git a/src/mode/roster.h b/src/mode/roster.h
new file mode 100644
index 0000000..f266387
--- /dev/null
+++ b/src/mode/roster.h
@@ -0,0 +1,50 @@
+/*!
+ * @file roster.h
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+
+
+#ifndef XMPPC_ROSTER_H__
+#define XMPPC_ROSTER_H__
+
+#include "xmppc.h"
+
+void roster_execute_command(xmppc_t *xmppc, int agrc, char *argv[]);
+
+#endif // XMPPC_ROSTER_H__
diff --git a/src/xmpp.c b/src/xmpp.c
new file mode 100644
index 0000000..e635c52
--- /dev/null
+++ b/src/xmpp.c
@@ -0,0 +1,142 @@
+/*
+ * @file xmppc.c
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @copyright
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#include "xmppc.h"
+#include
+#include
+#include
+
+/*! @file xmppc.c
+ *
+ * xmppc
+ *
+ */
+
+/*!
+ * Error logging
+ *
+ * \param xmppc the xmppc context structure
+ * \param fmt format of message
+ *
+ */
+void logError(xmppc_t *xmppc, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+
+void logWarn(xmppc_t *xmppc, const char *fmt, ...) {
+ if (xmppc->loglevel) {
+ va_list args;
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+ }
+}
+
+void logInfo(xmppc_t *xmppc, const char *fmt, ...) {
+ if (xmppc->loglevel) {
+ va_list args;
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+ }
+}
+
+void logDebug(xmppc_t *xmppc, const char *fmt, ...) {
+ if (xmppc->loglevel) {
+ va_list args;
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+ }
+}
+
+/*!
+ * \brief Setup the application context.
+ *
+ * \param xmppc
+ * \return 0 - ok
+ *
+ **/
+int xmppc_context(xmppc_t *xmppc, int level) {
+ assert(xmppc != NULL);
+ assert(xmppc->ctx == NULL);
+ xmpp_log_t *log = NULL;
+
+ if (level > TRACE) {
+ logError(xmppc, "Log level %d not supported. Max: %d.\n", level, TRACE);
+ exit(-1);
+ }
+
+ xmppc->loglevel = level;
+
+ if (level == ERROR) {
+ log = xmpp_get_default_logger(XMPP_LEVEL_ERROR);
+ } else if (level == WARN) {
+ log = xmpp_get_default_logger(XMPP_LEVEL_WARN);
+ } else if (level == INFO) {
+ log = xmpp_get_default_logger(XMPP_LEVEL_INFO);
+ } else if (level == DEBUG) {
+ log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
+ } else if (level == TRACE) {
+ log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
+ }
+
+ xmpp_ctx_t *ctx = xmpp_ctx_new(NULL, log);
+ xmppc->ctx = ctx;
+ return 0;
+}
+
+int xmppc_connect(xmppc_t *xmppc, char *jid, char *password) {
+ assert(xmppc != NULL);
+ assert(jid != NULL);
+ assert(password != NULL);
+ xmpp_conn_t *conn = xmpp_conn_new(xmppc->ctx);
+ assert(conn != NULL);
+
+ xmpp_conn_set_jid(conn, jid);
+ xmpp_conn_set_pass(conn, password);
+ xmppc->conn = conn;
+ return 0;
+}
diff --git a/src/xmpp.h b/src/xmpp.h
new file mode 100644
index 0000000..b05cafd
--- /dev/null
+++ b/src/xmpp.h
@@ -0,0 +1,100 @@
+/*
+ * @file xmppc.h
+ *
+ * vim: expandtab:ts=2:sts=2:sw=2
+ *
+ * @copyright
+ *
+ * Copyright (C) 2020 Anoxinon e.V.
+ *
+ * This file is part of xmppc.
+ *
+ * xmppc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * xmppc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see .
+ *
+ * German
+ *
+ * Diese Datei ist Teil von xmppc.
+ *
+ * xmppc ist Freie Software: Sie können es unter den Bedingungen
+ * der GNU General Public License, wie von der Free Software Foundation,
+ * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
+ * veröffentlichten Version, weiter verteilen und/oder modifizieren.
+ *
+ * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
+ * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
+ * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
+ * Siehe die GNU General Public License für weitere Details.
+ *
+ * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
+ * Programm erhalten haben. Wenn nicht, siehe .
+ */
+
+#ifndef XMPPC_XMPPC_H__
+#define XMPPC_XMPPC_H__
+
+#include "config.h"
+
+#include
+#include
+#include
+
+#define ANSI_COLOR_RED "\x1b[31m"
+#define ANSI_COLOR_GREEN "\x1b[32m"
+#define ANSI_COLOR_YELLOW "\x1b[33m"
+#define ANSI_COLOR_BLUE "\x1b[34m"
+#define ANSI_COLOR_MAGENTA "\x1b[35m"
+#define ANSI_COLOR_CYAN "\x1b[36m"
+
+#define ANSI_COLOR_B_RED "\x1b[91m"
+
+
+/**
+ * XMPPC Level of Logging
+ *
+ */
+typedef enum loglevel {
+ ERROR = 0,
+ WARN = 1,
+ INFO = 2,
+ DEBUG = 3,
+ TRACE = 4
+} loglevel_t;
+
+typedef enum mode { UNKOWN, ACCOUNT, ROSTER, MESSAGE, MUC, OMEMO, PGP, OPENPGP, MONITOR } xmppc_mode_t;
+
+typedef struct {
+ /** log level **/
+ loglevel_t loglevel;
+ xmpp_ctx_t *ctx;
+ xmpp_conn_t *conn;
+ xmppc_mode_t mode;
+} xmppc_t;
+
+#define INIT_XMPPC(X) xmppc_t X = {.loglevel = ERROR, .ctx = NULL, .conn = NULL, .mode = UNKOWN}
+
+typedef void (*ExecuteHandler)(xmppc_t *, int, char **);
+
+void logError(xmppc_t *xmppc_t, const char *fmt, ...);
+
+void logWarn(xmppc_t *xmppc, const char *fmt, ...);
+
+void logInfo(xmppc_t *xmppc, const char *fmt, ...);
+
+void logDebug(xmppc_t *xmppc, const char *fmt, ...);
+
+int xmppc_context(xmppc_t *xmppc, int level);
+
+int xmppc_connect(xmppc_t *_xmppc, char *jid, char *password);
+
+#endif // XMPPC_XMPPC_H__