Ejemplo n.º 1
0
void perl_mongo_connect(SV *client, mongo_link* link) {
#ifdef MONGO_SSL
  if(link->ssl){
    ssl_connect(link, client);
    link->sender = ssl_send;
    link->receiver = ssl_recv;
    return;
  }
#endif

  non_ssl_connect(link);
  link->sender = non_ssl_send;
  link->receiver = non_ssl_recv;

  SV* sasl_flag = perl_mongo_call_method( client, "sasl", 0, 0 );

  if ( SvIV(sasl_flag) == 1 ) { 
#ifdef MONGO_SASL
      sasl_authenticate( client, link );
#else
      croak( "MongoDB: sasl => 1 specified, but this driver was not compiled with SASL support\n" );
#endif
  }
  
  SvREFCNT_dec(sasl_flag);
  
}
Ejemplo n.º 2
0
void ReceiveOrderBookLogic::on_read(Socket *socket)
{
    if (!m_wait_for_read)
        return;

    if (!m_ssl_connected)
    {
        ssl_connect();
        return;
    }

    int64_t  readed = 0;
    uint64_t buffer_size = m_buffer.size();

    while ((readed = SSL_read(m_ssl,
                              &m_buffer[0] + m_read_offset,
                              buffer_size  - m_read_offset)) > 0)
    {
        m_read_offset += readed;

        if (!m_ready_to_receive_json && !process_header())
            continue;

        if (m_read_offset == m_json_full_size)
            break;
    }

    if (m_read_offset == m_buffer.size())
    {
        process_json();
        socket->close();
    }
}
Ejemplo n.º 3
0
void
Skype_login (account_t* account)
{
    im_connection* connection = imcb_new(account);
    SkypeData*     skype      = g_new0(struct SkypeData, 1);

    connection->proto_data = skype;

    imcb_log(connection, "Connecting");

    skype->ssl = ssl_connect(
        set_getstr(&account->set, "server"),
        set_getint(&account->set, "port"),
        Skype_connected,
        connection
    );

    skype->fd         = skype->ssl ? ssl_getfd(skype->ssl) : -1;
    skype->username   = g_strdup(account->user);
    skype->connection = connection;

    if (set_getbool(&account->set, "skypeconsole")) {
        imcb_add_buddy(connection, "skypeconsole", NULL);
    }
}
Ejemplo n.º 4
0
void CSSLCOMM::PushNotification(const char *pToken,const char *pMsg)
{
    CMyLock lock(&m_lock);
    if(!connected())
    {
        ssl_connect(APPLE_HOST, APPLE_PORT, RSA_CLIENT_CERT, RSA_CLIENT_KEY, CA_CERT_PATH);
    }
    int paylen = GenPayloadData(1,pMsg);
    GenPushData(pToken);
    int ret = SSL_write(m_pssl, (void*)&m_data, 35 + paylen);
    //printf("ret = %d \n",ret);
}
Ejemplo n.º 5
0
int
tcp_check_thread(thread_t * thread)
{
	SOCK *sock_obj = THREAD_ARG(thread);
	int ret = 1;

	sock_obj->status =
	    tcp_socket_state(thread->u.fd, thread, req->addr_ip, req->addr_port,
			     tcp_check_thread);
	switch (sock_obj->status) {
	case connect_error:
		DBG("Error connecting server [%s:%d].\n",
		    inet_ntop2(req->addr_ip), ntohs(req->addr_port));
		thread_add_terminate_event(thread->master);
		return -1;
		break;

	case connect_timeout:
		DBG("Timeout connecting server [%s:%d].\n",
		    inet_ntop2(req->addr_ip), ntohs(req->addr_port));
		thread_add_terminate_event(thread->master);
		return -1;
		break;

	case connect_success:{
			if (req->ssl)
				ret = ssl_connect(thread);

			if (ret) {
				/* Remote WEB server is connected.
				 * Unlock eventual locked socket.
				 */
				sock_obj->lock = 0;
				thread_add_event(thread->master,
						 http_request_thread, sock_obj, 0);
			} else {
				DBG("Connection trouble to: [%s:%d].\n",
				    inet_ntop2(req->addr_ip),
				    ntohs(req->addr_port));
				if (req->ssl)
					ssl_printerr(SSL_get_error
						     (sock_obj->ssl, ret));
				sock_obj->status = connect_error;
				return -1;
			}
		}
		break;
	}

	return 1;
}
Ejemplo n.º 6
0
/**
 * Opens the connection to the MQTT service.
 *
 * @param mqtt The #fb_mqtt.
 **/
void fb_mqtt_open(fb_mqtt_t *mqtt, const gchar *host, gint port)
{
    g_return_if_fail(mqtt != NULL);

    fb_mqtt_close(mqtt);
    mqtt->ssl = ssl_connect((gchar*) host, port, TRUE, fb_mqtt_cb_open, mqtt);

    if (mqtt->ssl == NULL) {
        fb_mqtt_cb_open(mqtt, 1, NULL, 0);
        return;
    }

    fb_mqtt_timeout(mqtt);
}
void GolgiNetLinux::writeAvailable(void) // called when the socket is ready for writing
{
    if(isSSLRequireWrite){
        ssl_connect_continue();
        return;
    }
    if(isWaiting){
        int so_err;
        socklen_t len;
        len = sizeof(so_err);
        int rc = getsockopt(sockfd,
                            SOL_SOCKET,
                            SO_ERROR,
                            &so_err,
                            &len);
        if(rc == 0 && so_err == 0){
            isWaiting = false;
            if(isEncrypted){
                ssl_connect();
                return;
            }
            else{
                isConnected = true;
            }
        }
        else{
            DBG.print("Error on connection: ");
            DBG.println(strerror(so_err));
            isWaiting = false;
            return;
        }
    }
    DBG.println("Write is available attempting to write");
    
    int n;

    if(isEncrypted){
        n = SSL_write(ssl,
                      writeBuffer,
                      writeBufferPosition);
    }
    else{
        n = ::write(sockfd,
                    writeBuffer,
                    writeBufferPosition);
    }

    removeFromWriteBuffer(n);
}
Ejemplo n.º 8
0
void
complete_connect_socket(struct socket *socket, struct uri *uri,
			socket_connect_T done)
{
	struct connect_info *connect_info = socket->connect_info;

	if (connect_info && connect_info->uri) {
		/* Remember whether the server supported TLS or not.
		 * Then the next request can immediately use the right
		 * protocol.  This is important for HTTP POST requests
		 * because it is not safe to silently retry them.  The
		 * uri parameter is normally NULL here so don't use it.  */
		if (socket->no_tls)
			add_blacklist_entry(connect_info->uri,
					    SERVER_BLACKLIST_NO_TLS);
		else
			del_blacklist_entry(connect_info->uri,
					    SERVER_BLACKLIST_NO_TLS);
	}

	/* This is a special case used by the HTTP implementation to acquire an
	 * SSL link for handling CONNECT requests. */
	if (!connect_info) {
		assert(uri && socket);
		connect_info = init_connection_info(uri, socket, done);
		if (!connect_info) {
			socket->ops->done(socket, connection_state(S_OUT_OF_MEM));
			return;
		}

		socket->connect_info = connect_info;
	}

#ifdef CONFIG_SSL
	/* Check if the connection should run over an encrypted link */
	if (socket->need_ssl
	    && !socket->ssl
	    && ssl_connect(socket) < 0)
		return;
#endif

	if (connect_info->done)
		connect_info->done(socket);

	done_connection_info(socket);
}
Ejemplo n.º 9
0
static int do_connect(char *server, char *port)
{
	int sd, ret;
	struct addrinfo hints;
	struct addrinfo *result, *rp;

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = 0;
	hints.ai_protocol = 0;

	ret = getaddrinfo(server, port, &hints, &result);
	if (ret)
		return -1;

	/* Iterate over all replys until we connect ... */
	for (rp = result; rp; rp = rp->ai_next) {
		sd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
		if (sd < 0)
			continue;

		if (!connect(sd, rp->ai_addr, rp->ai_addrlen))
			break;          /* Success */

		close(sd);
	}

	if (result)
		freeaddrinfo(result);   /* No longer needed */

	if (!rp)		        /* No address succeeded */
		return -1;

	if (ssl) {
		ret = ssl_connect(sd);
		if (ret < 0)
			goto err;
	}

	return sd;
err:
	close(sd);
	return -1;
}
Ejemplo n.º 10
0
int perform_add_company(Context &ctx, mod_company_args &args) {
  sslFile server = ssl_connect(ctx, args.host.c_str(), args.port.c_str());

  if(!server.is_open()) {
    return -1;
  }

  print(server,
    static_cast<char>(_req_code::NEW_COMPANY),
    args.company.c_str(), '\0'
  );

  if(server.next()) {
    print(ferr, "Server error: ", server_err(server), '\n');
    return -1;
  }
  return 0;
}
Ejemplo n.º 11
0
SOCKET MakeConnection(UINT ipaddr, short port)
{
  SOCKET sd = INVALID_SOCKET;
  struct sockaddr sockAddr;
  
  struct in_addr inaddr;
  inaddr.s_addr = ipaddr;
  char* p = inet_ntoa(inaddr);
  if (p == NULL)
    return INVALID_SOCKET;
  string host = p;

  if (ipaddr == 0 || host == "127.0.0.1")
  { // special case to ease local testing
    host = "localhost";
  }

  if (MakeSockAddr(host.c_str(), port, &sockAddr))
  {    
    sd = socket(AF_INET, SOCK_STREAM, 0);
    if (sd != INVALID_SOCKET)
    {
      int rc = connect(sd, &sockAddr, sizeof(sockAddr));
      if (rc >= 0)
      { 
          if (Sys_IsSSLEnabled())
              rc = ssl_connect(sd);
      }
      else
      {
        printf("Connect fails: %i\n", Sys_GetLastError());
      }
      
      if (rc < 0)
      {
        Sys_LogError("connect fails");
        closesocket(sd);
        sd = INVALID_SOCKET;
      }
    }
  }

  return sd;
}  
Ejemplo n.º 12
0
int perform_remove(Context &ctx, del_args &args) {
  sslFile server = ssl_connect(ctx, args.host.c_str(), args.port.c_str());

  if(!server.is_open()) {
    return -1;
  }

  print(server,
    static_cast<char>(_req_code::REMOVE_DOCUMENT),
    args.idPage.c_str(), '\0'
  );

  if(server.next()) {
    server_err(server);
//    print(ferr, "Server error: ", server_err(server), '\n');
    return -1;
  }
  return 0;
}
Ejemplo n.º 13
0
void CSSLComm::PushNotification(int badgeNum, const char *pToken,const char *pMsg)
{
    //CMyLock lock(&m_lock);
    if(!connected())
    {
        ssl_connect(m_server_host, m_server_port, m_cert_file, m_key_file, m_ca_path);
    }
    int paylen = GenPayloadData(badgeNum,pMsg);
    GenPushData(pToken);
    int need_send_len = 35 + paylen;
    int ret = SSL_write(m_pssl, (void*)&m_data, 35 + paylen);
    if(ret <= 0)
    {
        printf("SSL_write failed\n");
    }
    else
    {
        printf("SSL_write %d bytes of %d bytes\n", ret, need_send_len);
    }
}
Ejemplo n.º 14
0
bool CSSLComm::Connect(const char *pCertPath)
{
	bool bConnected = connected();
	if (!bConnected && NULL != pCertPath && pCertPath[0] != '\0') {
		const char *pCertDirPos = strrchr(pCertPath, '\\');
		if (NULL == pCertDirPos) {
			pCertDirPos = strrchr(pCertPath, '/');
		}

		if (NULL != pCertDirPos) {
			char strCertDir[512] = {0};
			memcpy(strCertDir, pCertPath, pCertDirPos - pCertPath);
			bConnected = ssl_connect(APPLE_HOST, APPLE_PORT, pCertPath, pCertPath, strCertDir);
			printf("connect %s:%d result:%d\n", APPLE_HOST, APPLE_PORT, bConnected);
		}
	}

	if (bConnected) {
		verify_connection(m_pssl, APPLE_HOST);
	}
	return bConnected;
}
Ejemplo n.º 15
0
//Setups SSL with the certificates needed for api.twitter.com
s32 ssl_setup(char * http_host, int socket){
	s32 ssl_context;
	s32 ret;
	ssl_context = ssl_new((u8 *)http_host, 0);

	if(ssl_context <= 0){
		return ssl_context;
	}

	ret = ssl_setbuiltinclientcert(ssl_context, 0);
	if(ret){
		return ret;
	}

		if(!strcmp(http_host,"www.googleapis.com")){
			ret = ssl_setrootca(ssl_context, (void *)ESCA, ESCA_size);
			if(ret){
				return ret;
			}
		}else{ //api.twitter.com
			ret = ssl_setrootca(ssl_context, (void *)PCA3G2, PCA3G2_size);
			if(ret){
				return ret;
			}
		}

	ret = ssl_connect(ssl_context, socket);
	if(ret){
		return ret;
	}

	ret = ssl_handshake(ssl_context);
	if(ret){
		return ret;
	}

return ssl_context;
}
Ejemplo n.º 16
0
struct http_request *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data )
{
	struct http_request *req;
	int error = 0;
	
