Example #1
0
static void save_error( MYSQL *m, MYSQL_PACKET *p ) {
	int ecode;
	p->pos = 0;
	// seems like we sometimes get some FFFFFF sequences before
	// the actual error...
	do {
		if( myp_read_byte(p) != 0xFF ) {
			m->errcode = -1;
			error(m,"Failed to decode error",NULL);
			return;
		}
		ecode = myp_read_ui16(p);
	} while( ecode == 0xFFFF );
	if( m->is41 && p->buf[p->pos] == '#' )
		p->pos += 6; // skip sqlstate marker
	error(m,"%s",myp_read_string(p));
	m->errcode = ecode;
}
Example #2
0
int myp_read_bin( MYSQL_PACKET *p ) {
	int c = myp_read_byte(p);
	if( c <= 250 )
		return c;
	if( c == 251 )
		return -1; // NULL
	if( c == 252 )
		return myp_read_ui16(p);
	if( c == 253 ) {
		c = 0;
		myp_read(p,&c,3);
		return c;
	}
	if( c == 254 )
		return myp_read_int(p);
	p->error = 1;
	return 0;
}
Example #3
0
static int do_store( MYSQL *m, MYSQL_RES *r ) {
	int i;
	MYSQL_PACKET *p = &m->packet;
	p->pos = 0;
	r->nfields = myp_read_bin(p);
	if( p->error ) return 0;
	r->fields = (MYSQL_FIELD*)malloc(sizeof(MYSQL_FIELD) * r->nfields);
	memset(r->fields,0,sizeof(MYSQL_FIELD) * r->nfields);
	for(i=0;i<r->nfields;i++) {
		if( !myp_read_packet(m,p) )
			return 0;
		{
			MYSQL_FIELD *f = r->fields + i;
			f->catalog = m->is41 ? myp_read_bin_str(p) : NULL;
			f->db = m->is41 ? myp_read_bin_str(p) : NULL;
			f->table = myp_read_bin_str(p);
			f->org_table = m->is41 ? myp_read_bin_str(p) : NULL;
			f->name = myp_read_bin_str(p);
			f->org_name = m->is41 ? myp_read_bin_str(p) : NULL;
			if( m->is41 ) myp_read_byte(p);
			f->charset = m->is41 ? myp_read_ui16(p) : 0x08;
			f->length = m->is41 ? myp_read_int(p) : myp_read_bin(p);
			f->type = (FIELD_TYPE)(m->is41 ? myp_read_byte(p) : myp_read_bin(p));
			f->flags = m->is41 ? myp_read_ui16(p) : myp_read_bin(p);
			f->decimals = myp_read_byte(p);
			if( m->is41 ) myp_read_byte(p); // should be 0
			if( m->is41 ) myp_read_byte(p); // should be 0
			if( p->error )
				return 0;
		}
	}
	// first EOF packet
	if( !myp_read_packet(m,p) )
		return 0;
	if( myp_read_byte(p) != 0xFE || p->size >= 9 )
		return 0;
	// reset packet buffer (to prevent to store large buffer in row data)
	free(p->buf);
	p->buf = NULL;
	p->mem = 0;
	// datas
	while( 1 ) {
		if( !myp_read_packet(m,p) )
			return 0;
		// EOF : end of datas
		if( (unsigned char)p->buf[0] == 0xFE && p->size < 9 )
			break;
		// ERROR ?
		if( (unsigned char)p->buf[0] == 0xFF ) {
			save_error(m,p);
			return 0;
		}
		// allocate one more row
		if( r->row_count == r->memory_rows ) {
			MYSQL_ROW_DATA *rows;
			r->memory_rows = r->memory_rows ? (r->memory_rows << 1) : 1;
			rows = (MYSQL_ROW_DATA*)malloc(r->memory_rows * sizeof(MYSQL_ROW_DATA));
			memcpy(rows,r->rows,r->row_count * sizeof(MYSQL_ROW_DATA));
			free(r->rows);
			r->rows = rows;
		}
		// read row fields
		{
			MYSQL_ROW_DATA *current = r->rows + r->row_count++;
			int prev = 0;			
			current->raw = p->buf;
			current->lengths = (unsigned long*)malloc(sizeof(unsigned long) * r->nfields);
			current->datas = (char**)malloc(sizeof(char*) * r->nfields);
			for(i=0;i<r->nfields;i++) {
				int l = myp_read_bin(p);
				if( !p->error )
					p->buf[prev] = 0;
				if( l == -1 ) {
					current->lengths[i] = 0;
					current->datas[i] = NULL;
				} else {
					current->lengths[i] = l;
					current->datas[i] = p->buf + p->pos;
					p->pos += l;
				}
				prev = p->pos;
			}
			if( !p->error )
				p->buf[prev] = 0;
		}
		// the packet buffer as been stored, don't reuse it
		p->buf = NULL;
		p->mem = 0;
		if( p->error )
			return 0;
	}
	return 1;
}
Example #4
0
MYSQL *mysql_real_connect( MYSQL *m, const char *host, const char *user, const char *pass, void *unused, int port, const char *socket, int options ) {
	PHOST h;
	char scramble_buf[21];
	MYSQL_PACKET *p = &m->packet;
	int pcount = 1;
	if( socket && *socket ) {
		error(m,"Unix Socket connections are not supported",NULL);
		return NULL;
	}
	h = phost_resolve(host);
	if( h == UNRESOLVED_HOST ) {
		error(m,"Failed to resolve host '%s'",host);
		return NULL;
	}
	m->s = psock_create();
	if( m->s == INVALID_SOCKET ) {
		error(m,"Failed to create socket",NULL);
		return NULL;
	}
	psock_set_fastsend(m->s,1);
	psock_set_timeout(m->s,50); // 50 seconds
	if( psock_connect(m->s,h,port) != PS_OK ) {
		myp_close(m);
		error(m,"Failed to connect on host '%s'",host);
		return NULL;
	}
	if( !myp_read_packet(m,p) ) {
		myp_close(m);
		error(m,"Failed to read handshake packet",NULL);
		return NULL;
	}
	// process handshake packet
	{
		char filler[13];
		unsigned int len;
		m->infos.proto_version = myp_read_byte(p);
		// this seems like an error packet
		if( m->infos.proto_version == 0xFF ) {
			myp_close(m);
			save_error(m,p);
			return NULL;
		}	
		m->infos.server_version = strdup(myp_read_string(p));
		m->infos.thread_id = myp_read_int(p);
		myp_read(p,scramble_buf,8);
		myp_read_byte(p); // should be 0
		m->infos.server_flags = myp_read_ui16(p);
		m->infos.server_charset = myp_read_byte(p);
		m->infos.server_status = myp_read_ui16(p);
		m->infos.server_flags |= myp_read_ui16(p) << 16;
		len = myp_read_byte(p);
		myp_read(p,filler,10);
		// try to disable 41
		m->is41 = (m->infos.server_flags & FL_PROTOCOL_41) != 0;
		if( !p->error && m->is41 )
			myp_read(p,scramble_buf + 8,13);
		if( p->pos != p->size )
			myp_read_string(p); // 5.5+
		if( p->error ) {
			myp_close(m);
			error(m,"Failed to decode server handshake",NULL);
			return NULL;
		}
		// fill answer packet
		{
			unsigned int flags = m->infos.server_flags;
			int max_packet_size = 0x01000000;
			SHA1_DIGEST hpass;
			char filler[23];
			flags &= (FL_PROTOCOL_41 | FL_TRANSACTIONS | FL_SECURE_CONNECTION);
			myp_begin_packet(p,128);
			if( m->is41 ) {
				myp_write_int(p,flags);
				myp_write_int(p,max_packet_size);
				myp_write_byte(p,m->infos.server_charset);
				memset(filler,0,23);
				myp_write(p,filler,23);
				myp_write_string(p,user);
				if( *pass ) {
					myp_encrypt_password(pass,scramble_buf,hpass);
					myp_write_bin(p,SHA1_SIZE);
					myp_write(p,hpass,SHA1_SIZE);
					myp_write_byte(p,0);
				} else
					myp_write_bin(p,0);
			} else {
				myp_write_ui16(p,flags);
				// max_packet_size
				myp_write_byte(p,0xFF);
				myp_write_byte(p,0xFF);
				myp_write_byte(p,0xFF);
				myp_write_string(p,user);
				if( *pass ) {
					char hpass[SEED_LENGTH_323 + 1];
					myp_encrypt_pass_323(pass,scramble_buf,hpass);
					hpass[SEED_LENGTH_323] = 0;
					myp_write(p,hpass,SEED_LENGTH_323 + 1);
				} else
					myp_write_bin(p,0);
			}
		}
	}
	// send connection packet
send_cnx_packet:
	if( !myp_send_packet(m,p,&pcount) ) {
		myp_close(m);
		error(m,"Failed to send connection packet",NULL);
		return NULL;
	}
	// read answer packet
	if( !myp_read_packet(m,p) ) {
		myp_close(m);
		error(m,"Failed to read packet",NULL);
		return NULL;
	}
	// increase packet counter (because we read one packet)
	pcount++;
	// process answer
	{
		int code = myp_read_byte(p);
		switch( code ) {
		case 0: // OK packet
			break;
		case 0xFF: // ERROR
			myp_close(m);
			save_error(m,p);
			return NULL;
		case 0xFE: // EOF
			// we are asked to send old password authentification
			if( p->size == 1 ) {
				char hpass[SEED_LENGTH_323 + 1];
				myp_encrypt_pass_323(pass,scramble_buf,hpass);
				hpass[SEED_LENGTH_323] = 0;
				myp_begin_packet(p,0);
				myp_write(p,hpass,SEED_LENGTH_323 + 1);
				goto send_cnx_packet;
			}
			// fallthrough
		default:
			myp_close(m);
			error(m,"Invalid packet error",NULL);
			return NULL;
		}
	}
	// we are connected, setup a longer timeout
	psock_set_timeout(m->s,18000);
	return m;
}