Move the xmlSAXHandler out of the header and into the
[OpenSRF.git] / src / jserver / osrf_chat.h
1 /*
2 Copyright (C) 2005  Georgia Public Library Service 
3 Bill Erickson <billserickson@gmail.com>
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 */
15
16 #ifndef OSRF_CHAT_H
17 #define OSRF_CHAT_H
18
19
20 /* opensrf headers */
21 #include "opensrf/utils.h"
22 #include "opensrf/osrf_hash.h"
23 #include "opensrf/osrf_list.h"
24 #include "opensrf/log.h"
25 #include "opensrf/xml_utils.h"
26 #include "opensrf/socket_bundle.h"
27 #include "opensrf/sha.h"
28 #include "opensrf/transport_message.h"
29
30 /* libxml2 headers */
31 #include <libxml/parser.h>
32 #include <libxml/tree.h>
33 #include <libxml/globals.h>
34 #include <libxml/xmlerror.h>
35
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39
40 /* client to server XML */
41 #define OSRF_CHAT_START_STREAM "<?xml version='1.0'?><stream:stream "\
42         "xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' "\
43         "from='%s' version='1.0' id='%s'>" 
44
45 #define OSRF_CHAT_PARSE_ERROR "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "\
46         "version='1.0'><stream:error xmlns:stream='http://etherx.jabber.org/streams'>"\
47         "<xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>"    \
48         "<text xmlns='urn:ietf:params:xml:ns:xmpp-streams'>syntax error</text></stream:error></stream:stream>" 
49
50 #define OSRF_CHAT_LOGIN_OK "<iq xmlns='jabber:client' id='0123456789' type='result'/>"
51
52 #define OSRF_CHAT_NO_RECIPIENT "<message xmlns='jabber:client' type='error' from='%s' to='%s'>"\
53         "<error type='cancel' code='404'><item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"\
54         "</error><body>NOT ADDING BODY</body></message>"
55
56 /* ---------------------------------------------------------------------------------- */
57 /* server to server XML */
58
59 // client to server init
60 #define OSRF_CHAT_S2S_INIT "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "\
61         "xmlns='jabber:server' xmlns:db='jabber:server:dialback'>"
62
63 // server to client challenge 
64 #define OSRF_CHAT_S2S_CHALLENGE "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "\
65         "xmlns='jabber:server' id='%s' xmlns:db='jabber:server:dialback'>"
66
67 // client to server challenge response
68 #define OSRF_CHAT_S2S_RESPONSE "<db:result xmlns:db='jabber:server:dialback' to='%s' from='%s'>%s</db:result>"
69
70 // server to client verify
71 #define OSRF_CHAT_S2S_VERIFY_REQUEST "<db:verify xmlns:db='jabber:server:dialback' id='%s' from='%s' to='%s'>%s</db:verify>"
72
73 // client to server verify response
74 #define OSRF_CHAT_S2S_VERIFY_RESPONSE "<db:verify xmlns:db='jabber:server:dialback' type='valid' to='%s' from='%s' id='%s'/>"
75
76 //server to client final verification
77 #define OSRF_CHAT_S2S_VERIFY_FINAL "<db:result xmlns:db='jabber:server:dialback' type='valid' from='%s' to ='%s'/>"
78
79
80 /* c2s states */
81 #define OSRF_CHAT_STATE_NONE                                            0               /* blank node */
82 #define OSRF_CHAT_STATE_CONNECTING                              1               /* we have received the opening stream */
83 #define OSRF_CHAT_STATE_CONNECTED                               2               /* we have sent the OK/result message */
84
85 /* s2s states */
86 #define OSRF_CHAT_STATE_S2S_CHALLENGE                   4               /* client : waiting for the challenge */
87 #define OSRF_CHAT_STATE_S2S_RESPONSE                    5               /* server : waiting for the challenge response */
88 #define OSRF_CHAT_STATE_S2S_VERIFY                              6               /* client : waiting for verify message */
89 #define OSRF_CHAT_STATE_S2S_VERIFY_RESPONSE     7               /* server : waiting for verify response */
90 #define OSRF_CHAT_STATE_S2S_VERIFY_FINAL                8               /* client : waiting for final verify response */
91
92 /* xml parser states */
93 #define OSRF_CHAT_STATE_INMESSAGE               1
94 #define OSRF_CHAT_STATE_INIQ                            2
95 #define OSRF_CHAT_STATE_INUSERNAME              4
96 #define OSRF_CHAT_STATE_INRESOURCE              8
97 #define OSRF_CHAT_STATE_INS2SRESULT             16
98 #define OSRF_CHAT_STATE_INS2SVERIFY             32
99
100
101 struct __osrfChatNodeStruct {
102
103         int sockid;                     /* our socket id */
104
105         int type;                       /* 0 for client, 1 for server */
106
107         /* for clients this is the full JID of the client that connected to this server.
108                 for servers it's the domain (network id) of the server we're connected to */
109         char* remote;           
110
111
112         int state;                      /* for the various stages of connectivity and parsing */
113         int xmlstate;           /* what part of the message are we currently parsing */
114         int inparse;            /* true if we are currently parsing a chunk of XML.  If so, we can't 
115                                                                         free the node.  we have to cache it and free it later */
116
117         char* to;                       /* The JID where the current message is being routed */
118
119         char* domain;           /* the domain, resource, and username of our connecting entity. */ 
120         char* resource; /* for s2s nodes, resource and username will be empty . */
121         char* username;
122
123         char* authkey;          /* when doing any auth negotiation, this is the auth seed hash */
124         osrfList* msgs; /* if we're a server node we may have a pool of messages waiting to be delivered */
125
126         xmlParserCtxtPtr parserCtx; 
127         xmlDocPtr msgDoc;
128         struct __osrfChatServerStruct* parent;
129
130 };
131 typedef struct __osrfChatNodeStruct osrfChatNode;
132
133 /*
134 struct __osrfChatS2SMessageStruct {
135         char* toAddr;
136         char* msgXML;
137 };
138 typedef struct __osrfChatS2SMessageStruct osrfChatS2SMessage;
139 */
140
141 struct __osrfChatServerStruct {
142         osrfHash* nodeHash; /* sometimes we need hash (remote id) lookup, sometimes we need socket id lookup */
143         osrfList* nodeList;
144         osrfList* deadNodes; /* collection of nodes to free when we get a chance */
145         socket_manager* mgr;
146         char* secret;                   /* shared S2S secret */
147         char* domain;                   /* the domain this server hosts */
148         int s2sport;
149         int port;
150 };
151
152 typedef struct __osrfChatServerStruct osrfChatServer;
153
154
155 void osrfChatCacheS2SMessage( char* toAddr, char* msgXML, osrfChatNode* snode );
156
157 osrfChatNode* osrfNewChatS2SNode( char* domain, char* remote );
158 osrfChatNode* osrfNewChatNode( int sockid, char* domain );
159 void osrfChatNodeFree( void* node );
160
161 /* @param s2sSecret The Server to server secret.  OK to leave NULL if no 
162         server to server communication is expected
163         */
164 osrfChatServer* osrfNewChatServer( char* domain, char* s2sSecret, int s2sport );
165
166 int osrfChatServerConnect( osrfChatServer* cs,  int port, int s2sport, char* listenAddr );
167
168 int osrfChatServerWait( osrfChatServer* server );
169 void osrfChatServerFree(osrfChatServer* cs);
170
171 void osrfChatHandleData( void* cs, 
172         socket_manager* mgr, int sockid, char* data, int parent_id );
173
174
175 /* removes dead nodes that have been cached due to mid-parse removals */
176 void osrfChatCleanupClients( osrfChatServer* server );
177
178
179 osrfChatNode* osrfChatAddNode( osrfChatServer* server, int sockid );
180
181
182 void osrfChatRemoveNode( osrfChatServer* server, osrfChatNode* node );
183
184 /** pushes new data into the nodes parser */
185 int osrfChatPushData( osrfChatServer* server, osrfChatNode* node, char* data );
186
187
188 void osrfChatSocketClosed( void* blob, int sockid );
189
190 /**
191   Sends msgXML to the client with remote 'toAddr'.  if we have no connection
192   to 'toAddr' and the domain for 'toAddr' is different than our hosted domain
193   we attempt to send the message to the domain found in 'toAddr'.
194   */
195 int osrfChatSend( osrfChatServer* cs, osrfChatNode* node, char* toAddr, char* fromAddr, char* msgXML );
196
197 int osrfChatSendRaw( osrfChatNode* node, char* xml );
198
199
200 void osrfChatNodeFinish( osrfChatServer* server, osrfChatNode* node );
201
202 /* initializes the negotiation of a server to server connection */
203 int osrfChatInitS2S( osrfChatServer* cs, char* remote, char* toAddr, char* msgXML );
204
205 int osrfChatHandleNewConnection( osrfChatNode* node, const char* name, const xmlChar** atts );
206 int osrfChatHandleConnecting( osrfChatNode* node, const char* name, const xmlChar** atts );
207 int osrfChatHandleConnected( osrfChatNode* node, const char* name, const xmlChar** atts );
208 int osrfChatHandleS2SInit( osrfChatNode* node, const char* name, const xmlChar** atts );
209 int osrfChatHandleS2SChallenge( osrfChatNode* node, const char* name, const xmlChar** atts );
210 int osrfChatHandleS2SResponse( osrfChatNode* node, const char* name, const xmlChar** atts );
211
212 int osrfChatHandleS2SConnected( osrfChatNode* node, const char* nm, const xmlChar**atts );
213
214 void osrfChatS2SMessageFree(void* n);
215
216 /* generates a random sha1 hex key */
217 char* osrfChatMkAuthKey();
218
219 #ifdef __cplusplus
220 }
221 #endif
222
223 #endif
224
225