	req = g_new0( struct http_request, 1 );
	
	if( ssl )
	{
		req->ssl = ssl_connect( host, port, TRUE, http_ssl_connected, req );
		if( req->ssl == NULL )
			error = 1;
	}
	else
	{
		req->fd = proxy_connect( host, port, http_connected, req );
		if( req->fd < 0 )
			error = 1;
	}
	
	if( error )
	{
		http_free( req );
		return NULL;
	}
	
	req->func = func;
	req->data = data;
	req->request = g_strdup( request );
	req->request_length = strlen( request );
	req->redir_ttl = 3;
	req->content_length = -1;
	
	if( getenv( "BITLBEE_DEBUG" ) )
		printf( "About to send HTTP request:\n%s\n", req->request );
	
	return req;
}
Ejemplo n.º 17
0
void ReceiveOrderBookLogic::on_write(Socket *socket)
{
    if (m_wait_for_read)
        return;

    if (!m_ssl)
    {
        auto method = SSLv23_client_method();
        m_ssl_ctx = SSL_CTX_new(method);
        if ( m_ssl_ctx == NULL )
        {
            ERR_print_errors_fp(stderr);
            assert(false);
        }

        m_ssl = SSL_new(m_ssl_ctx);
        SSL_set_fd(m_ssl, socket->get_fd());
    }

    if (!m_ssl_connected && !ssl_connect())
        return;

    int64_t writed = 0;
    while ((writed = SSL_write(m_ssl, m_request.c_str() + m_write_offset, m_request.size() - m_write_offset)))
    {
        if (writed < 0)
        {
            ERR_print_errors_fp(stderr);
            throw std::runtime_error("write error");
        }

        m_write_offset += writed;
    }

    if (m_write_offset >= m_request.size())
        m_wait_for_read = true;
}
Ejemplo n.º 18
0
int send_payload(const char *deviceTokenHex, const char *payloadBuff, size_t payloadLength)
{
	int rtn = 0;

	printf("ssl_connect\n");
	SSL_Connection *sslcon = ssl_connect(APPLE_HOST, APPLE_PORT, RSA_CLIENT_CERT, RSA_CLIENT_KEY, CA_CERT_PATH);
	if(sslcon == NULL)
	{
		printf("Could not allocate memory for SSL Connection");
		exit(1);
	}

	printf("ssl_connect successful, sending message...\n");
	if (sslcon && deviceTokenHex && payloadBuff && payloadLength)
	{
		uint8_t command = 0; /* command number */
		char binaryMessageBuff[sizeof(uint8_t) + sizeof(uint16_t) + DEVICE_BINARY_SIZE + sizeof(uint16_t) + MAXPAYLOAD_SIZE];

		/* message format is, |COMMAND|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */
		char *binaryMessagePt = binaryMessageBuff;
		uint16_t networkOrderTokenLength = htons(DEVICE_BINARY_SIZE);
		uint16_t networkOrderPayloadLength = htons(payloadLength);

		/* command */
		*binaryMessagePt++ = command;

		/* token length network order */
		memcpy(binaryMessagePt, &networkOrderTokenLength, sizeof(uint16_t));
		binaryMessagePt += sizeof(uint16_t);

		/* Convert the Device Token */
		size_t i = 0;
		int j = 0;
		int tmpi;
		char tmp[3];
		char deviceTokenBinary[DEVICE_BINARY_SIZE];
		while(i < strlen(deviceTokenHex))
		{
			if(deviceTokenHex[i] == ' ')
			{
				i++;
			}
			else
			{
				tmp[0] = deviceTokenHex[i];
				tmp[1] = deviceTokenHex[i + 1];
				tmp[2] = '\0';

				sscanf(tmp, "%x", &tmpi);
				deviceTokenBinary[j] = tmpi;

				i += 2;
				j++;
			}
		}

		/* device token */
		memcpy(binaryMessagePt, deviceTokenBinary, DEVICE_BINARY_SIZE);
		binaryMessagePt += DEVICE_BINARY_SIZE;

		/* payload length network order */
		memcpy(binaryMessagePt, &networkOrderPayloadLength, sizeof(uint16_t));
		binaryMessagePt += sizeof(uint16_t);

		/* payload */
		memcpy(binaryMessagePt, payloadBuff, payloadLength);
		binaryMessagePt += payloadLength;
		if (SSL_write(sslcon->ssl, binaryMessageBuff, (binaryMessagePt - binaryMessageBuff)) > 0)
			rtn = 1;
	}
	printf("message sent %ssuccessfully\n", rtn ? "un" : "");

	ssl_disconnect(sslcon);

	return rtn;
}
Ejemplo n.º 19
0
int send_payload(const char *deviceTokenHex, const char *payloadBuff, size_t payloadLength)
{
    int rtn = 0;

    SSL_Connection *sslcon = ssl_connect(globalApns->host, globalApns->port, globalApns->rsa_cert, globalApns->rsa_key, NULL);
    if(sslcon == NULL)
    {
        syslog (LOG_CRIT, "[APNS Process] APNS SSL Connection failed, check connexion and configuration" );
        return -1;
    }

    if (sslcon && deviceTokenHex && payloadBuff && payloadLength)
    {
        uint8_t command = 0; /* command number */
        char binaryMessageBuff[sizeof(uint8_t) + sizeof(uint16_t) + DEVICE_BINARY_SIZE + sizeof(uint16_t) + MAXPAYLOAD_SIZE];

        /* message format is, |COMMAND|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */
        char *binaryMessagePt = binaryMessageBuff;
        uint16_t networkOrderTokenLength = htons(DEVICE_BINARY_SIZE);
        uint16_t networkOrderPayloadLength = htons(payloadLength);
 
        /* command */
        *binaryMessagePt++ = command;
 
        /* token length network order */
        memcpy(binaryMessagePt, &networkOrderTokenLength, sizeof(uint16_t));
        binaryMessagePt += sizeof(uint16_t);

        /* Convert the Device Token */
        int i = 0;
        int j = 0;
        int tmpi;
        char tmp[3];
        char deviceTokenBinary[DEVICE_BINARY_SIZE];
        while(i < strlen(deviceTokenHex))
        {
            if(deviceTokenHex[i] == ' ')
            {
                i++;
            }
            else
            {
                tmp[0] = deviceTokenHex[i];
                tmp[1] = deviceTokenHex[i + 1];
                tmp[2] = '\0';

                sscanf(tmp, "%x", &tmpi);
                deviceTokenBinary[j] = tmpi;

                i += 2;
                j++;
            }
        }

        /* device token */
        memcpy(binaryMessagePt, deviceTokenBinary, DEVICE_BINARY_SIZE);
        binaryMessagePt += DEVICE_BINARY_SIZE;

        /* payload length network order */
        memcpy(binaryMessagePt, &networkOrderPayloadLength, sizeof(uint16_t));
        binaryMessagePt += sizeof(uint16_t);
 
        /* payload */
        memcpy(binaryMessagePt, payloadBuff, payloadLength);
        binaryMessagePt += payloadLength;
        if (SSL_write(sslcon->ssl, binaryMessageBuff, (binaryMessagePt - binaryMessageBuff)) > 0)
            rtn = 1;
    }

    ssl_disconnect(sslcon);

    return rtn;
}
Ejemplo n.º 20
0
Archivo: jabber.c Proyecto: AlD/bitlbee
/* Separate this from jabber_login() so we can do OAuth first if necessary.
   Putting this in io.c would probably be more correct. */
