Skip to content
This repository was archived by the owner on Oct 29, 2021. It is now read-only.

Commit ad87bbd

Browse files
committed
Merge remote-tracking branch 'upstream/master'
Conflicts: src/conn.c
2 parents 73e3487 + 7217308 commit ad87bbd

File tree

5 files changed

+180
-55
lines changed

5 files changed

+180
-55
lines changed

ChangeLog

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
according to RFC2052.
77
- xmpp_connect_raw() provides access to a xmpp_conn object just after
88
establishing TCP connection. This allows to implement in-band
9-
registration or authentication mechanisms.
9+
registration, authentication mechanisms or serverless messaging.
1010
- xmpp_conn_t object is reusable now and can be reconnected with saving
1111
all handlers, flags, jid and password.
1212
- New API:
1313
- xmpp_uuid_gen()
1414
- xmpp_connect_raw()
15-
- xmpp_conn_raw_open_stream()
16-
- xmpp_conn_raw_tls_start()
15+
- xmpp_conn_open_stream_default()
16+
- xmpp_conn_open_stream()
17+
- xmpp_conn_tls_start()
1718
- xmpp_conn_get_flags()
1819
- xmpp_conn_set_flags()
1920
- xmpp_conn_set_keepalive()

configure.ac

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ AS_CASE([$host_os],
1414
[netbsd*], [PLATFORM="bsd"],
1515
[*nto*|*qnx*], [PLATFORM="qnx"],
1616
[*solaris*], [PLATFORM="solaris"],
17+
[*android*], [PLATFORM="android"],
1718
[PLATFORM="nix"])
1819

1920
PKG_CHECK_MODULES([expat], [expat >= 2.0.0],
@@ -55,6 +56,7 @@ AS_CASE([$PLATFORM],
5556
[bsd], [RESOLV_LIBS=""],
5657
[qnx], [RESOLV_LIBS="-lsocket"],
5758
[solaris], [RESOLV_LIBS="-lresolv -lsocket -lnsl"],
59+
[android], [RESOLV_LIBS=""],
5860
[RESOLV_LIBS="-lresolv"])
5961

6062
LIBS_TMP="${LIBS}"

mesode.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,10 @@ int xmpp_connect_raw(xmpp_conn_t * const conn,
263263
xmpp_certfail_handler certfail_cb,
264264
xmpp_conn_handler callback,
265265
void * const userdata);
266-
int xmpp_conn_raw_open_stream(xmpp_conn_t * const conn);
267-
int xmpp_conn_raw_tls_start(xmpp_conn_t * const conn);
266+
int xmpp_conn_open_stream_default(xmpp_conn_t * const conn);
267+
int xmpp_conn_open_stream(xmpp_conn_t * const conn, char **attributes,
268+
size_t attributes_len);
269+
int xmpp_conn_tls_start(xmpp_conn_t * const conn);
268270

269271
void xmpp_disconnect(xmpp_conn_t * const conn);
270272

src/auth.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,8 @@ static int _handle_missing_legacy(xmpp_conn_t * const conn,
11401140

11411141
void auth_handle_component_open(xmpp_conn_t * const conn)
11421142
{
1143+
int rc;
1144+
11431145
/* reset all timed handlers */
11441146
handler_reset_timed(conn, 0);
11451147

@@ -1148,7 +1150,11 @@ void auth_handle_component_open(xmpp_conn_t * const conn)
11481150
"handshake", NULL, NULL);
11491151
handler_add_timed(conn, _handle_missing_handshake, HANDSHAKE_TIMEOUT, NULL);
11501152

1151-
_handle_component_auth(conn);
1153+
rc = _handle_component_auth(conn);
1154+
if (rc != 0) {
1155+
xmpp_error(conn->ctx, "auth", "Component authentication failed.");
1156+
xmpp_disconnect(conn);
1157+
}
11521158
}
11531159

11541160
/* Will compute SHA1 and authenticate the component to the server */
@@ -1159,6 +1165,11 @@ int _handle_component_auth(xmpp_conn_t * const conn)
11591165
char *digest;
11601166
size_t i;
11611167

1168+
if (conn->stream_id == NULL) {
1169+
xmpp_error(conn->ctx, "auth", "Received no stream id from the server.");
1170+
return XMPP_EINT;
1171+
}
1172+
11621173
/* Feed the session id and passphrase to the algorithm.
11631174
* We need to compute SHA1(session_id + passphrase)
11641175
*/
@@ -1186,7 +1197,6 @@ int _handle_component_auth(xmpp_conn_t * const conn)
11861197
} else {
11871198
xmpp_debug(conn->ctx, "auth", "Couldn't allocate memory for component "\
11881199
"handshake digest.");
1189-
xmpp_disconnect(conn);
11901200
return XMPP_EMEM;
11911201
}
11921202

