Beispiel #1
0
static xt_status jabber_do_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )
{
	struct jabber_data *jd = ic->proto_data;
	struct xt_node *reply, *query;
	xt_status st;
	char *s;
	
	if( !( query = xt_find_node( node->children, "query" ) ) )
	{
		imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" );
		imc_logout( ic, FALSE );
		return XT_HANDLED;
	}
	
	/* Time to authenticate ourselves! */
	reply = xt_new_node( "query", NULL, NULL );
	xt_add_attr( reply, "xmlns", XMLNS_AUTH );
	xt_add_child( reply, xt_new_node( "username", jd->username, NULL ) );
	xt_add_child( reply, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) );
	
	if( xt_find_node( query->children, "digest" ) && ( s = xt_find_attr( jd->xt->root, "id" ) ) )
	{
		/* We can do digest authentication, it seems, and of
		   course we prefer that. */
		sha1_state_t sha;
		char hash_hex[41];
		unsigned char hash[20];
		int i;
		
		sha1_init( &sha );
		sha1_append( &sha, (unsigned char*) s, strlen( s ) );
		sha1_append( &sha, (unsigned char*) ic->acc->pass, strlen( ic->acc->pass ) );
		sha1_finish( &sha, hash );
		
		for( i = 0; i < 20; i ++ )
			sprintf( hash_hex + i * 2, "%02x", hash[i] );
		
		xt_add_child( reply, xt_new_node( "digest", hash_hex, NULL ) );
	}
	else if( xt_find_node( query->children, "password" ) )
	{
		/* We'll have to stick with plaintext. Let's hope we're using SSL/TLS... */
		xt_add_child( reply, xt_new_node( "password", ic->acc->pass, NULL ) );
	}
	else
	{
		xt_free_node( reply );
		
		imcb_error( ic, "Can't find suitable authentication method" );
		imc_logout( ic, FALSE );
		return XT_ABORT;
	}
	
	reply = jabber_make_packet( "iq", "set", NULL, reply );
	jabber_cache_add( ic, reply, jabber_finish_iq_auth );
	st = jabber_write_packet( ic, reply );
	
	return st ? XT_HANDLED : XT_ABORT;
}
Beispiel #2
0
static gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond )
{
	struct msn_handler_data *handler = data;
	struct im_connection *ic = handler->data;
	struct msn_data *md;
	
	if( !g_slist_find( msn_connections, ic ) )
		return FALSE;
	
	md = ic->proto_data;
	
	if( source == -1 )
	{
		imcb_error( ic, "Could not connect to server" );
		imc_logout( ic, TRUE );
		return FALSE;
	}
	
	g_free( handler->rxq );
	handler->rxlen = 0;
	handler->rxq = g_new0( char, 1 );
	
	if( md->uuid == NULL )
	{
		struct utsname name;
		sha1_state_t sha[1];
		
		/* UUID == SHA1("BitlBee" + my hostname + MSN username) */
		sha1_init( sha );
		sha1_append( sha, (void*) "BitlBee", 7 );
		if( uname( &name ) == 0 )
		{
			sha1_append( sha, (void*) name.nodename, strlen( name.nodename ) );
		}
		sha1_append( sha, (void*) ic->acc->user, strlen( ic->acc->user ) );
		md->uuid = sha1_random_uuid( sha );
		memcpy( md->uuid, "b171be3e", 8 ); /* :-P */
	}
	
	if( msn_ns_write( ic, source, "VER %d %s CVR0\r\n", ++md->trId, MSNP_VER ) )
	{
		handler->inpa = b_input_add( handler->fd, B_EV_IO_READ, msn_ns_callback, handler );
		imcb_log( ic, "Connected to server, waiting for reply" );
	}
	
	return FALSE;
}
gchar *
fb_util_rand_uuid(void)
{
    guint8 buf[50];
    sha1_state_t sha;

    sha1_init(&sha);
    random_bytes(buf, sizeof buf);
    sha1_append(&sha, buf, sizeof buf);
    return sha1_random_uuid(&sha);
}
// Set the password (see http://dev.mysql.com/doc/internals/en/secure-password-authentication.html):
static char *_password(char result[SHA1_DIGEST_SIZE], const char *password, const char *salt) {
        sha1_context_t ctx;
        // SHA1(password)
        uint8_t stage1[SHA1_DIGEST_SIZE];
        sha1_init(&ctx);
        sha1_append(&ctx, (const unsigned char *)password, strlen(password));
        sha1_finish(&ctx, stage1);
        // SHA1(SHA1(password))
        uint8_t stage2[SHA1_DIGEST_SIZE];
        sha1_init(&ctx);
        sha1_append(&ctx, (const unsigned char *)stage1, SHA1_DIGEST_SIZE);
        sha1_finish(&ctx, stage2);
        // SHA1("20-bytes random data from server" <concat> SHA1(SHA1(password)))
        uint8_t stage3[SHA1_DIGEST_SIZE];
        sha1_init(&ctx);
        sha1_append(&ctx, (const unsigned char *)salt, strlen(salt));
        sha1_append(&ctx, (const unsigned char *)stage2, SHA1_DIGEST_SIZE);
        sha1_finish(&ctx, stage3);
        // XOR
        for (int i = 0; i < SHA1_DIGEST_SIZE; i++)
                result[i] = stage1[i] ^ stage3[i];
        return result;
}
Beispiel #5
0
struct groupchat *jabber_chat_with(struct im_connection *ic, char *who)
{
	struct jabber_data *jd = ic->proto_data;
	struct jabber_chat *jc;
	struct groupchat *c;
	sha1_state_t sum;
	double now = gettime();
	char *uuid, *rjid, *cserv;