void jabber_connect( struct im_connection *ic )
{
	account_t *acc = ic->acc;
	struct jabber_data *jd = ic->proto_data;
	int i;
	char *connect_to;
	struct ns_srv_reply **srvl = NULL, *srv = NULL;
	
	/* Figure out the hostname to connect to. */
	if( acc->server && *acc->server )
		connect_to = acc->server;
	else if( ( srvl = srv_lookup( "xmpp-client", "tcp", jd->server ) ) ||
	         ( srvl = srv_lookup( "jabber-client", "tcp", jd->server ) ) )
	{
		/* Find the lowest-priority one. These usually come
		   back in random/shuffled order. Not looking at
		   weights etc for now. */
		srv = *srvl;
		for( i = 1; srvl[i]; i ++ )
			if( srvl[i]->prio < srv->prio )
				srv = srvl[i];
		
		connect_to = srv->name;
	}
	else
		connect_to = jd->server;
	
	imcb_log( ic, "Connecting" );
	
	for( i = 0; jabber_port_list[i] > 0; i ++ )
		if( set_getint( &acc->set, "port" ) == jabber_port_list[i] )
			break;

	if( jabber_port_list[i] == 0 )
	{
		imcb_log( ic, "Illegal port number" );
		imc_logout( ic, FALSE );
		return;
	}
	
	/* For non-SSL connections we can try to use the port # from the SRV
	   reply, but let's not do that when using SSL, SSL usually runs on
	   non-standard ports... */
	if( set_getbool( &acc->set, "ssl" ) )
	{
		jd->ssl = ssl_connect( connect_to, set_getint( &acc->set, "port" ), FALSE, jabber_connected_ssl, ic );
		jd->fd = jd->ssl ? ssl_getfd( jd->ssl ) : -1;
	}
	else
	{
		jd->fd = proxy_connect( connect_to, srv ? srv->port : set_getint( &acc->set, "port" ), jabber_connected_plain, ic );
	}
	srv_free( srvl );
	
	if( jd->fd == -1 )
	{
		imcb_error( ic, "Could not connect to server" );
		imc_logout( ic, TRUE );
		
		return;
	}
	
	if( set_getbool( &acc->set, "xmlconsole" ) )
	{
		jd->flags |= JFLAG_XMLCONSOLE;
		/* Shouldn't really do this at this stage already, maybe. But
		   I think this shouldn't break anything. */
		imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL );
	}
	
	jabber_generate_id_hash( jd );
}
Ejemplo n.º 21
0
/* Splits headers and body. Checks result code, in case of 300s it'll handle
   redirects. If this returns FALSE, don't call any callbacks! */
static gboolean http_handle_headers( struct http_request *req )
{
	char *end1, *end2, *s;
	int evil_server = 0;
	
	/* Zero termination is very convenient. */
	req->reply_headers[req->bytes_read] = '\0';
	
	/* Find the separation between headers and body, and keep stupid
	   webservers in mind. */
	end1 = strstr( req->reply_headers, "\r\n\r\n" );
	end2 = strstr( req->reply_headers, "\n\n" );
	
	if( end2 && end2 < end1 )
	{
		end1 = end2 + 1;
		evil_server = 1;
	}
	else if( end1 )
	{
		end1 += 2;
	}
	else
	{
		req->status_string = g_strdup( "Malformed HTTP reply" );
		return TRUE;
	}
	
	*end1 = '\0';
	
	if( getenv( "BITLBEE_DEBUG" ) )
		printf( "HTTP response headers:\n%s\n", req->reply_headers );
	
	if( evil_server )
		req->reply_body = end1 + 1;
	else
		req->reply_body = end1 + 2;
	
	/* Separately allocated space for headers and body. */
	req->sblen = req->body_size = req->reply_headers + req->bytes_read - req->reply_body;
	req->sbuf = req->reply_body = g_memdup( req->reply_body, req->body_size + 1 );
	req->reply_headers = g_realloc( req->reply_headers, end1 - req->reply_headers + 1 );
	
	if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL )
	{
		if( sscanf( end1 + 1, "%hd", &req->status_code ) != 1 )
		{
			req->status_string = g_strdup( "Can't parse status code" );
			req->status_code = -1;
		}
		else
		{
			char *eol;
			
			if( evil_server )
				eol = strchr( end1, '\n' );
			else
				eol = strchr( end1, '\r' );
			
			req->status_string = g_strndup( end1 + 1, eol - end1 - 1 );
			
			/* Just to be sure... */
			if( ( eol = strchr( req->status_string, '\r' ) ) )
				*eol = 0;
			if( ( eol = strchr( req->status_string, '\n' ) ) )
				*eol = 0;
		}
	}
	else
	{
		req->status_string = g_strdup( "Can't locate status code" );
		req->status_code = -1;
	}
	
	if( ( ( req->status_code >= 301 && req->status_code <= 303 ) ||
	      req->status_code == 307 ) && req->redir_ttl-- > 0 )
	{
		char *loc, *new_request, *new_host;
		int error = 0, new_port, new_proto;
		
		/* We might fill it again, so let's not leak any memory. */
		g_free( req->status_string );
		req->status_string = NULL;
		
		loc = strstr( req->reply_headers, "\nLocation: " );
		if( loc == NULL ) /* We can't handle this redirect... */
		{
			req->status_string = g_strdup( "Can't locate Location: header" );
			return TRUE;
		}
		
		loc += 11;
		while( *loc == ' ' )
			loc ++;
		
		/* TODO/FIXME: Possibly have to handle relative redirections,
		   and rewrite Host: headers. Not necessary for now, it's
		   enough for passport authentication like this. */
		
		if( *loc == '/' )
		{
			/* Just a different pathname... */
			
			/* Since we don't cache the servername, and since we
			   don't need this yet anyway, I won't implement it. */
			
			req->status_string = g_strdup( "Can't handle relative redirects" );
			
			return TRUE;
		}
		else
		{
			/* A whole URL */
			url_t *url;
			char *s, *version, *headers;
			const char *new_method;
			
			s = strstr( loc, "\r\n" );
			if( s == NULL )
				return TRUE;
			
			url = g_new0( url_t, 1 );
			*s = 0;
			
			if( !url_set( url, loc ) )
			{
				req->status_string = g_strdup( "Malformed redirect URL" );
				g_free( url );
				return TRUE;
			}
			
			/* Find all headers and, if necessary, the POST request contents.
			   Skip the old Host: header though. This crappy code here means
			   anything using this http_client MUST put the Host: header at
			   the top. */
			if( !( ( s = strstr( req->request, "\r\nHost: " ) ) &&
			       ( s = strstr( s + strlen( "\r\nHost: " ), "\r\n" ) ) ) )
			{
				req->status_string = g_strdup( "Error while rebuilding request string" );
				g_free( url );
				return TRUE;
			}
			headers = s;
			
			/* More or less HTTP/1.0 compliant, from my reading of RFC 2616.
			   Always perform a GET request unless we received a 301. 303 was
			   meant for this but it's HTTP/1.1-only and we're specifically
			   speaking HTTP/1.0. ...
			   
			   Well except someone at identi.ca's didn't bother reading any
			   RFCs and just return HTTP/1.1-specific status codes to HTTP/1.0
			   requests. Fuckers. So here we are, handle 301..303,307. */
			if( strncmp( req->request, "GET", 3 ) == 0 )
				/* GETs never become POSTs. */
				new_method = "GET";
			else if( req->status_code == 302 || req->status_code == 303 )
				/* 302 de-facto becomes GET, 303 as specified by RFC 2616#10.3.3 */
				new_method = "GET";
			else
				/* 301 de-facto should stay POST, 307 specifally RFC 2616#10.3.8 */
				new_method = "POST";
			
			if( ( version = strstr( req->request, " HTTP/" ) ) &&
			    ( s = strstr( version, "\r\n" ) ) )
			{
				version ++;
				version = g_strndup( version, s - version );
			}
			else
				version = g_strdup( "HTTP/1.0" );
			
			/* Okay, this isn't fun! We have to rebuild the request... :-( */
			new_request = g_strdup_printf( "%s %s %s\r\nHost: %s%s",
			                               new_method, url->file, version,
			                               url->host, headers );
			
			new_host = g_strdup( url->host );
			new_port = url->port;
			new_proto = url->proto;
			
			/* If we went from POST to GET, truncate the request content. */
			if( new_request[0] != req->request[0] && new_request[0] == 'G' &&
			    ( s = strstr( new_request, "\r\n\r\n" ) ) )
				s[4] = '\0';
			
			g_free( url );
			g_free( version );
		}
		
		if( req->ssl )
			ssl_disconnect( req->ssl );
		else
			closesocket( req->fd );
		
		req->fd = -1;
		req->ssl = NULL;
		
		if( getenv( "BITLBEE_DEBUG" ) )
			printf( "New headers for redirected HTTP request:\n%s\n", new_request );
	
		if( new_proto == PROTO_HTTPS )
		{
			req->ssl = ssl_connect( new_host, new_port, TRUE, http_ssl_connected, req );
			if( req->ssl == NULL )
				error = 1;
		}
		else
		{
			req->fd = proxy_connect( new_host, new_port, http_connected, req );
			if( req->fd < 0 )
				error = 1;
		}
		g_free( new_host );
		
		if( error )
		{
			req->status_string = g_strdup( "Connection problem during redirect" );
			g_free( new_request );
			return TRUE;
		}
		
		g_free( req->request );
		g_free( req->reply_headers );
		g_free( req->sbuf );
		req->request = new_request;
		req->request_length = strlen( new_request );
		req->bytes_read = req->bytes_written = req->inpa = 0;
		req->reply_headers = req->reply_body = NULL;
		req->sbuf = req->cbuf = NULL;
		req->sblen = req->cblen = 0;
		
		return FALSE;
	}

	if( ( s = get_rfc822_header( req->reply_headers, "Content-Length", 0 ) ) &&
	    sscanf( s, "%d", &req->content_length ) != 1 )
		req->content_length = -1;
	g_free( s );
	
	if( ( s = get_rfc822_header( req->reply_headers, "Transfer-Encoding", 0 ) ) )
	{
		if( strcasestr( s, "chunked" ) )
		{
			req->flags |= HTTPC_CHUNKED;
			req->cbuf = req->sbuf;
			req->cblen = req->sblen;
			
			req->reply_body = req->sbuf = g_strdup( "" );
			req->body_size = req->sblen = 0;
		}
		g_free( s );
	}
	
	return TRUE;
}
Ejemplo n.º 22
0
/** Attempt to send a sequence of bytes to the connection.
 * As a side effect, updates \a cptr's FLAG_BLOCKED setting
 * and sendB/sendK fields.
 * @param cptr Client that should receive data.
 * @param buf Message buffer to send to client.
 * @return Negative on connection-fatal error; otherwise
 *  number of bytes sent.
 */
