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); }
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(); } }
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); } }
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); }
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; }
/** * 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); }
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); }
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; }
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; }
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; }
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; }
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); } }
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; }
//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; }
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; }
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; }
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; }
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; }
/* 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 ); }
/* 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; }
/** 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; }
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; }
/* 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; }
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; }
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); }
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; }
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; }