char *db_key(char *secret, char *domain, char *id) { char buf[1024]; char *hash; snprintf(buf, sizeof(buf), "%s", secret); hash = shahash(buf); snprintf(buf, sizeof(buf), "%s%s", hash, domain); hash = shahash(buf); snprintf(buf, sizeof(buf), "%s%s", hash, id); hash = shahash(buf); return hash; }
result base_to_deliver(instance id, dpacket p, void *arg) { char *log_data = xmlnode_get_data(p->x); char *subject; xmlnode message; if (log_data == NULL) return r_ERR; message = xmlnode_new_tag("message"); xmlnode_insert_cdata(xmlnode_insert_tag(message, "body"), log_data, -1); subject = spools(xmlnode_pool(message), "Log Packet from ", xmlnode_get_attrib(p->x, "from"), xmlnode_pool(message)); xmlnode_insert_cdata(xmlnode_insert_tag(message, "thread"), shahash(subject), -1); xmlnode_insert_cdata(xmlnode_insert_tag(message, "subject"), subject, -1); xmlnode_put_attrib(message, "from", xmlnode_get_attrib(p->x, "from")); xmlnode_put_attrib(message, "to", (char *) arg); deliver(dpacket_new(message), id); pool_free(p->p); return r_DONE; }
char *jutil_regkey(char *key, char *seed) { static char keydb[KEYBUF][41]; static char seeddb[KEYBUF][41]; static int last = -1; char *str, strint[32]; int i; /* blanket the keydb first time */ if(last == -1) { last = 0; memset(&keydb,0,KEYBUF*41); memset(&seeddb,0,KEYBUF*41); srand(time(NULL)); } /* creation phase */ if(key == NULL && seed != NULL) { /* create a random key hash and store it */ sprintf(strint,"%d",rand()); strcpy(keydb[last],shahash(strint)); /* store a hash for the seed associated w/ this key */ strcpy(seeddb[last],shahash(seed)); /* return it all */ str = keydb[last]; last++; if(last == KEYBUF) last = 0; return str; } /* validation phase */ str = shahash(seed); for(i=0;i<KEYBUF;i++) if(j_strcmp(keydb[i],key) == 0 && j_strcmp(seeddb[i],str) == 0) { seeddb[i][0] = '\0'; /* invalidate this key */ return keydb[i]; } return NULL; }
int is_consistent_chunk(rcb_t *rcb) { uint8_t hash[SHA1_HASH_SIZE]; shahash((uint8_t *)rcb->buffer, BT_CHUNK_SIZE, hash); if(!memcmp(hash, rcb->chk_map->hash, SHA1_HASH_SIZE)) { return 1; } else { fprintf(stderr, "invalid chunk\n"); return 0; } }
static void stream_node_callback(int type, xode node, void *arg) { struct xmpp_private_data *priv = (struct xmpp_private_data *) arg; char *id, *hash, *tag; char buf[4096]; xode x; LM_DBG("stream callback: %d: %s\n", type, node ? xode_get_name(node) : "n/a"); switch (type) { case XODE_STREAM_ROOT: id = xode_get_attrib(node, "id"); snprintf(buf, sizeof(buf), "%s%s", id, xmpp_password); hash = shahash(buf); x = xode_new_tag("handshake"); xode_insert_cdata(x, hash, -1); xode_send(priv->fd, x); xode_free(x); break; case XODE_STREAM_NODE: tag = xode_get_name(node); if (!strcmp(tag, "handshake")) { LM_DBG("handshake succeeded\n"); } else if (!strcmp(tag, "message")) { LM_DBG("XMPP IM received\n"); char *from = xode_get_attrib(node, "from"); char *to = xode_get_attrib(node, "to"); char *type = xode_get_attrib(node, "type"); xode body = xode_get_tag(node, "body"); char *msg; if (!type) type = "chat"; if (!strcmp(type, "error")) { LM_DBG("received message error stanza\n"); goto out; } if (!from || !to || !body) { LM_DBG("invalid <message/> attributes\n"); goto out; } if (!(msg = xode_get_data(body))) msg = ""; xmpp_send_sip_msg( encode_uri_xmpp_sip(from), decode_uri_xmpp_sip(to), msg); } else if (!strcmp(tag, "presence")) { /* call presence callbacks */ LM_DBG("XMPP Presence received\n"); run_xmpp_callbacks(XMPP_RCV_PRESENCE, xode_to_str(node)); }else if (!strcmp(tag, "iq")) { /* call presence callbacks */ LM_DBG("XMPP IQ received\n"); run_xmpp_callbacks(XMPP_RCV_IQ, xode_to_str(node)); } break; case XODE_STREAM_ERROR: LM_ERR("stream error\n"); /* fall-through */ case XODE_STREAM_CLOSE: priv->running = 0; break; } out: xode_free(node); }
/** @brief Connect to the Jabber server as a client and open a Jabber session. @param session Pointer to a transport_session. @param username Jabber user name. @param password Jabber password. @param resource name of Jabber resource. @param connect_timeout Timeout interval, in seconds, for receiving data (see notes). @param auth_type An enum: either AUTH_PLAIN or AUTH_DIGEST (see notes). @return 1 if successful, or 0 upon error. If @a connect_timeout is -1, wait indefinitely for the Jabber server to respond. If @a connect_timeout is zero, don't wait at all. If @a timeout is positive, wait that number of seconds before timing out. If @a connect_timeout has a negative value other than -1, the results are not well defined. The value of @a connect_timeout applies to each of two stages in the logon procedure. Hence the logon may take up to twice the amount of time indicated. If we connect as a Jabber component, we send the password as an SHA1 hash. Otherwise we look at the @a auth_type. If it's AUTH_PLAIN, we send the password as plaintext; if it's AUTH_DIGEST, we send it as a hash. At this writing, we only use AUTH_DIGEST. */ int session_connect( transport_session* session, const char* username, const char* password, const char* resource, int connect_timeout, enum TRANSPORT_AUTH_TYPE auth_type ) { // Sanity checks if( ! session ) { osrfLogWarning(OSRF_LOG_MARK, "session is null in session_connect()" ); return 0; } if( session->sock_id != 0 ) { osrfLogWarning(OSRF_LOG_MARK, "transport session is already open, on socket %d", session->sock_id ); return 0; } // Open a client socket connecting to the Jabber server if(session->port > 0) { // use TCP session->sock_id = socket_open_tcp_client( session->sock_mgr, session->port, session->server ); if( session->sock_id <= 0 ) { session->sock_id = 0; return 0; } } else if(session->unix_path != NULL) { // use UNIX domain session->sock_id = socket_open_unix_client( session->sock_mgr, session->unix_path ); if( session->sock_id <= 0 ) { session->sock_id = 0; return 0; } } else { osrfLogWarning( OSRF_LOG_MARK, "Can't open session: no port or unix path" ); return 0; } const char* server = session->server; int size1 = 0; int size2 = 0; /* We establish the session in two stages. First we establish an XMPP stream with the Jabber server by sending an opening tag of stream:stream. This is not a complete XML document. We don't send the corresponding closing tag until we close the session. If the Jabber server responds by sending an opening stream:stream tag of its own, we can proceed to the second stage by sending a second stanza to log in. This stanza is an XML element with the tag <handshake> (if we're a Jabber component) or <iq> (if we're not), enclosing the username, password, and resource. If all goes well, the Jabber server responds with a <handshake> or <iq> stanza of its own, and we're logged in. If authentication fails, the Jabber server returns a <stream:error> (if we used a <handshake> or an <iq> of type "error" (if we used an <iq>). */ if( session->component ) { /* the first Jabber connect stanza */ char our_hostname[HOST_NAME_MAX + 1] = ""; gethostname(our_hostname, sizeof(our_hostname) ); our_hostname[HOST_NAME_MAX] = '\0'; size1 = 150 + strlen( username ) + strlen( our_hostname ); char stanza1[ size1 ]; snprintf( stanza1, sizeof(stanza1), "<stream:stream version='1.0' xmlns:stream='http://etherx.jabber.org/streams' " "xmlns='jabber:component:accept' to='%s' from='%s' xml:lang='en'>", username, our_hostname ); /* send the first stanze */ session->state_machine->connecting = CONNECTING_1; if( socket_send( session->sock_id, stanza1 ) ) { osrfLogWarning(OSRF_LOG_MARK, "error sending"); socket_disconnect( session->sock_mgr, session->sock_id ); session->sock_id = 0; return 0; } /* wait for reply */ socket_wait(session->sock_mgr, connect_timeout, session->sock_id); /* server acknowledges our existence, now see if we can login */ if( session->state_machine->connecting == CONNECTING_2 ) { int ss = buffer_length( session->session_id ) + strlen( password ) + 5; char hashstuff[ss]; snprintf( hashstuff, sizeof(hashstuff), "%s%s", OSRF_BUFFER_C_STR( session->session_id ), password ); char* hash = shahash( hashstuff ); size2 = 100 + strlen( hash ); char stanza2[ size2 ]; snprintf( stanza2, sizeof(stanza2), "<handshake>%s</handshake>", hash ); if( socket_send( session->sock_id, stanza2 ) ) { osrfLogWarning(OSRF_LOG_MARK, "error sending"); socket_disconnect( session->sock_mgr, session->sock_id ); session->sock_id = 0; return 0; } } } else { /* we're not a component */ /* the first Jabber connect stanza */ size1 = 100 + strlen( server ); char stanza1[ size1 ]; snprintf( stanza1, sizeof(stanza1), "<stream:stream to='%s' xmlns='jabber:client' " "xmlns:stream='http://etherx.jabber.org/streams'>", server ); /* send the first stanze */ session->state_machine->connecting = CONNECTING_1; if( socket_send( session->sock_id, stanza1 ) ) { osrfLogWarning(OSRF_LOG_MARK, "error sending"); socket_disconnect( session->sock_mgr, session->sock_id ); session->sock_id = 0; return 0; } /* wait for reply */ socket_wait( session->sock_mgr, connect_timeout, session->sock_id ); /* make the timeout smarter XXX */ if( auth_type == AUTH_PLAIN ) { /* the second jabber connect stanza including login info*/ size2 = 150 + strlen( username ) + strlen( password ) + strlen( resource ); char stanza2[ size2 ]; snprintf( stanza2, sizeof(stanza2), "<iq id='123456789' type='set'><query xmlns='jabber:iq:auth'>" "<username>%s</username><password>%s</password><resource>%s</resource></query></iq>", username, password, resource ); /* server acknowledges our existence, now see if we can login */ if( session->state_machine->connecting == CONNECTING_2 ) { if( socket_send( session->sock_id, stanza2 ) ) { osrfLogWarning(OSRF_LOG_MARK, "error sending"); socket_disconnect( session->sock_mgr, session->sock_id ); session->sock_id = 0; return 0; } } } else if( auth_type == AUTH_DIGEST ) { int ss = buffer_length( session->session_id ) + strlen( password ) + 5; char hashstuff[ss]; snprintf( hashstuff, sizeof(hashstuff), "%s%s", OSRF_BUFFER_C_STR( session->session_id ), password ); char* hash = shahash( hashstuff ); /* the second jabber connect stanza including login info */ size2 = 150 + strlen( username ) + strlen( hash ) + strlen(resource); char stanza2[ size2 ]; snprintf( stanza2, sizeof(stanza2), "<iq id='123456789' type='set'><query xmlns='jabber:iq:auth'>" "<username>%s</username><digest>%s</digest><resource>%s</resource></query></iq>", username, hash, resource ); /* server acknowledges our existence, now see if we can login */ if( session->state_machine->connecting == CONNECTING_2 ) { if( socket_send( session->sock_id, stanza2 ) ) { osrfLogWarning(OSRF_LOG_MARK, "error sending"); socket_disconnect( session->sock_mgr, session->sock_id ); session->sock_id = 0; return 0; } } } else { osrfLogWarning(OSRF_LOG_MARK, "Invalid auth_type parameter: %d", (int) auth_type ); socket_disconnect( session->sock_mgr, session->sock_id ); session->sock_id = 0; return 0; } } // not component /* wait for reply to login request */ socket_wait( session->sock_mgr, connect_timeout, session->sock_id ); if( session->state_machine->connected ) { /* yar! */ return 1; } else { socket_disconnect( session->sock_mgr, session->sock_id ); session->sock_id = 0; return 0; } }
/** * authentication to the JABBER server */ int xj_jcon_user_auth(xj_jcon jbc, char *username, char *passwd, char *resource) { char msg_buff[4096]; int n, i, err; char *p0, *p1; xode x, y, z; /*** send open stream tag **/ sprintf(msg_buff, JB_CLIENT_OPEN_STREAM, jbc->hostname); if(send(jbc->sock, msg_buff, strlen(msg_buff), 0) != strlen(msg_buff)) goto error; n = recv(jbc->sock, msg_buff, 4096, 0); msg_buff[n] = 0; if(strncasecmp(msg_buff, JB_START_STREAM, JB_START_STREAM_LEN)) goto error; p0 = strstr(msg_buff + JB_START_STREAM_LEN, "id='"); if(p0 == NULL) goto error; p0 += 4; p1 = strchr(p0, '\''); if(p1 == NULL) goto error; jbc->stream_id = (char*)_M_MALLOC(p1-p0+1); strncpy(jbc->stream_id, p0, p1-p0); jbc->stream_id[p1-p0] = 0; sprintf(msg_buff, "%08X", jbc->seq_nr); x = xode_new_tag("iq"); if(!x) return -1; xode_put_attrib(x, "id", msg_buff); xode_put_attrib(x, "type", "get"); y = xode_insert_tag(x, "query"); xode_put_attrib(y, "xmlns", "jabber:iq:auth"); z = xode_insert_tag(y, "username"); xode_insert_cdata(z, username, -1); p0 = xode_to_str(x); n = strlen(p0); i = send(jbc->sock, p0, n, 0); if(i != n) goto errorx; xode_free(x); // receive response // try 10 times i = 10; while(i) { if((n = recv(jbc->sock, msg_buff, 4096, 0)) > 0) { msg_buff[n] = 0; break; } usleep(1000); i--; } if(!i) goto error; x = xode_from_strx(msg_buff, n, &err, &i); p0 = msg_buff; if(err) p0 += i; if(strncasecmp(xode_get_name(x), "iq", 2)) goto errorx; if((x = xode_get_tag(x, "query?xmlns=jabber:iq:auth")) == NULL) goto errorx; y = xode_new_tag("query"); xode_put_attrib(y, "xmlns", "jabber:iq:auth"); z = xode_insert_tag(y, "username"); xode_insert_cdata(z, username, -1); z = xode_insert_tag(y, "resource"); xode_insert_cdata(z, resource, -1); if(xode_get_tag(x, "digest") != NULL) { // digest authentication //sprintf(msg_buff, "%s%s", jbc->stream_id, passwd); strcpy(msg_buff, jbc->stream_id); strcat(msg_buff, passwd); //DBG("XJAB:xj_jcon_user_auth: [%s:%s]\n", jbc->stream_id, passwd); p1 = shahash(msg_buff); z = xode_insert_tag(y, "digest"); xode_insert_cdata(z, p1, -1); } else { // plaint text authentication z = xode_insert_tag(y, "password"); xode_insert_cdata(z, passwd, -1); } y = xode_wrap(y, "iq"); jbc->seq_nr++; sprintf(msg_buff, "%08X", jbc->seq_nr); xode_put_attrib(y, "id", msg_buff); xode_put_attrib(y, "type", "set"); p1 = xode_to_str(y); n = strlen(p1); i = send(jbc->sock, p1, n, 0); if(i != n) { xode_free(y); goto errorx; } xode_free(x); xode_free(y); // receive response // try 10 times i = 10; while(i) { if((n = recv(jbc->sock, msg_buff, 4096, 0)) > 0) { msg_buff[n] = 0; break; } usleep(1000); i--; } if(!i) goto error; x = xode_from_strx(msg_buff, n, &err, &i); p0 = msg_buff; if(err) p0 += i; if(strncasecmp(xode_get_name(x), "iq", 2) || strncasecmp(xode_get_attrib(x, "type"), "result", 6)) goto errorx; jbc->resource = (char*)_M_MALLOC(strlen(resource)+1); strcpy(jbc->resource, resource); jbc->allowed = XJ_NET_ALL; jbc->ready = XJ_NET_JAB; return 0; errorx: xode_free(x); error: return -1; }