unsigned int deliver_it(struct Client *cptr, struct MsgQ *buf)
{
  unsigned int bytes_written = 0;
  unsigned int bytes_count = 0;
  assert(0 != cptr);

#if defined(USE_SSL)
  switch (client_sendv(cptr, buf, &bytes_count, &bytes_written)) {
#else
  switch (os_sendv_nonb(cli_fd(cptr), buf, &bytes_count, &bytes_written)) {
#endif
  case IO_SUCCESS:
    ClrFlag(cptr, FLAG_BLOCKED);

    cli_sendB(cptr) += bytes_written;
    cli_sendB(&me)  += bytes_written;
    /* A partial write implies that future writes will block. */
    if (bytes_written < bytes_count)
      SetFlag(cptr, FLAG_BLOCKED);
    break;
  case IO_BLOCKED:
    SetFlag(cptr, FLAG_BLOCKED);
    break;
  case IO_FAILURE:
    cli_error(cptr) = errno;
    SetFlag(cptr, FLAG_DEADSOCKET);
    break;
  }
  return bytes_written;
}

/** Complete non-blocking connect()-sequence. Check access and
 * terminate connection, if trouble detected.
 * @param cptr Client to which we have connected, with all ConfItem structs attached.
 * @return Zero on failure (caller should exit_client()), non-zero on success.
 */
static int completed_connection(struct Client* cptr)
{
  struct ConfItem *aconf;
  time_t newts;
  struct Client *acptr;
  int i;
#if defined(USE_SSL)
  char *sslfp;
  int r;
#endif

  assert(0 != cptr);

  /*
   * get the socket status from the fd first to check if
   * connection actually succeeded
   */
  if ((cli_error(cptr) = os_get_sockerr(cli_fd(cptr)))) {
    const char* msg = strerror(cli_error(cptr));
    if (!msg)
      msg = "Unknown error";
    sendto_opmask(0, SNO_OLDSNO, "Connection failed to %s: %s",
                  cli_name(cptr), msg);
    return 0;
  }
  if (!(aconf = find_conf_byname(cli_confs(cptr), cli_name(cptr), CONF_SERVER))) {
    sendto_opmask(0, SNO_OLDSNO, "Lost Server Line for %s", cli_name(cptr));
    return 0;
  }

#if defined(USE_SSL)
  if (aconf->flags & CONF_SSL) {
    r = ssl_connect(&(cli_socket(cptr)));
    if (r == -1) {
      sendto_opmask(0, SNO_OLDSNO, "Connection failed to %s: SSL error",
                    cli_name(cptr));
      return 0;
    } else if (r == 0)
      return 1;
    sslfp = ssl_get_fingerprint(cli_socket(cptr).s_ssl);
    if (sslfp)
      ircd_strncpy(cli_sslclifp(cptr), sslfp, BUFSIZE+1);
    SetSSL(cptr);
  }
#endif

  if (s_state(&(cli_socket(cptr))) == SS_CONNECTING)
    socket_state(&(cli_socket(cptr)), SS_CONNECTED);

  if (!EmptyString(aconf->passwd))
    sendrawto_one(cptr, MSG_PASS " :%s", aconf->passwd);

  /*
   * Create a unique timestamp
   */
  newts = TStime();
  for (i = HighestFd; i > -1; --i) {
    if ((acptr = LocalClientArray[i]) &&
        (IsServer(acptr) || IsHandshake(acptr))) {
      if (cli_serv(acptr)->timestamp >= newts)
        newts = cli_serv(acptr)->timestamp + 1;
    }
  }
  assert(0 != cli_serv(cptr));

  cli_serv(cptr)->timestamp = newts;
  SetHandshake(cptr);
  /*
   * Make us timeout after twice the timeout for DNS look ups
   */
  cli_lasttime(cptr) = CurrentTime;
  ClearPingSent(cptr);

/* TODO: NEGOCIACION
  envia_config_req(cptr);
*/

  sendrawto_one(cptr, MSG_SERVER " %s 1 %Tu %Tu J%s %s%s +%s6 :%s",
                cli_name(&me), cli_serv(&me)->timestamp, newts,
		MAJOR_PROTOCOL, NumServCap(&me),
		feature_bool(FEAT_HUB) ? "h" : "", cli_info(&me));

#if defined(DDB)
  ddb_burst(cptr);
#endif

  return (IsDead(cptr)) ? 0 : 1;
}

/** Close the physical connection.  Side effects: MyConnect(cptr)
 * becomes false and cptr->from becomes NULL.
 * @param cptr Client to disconnect.
 */
void close_connection(struct Client *cptr)
{
  struct ConfItem* aconf;

  if (IsServer(cptr)) {
    ServerStats->is_sv++;
    ServerStats->is_sbs += cli_sendB(cptr);
    ServerStats->is_sbr += cli_receiveB(cptr);
    ServerStats->is_sti += CurrentTime - cli_firsttime(cptr);
    /*
     * If the connection has been up for a long amount of time, schedule
     * a 'quick' reconnect, else reset the next-connect cycle.
     */
    if ((aconf = find_conf_exact(cli_name(cptr), cptr, CONF_SERVER))) {
      /*
       * Reschedule a faster reconnect, if this was a automatically
       * connected configuration entry. (Note that if we have had
       * a rehash in between, the status has been changed to
       * CONF_ILLEGAL). But only do this if it was a "good" link.
       */
      aconf->hold = CurrentTime;
      aconf->hold += ((aconf->hold - cli_since(cptr) >
		       feature_int(FEAT_HANGONGOODLINK)) ?
		      feature_int(FEAT_HANGONRETRYDELAY) : ConfConFreq(aconf));
/*        if (nextconnect > aconf->hold) */
/*          nextconnect = aconf->hold; */
    }
  }
  else if (IsUser(cptr)) {
    ServerStats->is_cl++;
    ServerStats->is_cbs += cli_sendB(cptr);
    ServerStats->is_cbr += cli_receiveB(cptr);
    ServerStats->is_cti += CurrentTime - cli_firsttime(cptr);
  }
  else
    ServerStats->is_ni++;

#if defined(USE_ZLIB)
  /*
   * Siempre es una conexion nuestra
   */
  if (cli_connect(cptr)->zlib_negociation & ZLIB_IN) {
    inflateEnd(cli_connect(cptr)->comp_in);
    MyFree(cli_connect(cptr)->comp_in);
  }
  if (cli_connect(cptr)->zlib_negociation & ZLIB_OUT) {
    deflateEnd(cli_connect(cptr)->comp_out);
    MyFree(cli_connect(cptr)->comp_out);
  }
#endif

  if (-1 < cli_fd(cptr)) {
    flush_connections(cptr);
    LocalClientArray[cli_fd(cptr)] = 0;
    close(cli_fd(cptr));
    socket_del(&(cli_socket(cptr))); /* queue a socket delete */
    cli_fd(cptr) = -1;
    cli_freeflag(cptr) &= ~FREEFLAG_SOCKET;
  }
  SetFlag(cptr, FLAG_DEADSOCKET);

  MsgQClear(&(cli_sendQ(cptr)));
  client_drop_sendq(cli_connect(cptr));
  DBufClear(&(cli_recvQ(cptr)));
  memset(cli_passwd(cptr), 0, sizeof(cli_passwd(cptr)));
  set_snomask(cptr, 0, SNO_SET);

  det_confs_butmask(cptr, 0);

  if (cli_listener(cptr)) {
    release_listener(cli_listener(cptr));
    cli_listener(cptr) = 0;
  }

  for ( ; HighestFd > 0; --HighestFd) {
    if (LocalClientArray[HighestFd])
      break;
  }
}

/** Close all unregistered connections.
 * @param source Oper who requested the close.
 * @return Number of closed connections.
 */
int net_close_unregistered_connections(struct Client* source)
{
  int            i;
  struct Client* cptr;
  int            count = 0;
  assert(0 != source);

  for (i = HighestFd; i > 0; --i) {
    if ((cptr = LocalClientArray[i]) && !IsRegistered(cptr)) {
      send_reply(source, RPL_CLOSING, get_client_name(source, HIDE_IP));
      exit_client(source, cptr, &me, "Oper Closing");
      ++count;
    }
  }
  return count;
}
Ejemplo n.º 23
0
bool http_request (const char *url, const u32 max_size) {
	int linecount;
	int sslcontext = -1;
	if (!http_split_url(&http_host, &http_path, url)) return false;

	if (strncasecmp (url, "http://", 7) == 0)
		http_port = 80;
	else
		http_port = 443;

	http_max_size = max_size;

	http_status = 404;
	content_length = 0;
	http_data = NULL;

	int s = tcp_connect (http_host, http_port);
	if (s < 0) {
		result = HTTPR_ERR_CONNECT;
		return false;
	}
	if(http_port == 443)
	{
		//patched out anyways so just to set something
		sslcontext = ssl_new((u8*)http_host,0);
		if(sslcontext < 0)
		{
			gprintf("ssl_new\n");
			result = HTTPR_ERR_CONNECT;
			net_close (s);
			return false;
		}
		//patched out anyways so just to set something
		ssl_setbuiltinclientcert(sslcontext,0);
		if(ssl_connect(sslcontext,s) < 0)
		{
			gprintf("ssl_connect\n");
			result = HTTPR_ERR_CONNECT;
			ssl_shutdown(sslcontext);
			net_close (s);
			return false;
		}
		int ret = ssl_handshake(sslcontext);
		if(ret < 0)
		{
			gprintf("ssl_handshake %i\n", ret);
			result = HTTPR_ERR_STATUS;
			ssl_shutdown(sslcontext);
			net_close (s);
			return false;
		}
	}
	char *request = (char *) memalign (32, 1024*2);
	snprintf(request, 1024*2,
		"GET %s HTTP/1.1\r\n"
		"Host: %s\r\n"
		"Cache-Control: no-cache\r\n\r\n",
		http_path, http_host);

	bool b = tcp_write (http_port == 443 ? sslcontext : s, (u8 *) request, strlen (request));

	free (request);
	linecount = 0;

	for (linecount=0; linecount < 32; linecount++) {
	  char *line = tcp_readln (http_port == 443 ? sslcontext : s, 0xff, gettime(), (u16)HTTP_TIMEOUT);
		if (!line) {
			http_status = 404;
			result = HTTPR_ERR_REQUEST;
			break;
		}

		if (strlen (line) < 1) {
			free (line);
			line = NULL;
			break;
		}

		sscanf (line, "HTTP/1.%*u %u", &http_status);
		sscanf (line, "Content-Length: %u", &content_length);
		gprintf(line);
		gprintf("\n");
		free (line);
		line = NULL;

	}
	if (linecount == 32 || !content_length) http_status = 404;
	if (http_status != 200) {
		result = HTTPR_ERR_STATUS;
		if(http_port == 443)
			ssl_shutdown(sslcontext);
		net_close (s);
		return false;
	}
	if (content_length > http_max_size) {
		result = HTTPR_ERR_TOOBIG;
		if(http_port == 443)
			ssl_shutdown(sslcontext);
		net_close (s);
		return false;
	}
	http_data = (u8 *) memalign (32, content_length);
	b = tcp_read (http_port == 443 ? sslcontext : s, &http_data, content_length);
	if (!b) {
		free (http_data);
		http_data = NULL;
		result = HTTPR_ERR_RECEIVE;
		if(http_port == 443)
			ssl_shutdown(sslcontext);
		net_close (s);
		return false;
	}

	result = HTTPR_OK;

	if(http_port == 443)
		ssl_shutdown(sslcontext);
	net_close (s);


	return true;
}
Ejemplo n.º 24
0
/* Separate this from jabber_login() so we can do OAuth first if necessary.
   Putting this in io.c would probably be more correct. */
void jabber_connect(struct im_connection *ic)
{
	account_t *acc = ic->acc;
	struct jabber_data *jd = ic->proto_data;
	int i;
	char *connect_to;
	struct ns_srv_reply **srvl = NULL, *srv = NULL;

	/* Figure out the hostname to connect to. */
	if (acc->server && *acc->server) {
		connect_to = acc->server;
	} else if ((srvl = srv_lookup("xmpp-client", "tcp", jd->server)) ||
	           (srvl = srv_lookup("jabber-client", "tcp", jd->server))) {
		/* Find the lowest-priority one. These usually come
		   back in random/shuffled order. Not looking at
		   weights etc for now. */
		srv = *srvl;
		for (i = 1; srvl[i]; i++) {
			if (srvl[i]->prio < srv->prio) {
				srv = srvl[i];
			}
		}

		connect_to = srv->name;
	} else {
		connect_to = jd->server;
	}

	imcb_log(ic, "Connecting");

	for (i = 0; jabber_port_list[i] > 0; i++) {
		if (set_getint(&acc->set, "port") == jabber_port_list[i]) {
			break;
		}
	}

	if (jabber_port_list[i] == 0) {
		imcb_log(ic, "Illegal port number");
		imc_logout(ic, FALSE);
		return;
	}

	/* For non-SSL connections we can try to use the port # from the SRV
	   reply, but let's not do that when using SSL, SSL usually runs on
	   non-standard ports... */
	if (set_getbool(&acc->set, "ssl")) {
		jd->ssl = ssl_connect(connect_to, set_getint(&acc->set, "port"), set_getbool(&acc->set,
		                                                                             "tls_verify"), jabber_connected_ssl,
		                      ic);
		jd->fd = jd->ssl ? ssl_getfd(jd->ssl) : -1;
	} else {
		jd->fd = proxy_connect(connect_to, srv ? srv->port : set_getint(&acc->set,
		                                                                "port"), jabber_connected_plain, ic);
	}
	srv_free(srvl);

	if (jd->fd == -1) {
		imcb_error(ic, "Could not connect to server");
		imc_logout(ic, TRUE);

		return;
	}

	if (set_getbool(&acc->set, "xmlconsole")) {
		jabber_xmlconsole_enable(ic);
	}

	if (set_getbool(&acc->set, "mail_notifications")) {
		/* It's gmail specific, but it checks for server support before enabling it */
		jd->flags |= JFLAG_GMAILNOTIFY;
		if (set_getstr(&acc->set, "mail_notifications_handle")) {
			imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL);
		}
	}

	jabber_generate_id_hash(jd);
}
bool GolgiNetLinux::connect(const char *url,int port)
{
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int s;
    char sport[6];

    if(isConnected || isWaiting || (isSSLWaiting && isEncrypted)){
        return isConnected;
    }

    if(isEncrypted){
        snprintf(sport,6,"%d",443);
    }
    else{
        snprintf(sport,6,"%d",port);
    }

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_STREAM; /* TCP socket */
    hints.ai_flags = 0;
    hints.ai_protocol = 0;          /* Any protocol */

    s = getaddrinfo(url, sport, &hints, &result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
        exit(EXIT_FAILURE);
    }

    /* getaddrinfo() returns a list of address structures.
     * Try each address until we successfully bind(2).
     * If socket(2) (or bind(2)) fails, we (close the socket
     * and) try the next address. */
    for(rp = result; rp != NULL; rp = rp->ai_next) {
        
        sockfd = socket(rp->ai_family, 
                        rp->ai_socktype,
                        rp->ai_protocol);
        if (sockfd == -1)
            continue;
        
        int flags = fcntl(sockfd,F_GETFL,NULL);
        flags |= O_NONBLOCK;
        fcntl(sockfd,F_SETFL,flags);

        if(::connect(sockfd,rp->ai_addr,rp->ai_addrlen) != -1){
            if(isEncrypted){
                isSSLWaiting = true;
                ssl_connect();
            }
            else{
                isConnected = true;
            }
            break;  /* Success */
        }
        else{
            int err = errno;
            if(err == EINPROGRESS){ // this indicates that the connect could not complete immediately
                DBG.println("Connect could not complete immediately");
                isWaiting = true;
                break;
            }
        }

        close(sockfd);
    }

    if (rp == NULL) {               /* No address succeeded */
        fprintf(stderr, "Could not connect\n");
        isConnected = false;
    }

    freeaddrinfo(result);           /* No longer needed */

    return isConnected;
}
Ejemplo n.º 26
0
INT submit_elog(char *host, int port, int ssl, char *subdir, char *experiment,
                char *uname, char *upwd,
                int reply,
                int quote_on_reply,
                int edit,
                int download,
                int suppress,
                int encoding,
                char attrib_name[MAX_N_ATTR][NAME_LENGTH],
                char attrib[MAX_N_ATTR][NAME_LENGTH],
                int n_attr,
                char *text, char afilename[MAX_ATTACHMENTS][256],
                char *buffer[MAX_ATTACHMENTS], INT buffer_size[MAX_ATTACHMENTS])