	sha1_init(&sum);
	sha1_append(&sum, (uint8_t *) ic->acc->user, strlen(ic->acc->user));
	sha1_append(&sum, (uint8_t *) &now, sizeof(now));
	sha1_append(&sum, (uint8_t *) who, strlen(who));
	uuid = sha1_random_uuid(&sum);

	if (jd->flags & JFLAG_GTALK) {
		cserv = g_strdup("groupchat.google.com");
	} else {
		/* Guess... */
		cserv = g_strdup_printf("conference.%s", jd->server);
	}

	rjid = g_strdup_printf("private-chat-%s@%s", uuid, cserv);
	g_free(uuid);
	g_free(cserv);

	c = jabber_chat_join(ic, rjid, jd->username, NULL);
	g_free(rjid);
	if (c == NULL) {
		return NULL;
	}

	jc = c->data;
	jc->invite = g_strdup(who);

	return c;
}
Beispiel #6
0
Exec_stat MCSHA1Digest::eval(MCExecPoint &ep)
{
	if (source->eval(ep) != ES_NORMAL)
	{
		MCeerror->add(EE_SHA1DIGEST_BADSOURCE, line, pos);
		return ES_ERROR;
	}
	sha1_state_t state;
	uint8_t digest[20];
	sha1_init(&state);
	sha1_append(&state, ep.getsvalue().getstring(), ep.getsvalue().getlength());
	sha1_finish(&state, digest);
	ep.copysvalue((char *)digest, 20);
	return ES_NORMAL;
}
Beispiel #7
0
static int check_request_checksum(Socket_T socket, int content_length, char *checksum, int hashtype) {
        int n, keylength = 0;
        MD_T result, hash;
        md5_context_t ctx_md5;
        sha1_context_t ctx_sha1;
        char buf[READ_SIZE];

        if (content_length <= 0) {
                DEBUG("HTTP warning: Response does not contain a valid Content-Length -- cannot compute checksum\n");
                return TRUE;
        }

        switch (hashtype) {
                case HASH_MD5:
                        md5_init(&ctx_md5);
                        while (content_length > 0) {
                                if ((n = socket_read(socket, buf, content_length > sizeof(buf) ? sizeof(buf) : content_length)) < 0)
                                        break;
                                md5_append(&ctx_md5, (const md5_byte_t *)buf, n);
                                content_length -= n;
                        }
                        md5_finish(&ctx_md5, (md5_byte_t *)hash);
                        keylength = 16; /* Raw key bytes not string chars! */
                        break;
                case HASH_SHA1:
                        sha1_init(&ctx_sha1);
                        while (content_length > 0) {
                                if ((n = socket_read(socket, buf, content_length > sizeof(buf) ? sizeof(buf) : content_length)) < 0)
                                        break;
                                sha1_append(&ctx_sha1, (md5_byte_t *)buf, n);
                                content_length -= n;
                        }
                        sha1_finish(&ctx_sha1, (md5_byte_t *)hash);
                        keylength = 20; /* Raw key bytes not string chars! */
                        break;
                default:
                        socket_setError(socket, "HTTP checksum error: Unknown hash type\n");
                        return FALSE;
        }

        if (strncasecmp(Util_digest2Bytes((unsigned char *)hash, keylength, result), checksum, keylength * 2) != 0) {
                socket_setError(socket, "HTTP checksum error: Document checksum mismatch\n");
                return FALSE;
        } else {
                DEBUG("HTTP: Succeeded testing document checksum\n");
        }
        return TRUE;
}
Beispiel #8
0
/**
 * @brief Create content hash key for a byte array
 *
 * Create a content hash key for the given buffer and size.
 *
 * @param key pointer to the receiving chkey_t
 * @param buff byte array of data to hash
 * @param size size of byte array to has
 *
 * @result zero on success
 */