src/conn.c

Lines changed: 158 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@
5151

5252
static int _disconnect_cleanup(xmpp_conn_t * const conn,
5353
void * const userdata);
54-
54+
static char *_conn_build_stream_tag(xmpp_conn_t * const conn,
55+
char **attributes, size_t attributes_len);
56+
static void _conn_attributes_new(xmpp_conn_t *conn, char **attrs,
57+
char ***attributes, size_t *attributes_len);
58+
static void _conn_attributes_destroy(xmpp_conn_t *conn, char **attributes,
59+
size_t attributes_len);
5560
static void _handle_stream_start(char *name, char **attrs,
5661
void * const userdata);
5762
static void _handle_stream_end(char *name,
@@ -536,9 +541,8 @@ int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server,
536541
* the only required configuration is a domain (or full jid) passed via
537542
* xmpp_conn_set_jid().
538543
*
539-
* Next step should be xmpp_conn_raw_open_stream(). In case of legacy SSL,
540-
* user might want to call xmpp_conn_raw_tls_start() before opening the
541-
* stream.
544+
* Next step should be xmpp_conn_open_stream(). In case of legacy SSL,
545+
* user might want to call xmpp_conn_tls_start() before opening the stream.
542546
*
543547
* @see xmpp_connect_client()
544548
*
@@ -580,15 +584,18 @@ void conn_established(xmpp_conn_t * const conn)
580584
}
581585
}
582586

583-
/** Send an opening stream tag.
587+
/** Send the default opening stream tag.
588+
* The default tag is the one sent by xmpp_connect_client().
584589
* User's connection handler is called with event XMPP_CONN_CONNECT when
585590
* server replies with its opening tag.
586591
*
587592
* @return XMPP_EOK (0) on success a number less than 0 on failure
588593
*
594+
* @note The connection must be connected with xmpp_connect_raw().
595+
*
589596
* @ingroup Connections
590597
*/
591-
int xmpp_conn_raw_open_stream(xmpp_conn_t * const conn)
598+
int xmpp_conn_open_stream_default(xmpp_conn_t * const conn)
592599
{
593600
if (!conn->is_raw)
594601
return XMPP_EINVOP;
@@ -599,11 +606,48 @@ int xmpp_conn_raw_open_stream(xmpp_conn_t * const conn)
599606
return XMPP_EOK;
600607
}
601608

609+
/** Send an opening stream tag.
610+
* User's connection handler is called with event XMPP_CONN_CONNECT when
611+
* server replies with its opening tag.
612+
*
613+
* @param conn a Strophe connection object
614+
* @param attributes Array of strings in format: even index points to
615+
* an attribute name and odd index points to its value
616+
* @param attributes_len Number of elements in the attributes array, it
617+
* should be number of attributes multiplied by 2
618+
*
619+
* @return XMPP_EOK (0) on success a number less than 0 on failure
620+
*
621+
* @note The connection must be connected with xmpp_connect_raw().
622+
*
623+
* @ingroup Connections
624+
*/
625+
int xmpp_conn_open_stream(xmpp_conn_t * const conn, char **attributes,
626+
size_t attributes_len)
627+
{
628+
char *tag;
629+
630+
if (!conn->is_raw)
631+
return XMPP_EINVOP;
632+
633+
tag = _conn_build_stream_tag(conn, attributes, attributes_len);
634+
if (!tag)
635+
return XMPP_EMEM;
636+
637+
conn_prepare_reset(conn, auth_handle_open_raw);
638+
xmpp_send_raw_string(conn, "<?xml version=\"1.0\"?>%s", tag);
639+
xmpp_free(conn->ctx, tag);
640+
641+
return XMPP_EOK;
642+
}
643+
602644
/** Start synchronous TLS handshake with the server.
603645
*
604646
* @return XMPP_EOK (0) on success a number less than 0 on failure
647+
*
648+
* @ingroup Connections
605649
*/
606-
int xmpp_conn_raw_tls_start(xmpp_conn_t * const conn)
650+
int xmpp_conn_tls_start(xmpp_conn_t * const conn)
607651
{
608652
return conn_tls_start(conn);
609653
}
@@ -659,18 +703,6 @@ void conn_parser_reset(xmpp_conn_t * const conn)
659703
parser_reset(conn->parser);
660704
}
661705