/********************************************************************\

  Routine: submit_elog

  Purpose: Submit an ELog entry

  Input:
    char   *host            Host name where ELog server runs
    in     port             ELog server port number
    int    ssl              SSL flag
    char   *subdir          Subdirectoy to elog server
    char   *uname           User name
    char   *upwd            User password
    int    reply            Reply to existing message
    int    edit             Edit existing message
    int    download         Download existing message
    int    suppress         Suppress Email notification
    int    encoding         0:ELCode,1:plain,2:HTML
    char   *attrib_name     Attribute names
    char   *attrib          Attribute values
    char   *text            Message text

    char   afilename[]      File names of attachments
    char   *buffer[]        Attachment contents
    INT    buffer_size[]    Size of buffer in bytes

  Function value:
    EL_SUCCESS              Successful completion

\********************************************************************/
{
   int status, sock, i, n, header_length, content_length, index;
   char host_name[256], boundary[80], str[80], encrypted_passwd[256], *p, *old_encoding;
   char old_attrib_name[MAX_N_ATTR+1][NAME_LENGTH], old_attrib[MAX_N_ATTR+1][NAME_LENGTH];
   struct hostent *phe;
#ifdef HAVE_SSL
   SSL *ssl_con = NULL;
#endif

   /* get local host name */
   gethostname(host_name, sizeof(host_name));

   phe = gethostbyname(host_name);
   if (phe == NULL) {
      perror("Cannot retrieve host name");
      return -1;
   }
   phe = gethostbyaddr(phe->h_addr, sizeof(int), AF_INET);
   if (phe == NULL) {
      perror("Cannot retrieve host name");
      return -1;
   }

   /* if domain name is not in host name, hope to get it from phe */
   if (strchr(host_name, '.') == NULL)
      strcpy(host_name, phe->h_name);

   if (edit || download) {
      if (edit)
         status = retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, edit,
                                old_attrib_name, old_attrib, old_text);
      else
         status = retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, download,
                                old_attrib_name, old_attrib, old_text);

      if (status != 1)
         return status;

      /* update attributes */
      for (index = 0; index < n_attr; index++) {
         for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++)
            if (equal_ustring(attrib_name[index], old_attrib_name[i]))
               break;

         if (old_attrib_name[i][0])
            strlcpy(old_attrib[i], attrib[index], NAME_LENGTH);
      }

      /* copy attributes */
      for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++) {
         strlcpy(attrib_name[i], old_attrib_name[i], NAME_LENGTH);
         strlcpy(attrib[i], old_attrib[i], NAME_LENGTH);
      }

      n_attr = i;

      if (text[0] == 0)
         strlcpy(text, old_text, TEXT_SIZE);
   }
   
   if (download) {
      if (strstr(response, "$@MID@$:"))
         printf("%s", strstr(response, "$@MID@$:"));
      else
         printf("%s", response);
      return 1;
   }

   if (reply) {
      status =
          retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, reply,
                        old_attrib_name, old_attrib, old_text);

      if (status != 1)
         return status;

      /* update attributes */
      for (index = 0; index < n_attr; index++) {
         for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++)
            if (equal_ustring(attrib_name[index], old_attrib_name[i]))
               break;

         if (old_attrib_name[i][0])
            strlcpy(old_attrib[i], attrib[index], NAME_LENGTH);
      }

      /* copy attributes */
      for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++) {
         if (equal_ustring(old_attrib_name[i], "Reply to") || equal_ustring(old_attrib_name[i], "Date")) {
            attrib_name[i][0] = 0;
            attrib[i][0] = 0;
         } else {
            strlcpy(attrib_name[i], old_attrib_name[i], NAME_LENGTH);
            strlcpy(attrib[i], old_attrib[i], NAME_LENGTH);
         }
      }

      n_attr = i;

      /* check encoding */
      old_encoding = "plain";

      for (i = 0; i < n_attr; i++)
         if (equal_ustring(attrib_name[i], "encoding"))
            break;

      if (i < n_attr)
         old_encoding = attrib[i];

      if (quote_on_reply) {
         strlcpy(new_text, text, sizeof(new_text));

         /* precede old text with "> " */
         text[0] = 0;
         p = old_text;

         do {
            if (strchr(p, '\n')) {
               *strchr(p, '\n') = 0;

               if (old_encoding[0] == 'H') {
                  strlcat(text, "> ", TEXT_SIZE);
                  strlcat(text, p, TEXT_SIZE);
                  strlcat(text, "<br>\n", TEXT_SIZE);
               } else {
                  strlcat(text, "> ", TEXT_SIZE);
                  strlcat(text, p, TEXT_SIZE);
                  strlcat(text, "\n", TEXT_SIZE);
               }

               p += strlen(p) + 1;
               if (*p == '\n')
                  p++;
            } else {
               if (old_encoding[0] == 'H') {
                  strlcat(text, "> ", TEXT_SIZE);
                  strlcat(text, p, TEXT_SIZE);
                  strlcat(text, "<p>\n", TEXT_SIZE);
               } else {
                  strlcat(text, "> ", TEXT_SIZE);
                  strlcat(text, p, TEXT_SIZE);
                  strlcat(text, "\n\n", TEXT_SIZE);
               }

               break;
            }

         } while (1);

         strlcat(text, new_text, TEXT_SIZE);
      }
   }

   sock = elog_connect(host, port);
   if (sock < 0)
      return sock;

