示例#1
0
文件: kx.c 项目: GostCrypt/GnuTLS
/* This is called when we want send our certificate
 */
int _gnutls_send_server_certificate(gnutls_session_t session, int again)
{
	gnutls_buffer_st data;
	int ret = 0;


	if (session->internals.auth_struct->
	    gnutls_generate_server_certificate == NULL)
		return 0;

	_gnutls_buffer_init(&data);

	if (again == 0) {
		ret =
		    session->internals.auth_struct->
		    gnutls_generate_server_certificate(session, &data);

		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}
	ret = send_handshake(session, data.data, data.length,
			     GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
	if (ret < 0) {
		gnutls_assert();
	}

      cleanup:
	_gnutls_buffer_clear(&data);
	return ret;
}
示例#2
0
int Peer::Init(network::Socket & sock, const TorrentInterfaceInternalPtr & torrent, PEER_ADD peer_add)
{
    m_nm->Socket_set_assoc(sock, shared_from_this());
    memset(&m_buf, 0, sizeof(network::buffer));
    m_torrent = torrent;
    m_nm = torrent->get_nm();
    m_g_cfg = torrent->get_cfg();
    m_bitfield = new unsigned char[m_torrent->get_bitfield_length()];
    memset(m_bitfield, 0, m_torrent->get_bitfield_length());
    m_sleep_time = 0;
    m_peer_choking= true;
    m_peer_interested = false;
    m_am_choking = false;//
    m_am_interested = false;//
    m_downloaded = 0;
    m_uploaded = 0;
    m_sock = sock;
    memcpy(&m_addr, &m_sock->m_peer, sizeof(sockaddr_in));
    get_peer_key(m_sock->m_peer, m_ip);//inet_ntoa(m_sock->m_peer.sin_addr);
    switch(peer_add)
    {
    case PEER_ADD_TRACKER:
        m_state = PEER_STATE_SEND_HANDSHAKE;
        break;
    case PEER_ADD_INCOMING:
        if (send_handshake() != ERR_NO_ERROR)
            goto_sleep();
        if (send_bitfield() != ERR_NO_ERROR)
            goto_sleep();
        m_state = PEER_STATE_GENERAL_READY;
        break;
    }
    return ERR_NO_ERROR;
}
示例#3
0
/* This is the function for the client to send the key
 * exchange message 
 */
int
_gnutls_send_client_kx_message (gnutls_session_t session, int again)
{
  gnutls_buffer_st data;
  int ret = 0;

  if (session->internals.auth_struct->gnutls_generate_client_kx == NULL)
    return 0;

  _gnutls_buffer_init( &data);

  if (again == 0)
    {
      ret =
        session->internals.auth_struct->gnutls_generate_client_kx (session,
                                                                   &data);
      if (ret < 0)
        {
          gnutls_assert();
          goto cleanup;
        }
    }
  ret = send_handshake (session, data.data, data.length,
                        GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
  if (ret < 0)
    {
      gnutls_assert ();
    }
  
cleanup:
  _gnutls_buffer_clear (&data);
  return ret;
}
示例#4
0
/* This is called when we want send our certificate
 */
int
_gnutls_send_client_certificate (gnutls_session_t session, int again)
{
  gnutls_buffer_st data;
  int ret = 0;


  if (session->key->certificate_requested == 0)
    return 0;

  if (session->internals.auth_struct->gnutls_generate_client_certificate ==
      NULL)
    return 0;

  _gnutls_buffer_init( &data);

  if (again == 0)
    {
      if (gnutls_protocol_get_version (session) != GNUTLS_SSL3 ||
          session->internals.selected_cert_list_length > 0)
        {
          /* TLS 1.0 or SSL 3.0 with a valid certificate 
           */
          ret =
            session->internals.
            auth_struct->gnutls_generate_client_certificate (session, &data);

          if (ret < 0)
            {
              gnutls_assert();
              goto cleanup;
            }
        }
    }

  /* In the SSL 3.0 protocol we need to send a
   * no certificate alert instead of an
   * empty certificate.
   */
  if (gnutls_protocol_get_version (session) == GNUTLS_SSL3 &&
      session->internals.selected_cert_list_length == 0)
    {
      ret =
        gnutls_alert_send (session, GNUTLS_AL_WARNING,
                           GNUTLS_A_SSL3_NO_CERTIFICATE);

    }
  else
    {                           /* TLS 1.0 or SSL 3.0 with a valid certificate 
                                 */
      ret = send_handshake (session, data.data, data.length,
                            GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
    }

cleanup:
  _gnutls_buffer_clear (&data);
  return ret;
}
示例#5
0
/* This is the function for the client to send the certificate
 * verify message
 */
int
_gnutls_send_client_certificate_verify (gnutls_session_t session, int again)
{
  gnutls_buffer_st data;
  int ret = 0;

  /* This is a packet that is only sent by the client
   */
  if (session->security_parameters.entity == GNUTLS_SERVER)
    return 0;

  /* if certificate verify is not needed just exit 
   */
  if (session->key->certificate_requested == 0)
    return 0;


  if (session->internals.auth_struct->gnutls_generate_client_cert_vrfy ==
      NULL)
    {
      gnutls_assert ();
      return 0;                 /* this algorithm does not support cli_cert_vrfy 
                                 */
    }

  _gnutls_buffer_init( &data);

  if (again == 0)
    {
      ret =
        session->internals.
        auth_struct->gnutls_generate_client_cert_vrfy (session, &data);
      if (ret < 0)
        {
          gnutls_assert();
          goto cleanup;
        }

      if (ret == 0)
          goto cleanup;

    }
  ret = send_handshake (session, data.data, data.length,
                        GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);

  if (ret < 0)
    {
      gnutls_assert ();
    }
  
cleanup:
  _gnutls_buffer_clear (&data);
  return ret;
}
static void *
block_tx_client_thread (void *vdata)
{
    BlockTxClient *client = vdata;
    BlockTxInfo *info = client->info;
    BlockTxClientDoneCB cb = client->cb;
    evutil_socket_t data_fd;
    gboolean restart;

retry:
    data_fd = connect_chunk_server (info->cs);
    if (data_fd < 0) {
        info->result = BLOCK_CLIENT_NET_ERROR;
        if (!info->transfer_once) {
            pipewrite (info->done_pipe[1], &info->result, sizeof(info->result));
            /* Transfer manager always expects an ENDED response. */
            int rsp = BLOCK_CLIENT_ENDED;
            pipewrite (info->done_pipe[1], &rsp, sizeof(rsp));
        }
        return vdata;
    }
    client->data_fd = data_fd;

    if (send_handshake (data_fd, info) < 0) {
        if (!info->transfer_once) {
            pipewrite (info->done_pipe[1], &info->result, sizeof(info->result));
            int rsp = BLOCK_CLIENT_ENDED;
            pipewrite (info->done_pipe[1], &rsp, sizeof(rsp));
        }
        evutil_closesocket (client->data_fd);
        return vdata;
    }

    client->recv_buf = evbuffer_new ();

    restart = client_thread_loop (client);

    if (restart) {
        seaf_message ("Restarting block tx client.\n");
        memset (client, 0, sizeof(BlockTxClient));
        client->info = info;
        client->cb = cb;
        client->info->result = BLOCK_CLIENT_UNKNOWN;
        goto retry;
    }

    return vdata;
}
示例#7
0
/* Renvoie 1 en cas de succés, 0 en cas d'échec. */
int init_peer_connection(struct proto_peer *peer, const struct proto_client_handshake *hs) {
    int fd ;
    struct hostent *sp;
    struct sockaddr_in sins;
    pthread_mutex_lock(&peer->lock) ;
    sp = gethostbyaddr(&(peer->ipaddr), sizeof(peer->ipaddr), AF_INET);
    if (sp == NULL) {
        perror("gethostbyaddr");
        exit(errno);
    }
    
    fd = socket(PF_INET, SOCK_STREAM, 0);
    if (fd == -1) {
        perror ("socket");
        exit(errno);
    }    
    
    sins.sin_family = AF_INET;
    memcpy (&sins.sin_addr, sp->h_addr_list[0], (size_t)sp->h_length);
    sins.sin_port = htons(peer->port);
    
    if (connect (fd, (struct sockaddr *)&sins, sizeof(sins)) == -1) {
        switch(errno) {
            case ECONNREFUSED : 
                printf("Connection to peer %d failed. Peer removed from list.\n",peer->peerId); return 0 ;
            break ;
            default : perror ("connect");
        }
        exit (errno);
    }
    peer->sockfd = fd ;
    pthread_mutex_unlock(&peer->lock) ;
    send_handshake(peer,hs) ;
    receive_handshake(peer,hs) ; 
    return 1 ;
}
示例#8
0
文件: main.c 项目: Lens-Flare/pwnat2
int main(int argc, const char * argv[]) {
	struct {
		int verbose, _1_, keepalive, _2_, timeout, _3_;
		char * hostname, * port, * source_type, * source_name;
	} cfg;
	
	struct config_var vars[] = {
//		{"name",			{0, f, r, n},	'-',	"ENV_NAME",				DEFAULT_VALUE,				&my_variable},
		{"verbose",			{0, 1, 0, 0},	'v',	NULL,					(void *)1,					&cfg.verbose},
		{"quiet",			{0, 1, 0, 0},	'q',	NULL,					(void *)-1,					&cfg.verbose},
		{"hostname",		{0, 0, 1, 0},	'h',	"HOSTNAME",				"localhost",				&cfg.hostname},
		{"port",			{0, 0, 1, 0},	'p',	"PORT",					SERVER_PORT,				&cfg.port},
		{"source-type",		{0, 0, 1, 0},	't',	"SOURCE_TYPE",			"file",						&cfg.source_type},
		{"source-name",		{0, 0, 1, 0},	's',	"SOURCE_NAME",			NULL,						&cfg.source_name},
		{"keepalive-int",	{0, 0, 1, 1},	'k',	"KEEPALIVE_INTERVAL",	(void *)300,				&cfg.keepalive},
		{"packet-timeout",	{0, 0, 1, 1},	't',	"PACKET_TIMEOUT",		(void *)DEFAULT_TIMEOUT,	&cfg.timeout}
	};
	
	int sockfd = 0;
	ssize_t retv = 0;
	char buf[256];
	
	pk_keepalive_t * pk = (pk_keepalive_t *)buf;
	pk_advertize_t * ad;
	
	pid_t keepalive_pid = 0;
	struct keepalive_param kp = {&sockfd, &cfg.keepalive};
	
	
	config(argc, argv, sizeof(vars)/sizeof(struct config_var), vars);
	
	ad = (pk_advertize_t *)alloc_packet(PACKET_SIZE_MAX);
	if ((retv = !ad))
		goto exit;
	
	printf("Connecting to %s:%s\n", cfg.hostname, cfg.port);
	if ((retv = connect_socket(cfg.hostname, cfg.port, &sockfd))) {
		fprintf(stderr, "Connection failed\n");
		goto free;
	}
	
	if ((retv = send_handshake(sockfd, cfg.timeout))) {
		fprintf(stderr, "Bad handshake\n");
		goto free;
	}
	
	
	_fork(&keepalive_pid, &do_keepalive, &kp);
	
	
	if (!strcasecmp("file", cfg.source_type)) {
		FILE * file = fopen(cfg.source_name, "r");
		if ((retv = !file)) {
			perror("fopen");
			goto free;
		}
		
		// states:
		//  0 - whitespace before name
		//  1 - name
		//  2 - whitespace between name and port
		//  3 - port
		//  4 - whitespace after port
		char state = 0, name[220], port[7];
		for (int c = 0, i = 0, j = 0; (c = fgetc(file)) > 0;)
			switch (state) {
				case 0: // whitespace before name
					if (c == '#') {
						state = 4;
						break;
					} else if (c <= 0x20 || 0x7F <= c)
						break;
					state = 1;
					i = 0;
					
				case 1: // name
					if ((retv = i >= sizeof(name))) {
						fprintf(stderr, "Names cannot be more than %lu characters\n", sizeof(name) - 1);
						goto fclose;
					} else if (j == 0 && 0x30 <= c && c <= 0x39) {
						// if the first character is a number, interpret it as a port
						port[j++] = c;
						state = 3;
						break;
					} if (0x20 < c && c < 0x7F) {
						name[i++] = c;
						break;
					}
					state = 2;
					
				case 2: // whitespace between name and port
					if (c <= 0x20 || 0x7F <= c)
						break;
					state = 3;
					j = 0;
					
				case 3: // port
					if ((retv = j >= sizeof(port))) {
						fprintf(stderr, "Port number cannot be greater than 65535\n");
						goto fclose;
					} else if (0x30 <= c && c <= 0x39) {
						port[j++] = c;
						state = 3;
						break;
					} else if (0x20 < c && c < 0x7F && c != '#') {
						fprintf(stderr, "Port numbers must be numeric\n");
						goto fclose;
					}
					state = 4;
					
				case 4: // whitespace after port
					if (c == '\n' || c == '\r') {
						name[i] = 0;
						port[j] = 0;
						
						if (i == 0 && j == 0) {
							state = 0;
							break;
						}
						
						int portnum = atoi(port);
						if ((retv = portnum > USHRT_MAX)) {
							fprintf(stderr, "Port number cannot be greater than 65535\n");
							goto fclose;
						}
						
						init_pk_advertize(ad, portnum, name);
						
						if (!*name)
							ad->name.data[0] = '+';
						
						retv = pk_send(sockfd, (pk_keepalive_t *)ad, 0); if ((retv = retv < 0)) goto free;
						
						state = 0;
					}
					break;
					
				default:
					fprintf(stderr, "Internal error\n");
					retv = 1;
					goto fclose;
					break;
			}
		
	fclose:
		fclose(file);
	} else if (!strcasecmp("sqlite", cfg.source_type)) {
		fprintf(stderr, "Using SQLite as a source is currently unsupported\n");
		retv = 1;
		goto free;
	} else {
		fprintf(stderr, "Bad source type %s\n", cfg.source_type);
		retv = 1;
		goto free;
	}
	
free:
	free_packet((pk_keepalive_t *)ad);
	
	while (!retv) {
		retv = pk_recv(sockfd, buf, cfg.timeout, 0);
		
		if (retv <= 0)
			break;
		
		retv = check_version(pk);
	}
	
//close:
	if (sockfd)
		close(sockfd);
	kill(keepalive_pid, SIGTERM);
exit:
	return (int)retv;
}
示例#9
0
int Peer::clock()
{
    if (m_state == PEER_STATE_SEND_HANDSHAKE)
    {
        if (m_sock == NULL)
        {
            try
            {
                m_nm->Socket_add(m_addr, shared_from_this(), m_sock);
            }
            catch (...)
            {
                goto_sleep();
                return ERR_INTERNAL;
            }
        }
        if (send_handshake() != ERR_NO_ERROR)
            goto_sleep();
        if (send_bitfield() != ERR_NO_ERROR)
            goto_sleep();
        m_state = PEER_STATE_WAIT_HANDSHAKE;
    }
    if (!m_peer_choking)
    {
        if (m_state == PEER_STATE_GENERAL_READY )
            m_state = PEER_STATE_REQUEST_READY;
    }
    else if (m_state == PEER_STATE_GENERAL_READY || m_state == PEER_STATE_REQUEST_READY)
    {
        send_interested();
        m_state = PEER_STATE_WAIT_UNCHOKE;
    }
    //если находимся в нужном состоянии и очередь не пуста
    if ((m_state == PEER_STATE_GENERAL_READY || m_state == PEER_STATE_REQUEST_READY || m_state == PEER_STATE_WAIT_UNCHOKE) && !m_requests_queue.empty())
    {
        char block[BLOCK_LENGTH];
        uint32_t block_length;
        PIECE_INDEX piece_index;
        BLOCK_INDEX block_index;
        std::set<BLOCK_ID>::iterator iter = m_requests_queue.begin();
        get_piece_block_from_block_id(*iter, piece_index, block_index);
        //если удалось прочитать блок и отправить, удаляем индекс блока из очереди
        if (m_torrent->read_block(piece_index, block_index, block, block_length) == ERR_NO_ERROR &&
                send_piece(piece_index, BLOCK_LENGTH * block_index, block_length, block) == ERR_NO_ERROR)
        {
            m_requests_queue.erase(iter);
            m_torrent->inc_uploaded(block_length);
            m_uploaded += block_length;
            //logger::LOGGER() << "rx=%f tx=%f\n", get_rx_speed(), get_tx_speed());
        }
    }
    if (m_state == PEER_STATE_REQUEST_READY && m_requested_blocks.size() <= PEER_MAX_REQUEST_NUMBER && !m_blocks2request.empty())
    {
        std::set<BLOCK_ID>::iterator iter = m_blocks2request.begin();
        PIECE_INDEX piece;
        BLOCK_INDEX block;
        uint32_t length;
        get_piece_block_from_block_id(*iter, piece, block);
        m_torrent->get_block_length_by_index(piece, block, length);
        if (send_request(piece, block, length) == ERR_NO_ERROR)
        {
            m_requested_blocks.insert(*iter);
            m_blocks2request.erase(iter);
        }
    }
    return ERR_NO_ERROR;
}
示例#10
0
文件: hw4.c 项目: raghavan/networking
void listen_from_peers() 
{
    struct peer_state* peer = peers;
    unsigned int msglen = 0;
    while(missing_blocks() > 0)
    {
        fd_set fdrset_clone;
        fd_set fdwset_clone;
        FD_COPY(&fdrset,&fdrset_clone);
        FD_COPY(&fdwset,&fdwset_clone);
        int rdy = select(FD_SETSIZE,&fdrset_clone,&fdwset_clone,0, 0);
        if(rdy <= 0) {
            continue;
        }
        peer = peers;
        if(active_peers() == 0){
            break;
        }
        while(peer){
        
            if(FD_ISSET(peer->socket,&fdwset_clone)){
                if(peer->connected == 0){
                    //to send the handshake if it is not connected
                    send_handshake(peer);
                }
                else if(peer->send_count > 0) {
                    //to send the have/interested/piece messages to peers
                    send_buffed_msg(peer);
                }
            }

            if(FD_ISSET(peer->socket,&fdrset_clone)) 
            {
                int newbytes = recv(peer->socket,peer->incoming+peer->count,BUFSIZE-peer->count,0);
                if(newbytes <= 0){ 
                    peer->trying_to_connect = 0;
                    if(newbytes == 0){
                        piece_status[peer->requested_piece] = PIECE_EMPTY;
                    }
                    disconnet_peer(peer);
                    reconnect_peer(peer);
                    peer = peer->next;
                    continue; 
                } 
                peer->count += newbytes;
                if(!peer->handshaked){                    
                    peer->count -= peer->incoming[0]+49;
                    if(peer->count) {
                        memmove(peer->incoming,peer->incoming + peer->incoming[0]+49,peer->count);
                    }
                    peer->handshaked = 1;
                }

               if(memcmp(peer->incoming+peer->incoming[0]+8+20,"-UICCS450-",strlen("-UICCS450-"))==0) {
                    fprintf(stderr,"Caught a CS450 peer, exiting.\n");
                    disconnet_peer(peer);
                    continue;
                }   

                while(peer->count >= (ntohl(((int*)peer->incoming)[0])) + 4){ 
                msglen = ntohl(((int*)peer->incoming)[0]);

                   switch(peer->incoming[4]) {
                        // CHOKE
                        case 0: {
                                    if(debug)
                                        fprintf(stderr,"Choke\n");
                                    peer->choked = 1;
                                    piece_status[peer->requested_piece]=PIECE_EMPTY;
                                    peer->requested_piece = -1;
                                    break;
                                }
                                // UNCHOKE
                        case 1: {
                                    if(debug)
                                        fprintf(stderr,"Unchoke\n");
                                    peer->choked = 0;
                                    peer->requested_piece = next_piece(-1,peer);    
                                    request_block(peer,peer->requested_piece,0);
                                    break;
                                }
                                //Interested
                        case 2: {
                                    //dev_notifier();
                                    send_choke_unchoke_msg(peer,0); //ischoked = 0
                                    peer->not_interested = 0;
                                    break;
                                }
                                //Not interested
                        case 3: {
                                    //dev_notifier();
                                    peer->not_interested = 1;
                                    break;
                                }
                                // HAVE -- update the bitfield for this peer
                        case 4: {
                                    int piece = ntohl(*((int*)&peer->incoming[5]));
                                    int bitfield_byte = piece/8;
                                    int bitfield_bit = piece%8;
                                    if(debug)
                                        fprintf(stderr,"Have %d\n",piece);

                                    peer->bitfield[bitfield_byte] |= 1 << (7 - bitfield_bit);
                                    piece_occurence_value[piece]++;
                                    send_interested(peer);
                                    break;
                                }
                                // BITFIELD -- set the bitfield for this peer
                        case 5:
                                //peer->choked = 0; //commenting it according to prof's note in class
                                if(debug) 
                                    printf("Bitfield of length %d\n",msglen-1);
                                int fieldlen = msglen - 1;
                                if(fieldlen != (file_length/piece_length/8+1)) {
                                    disconnet_peer(peer);
                                    if(active_peers() == 0){
                                        break;
                                    }
                                    peer = peer->next;
                                    continue;
                                }               
                                memcpy(peer->bitfield,peer->incoming+5,fieldlen);
                                read_bit_maps(peer->bitfield,fieldlen);
                                send_interested(peer);
                                break;
                                //Request piece
                        case 6: { 
                                if(peer->i_choked_it == 1) 
                                    break;
                                decode_request_send_piece_to_peer(peer);
                                }       
                                break;                         
                                // PIECE
                        case 7: {
                                    //make the tit for tatter
                                    peer->send_recv_balancer++;
                                    if(peer->i_choked_it && peer->send_recv_balancer == 0){
                                        peer->i_choked_it = 0;
                                        send_choke_unchoke_msg(peer,0); //unchoke peer
                                    }
                                    int piece = ntohl(*((int*)&peer->incoming[5]));
                                    int offset = ntohl(*((int*)&peer->incoming[9]));
                                    int datalen = msglen - 9;

                                    fprintf(stderr,"Writing piece %d, offset %d, ending at %d\n",piece,offset,piece*piece_length+offset+datalen);
                                    write_block(peer->incoming+13,piece,offset,datalen,1);
                                    draw_state();
                                    offset+=datalen;
                                    if(offset==piece_length || (piece*piece_length+offset == file_length) ) {
                                        broadcast_have_msg(piece);
                                        draw_state();
                                        if(debug) 
                                            fprintf(stderr,"Reached end of piece %d at offset %d\n",piece,offset);

                                        peer->requested_piece=next_piece(piece,peer);
                                        offset = 0;
                                    }
                                    request_block(peer,peer->requested_piece,offset);
                                    break;                                  
                                }
                    }
                    drop_message(peer);      
                }
            }
            peer = peer->next;
        }
    }
    return;
}
// main check password function which do real job of authentication against dovecot
static authn_status check_password(request_rec * r, const char *user, const char *password)
{
	authn_dovecot_config_rec *conf = ap_get_module_config(r->per_dir_config,
							      &authn_dovecot_module);
	apr_pool_t *p;		// sub pool of r->pool

	int i, auths, readsocks, result, opts, fdmax, cnt, auth_in_progress, retval;
	struct sockaddr_un address;
	struct timeval tv;
	struct connection_state cs;

	apr_pool_create(&p, r->pool);	// create subpool for local functions, variables...

	// setting default values for connection state 
	cs.version_ok = 0;
	cs.mech_available = 0;
	cs.hshake_done = 0;
	cs.authenticated = 0;	// by default user is NOT authenticated :)
	cs.handshake_sent = 0;
	cs.user = NULL;

	fd_set socks_r;
	fd_set socks_w;
	fd_set error_fd;
	
	char * const line = apr_pcalloc(p, sizeof(char) * (BUFFMAX + 1));
	ap_assert(line != NULL);
	auths = socket(AF_UNIX, SOCK_STREAM, 0);
	opts = fcntl(auths, F_GETFL);
	opts = (opts | O_NONBLOCK);
	if (fcntl(auths, F_SETFL, opts) < 0) {
		perror("fcntl(F_SETFL)");
	}
	address.sun_family = AF_UNIX;
	strncpy(address.sun_path,conf->dovecotauthsocket, strlen(conf->dovecotauthsocket));
	result = connect(auths, (struct sockaddr *)&address, sizeof address);
	if (result) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication: could not connect to dovecot socket");
		if (conf->authoritative == 0) {
			return DECLINED;
		} else {
			return AUTH_USER_NOT_FOUND;
		}
	}
	cnt = 0;

	auth_in_progress = 0;
	// loop trough sockets for writability and for data on socket to read,
	// wait untill authenticated or if timeoout occurs error out with AUTH_USER_NOT_FOUND and log it
	while (cnt < conf->dovecotauthtimeout) {
		fdmax = auths;	// simply this is only one really used socket so ...
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		FD_ZERO(&socks_r);
		FD_SET(auths, &socks_r);
		FD_ZERO(&error_fd);
		FD_SET(auths, &error_fd);
		if (cs.handshake_sent == 0) {
			FD_ZERO(&socks_w);
			FD_SET(auths, &socks_w);
		} else {
			FD_ZERO(&socks_w);
		}

		readsocks = select(fdmax + 1, &socks_r, &socks_w, NULL, &tv);
		if (readsocks < 0) {
			ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication: socket select");
			return DECLINED;
		}

		if (readsocks == 0) {
			cnt++;	// wait for timeout and count to conf->dovecotauthtimeout
			// only add to counter in case of timeout!
			//fprintf(stderr, "%i ", cnt);
			fflush(stdout);
		} else {
			for (i = 0; i <= fdmax; i++) {
				if (FD_ISSET(i, &socks_w)) {
					if (cs.handshake_sent == 0) {
						cs.handshake_sent = send_handshake(p, r, i);
						ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Dovecot Authentication: handshake is sent");
					}
				}
				if (FD_ISSET(i, &socks_r)) {
					while ((retval = sock_readline(p, r, i, line)) > 0) {
						if (!receive_data(p, r, &cs, line)) {
							ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Dovecot Authentication: problems while receiving data from socket");
							if (conf->authoritative == 0) {
								return DECLINED;
							} else {
								return AUTH_USER_NOT_FOUND;
							}
						} else {
							if (cs.hshake_done == 1) {
								if (!cs.version_ok && !cs.mech_available) {
									ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
										      "Dovecot Authentication: No authentication possible protocol version wrong or plaintext method not available...");
									close(auths);
									return AUTH_USER_NOT_FOUND;
								} else {
									if (auth_in_progress != 1) {
										ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Dovecot Authentication: Sending authentication request");
										send_auth_request(p, r, i, user, password,
#if MODULE_MAGIC_NUMBER_MAJOR >= 20120211
                                            r->connection->client_ip
#else
                                            r->connection->remote_ip
#endif
                                            );
										auth_in_progress = 1;
									}
								}
							}
							if (cs.authenticated == 1) {
								ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Dovecot Authentication: Authenticated user=\"%s\"", user);
								close(auths);
								if (cs.user != NULL) {
									r->user = cs.user;
								}
								return AUTH_GRANTED;
							}
							if (cs.authenticated == -1) {
								ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication: Denied authentication for user=\"%s\"", user);
								close(auths);
								if (conf->authoritative == 0) {
									return DECLINED;
								} else {
									return AUTH_USER_NOT_FOUND;
								}
							}
							break;
						}
					}
					if (retval == -1) {
						ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication: socket reading failed bailing out");
						close(auths);
						if (conf->authoritative == 0) {
							return DECLINED;
						} else {
							return AUTH_USER_NOT_FOUND;
						}
					}
				}
			}
		}
	}
	close(auths);
	ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication Timeout");
	if (conf->authoritative == 0) {
		return DECLINED;
	} else {
		return AUTH_USER_NOT_FOUND;
	}
}
示例#12
0
文件: bt_connect.c 项目: sdini1/bt
int leecher_handshake(int sockfd, char *fname, char *id, struct sockaddr_in* sockaddr){
  int response;
  response = get_handshake(sockfd, fname, sockaddr);
  send_handshake(sockfd, fname, id);
  return response;
}
示例#13
0
文件: bt_connect.c 项目: sdini1/bt
//perform handshake from the leecher's perspective
//Compute the necessary computations, listen for incoming packet, verify it 
//and then send ours back.
int seeder_handshake(int sockfd, char* fname, char *id,struct sockaddr_in sockaddr) {
  send_handshake(sockfd, fname, id);  
  return get_handshake(sockfd, fname, &sockaddr);

}