662-
/* timed handler for cleanup if normal disconnect procedure takes too long */
663-
static int _disconnect_cleanup(xmpp_conn_t * const conn,
664-
void * const userdata)
665-
{
666-
xmpp_debug(conn->ctx, "xmpp",
667-
"disconnection forced by cleanup timeout");
668-
669-
conn_disconnect(conn);
670-
671-
return 0;
672-
}
673-
674706
/** Initiate termination of the connection to the XMPP server.
675707
* This function starts the disconnection sequence by sending
676708
* </stream:stream> to the XMPP server. This function will do nothing
@@ -1025,34 +1057,111 @@ void xmpp_conn_free_tlscert(xmpp_ctx_t *ctx, struct _tlscert_t *cert)
10251057
xmpp_free(ctx, cert);
10261058
}
10271059

1028-
static void _log_open_tag(xmpp_conn_t *conn, char **attrs)
1060+
/* timed handler for cleanup if normal disconnect procedure takes too long */
1061+
static int _disconnect_cleanup(xmpp_conn_t * const conn,
1062+
void * const userdata)
10291063
{
1030-
char buf[4096];
1031-
size_t pos;
1032-
int len;
1033-
int i;
1034-
char *attr;
1035-
1036-
if (!attrs) return;
1037-
1038-
pos = 0;
1039-
len = xmpp_snprintf(buf, 4096, "<stream:stream");
1040-
if (len < 0) return;
1041-
1042-
pos += len;
1043-
for (i = 0; attrs[i]; i += 2) {
1044-
attr = parser_attr_name(conn->ctx, attrs[i]);
1045-
len = xmpp_snprintf(&buf[pos], 4096 - pos, " %s='%s'",
1046-
attr, attrs[i+1]);
1047-
xmpp_free(conn->ctx, attr);
1048-
if (len < 0) return;
1049-
pos += len;
1064+
xmpp_debug(conn->ctx, "xmpp",
1065+
"disconnection forced by cleanup timeout");
1066+
1067+
conn_disconnect(conn);
1068+
1069+
return 0;
1070+
}
1071+
1072+
static char *_conn_build_stream_tag(xmpp_conn_t * const conn,
1073+
char **attributes, size_t attributes_len)
1074+
{
1075+
char *tag;
1076+
size_t len;
1077+
size_t i;
1078+
1079+
static const char *tag_head = "<stream:stream";
1080+
static const char *tag_tail = ">";
1081+
1082+
/* ignore the last element unless number is even */
1083+
attributes_len &= ~(size_t)1;
1084+
1085+
len = strlen(tag_head) + strlen(tag_tail);
1086+
for (i = 0; i < attributes_len; ++i)
1087+
len += strlen(attributes[i]) + 2;
1088+
tag = xmpp_alloc(conn->ctx, len + 1);
1089+
if (!tag) return NULL;
1090+
1091+
strcpy(tag, tag_head);
1092+
for (i = 0; i < attributes_len; ++i) {
1093+
if ((i & 1) == 0) {
1094+
strcat(tag, " ");
1095+
strcat(tag, attributes[i]);
1096+
strcat(tag, "=\"");
1097+
} else {
1098+
strcat(tag, attributes[i]);
1099+
strcat(tag, "\"");
1100+
}
10501101
}
1102+
strcat(tag, tag_tail);
10511103

1052-
len = xmpp_snprintf(&buf[pos], 4096 - pos, ">");
1053-
if (len < 0) return;
1104+
if (strlen(tag) != len) {
1105+
xmpp_error(conn->ctx, "xmpp", "Internal error in "
1106+
"_conn_build_stream_tag().");
1107+
xmpp_free(conn->ctx, tag);
1108+
tag = NULL;
1109+
}
1110+
1111+
return tag;
1112+
}
1113+
1114+
static void _conn_attributes_new(xmpp_conn_t *conn, char **attrs,
1115+
char ***attributes, size_t *attributes_len)
1116+
{
1117+
char **array = NULL;
1118+
size_t nr = 0;
1119+
size_t i;
1120+
1121+
if (attrs) {
1122+
for (; attrs[nr]; ++nr);
1123+
array = xmpp_alloc(conn->ctx, sizeof(*array) * nr);
1124+
for (i = 0; array && i < nr; ++i) {
1125+
array[i] = (i & 1) == 0 ? parser_attr_name(conn->ctx, attrs[i])
1126+
: xmpp_strdup(conn->ctx, attrs[i]);
1127+
if (array[i] == NULL) break;
1128+
}
1129+
if (!array || i < nr) {
1130+
xmpp_error(conn->ctx, "xmpp", "Memory allocation error.");
1131+
_conn_attributes_destroy(conn, array, i);
1132+
array = NULL;
1133+
nr = 0;
1134+
}
1135+
}
1136+
*attributes = array;
1137+
*attributes_len = nr;
1138+
}
10541139

1055-
xmpp_debug(conn->ctx, "xmpp", "RECV: %s", buf);
1140+
static void _conn_attributes_destroy(xmpp_conn_t *conn, char **attributes,
1141+
size_t attributes_len)
1142+
{
1143+
size_t i;
1144+
1145+
if (attributes) {
1146+
for (i = 0; i < attributes_len; ++i)
1147+
xmpp_free(conn->ctx, attributes[i]);
1148+
xmpp_free(conn->ctx, attributes);
1149+
}
1150+
}
1151+
1152+
static void _log_open_tag(xmpp_conn_t *conn, char **attrs)
1153+
{
1154+
char **attributes;
1155+
char *tag;
1156+
size_t nr;
1157+
1158+
_conn_attributes_new(conn, attrs, &attributes, &nr);
1159+
tag = _conn_build_stream_tag(conn, attributes, nr);
1160+
if (tag) {
1161+
xmpp_debug(conn->ctx, "xmpp", "RECV: %s", tag);
1162+
xmpp_free(conn->ctx, tag);
1163+
}
1164+
_conn_attributes_destroy(conn, attributes, nr);
10561165
}
10571166

10581167
static char *_get_stream_attribute(char **attrs, char *name)
@@ -1073,6 +1182,7 @@ static void _handle_stream_start(char *name, char **attrs,
10731182
{
10741183
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
10751184
char *id;
1185+
int failed = 0;
10761186

10771187
if (conn->stream_id) xmpp_free(conn->ctx, conn->stream_id);
10781188
conn->stream_id = NULL;
@@ -1083,17 +1193,17 @@ static void _handle_stream_start(char *name, char **attrs,
10831193
if (id)
10841194
conn->stream_id = xmpp_strdup(conn->ctx, id);
10851195

1086-
/* check and log errors */
1087-
if (!id)
1088-
xmpp_error(conn->ctx, "conn", "No id attribute.");
1089-
else if (!conn->stream_id)
1196+
if (id && !conn->stream_id) {
10901197
xmpp_error(conn->ctx, "conn", "Memory allocation failed.");
1198+
failed = 1;
1199+
}
10911200
} else {
10921201
xmpp_error(conn->ctx, "conn", "Server did not open valid stream."
10931202
" name = %s.", name);
1203+
failed = 1;
10941204
}
10951205

1096-
if (conn->stream_id) {
1206+
if (!failed) {
10971207
/* call stream open handler */
10981208
conn->open_handler(conn);
10991209
} else {

0 commit comments

Comments
 (0)