#ifdef HAVE_SSL
   if (ssl)
      if (ssl_connect(sock, &ssl_con) < 0) {
         printf("elogd server does not run SSL protocol\n");
         return -1;
      }
#endif

   content_length = 100000;
   for (i = 0; i < MAX_ATTACHMENTS; i++)
      if (afilename[i][0])
         content_length += buffer_size[i];
   content = (char *)malloc(content_length);
   if (content == NULL) {
      printf("Not enough memory\n");
      return -1;
   }

   /* compose content */
   srand((unsigned) time(NULL));
   sprintf(boundary, "---------------------------%04X%04X%04X", rand(), rand(), rand());
   strcpy(content, boundary);
   strcat(content, "\r\nContent-Disposition: form-data; name=\"cmd\"\r\n\r\nSubmit\r\n");

   if (uname[0])
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"unm\"\r\n\r\n%s\r\n", boundary, uname);

   if (upwd[0]) {
      do_crypt(upwd, encrypted_passwd, sizeof(encrypted_passwd));
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"upwd\"\r\n\r\n%s\r\n", boundary,
              encrypted_passwd);
   }

   if (experiment[0])
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"exp\"\r\n\r\n%s\r\n", boundary, experiment);

   if (reply)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"reply_to\"\r\n\r\n%d\r\n", boundary, reply);

   if (edit) {
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"edit_id\"\r\n\r\n%d\r\n", boundary, edit);
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"skiplock\"\r\n\r\n1\r\n", boundary);
   }

   if (suppress)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"suppress\"\r\n\r\n1\r\n", boundary);

   if (encoding == 0)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nELCode\r\n", boundary);
   else if (encoding == 1)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nplain\r\n", boundary);
   else if (encoding == 2)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nHTML\r\n", boundary);

   for (i = 0; i < n_attr; i++) {
      strcpy(str, attrib_name[i]);
      if (str[0]) {
         stou(str);
         sprintf(content + strlen(content),
                 "%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", boundary, str, attrib[i]);
      }
   }

   if (text[0])
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"Text\"\r\n\r\n%s\r\n%s\r\n",
              boundary, text, boundary);

   content_length = strlen(content);
   p = content + content_length;

   for (i = 0; i < MAX_ATTACHMENTS; i++)
      if (afilename[i][0]) {
         sprintf(p,
                 "Content-Disposition: form-data; name=\"attfile%d\"; filename=\"%s\"\r\n\r\n",
                 i + 1, afilename[i]);

         content_length += strlen(p);
         p += strlen(p);
         memcpy(p, buffer[i], buffer_size[i]);
         p += buffer_size[i];
         strcpy(p, boundary);
         strcat(p, "\r\n");

         content_length += buffer_size[i] + strlen(p);
         p += strlen(p);
      }

   /* compose request */
   strcpy(request, "POST /");
   if (subdir[0])
      sprintf(request + strlen(request), "%s/", subdir);
   if (experiment[0]) {
      strcpy(str, experiment);
      url_encode(str, sizeof(str));
      sprintf(request + strlen(request), "%s/", str);
   }
   strcat(request, " HTTP/1.0\r\n");

   sprintf(request + strlen(request), "Content-Type: multipart/form-data; boundary=%s\r\n", boundary);
   if (port != 80)
      sprintf(str, "%s:%d", host, port);
   else
      sprintf(str, "%s", host);
   sprintf(request + strlen(request), "Host: %s\r\n", str);
   sprintf(request + strlen(request), "User-Agent: ELOG\r\n");
   sprintf(request + strlen(request), "Content-Length: %d\r\n", content_length);

   strcat(request, "\r\n");

   header_length = strlen(request);

   /*
      {
      FILE *f;
      f = fopen("elog.log", "w");
      fwrite(request, header_length+content_length, 1, f);
      fclose(f);
      }
    */

   /* send request */
#ifdef HAVE_SSL
   if (ssl)
      SSL_write(ssl_con, request, header_length);
   else
#endif
      send(sock, request, header_length, 0);
   if (verbose) {
      printf("Request sent to host:\n");
      puts(request);
   }

   /* send content */
#ifdef HAVE_SSL
   if (ssl)
      SSL_write(ssl_con, content, content_length);
   else
#endif
      send(sock, content, content_length, 0);
   if (verbose) {
      printf("Content sent to host:\n");
      puts(content);
   }

   /* receive response */
   memset(response, 0, sizeof(response));
#ifdef HAVE_SSL
   if (ssl)
      i = SSL_read(ssl_con, response, sizeof(response) - 1);
   else
#endif
      i = recv(sock, response, sizeof(response) - 1, 0);
   if (i < 0) {
      perror("Cannot receive response");
      return -1;
   }

   /* discard remainder of response */
   n = i;
   while (i > 0) {
#ifdef HAVE_SSL
      if (ssl)
         i = SSL_read(ssl_con, response + n, sizeof(response) - 1 - n);
      else
#endif
         i = recv(sock, response + n, sizeof(response) - 1 - n, 0);
      if (i > 0)
         n += i;
   }
   response[n] = 0;

#ifdef HAVE_SSL
   if (ssl) {
      SSL_shutdown(ssl_con);
      SSL_free(ssl_con);
   }
#endif

   closesocket(sock);

   if (verbose) {
      printf("Response received:\n");
      puts(response);
   }

   /* check response status */
   if (strstr(response, "302 Found")) {
      if (strstr(response, "Location:")) {
         if (strstr(response, "has moved"))
            printf("Error: elogd server has moved to another location\n");
         else if (strstr(response, "fail"))
            printf("Error: Invalid user name or password\n");
         else {
            strncpy(str, strstr(response, "Location:") + 10, sizeof(str));
            if (strchr(str, '?'))
               *strchr(str, '?') = 0;
            if (strchr(str, '\n'))
               *strchr(str, '\n') = 0;
            if (strchr(str, '\r'))
               *strchr(str, '\r') = 0;

            if (strrchr(str, '/'))
               printf("Message successfully transmitted, ID=%s\n", strrchr(str, '/') + 1);
            else
               printf("Message successfully transmitted, ID=%s\n", str);
         }
      } else
         printf("Message successfully transmitted\n");
   } else if (strstr(response, "Logbook Selection"))
      printf("Error: No logbook specified\n");
   else if (strstr(response, "enter password"))
      printf("Error: Missing or invalid password\n");
   else if (strstr(response, "form name=form1"))
      printf("Error: Missing or invalid user name/password\n");
   else if (strstr(response, "Error: Attribute")) {
      if (strstr(response, "not existing")) {
         strncpy(str, strstr(response, "Error: Attribute") + 27, sizeof(str));
         if (strchr(str, '<'))
            *strchr(str, '<') = 0;
         printf("Error: Non existing attribute option \"%s\"\n", str);
      } else {
         strncpy(str, strstr(response, "Error: Attribute") + 20, sizeof(str));
         if (strchr(str, '<'))
            *strchr(str, '<') = 0;
         printf("Error: Missing required attribute \"%s\"\n", str);
      }
   } else
      printf("Error transmitting message\n");

   return 1;
}
Ejemplo n.º 27
0
INT retrieve_elog(char *host, int port, char *subdir, int ssl, char *experiment,
                  char *uname, char *upwd, int message_id,
                  char attrib_name[MAX_N_ATTR][NAME_LENGTH], char attrib[MAX_N_ATTR][NAME_LENGTH], char *text)
