iks * iks_make_auth (iksid *id, const char *pass, const char *sid) { iks *x, *y; x = iks_new ("iq"); iks_insert_attrib (x, "type", "set"); y = iks_insert (x, "query"); iks_insert_attrib (y, "xmlns", IKS_NS_AUTH); iks_insert_cdata (iks_insert (y, "username"), id->user, 0); iks_insert_cdata (iks_insert (y, "resource"), id->resource, 0); if(sid) { char buf[41]; iksha *sha; sha = iks_sha_new (); iks_sha_hash (sha, sid, strlen (sid), 0); iks_sha_hash (sha, pass, strlen (pass), 1); iks_sha_print (sha, buf); iks_sha_delete (sha); iks_insert_cdata (iks_insert (y, "digest"), buf, 40); } else { iks_insert_cdata (iks_insert (y, "password"), pass, 0); } return x; }
int iks_start_sasl(iksparser *prs, enum ikssasltype type, char *username, char *pass) { iks *x; x = iks_new("auth"); iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_SASL); switch(type) { case IKS_SASL_PLAIN: { int len = iks_strlen(username) + iks_strlen(pass) + 2; char *s = iks_malloc(80 + len); char *base64; iks_insert_attrib(x, "mechanism", "PLAIN"); sprintf(s, "%c%s%c%s", 0, username, 0, pass); base64 = iks_base64_encode(s, len); iks_insert_cdata(x, base64, 0); iks_free(base64); iks_free(s); break; } case IKS_SASL_DIGEST_MD5: { struct stream_data *data = iks_user_data(prs); iks_insert_attrib(x, "mechanism", "DIGEST-MD5"); data->auth_username = username; data->auth_pass = pass; break; } case IKS_SASL_OAUTH_2: { int len = iks_strlen(username) + iks_strlen(pass) + 2; char *s = iks_malloc(80 + len); char *base64; iks_insert_attrib(x, "mechanism", "X-OAUTH2"); iks_insert_attrib(x, "auth:service", "oauth2"); iks_insert_attrib(x, "xmlns:auth", "http://www.google.com/talk/protocol/auth"); sprintf(s, "%c%s%c%s", 0, username, 0, pass); base64 = iks_base64_encode(s, len); iks_insert_cdata(x, base64, 0); iks_free(base64); iks_free(s); break; } default: iks_delete(x); return IKS_NET_NOTSUPP; } iks_send(prs, x); iks_delete(x); return IKS_OK; }
/** * Construct an NLSML result for digit match * @param digits the matching digits * @return the NLSML <result> */ iks *nlsml_create_dtmf_match(const char *digits) { iks *result = iks_new("result"); iks_insert_attrib(result, "xmlns", NLSML_NS); iks_insert_attrib(result, "xmlns:xf", "http://www.w3.org/2000/xforms"); if (!zstr(digits)) { int first = 1; int i; int num_digits = strlen(digits); switch_stream_handle_t stream = { 0 }; iks *interpretation = iks_insert(result, "interpretation"); iks *input = iks_insert(interpretation, "input"); input = iks_insert(input, "input"); iks_insert_attrib(input, "mode", "dtmf"); iks_insert_attrib(input, "confidence", "100"); SWITCH_STANDARD_STREAM(stream); for (i = 0; i < num_digits; i++) { if (isdigit(digits[i])) { if (first) { stream.write_function(&stream, "%c", digits[i]); first = 0; } else { stream.write_function(&stream, " %c", digits[i]); } } } iks_insert_cdata(input, stream.data, strlen(stream.data)); switch_safe_free(stream.data); } return result; }
char * db_dump_profile(void) { struct databases db; struct pack *p; DBC *cursor = NULL; DBT pair[2]; int e; iks *xml = NULL, *item, *x; char *ret = NULL; memset(&pair[0], 0, sizeof(DBT) * 2); pair[1].flags = DB_DBT_MALLOC; if (open_env(&db, PROFILE_DB)) goto out; db.profile->cursor(db.profile, NULL, &cursor, 0); xml = iks_new("comarProfile"); iks_insert_cdata(xml, "\n", 1); while ((e = cursor->c_get(cursor, &pair[0], &pair[1], DB_NEXT)) == 0) { char *t; size_t ts; item = iks_insert(xml, "item"); iks_insert_cdata(iks_insert(item, "key"), pair[0].data, pair[0].size); p = pack_wrap(pair[1].data, pair[1].size); while (pack_get(p, &t, &ts)) { iks_insert_cdata(item, "\n", 1); x = iks_insert(item, "data"); iks_insert_attrib(x, "key", t); pack_get(p, &t, &ts); iks_insert_cdata(iks_insert(x, "value"), t, ts); } pack_delete(p); iks_insert_cdata(xml, "\n", 1); } if (e != DB_NOTFOUND) { goto out; } ret = iks_string(NULL, xml); out: if (cursor) cursor->c_close(cursor); close_env(&db); if (xml) iks_delete(xml); return ret; }
// 服务器端组装发给客户端的协商包 char* pkg_talk_rtn(const packet_parser_t *pkg) { char *r; unsigned char *encrypted_key;// 使用公钥加密过的临时密钥 char *output; iks *x, *tmp; int dest_len; x = iks_new ("connection"); if(NULL == x) return NULL; iks_insert_attrib(x, "xmlns", TALK_XMLNS); iks_insert_attrib(x, "type", "result"); tmp = iks_insert(x, "encryption"); iks_insert_attrib(tmp, "type", pkg->curr_ert.transfer_ert_type); // 使用公钥对临时密钥进行加密 if (pkg->asym_encrypt_hook == NULL) { encrypted_key = rsa_encrypt((unsigned char *)get_transfer_crt_key(pkg), strlen(get_transfer_crt_key(pkg)), &dest_len, (char *)(pkg->curr_ert.ert_keys[0]), CRYPT_TYPE_ENCRYPT); } else { encrypted_key = pkg->asym_encrypt_hook((unsigned char *)get_transfer_crt_key(pkg), strlen(get_transfer_crt_key(pkg)), &dest_len, (char *)(pkg->curr_ert.ert_keys[0]), CRYPT_TYPE_ENCRYPT); } output = (char *)calloc(dest_len*2+1, 1); byte2hex(encrypted_key, dest_len, output); iks_insert_cdata(tmp, output, 0); free(output); free(encrypted_key); iks_insert_cdata(iks_insert(x, "compression"), pkg->cps_type, 0); tmp = iks_insert(x, "heartbeat"); // TODO:在初始化服务器端包解析器的时候应该设置心跳参数 iks_insert_attrib(tmp, "sponsor", "server"); iks_insert_attrib(tmp, "seconds", "60"); r = iks_string(NULL, x); iks_delete(x); return r; }
iks * iks_make_pres (enum ikshowtype show, const char *status) { iks *x; char *t; x = iks_new ("presence"); switch (show) { case IKS_SHOW_CHAT: t = "chat"; break; case IKS_SHOW_AWAY: t = "away"; break; case IKS_SHOW_XA: t = "xa"; break; case IKS_SHOW_DND: t = "dnd"; break; case IKS_SHOW_UNAVAILABLE: t = NULL; iks_insert_attrib (x, "type", "unavailable"); break; default: t = NULL; break; } if (t) iks_insert_cdata (iks_insert (x, "show"), t, 0); if (status) iks_insert_cdata(iks_insert (x, "status"), status, 0); return x; }
void prefs_setup (void) { iks *x; memset (&prefs, 0, sizeof (struct prefs_struct)); prefs_chdir (".ulubot"); if (iks_load ("ayarlar.xml", &x) == IKS_OK) { if (iks_strcmp (iks_name (x), "ulubot") == 0) { prefs.jid = iks_strdup (iks_find_cdata (x, "id")); prefs.pass = iks_strdup (iks_find_cdata (x, "password")); prefs.admin_jid = iks_strdup (iks_find_cdata (x, "admin_id")); iks_delete (x); if (prefs.jid && prefs.pass && prefs.admin_jid) return; } } puts (PACKAGE" v"VERSION" sözlük sunucusuna hoşgeldiniz!"); puts ("Hemen bir kaç ayar yapalım:"); prefs.jid = iks_strdup (input ("Botun Jabber hesabı")); prefs.pass = iks_strdup (input ("Botun Jabber şifresi")); prefs.admin_jid = iks_strdup (input ("Yöneticinin Jabber hesabı")); x = iks_new ("ulubot"); iks_insert_cdata (iks_insert (x, "id"), prefs.jid, 0); iks_insert_cdata (iks_insert (x, "password"), prefs.pass, 0); iks_insert_cdata (iks_insert (x, "admin_id"), prefs.admin_jid, 0); if (iks_save ("ayarlar.xml", x) != IKS_OK) { puts ("Hata: ayarları kaydedemedim!"); } iks_delete (x); puts ("Ayarlar tamam."); }
iks * iks_make_resource_bind (iksid *id) { iks *x, *y, *z; x = iks_new("iq"); iks_insert_attrib(x, "type", "set"); y = iks_insert(x, "bind"); iks_insert_attrib(y, "xmlns", IKS_NS_XMPP_BIND); if (id->resource && iks_strcmp(id->resource, "")) { z = iks_insert(y, "resource"); iks_insert_cdata(z, id->resource, 0); } return x; }
iks * iks_copy_within (iks *x, ikstack *s) { int level=0, dir=0; iks *copy = NULL; iks *cur = NULL; iks *y; while (1) { if (dir == 0) { if (x->type == IKS_TAG) { if (copy == NULL) { copy = iks_new_within (IKS_TAG_NAME (x), s); cur = copy; } else { cur = iks_insert (cur, IKS_TAG_NAME (x)); } for (y = IKS_TAG_ATTRIBS (x); y; y = y->next) { iks_insert_attrib (cur, IKS_ATTRIB_NAME (y), IKS_ATTRIB_VALUE (y)); } if (IKS_TAG_CHILDREN (x)) { x = IKS_TAG_CHILDREN (x); level++; continue; } else { cur = cur->parent; } } else { iks_insert_cdata (cur, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x)); } } y = x->next; if (y) { if (0 == level) break; x = y; dir = 0; } else { if (level < 2) break; level--; x = x->parent; cur = cur->parent; dir = 1; } } return copy; }
iks * iks_make_msg (enum iksubtype type, const char *to, const char *body) { iks *x; char *t = NULL; x = iks_new ("message"); switch (type) { case IKS_TYPE_CHAT: t = "chat"; break; case IKS_TYPE_GROUPCHAT: t = "groupchat"; break; case IKS_TYPE_HEADLINE: t = "headline"; break; default: break; } if (t) iks_insert_attrib (x, "type", t); if (to) iks_insert_attrib (x, "to", to); if (body) iks_insert_cdata (iks_insert (x, "body"), body, 0); return x; }
iks * iks_make_s10n (enum iksubtype type, const char *to, const char *msg) { iks *x; char *t; x = iks_new ("presence"); switch (type) { case IKS_TYPE_SUBSCRIBE: t = "subscribe"; break; case IKS_TYPE_SUBSCRIBED: t = "subscribed"; break; case IKS_TYPE_UNSUBSCRIBE: t = "unsubscribe"; break; case IKS_TYPE_UNSUBSCRIBED: t = "unsubscribed"; break; case IKS_TYPE_PROBE: t = "probe"; break; default: t = NULL; break; } if (t) iks_insert_attrib (x, "type", t); if (to) iks_insert_attrib (x, "to", to); if (msg) iks_insert_cdata(iks_insert (x, "status"), msg, 0); return x; }
// if returns IKS_OK, do not send more before ikss_SENT callback int ikss_Stream_start_sasl (ikss_Stream *self, enum ikssasltype type, const char *username, const char *pass) { iks *x; x = iks_new ("auth"); // xxx check return? iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL); // xxx check return? switch (type) { case IKS_SASL_PLAIN: { int len = iks_strlen (username) + iks_strlen (pass) + 2; char *s = iks_malloc (80+len); // xxx check for oom, on error free x and return error code char *base64; iks_insert_attrib (x, "mechanism", "PLAIN"); // xxx check return? sprintf (s, "%c%s%c%s", 0, username, 0, pass); base64 = iks_base64_encode (s, len); // xxx check return? iks_insert_cdata (x, base64, 0); iks_free (base64); iks_free (s); break; } case IKS_SASL_DIGEST_MD5: { iks_insert_attrib (x, "mechanism", "DIGEST-MD5"); // xxx check return? self->auth_username = username; self->auth_pass = pass; break; } default: iks_delete (x); return IKS_NET_NOTSUPP; } int ret = ikss_Stream_send_node (self, x); iks_delete (x); // delete ok since above makes a copy if (ret) return ret; return IKS_OK; }
/// 客户端组装发给服务器端的协商包。 char* pkg_talk_make(const packet_parser_t *pkg) { char *r; iks *x, *tmp; x = iks_new ("connection"); if(NULL == x) return NULL; iks_insert_attrib(x, "xmlns", TALK_XMLNS); iks_insert_attrib(x, "type", "create"); tmp = iks_insert(x, "client-id"); if(NULL != tmp) { iks_insert_cdata(tmp, pkg->client_cert.client_id, 0); } tmp = iks_insert(x, "public-key"); if(NULL != tmp) { iks_insert_cdata(tmp, pkg->curr_ert.ert_keys[0], 0); iks_insert_attrib(tmp, "type", pkg->curr_ert.talk_ert_type); } if(0 != strlen(pkg->curr_ert.talk_ert_type)){ tmp = iks_insert(x, "encryption"); iks_insert_cdata(iks_insert(tmp,"allow"), pkg->curr_ert.transfer_ert_type, 0); } if(0 != strlen(pkg->cps_type)){ tmp = iks_insert(x, "compression"); iks_insert_cdata(iks_insert(tmp,"allow"), pkg->cps_type, 0); } if( pkg->client_cert.signature[0] != 0 ){ tmp = iks_insert(x, "certificate"); iks_insert_attrib(tmp, "id", pkg->client_cert.cert_id); iks_insert_cdata(iks_insert(tmp, "subject"), pkg->client_cert.subject, 0); iks_insert_cdata(iks_insert(tmp, "signature"), pkg->client_cert.signature, 0); } r = iks_string(NULL, x); iks_delete(x); return r; }
static iks *make_sasl_response(struct stream_data *data, char *message) { iks *x = NULL; char *realm, *realm_end; char *nonce, *nonce_end; char cnonce[CNONCE_LEN * 8 + 1]; iksmd5 *md5; unsigned char a1_h[16], a1[33], a2[33], response_value[33]; char *response, *response_coded; int i; parse_digest(message, "realm=\"", &realm, &realm_end); parse_digest(message, "nonce=\"", &nonce, &nonce_end); /* nonce is necessary for auth */ if(!nonce || !nonce_end) return NULL; *nonce_end = '\0'; /* if no realm is given use the server hostname */ if(realm) { if(!realm_end) return NULL; *realm_end = '\0'; } else { realm = (char *) data->server; } /* generate random client challenge */ for(i = 0; i < CNONCE_LEN; ++i) sprintf(cnonce + i * 8, "%08x", rand()); md5 = iks_md5_new(); if(!md5) return NULL; iks_md5_hash(md5, (const unsigned char*)data->auth_username, iks_strlen(data->auth_username), 0); iks_md5_hash(md5, (const unsigned char*)":", 1, 0); iks_md5_hash(md5, (const unsigned char*)realm, iks_strlen(realm), 0); iks_md5_hash(md5, (const unsigned char*)":", 1, 0); iks_md5_hash(md5, (const unsigned char*)data->auth_pass, iks_strlen(data->auth_pass), 1); iks_md5_digest(md5, a1_h); iks_md5_reset(md5); iks_md5_hash(md5, (const unsigned char*)a1_h, 16, 0); iks_md5_hash(md5, (const unsigned char*)":", 1, 0); iks_md5_hash(md5, (const unsigned char*)nonce, iks_strlen(nonce), 0); iks_md5_hash(md5, (const unsigned char*)":", 1, 0); iks_md5_hash(md5, (const unsigned char*)cnonce, iks_strlen(cnonce), 1); iks_md5_print(md5, (char*)a1); iks_md5_reset(md5); iks_md5_hash(md5, (const unsigned char*)"AUTHENTICATE:xmpp/", 18, 0); iks_md5_hash(md5, (const unsigned char*)data->server, iks_strlen(data->server), 1); iks_md5_print(md5, (char*)a2); iks_md5_reset(md5); iks_md5_hash(md5, (const unsigned char*)a1, 32, 0); iks_md5_hash(md5, (const unsigned char*)":", 1, 0); iks_md5_hash(md5, (const unsigned char*)nonce, iks_strlen(nonce), 0); iks_md5_hash(md5, (const unsigned char*)":00000001:", 10, 0); iks_md5_hash(md5, (const unsigned char*)cnonce, iks_strlen(cnonce), 0); iks_md5_hash(md5, (const unsigned char*)":auth:", 6, 0); iks_md5_hash(md5, (const unsigned char*)a2, 32, 1); iks_md5_print(md5, (char*)response_value); iks_md5_delete(md5); i = iks_strlen(data->auth_username) + iks_strlen(realm) + iks_strlen(nonce) + iks_strlen(data->server) + CNONCE_LEN * 8 + 136; response = iks_malloc(i); if(!response) return NULL; sprintf(response, "username=\"%s\",realm=\"%s\",nonce=\"%s\"" ",cnonce=\"%s\",nc=00000001,qop=auth,digest-uri=\"" "xmpp/%s\",response=%s,charset=utf-8", data->auth_username, realm, nonce, cnonce, data->server, response_value); response_coded = iks_base64_encode(response, 0); if(response_coded) { x = iks_new("response"); iks_insert_cdata(x, response_coded, 0); iks_free(response_coded); } iks_free(response); return x; }
static int cdataHook(struct stream_data *data, char *cdata, size_t len) { if(data->current) iks_insert_cdata(data->current, cdata, len); return IKS_OK; }
// invoked by parser for character data static int cdataHook (ikss_Stream *self, char *cdata, size_t len) { if (self->current) iks_insert_cdata (self->current, cdata, len); return IKS_OK; }