int key_chk(chkey_t *key, const void *buff, size_t size)
{
	key_state_t ks;
	FUN("key_chk");

	sha1_init(&ks.ss);
	sha1_append(&ks.ss, buff, size);
	sha1_finish(&ks.ss, &key->sha1);

	key->log2size = log2size(size);

	key->type[0] = MSB(K_CHK);
	key->type[1] = LSB(K_CHK);

	ek5_init(&ks.es);
	ek5_append(&ks.es, buff, size);
	ek5_finish(&ks.es, &key->ek5);

	key->padding = 0;

	return 0;
}
Beispiel #9
0
/**
 * @brief Create the public SSK for a private SSK
 *
 * Create a public key from a private key,
 * simply by hashing the hex string of the SHA1 digest.
 *
 * @param key pointer to a key to receive the public SSK
 * @param ssk pointer to a key containing a private SSK
 *
 * @result zero on success
 */
int key_ssk_pub_from_priv(chkey_t *key, const chkey_t *ssk)
{
	char hex[SHA1SIZE*2+1];
	sha1_state_t sha1;
	size_t size;
	FUN("key_ssk_pub_from_priv");

	size = pm_snprintf(hex, sizeof(hex), "%s",
		sha1_hexstr(&ssk->sha1));

	sha1_init(&sha1);
	sha1_append(&sha1, hex, size);
	sha1_finish(&sha1, &key->sha1);

	key->type[0] = MSB(K_SSK_P);
	key->type[1] = LSB(K_SSK_P);
	key->log2size = log2size(size);

	memset(&key->ek5, 0, sizeof(key->ek5));

	return 0;
}
Beispiel #10
0
sess_t sess_start(sm_t sm, jid_t jid) {
    pool_t p;
    user_t user;
    sess_t sess, scan;
    sha1_state_t sha1;
    unsigned char hash[20];
    int replaced = 0;

    log_debug(ZONE, "session requested for %s", jid_full(jid));

    /* check whether it is to serviced domain */
    if(xhash_get(sm->hosts, jid->domain) == NULL) {
        log_write(sm->log, LOG_ERR, "request to start session in non-serviced domain: jid=%s", jid_full(jid));
        return NULL;
    }

    /* get user data for this guy */
    user = user_load(sm, jid);

    /* unknown user */
    if(user == NULL) {
        if(config_get(sm->config, "user.auto-create") == NULL) {
            log_write(sm->log, LOG_NOTICE, "user not found and user.auto-create not enabled, can't start session: jid=%s", jid_full(jid));
            return NULL;
        }

        log_debug(ZONE, "auto-creating user %s", jid_user(jid));

        if(user_create(sm, jid) != 0)
            return NULL;

        user = user_load(sm, jid);
        if(user == NULL) {
            log_write(sm->log, LOG_NOTICE, "couldn't load user, can't start session: jid=%s", jid_full(jid));
            return NULL;
        }
    }

    /* kill their old session if they have one */
    for(scan = user->sessions; scan != NULL; scan = scan->next)
        if(jid_compare_full(scan->jid, jid) == 0) {
            log_debug(ZONE, "replacing session %s (%s)", jid_full(jid), scan->c2s_id);

            /* !!! this "replaced" stuff is a hack - its really a subaction of "ended".
             *     hurrah, another control protocol rewrite is needed :(
             */
            sm_c2s_action(scan, "replaced", NULL);

            _sess_end_guts(scan);

            pool_free(scan->p);

            replaced = 1;

            break;
        }

    /* make a new session */
    p = pool_new();

    sess = (sess_t) pmalloco(p, sizeof(struct sess_st));
    sess->p = p;

    /* fill it out */
    sess->pri = 0;
    sess->user = user;

    sess->jid = jid_dup(jid);
    pool_cleanup(sess->p, (void (*))(void *) jid_free, sess->jid);

    /* a place for modules to store stuff */
    sess->module_data = (void **) pmalloco(sess->p, sizeof(void *) * sess->user->sm->mm->nindex);

    /* add it to the list */
    sess->next = user->sessions;
    user->sessions = sess;

    /* who c2s should address things to */
    sha1_init(&sha1);
    datetime_out(time(NULL), dt_DATETIME, sess->sm_id, 41);
    sha1_append(&sha1, sess->sm_id, strlen(sess->sm_id));
    sha1_append(&sha1, jid_full(sess->jid), strlen(jid_full(sess->jid)));
    sha1_finish(&sha1, hash);
    hex_from_raw(hash, 20, sess->sm_id);

    log_debug(ZONE, "smid is %s", sess->sm_id);

    /* remember it */
    xhash_put(sm->sessions, sess->sm_id, sess);

    /* inform the modules */
    /* !!! catch the return value - if its 1, don't let them in */
    mm_sess_start(sm->mm, sess);

    if(replaced)
        log_write(sm->log, LOG_NOTICE, "session replaced: jid=%s", jid_full(sess->jid));
    else
        log_write(sm->log, LOG_NOTICE, "session started: jid=%s", jid_full(sess->jid));
            
    return sess;
}