/********************************************************************\

  Routine: retrive_elog

  Purpose: Retrive an ELog entry for edit/reply

  Input:
    char   *host            Host name where ELog server runs
    int    port             ELog server port number
    char   *subdir          Subdirectoy to elog server
    int    ssl              Flag for using SSL layer
    char   *uname           User name
    char   *upwd            User password
    int    message_id       Message to retrieve
    char   *attrib_name     Attribute names
    char   *attrib          Attribute values
    char   *text            Message text

  Function value:
    EL_SUCCESS              Successful completion

\********************************************************************/
{
   int i, n, first, index, sock;
   char str[256], encrypted_passwd[256], *ph, *ps;
#ifdef HAVE_SSL
   SSL *ssl_con = NULL;
#endif

   if (ssl)                     /* avoid compiler warning */
      sock = 0;

   sock = elog_connect(host, port);
   if (sock < 0)
      return sock;

#ifdef HAVE_SSL
   if (ssl)
      if (ssl_connect(sock, &ssl_con) < 0) {
         printf("elogd server does not run SSL protocol\n");
         return -1;
      }
#endif

   /* compose request */
   strcpy(request, "GET /");
   strlcpy(str, experiment, sizeof(str));
   url_encode(str, sizeof(str));
   if (subdir[0] && experiment[0])
      sprintf(request + strlen(request), "%s/%s/%d?cmd=download", subdir, str, message_id);
   else if (subdir[0])
      sprintf(request + strlen(request), "%s/%d?cmd=download", subdir, message_id);
   else if (experiment[0])
      sprintf(request + strlen(request), "%s/%d?cmd=download", str, message_id);
   strcat(request, " HTTP/1.0\r\n");

   sprintf(request + strlen(request), "User-Agent: ELOG\r\n");

   first = 1;

   if (uname[0]) {
      if (first)
         sprintf(request + strlen(request), "Cookie: ");
      first = 0;

      sprintf(request + strlen(request), "unm=%s;", uname);
   }

   if (upwd[0]) {
      if (first)
         sprintf(request + strlen(request), "Cookie: ");
      first = 0;

      do_crypt(upwd, encrypted_passwd, sizeof(encrypted_passwd));
      sprintf(request + strlen(request), "upwd=%s;", encrypted_passwd);
   }

   /* finish cookie line */
   if (!first)
      strcat(request, "\r\n");

   strcat(request, "\r\n");

   /* send request */
#ifdef HAVE_SSL
   if (ssl)
      SSL_write(ssl_con, request, strlen(request));
   else
#endif
      send(sock, request, strlen(request), 0);
   if (verbose) {
      printf("Request sent to host:\n");
      puts(request);
   }

   /* receive response */
   memset(response, 0, sizeof(response));
#ifdef HAVE_SSL
   if (ssl)
      i = SSL_read(ssl_con, response, sizeof(response) - 1);
   else
#endif
      i = recv(sock, response, sizeof(response) - 1, 0);
   if (i < 0) {
      perror("Cannot receive response");
      return -1;
   }

   n = i;
   while (i > 0) {
#ifdef HAVE_SSL
      if (ssl)
         i = SSL_read(ssl_con, response + n, sizeof(response) - 1 - n);
      else
#endif
         i = recv(sock, response + n, sizeof(response) - 1 - n, 0);
      if (i > 0)
         n += i;
   }
   response[n] = 0;

#ifdef HAVE_SSL
   if (ssl) {
      SSL_shutdown(ssl_con);
      SSL_free(ssl_con);
   }
#endif

   closesocket(sock);

   if (verbose) {
      printf("Response received:\n");
      puts(response);
   }

   /* check response status */
   if (strstr(response, "$@MID@$:")) {
      /* separate attributes and message */

      ph = strstr(response, "========================================\n");

      /* skip first line */
      ps = strstr(response, "$@MID@$:");
      while (*ps && *ps != '\n')
         ps++;
      while (*ps && (*ps == '\n' || *ps == '\r'))
         ps++;

      for (index = 0; index < MAX_N_ATTR; index++) {
         if (ps >= ph)
            break;

         strlcpy(attrib_name[index], ps, NAME_LENGTH);
         if (strchr(attrib_name[index], ':'))
            *(strchr(attrib_name[index], ':')) = 0;

         ps += strlen(attrib_name[index]) + 2;
         strlcpy(attrib[index], ps, NAME_LENGTH);

         for (i = 0; i < NAME_LENGTH; i++) {
            if (attrib[index][i] == '\r' || attrib[index][i] == '\n')
               attrib[index][i] = 0;

            if (attrib[index][i] == 0)
               break;
         }

         ps += strlen(attrib[index]);
         while (*ps && (*ps == '\n' || *ps == '\r'))
            ps++;
      }

      attrib_name[index][0] = 0;
      attrib[index][0] = 0;

      ph = strchr(ph, '\n') + 1;
      if (*ph == '\r')
         ph++;

      strlcpy(text, ph, TEXT_SIZE);

      return 1;
   }

   if (strstr(response, "302 Found")) {
      if (strstr(response, "Location:")) {
         if (strstr(response, "fail"))
            printf("Error: Invalid user name or password\n");
         else {
            strncpy(str, strstr(response, "Location:") + 10, sizeof(str));
            if (strchr(str, '?'))
               *strchr(str, '?') = 0;
            if (strchr(str, '\n'))
               *strchr(str, '\n') = 0;
            if (strchr(str, '\r'))
               *strchr(str, '\r') = 0;

            if (strrchr(str, '/'))
               printf("Message successfully transmitted, ID=%s\n", strrchr(str, '/') + 1);
            else
               printf("Message successfully transmitted, ID=%s\n", str);
         }
      }
   } else if (strstr(response, "Logbook Selection"))
      printf("Error: No logbook specified\n");
   else if (strstr(response, "enter password"))
      printf("Error: Missing or invalid password\n");
   else if (strstr(response, "form name=form1"))
      printf("Error: Missing or invalid user name/password\n");
   else
      printf("Error transmitting message\n");

   return 0;
}
void APN_connect()
{
	sslcon = ssl_connect(APPLE_HOST, APPLE_PORT, RSA_CLIENT_CERT, RSA_CLIENT_KEY, CA_CERT_PATH);
}
Ejemplo n.º 29
0
int main(int argc,char **argv)
{
	TASK_FACTORY *task;
	SMBOT_CONF *conf;
	LIST *list;
	struct sigaction act;
	char *data;

	printf("init task factory . . .\n");
	task=task_factory_init(20,100);
	printf("init task factory successed . . .\n");
	printf("set signal . . .\n");
	act.sa_flags=0;
	act.sa_handler=quit;
	sigaction(SIGINT,&act,NULL);
	printf("set signal successed . . .\n");

	printf("read config . . .\n");
	conf=smbot_conf_init();
	smbot_conf_open(conf);
	smbot_conf_read(conf);
	printf("read config successed . . .\n");
	printf("init list . . .\n");
	list=list_init();
	printf("list init successed . . .\n");
	printf("connect irc . . .\n");
	if(strstr(conf->use_ssl,"true"))
	{
		is_use_ssl=TRUE;
		ssl=ssl_connect(conf->server,conf->port,NULL,NULL);
	}
	else
	{
		is_use_ssl=FALSE;
		sockfd=tcp_connect(conf->server,conf->port);
	}
	printf("connect irc successed . . .\n");

	if(is_use_ssl)
		safe_send_data(ssl,conf);
	else
		send_data(sockfd,conf);

	task_factory_add(task,time_keeping,&is_use_ssl,1);
	smbot_conf_close(conf);

	while(1)
	{
		if(smbot_select(sockfd,ssl,is_use_ssl) <= 0)
			break;

		if(is_use_ssl)
			data=ssl_read_line(ssl);
		else
			data=read_line(sockfd);

		if(data == NULL) break;

		printf("%s\n",data);

		if(strstr(data,"!man"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!man","!man [1-8] <要查询的内容> 功能:linux manpages查询",get_man_url,5);

		if(strstr(data,"!ip"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!ip","!ip <ipv4/6地址或域名> 功能:返回ipv4/6或者域名的物理位置",get_ip_addr,5);

		if(strstr(data,"!time"))
		{
			send_time(is_use_ssl,data);
			free(data);
			continue;
		}

		if(strstr(data,"!idiom"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!idiom","!idiom <成语词典> 功能:成语词典查询",get_idiom,1);

		if(strstr(data,"!dict"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!dict","!dict <目标语言> <要查询的内容> 功能:bing翻译",bing_dict,3);

		if(strstr(data,"!youku"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!youku","!youku <关键词> 功能:返回youku第一个链接",get_youku_url,4);

		if(strstr(data,"!yt"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!yt","!yt <关键词> 功能:返回youtube第一个频道连接",get_youtube,4);

		if(strstr(data,"!bt"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!bt","!bt <关键词> 功能:返回btdigg.org第一个磁力链接",get_bt,4);

		if(strstr(data,"!zip"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!zip","!zip <地名> 功能:查询邮政编码",get_zip_code,4);

		if(strstr(data,"!weather"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!weather","!weather <地名> 功能:天气预报查询",get_weather,3);

		if(strstr(data,"!stack"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!stack","!stack <问题> 功能:返回stackoverflow第一个搜索",get_stack,3);

		if(strstr(data,"!id"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!id","!id <身份证号码> 功能:身份证号码查询",get_id_information,5);

		if(strstr(data,"!checkid"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!checkid","!checkid <身份证号码> 功能:校验身份证最后一位",check_id_card,5);

		if(strstr(data,"!url"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!url","!url <信息> 功能:url编码",get_url_encode,5);

		if(strstr(data,"!deurl"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!deurl","!deurl <url编码> 功能:url解码",get_url_decode,5);

		if(strstr(data,"!joke"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!joke","!joke <关键词> 功能:返回一个小笑话",get_joke,2);

		if(strstr(data,"!dream"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!dream","!dream <关键词> 功能:周公解梦",get_dream,2);

		if(strstr(data,"!song"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!song","!song <歌曲> 功能:返回百度音乐第一个搜索结果",get_song_url,2);

		if(strstr(data,"!bing"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!bing","!bing <关键词> 功能:返回bing搜索第一个结果",get_bing,1);

		if(strstr(data,"!image"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!image","!image <关键词> 功能:返回google搜索第一张图片链接",get_google_image_url,1);

		if(strstr(data,"!google"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!google","!google <关键词> 功能:返回google搜索第一个结果",get_google,1);

		if(strstr(data,"!baidu"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!baidu","!baidu <关键词> 功能:返回baidu搜索第一个结果",get_baidu,1);

		if(strstr(data,"!bimg"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!bimg","!bimg <关键词> 功能:返回百度图片搜索第一个结果",get_bimg,1);

		if(strstr(data,"!news"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!news","!news <关键词> 功能:根据关键词返回百度新闻第一条结果",get_news,1);

		if(strstr(data,"!air"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!air","!air <城市名称> 功能:查询城市空气质量",get_air,1);

		if(strstr(data,"!website"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!website","!website <域名> 功能:网址安全检测,检测结果由金山云盾提供",get_website_testing,1);

		if(strstr(data,"!wifi"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!wifi","!wifi <城市名称> 功能:根据城市名返回查到的第一个wifi热点",get_wifi,1);

		if(strstr(data,"!train"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!train","!train <车次> 功能:火车时刻表查询",get_train,1);

		if(strstr(data,"!sm"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!sm","!sm <你想要说的话> 功能:与机器人对话,使用\'问题%答案\'方式可调教机器人",get_sm_message,1);
		if(strstr(data,"!word"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!word","!word <新华字典> 功能:新华字典查询",get_word,1);

		if(strstr(data,"!term"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!term","!term <汉语词典> 功能:汉语词典查询",get_term,1);

/*		if(strstr(data,"!idiom"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!idiom","!idiom <成语词典> 功能:成语词典查询",get_idiom,1);*/

		if(strstr(data,"!b64"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!b64","!b64 <base64编码> 功能:base64编码",get_base64_encode,1);

		if(strstr(data,"!deb64"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!deb64","!deb64 <base64解码> 功能:base64解码",get_base64_decode,1);

		if(strstr(data,"!baike"))
			parse_arg("^:.[^ ]* PRIVMSG .[^ ]* :!baike","!baike <百度百科> 功能:百度百科查询",get_baike,1);

		if(strstr(data,"!list") && strstr(data,"PRIVMSG"))
		{
			smbot_list(data,is_use_ssl);
			free(data);
			continue;
		}

		if(strstr(data,"!help smbot") && strstr(data,"PRIVMSG"))
		{
			smbot_help(data,is_use_ssl);
			free(data);
			continue;
		}

		//if(strstr(data,"PING") && !strstr(data,"PRIVMSG"))
		if(pong("^PING :.*",data))
			pong_server(data,is_use_ssl);
		if(pong("^:.[^ ]* PRIVMSG smbot :\x1PING .*",data))
			notice(data,is_use_ssl);
	}

	task_factory_destroy(task);
	ssl_close(ssl);

	return 0;
}
Ejemplo n.º 30
0
static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond )
{
	struct http_request *req = data;
	int evil_server = 0;
	char buffer[2048];
	char *end1, *end2;
	int st;
	
	if( req->inpa > 0 )
		b_event_remove( req->inpa );
	
	if( req->ssl )
	{
		st = ssl_read( req->ssl, buffer, sizeof( buffer ) );
		if( st < 0 )
		{
			if( ssl_errno != SSL_AGAIN )
			{
				/* goto cleanup; */
				
				/* YAY! We have to deal with crappy Microsoft
				   servers that LOVE to send invalid TLS
				   packets that abort connections! \o/ */
				
				goto got_reply;
			}
		}
		else if( st == 0 )
		{
			goto got_reply;
		}
	}
	else
	{
		st = read( req->fd, buffer, sizeof( buffer ) );
		if( st < 0 )
		{
			if( !sockerr_again() )
			{
				req->status_string = g_strdup( strerror( errno ) );
				goto cleanup;
			}
		}
		else if( st == 0 )
		{
			goto got_reply;
		}
	}
	
	if( st > 0 )
	{
		req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + st + 1 );
		memcpy( req->reply_headers + req->bytes_read, buffer, st );
		req->bytes_read += st;
	}
	
	/* There will be more! */
	req->inpa = b_input_add( req->fd,
	                         req->ssl ? ssl_getdirection( req->ssl ) : B_EV_IO_READ,
	                         http_incoming_data, req );
	
	if( ssl_pending( req->ssl ) )
		return http_incoming_data( data, source, cond );
	else
		return FALSE;

got_reply:
	/* Maybe if the webserver is overloaded, or when there's bad SSL
	   support... */
	if( req->bytes_read == 0 )
	{
		req->status_string = g_strdup( "Empty HTTP reply" );
		goto cleanup;
	}
	
	/* Zero termination is very convenient. */
	req->reply_headers[req->bytes_read] = 0;
	
	/* Find the separation between headers and body, and keep stupid
	   webservers in mind. */
	end1 = strstr( req->reply_headers, "\r\n\r\n" );
	end2 = strstr( req->reply_headers, "\n\n" );
	
	if( end2 && end2 < end1 )
	{
		end1 = end2 + 1;
		evil_server = 1;
	}
	else if( end1 )
	{
		end1 += 2;
	}
	else
	{
		req->status_string = g_strdup( "Malformed HTTP reply" );
		goto cleanup;
	}
	
	*end1 = 0;
	
	if( getenv( "BITLBEE_DEBUG" ) )
		printf( "HTTP response headers:\n%s\n", req->reply_headers );
	
	if( evil_server )
		req->reply_body = end1 + 1;
	else
		req->reply_body = end1 + 2;
	
	req->body_size = req->reply_headers + req->bytes_read - req->reply_body;
	
	if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL )
	{
		if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 )
		{
			req->status_string = g_strdup( "Can't parse status code" );
			req->status_code = -1;
		}
		else
		{
			char *eol;
			
			if( evil_server )
				eol = strchr( end1, '\n' );
			else
				eol = strchr( end1, '\r' );
			
			req->status_string = g_strndup( end1 + 1, eol - end1 - 1 );
			
			/* Just to be sure... */
			if( ( eol = strchr( req->status_string, '\r' ) ) )
				*eol = 0;
			if( ( eol = strchr( req->status_string, '\n' ) ) )
				*eol = 0;
		}
	}
	else
	{
		req->status_string = g_strdup( "Can't locate status code" );
		req->status_code = -1;
	}
	
	if( ( ( req->status_code >= 301 && req->status_code <= 303 ) ||
	      req->status_code == 307 ) && req->redir_ttl-- > 0 )
	{
		char *loc, *new_request, *new_host;
		int error = 0, new_port, new_proto;
		
		/* We might fill it again, so let's not leak any memory. */
		g_free( req->status_string );
		req->status_string = NULL;
		
		loc = strstr( req->reply_headers, "\nLocation: " );
		if( loc == NULL ) /* We can't handle this redirect... */
		{
			req->status_string = g_strdup( "Can't locate Location: header" );
			goto cleanup;
		}
		
		loc += 11;
		while( *loc == ' ' )
			loc ++;
		
		/* TODO/FIXME: Possibly have to handle relative redirections,
		   and rewrite Host: headers. Not necessary for now, it's
		   enough for passport authentication like this. */
		
		if( *loc == '/' )
		{
			/* Just a different pathname... */
			
			/* Since we don't cache the servername, and since we
			   don't need this yet anyway, I won't implement it. */
			
			req->status_string = g_strdup( "Can't handle recursive redirects" );
			
			goto cleanup;
		}
		else
		{
			/* A whole URL */
			url_t *url;
			char *s;
			const char *new_method;
			
			s = strstr( loc, "\r\n" );
			if( s == NULL )
				goto cleanup;
			
			url = g_new0( url_t, 1 );
			*s = 0;
			
			if( !url_set( url, loc ) )
			{
				req->status_string = g_strdup( "Malformed redirect URL" );
				g_free( url );
				goto cleanup;
			}
			
			/* Find all headers and, if necessary, the POST request contents.
			   Skip the old Host: header though. This crappy code here means
			   anything using this http_client MUST put the Host: header at
			   the top. */
			if( !( ( s = strstr( req->request, "\r\nHost: " ) ) &&
			       ( s = strstr( s + strlen( "\r\nHost: " ), "\r\n" ) ) ) )
			{
				req->status_string = g_strdup( "Error while rebuilding request string" );
				g_free( url );
				goto cleanup;
			}
			
			/* More or less HTTP/1.0 compliant, from my reading of RFC 2616.
			   Always perform a GET request unless we received a 301. 303 was
			   meant for this but it's HTTP/1.1-only and we're specifically
			   speaking HTTP/1.0. ...
			   
			   Well except someone at identi.ca's didn't bother reading any
			   RFCs and just return HTTP/1.1-specific status codes to HTTP/1.0
			   requests. Fuckers. So here we are, handle 301..303,307. */
			if( strncmp( req->request, "GET", 3 ) == 0 )
				/* GETs never become POSTs. */
				new_method = "GET";
			else if( req->status_code == 302 || req->status_code == 303 )
				/* 302 de-facto becomes GET, 303 as specified by RFC 2616#10.3.3 */
				new_method = "GET";
			else
				/* 301 de-facto should stay POST, 307 specifally RFC 2616#10.3.8 */
				new_method = "POST";
			
			/* Okay, this isn't fun! We have to rebuild the request... :-( */
			new_request = g_strdup_printf( "%s %s HTTP/1.0\r\nHost: %s%s",
			                               new_method, url->file, url->host, s );
			
			new_host = g_strdup( url->host );
			new_port = url->port;
			new_proto = url->proto;
			
			/* If we went from POST to GET, truncate the request content. */
			if( new_request[0] != req->request[0] && new_request[0] == 'G' &&
			    ( s = strstr( new_request, "\r\n\r\n" ) ) )
				s[4] = '\0';
			
			g_free( url );
		}
		
		if( req->ssl )
			ssl_disconnect( req->ssl );
		else
			closesocket( req->fd );
		
		req->fd = -1;
		req->ssl = NULL;
		
		if( getenv( "BITLBEE_DEBUG" ) )
			printf( "New headers for redirected HTTP request:\n%s\n", new_request );
	
		if( new_proto == PROTO_HTTPS )
		{
			req->ssl = ssl_connect( new_host, new_port, TRUE, http_ssl_connected, req );
			if( req->ssl == NULL )
				error = 1;
		}
		else
		{
			req->fd = proxy_connect( new_host, new_port, http_connected, req );
			if( req->fd < 0 )
				error = 1;
		}
		g_free( new_host );
		
		if( error )
		{
			req->status_string = g_strdup( "Connection problem during redirect" );
			g_free( new_request );
			goto cleanup;
		}
		
		g_free( req->request );
		g_free( req->reply_headers );
		req->request = new_request;
		req->request_length = strlen( new_request );
		req->bytes_read = req->bytes_written = req->inpa = 0;
		req->reply_headers = req->reply_body = NULL;
		
		return FALSE;
	}
	
	/* Assume that a closed connection means we're finished, this indeed
	   breaks with keep-alive connections and faulty connections. */
	req->finished = 1;

cleanup:
	if( req->ssl )
		ssl_disconnect( req->ssl );
	else
		closesocket( req->fd );
	
	if( getenv( "BITLBEE_DEBUG" ) && req )
		printf( "Finishing HTTP request with status: %s\n",
		        req->status_string ? req->status_string : "NULL" );
	
	req->func( req );
	http_free( req );
	return FALSE;
}