Exemple #1
0
int http_parse_input(char *src, int len, int is_cookie) {
  bstring name = bfromcstr("");
  bstring value = bfromcstr("");
  int start_pos=0, eq_pos=0, end_pos=0;
  int i, ret = 0;

  char stop = (is_cookie) ? ';' : '&';

  for (i=0; i <= len; i++) {
    if (i == len || src[i] == stop) {  end_pos = i; }
    else if (!eq_pos && src[i] == '=') {  eq_pos = i; }

    if (eq_pos && end_pos && start_pos != eq_pos) {

      bassigncstr(name, "");
      bassigncstr(value, "");

      if (is_cookie) {
        bassigncstr(name,"COOKIE_");
        bcatblk(name,src+start_pos,eq_pos-start_pos);
      } else {
        bassigncstr(name,"CAP_");
        bcatblk(name,src+start_pos,eq_pos-start_pos);
      }

      /*bunescape(name);*/

      if ((eq_pos + 1) == end_pos || (end_pos - eq_pos) <= 1) {
	syslog(LOG_DEBUG, "%s = nil", name->data);
      } else {
        bassignblk(value, src+eq_pos+1, end_pos-eq_pos-1);
        /*bunescape(value);*/
	syslog(LOG_DEBUG, "%s = %s", name->data, value->data);
	setenv((char *)name->data, (char *)value->data, 1);
      }
      start_pos = end_pos + 1;
      if (start_pos < len)
        while (src[start_pos] == ' ' && i < len)
          i++, start_pos++;

      end_pos = eq_pos = 0;
    }
  }

  ret = 1;
  bdestroy(name);
  bdestroy(value);
  return ret;
}
static int redir_cli_write(redir_request *req, uint8_t *d, int l) {
  int w = 0;

  if (redir_cli_rewrite(req, &req->conn) == -1)
    return -1;

  if (!conn_write_remaining(&req->conn)) {
    
    w = net_write(req->socket_fd, d, l);

#if(_debug_ )      
    log_dbg("client write: %d", w);
    /*log_dbg("write: [%s]", b);*/
#endif
  }
  
  if (w >= 0) {
    if (w < l) {
      bcatblk(req->dbuf, d + w, l - w);
      log_warn(errno, "buffering %d - %d = %d (%d queued)", 
	       l, w, l-w, req->dbuf->slen);
    }
  }
  
  return w;
}
Exemple #3
0
static int redir_cli_write(redir_request *req, uint8_t *d, int l) {
  int w = 0;

  if (redir_cli_rewrite(req, &req->conn) == -1)
    return -1;

  if (!conn_write_remaining(&req->conn)) {

    w = net_write(req->socket_fd, d, l);

#if(_debug_ )
    syslog(LOG_DEBUG, "client write: %d", w);
    /*syslog(LOG_DEBUG, "write: [%s]", b);*/
#endif
  }

  if (w >= 0) {
    if (w < l) {
      bcatblk(req->dbuf, d + w, l - w);
      syslog(LOG_WARNING, "%s: buffering %d - %d = %d (%d queued)",
             strerror(errno), l, w, l-w, req->dbuf->slen);
    }
  }

  return w;
}
Exemple #4
0
static bstring genrandmsg(){
    unsigned int len = WEBSOCKET_MEDIUM_MAX - 1000;
    printf("genrandmsg of len %u\n",len);
    int range = 'Z' - 'A';
    bstring randchars = bfromcstr("");
    for(int i=0; i<len; i++){
        char randchar = 'A' + rand()%range;
        bcatblk(randchars,&randchar,1);
    }
    bstring retval = bformat("Len: %d Data: %.*s",len,blength(randchars),bdata(randchars));
    return retval;
}
Exemple #5
0
static int tWrite (const void * buf, size_t elsize, size_t nelem, void * parm) {
bstring b = (bstring) parm;
size_t i;

	if (NULL == b || NULL == buf || 0 == elsize || 0 == nelem)
		return -__LINE__;

	for (i=0; i < nelem; i++) {
		if (0 > bcatblk (b, buf, elsize)) break;
		buf = (const void *) (elsize + (const char *) buf);
	}
	return (int) i;	
}
static int 
redir_handle_url(struct redir_t *redir, 
		 struct redir_conn_t *conn, 
		 struct redir_httpreq_t *httpreq,
		 struct redir_socket_t *socket,
		 struct sockaddr_in *peer, 
		 redir_request *req) {
  int port = 80;
  int matches = 1;
  int i = -1;
  char *p = 0;

#ifdef ENABLE_REDIRINJECT
  char hasInject = 0;
  if (conn->s_params.flags & UAM_INJECT_URL) {
    safe_strncpy((char *) req->inject_url,
		 (char *) conn->s_params.url,
		 REDIRINJECT_MAX);
    hasInject = 1;
  } else if (_options.inject && *_options.inject) { 
    safe_strncpy((char *) req->inject_url,
		 (char *) _options.inject,
		 REDIRINJECT_MAX);
    hasInject = 1;
  } else {
#endif
    for (i=0; i < MAX_REGEX_PASS_THROUGHS; i++) {
      
      if ( ! _options.regex_pass_throughs[i].inuse )
	break;
      
      /*
	if ( ! _options.regex_pass_throughs[i].regex_host[0] &&
	! _options.regex_pass_throughs[i].regex_path[0] &&
	! _options.regex_pass_throughs[i].regex_qs[0] )
	break;
      */
      
#if(_debug_)
      log_dbg("REGEX host=[%s] path=[%s] qs=[%s]",
	      _options.regex_pass_throughs[i].regex_host,
	      _options.regex_pass_throughs[i].regex_path,
	      _options.regex_pass_throughs[i].regex_qs);
      
      log_dbg("Host %s", httpreq->host);
#endif
      
      if (_options.regex_pass_throughs[i].regex_host[0]) {
	switch(check_regex(&_options.regex_pass_throughs[i].re_host, 
			   _options.regex_pass_throughs[i].regex_host, 
			   httpreq->host)) {
	case -1: return -1;  
	case 1: matches = _options.regex_pass_throughs[i].neg_host; break;
	case 0: matches = !_options.regex_pass_throughs[i].neg_host; break;
	}
      }
      
      if (matches && _options.regex_pass_throughs[i].regex_path[0]) {
	switch(check_regex(&_options.regex_pass_throughs[i].re_path, 
			   _options.regex_pass_throughs[i].regex_path, 
			   httpreq->path)) {
	case -1: return -1;  
	case 1: matches = _options.regex_pass_throughs[i].neg_path; break;
	case 0: matches = !_options.regex_pass_throughs[i].neg_path; break;
	}
      }
      
      if (matches && _options.regex_pass_throughs[i].regex_qs[0]) {
	switch(check_regex(&_options.regex_pass_throughs[i].re_qs, 
			   _options.regex_pass_throughs[i].regex_qs, 
			   httpreq->qs)) {
	case -1: return -1;  
	case 1: matches = _options.regex_pass_throughs[i].neg_qs; break;
	case 0: matches = !_options.regex_pass_throughs[i].neg_qs; break;
	}
      }
      
      if (matches) break;
    }
#ifdef ENABLE_REDIRINJECT
  }
#endif

  if (i == 0)
    matches = 0;
    
  if (matches) {
    log_dbg("Matched for Host %s", httpreq->host);
    
    req->proxy = 1;
    
#ifdef ENABLE_REDIRINJECT
    /* XXX */
    /* Check for headers we wish to filter out */
    if (hasInject) {
      bstring newhdr = bfromcstr("");
      char *hdr = (char *)req->wbuf->data;

      if (_options.inject_wispr)
	(void) inject_fmt(req, conn);
      
      while (hdr && *hdr) {
	char *p = strstr(hdr, "\r\n");
	int skip = 0;
	int l;
	
	if (p) {
	  l = (p - hdr);
	} else {
	  l = req->wbuf->slen - (hdr - (char*)req->wbuf->data);
	}
	
	if (!strncasecmp(hdr, "accept-encoding:", 16)) {
	  bcatcstr(newhdr, "Accept-Encoding: identity\r\n");
	  skip = 1;
	} else if (!strncasecmp(hdr, "connection:", 11)) {
	  bcatcstr(newhdr, "Connection: close\r\n");
	  skip = 1;
	} else if (!strncasecmp(hdr, "keep-alive:", 11)) {
	  skip = 1;
	}
	
	if (!skip)
	  bcatblk(newhdr, hdr, l);
	
	if (p) {
	  if (!skip)
	    bcatblk(newhdr, p, 2);
	  hdr = p + 2;
	} else { 
	  hdr = 0;
	}
      }
      
      if (req->wbuf->slen != newhdr->slen) {
	log_dbg("Changed HTTP Headers");
      }
      
      bassign(req->wbuf, newhdr);
      bdestroy(newhdr);
    }
    /* XXX */
#endif

    if ((p = strchr(httpreq->host, ':'))) {
      *p++ = 0;
      port = atoi(p);
    }

    if (conn_setup(&req->conn, httpreq->host, port, 
		   req->wbuf, req->dbuf)) {
      log_err(errno, "conn_setup()");
      return -1;
    }
    
    req->state |= REDIR_CONN_FD;
    net_select_addfd(&sctx, req->conn.sock, SELECT_READ);
    
    return 0;
  }
  
  return 1;
}
static int redir_conn_read(struct conn_t *conn, void *ctx) {
  redir_request *req = (redir_request *)ctx;
  uint8_t bb[PKT_MAX_LEN];
  int s, r;

  if ((s=redir_cli_rewrite(req, conn)) != 0) 
    return 0;
  
  r = safe_recv(conn->sock, bb, sizeof(bb)-1, 0);
  
#if(_debug_)
  log_dbg("conn_read: %d clen=%d", r, req->clen);
#endif
  
  if (r == 0) {

    if (req->read_closed && redir_cli_rewrite(req, conn) == 0) {
      log_dbg("done reading and writing");
      redir_conn_finish(conn, req);
      return -1;
    }

    req->read_closed = 1;
    
  } else if (r < 0 && 
	     errno != EWOULDBLOCK && errno != EAGAIN) {
    
    log_dbg("ERRNO %d", errno);
    redir_conn_finish(conn, ctx);
    
  } else if (r > 0) {
#ifdef ENABLE_REDIRINJECT
    bstring inject = inject_fmt(req, 0);
#endif
    
    bb[r]=0;
    req->last_active = mainclock_tick();
    
#ifdef ENABLE_REDIRINJECT

    /**
     *
     */
    if (inject && !req->headers) {
      char *newline = "\r\n\r\n";
      char *eoh;
      
      bcatblk(req->hbuf, bb, r);
      
      if ((eoh = strstr((char *)req->hbuf->data, newline))) {
	
	int header_len = eoh - (char *)req->hbuf->data;
	bstring newhdr = bfromcstr("");

	if (strncmp((char *)req->hbuf->data, "HTTP/1.", 7) ||
	    strncmp((char *)req->hbuf->data+8, " 2", 2)) {
	  
	  log_dbg("Not HTTP/1.X 2XX reply");
	  bcatblk(newhdr, req->hbuf->data, header_len + 4);
	  
	} else {
	  
	  char *hdr, *p;
	  int clen = 0;
	  
	  hdr = (char *)req->hbuf->data;
	  
	  while (hdr && *hdr) {
	    int l;
	    
	    p = strstr(hdr, "\r\n");
	    
	    if (p == hdr) {
	      break;
	    } else if (p) {
	      l = (p - hdr);
	    } else {
	      l = (eoh - hdr);
	    }
	    
	    if (!strncasecmp(hdr, "content-length:", 15)) {
	      char c = hdr[l];
	      hdr[l] = 0;
	      clen = req->clen = atoi(hdr+15);
	      log_dbg("Detected Content Length %d", req->clen);
	      hdr[l] = c;
	    } else if (!strncasecmp(hdr, "content-type:", 13)) {
	      if (strstr(hdr, "text/html")) {
		req->html = 1;
	      }
	    } else if (strcasestr(hdr, "content-encoding: gzip")) {
	      req->gzip = 1;
	    } else if (strcasestr(hdr, "transfer-encoding:") && 
		       strstr(hdr,"chunked")) {
	      req->chunked = 1;
	    }
	    
	    hdr += l + 2;
	    if (!p) break;
	  }

	  hdr = (char *)req->hbuf->data;
	  
	  while (hdr && *hdr) {
	    int l;
	    int skip = 0;
	    
	    p = strstr(hdr, "\r\n");
	    
	    if (p == hdr) {
	      break;
	    } else if (p) {
	      l = (p - hdr);
	    } else {
	      l = (eoh - hdr);
	    }
	    
	    if (req->html) {
	      if (clen && !strncasecmp(hdr, "content-length:", 15)) {
		char tmp[128];
		if (inject) clen += inject->slen;
		safe_snprintf(tmp, sizeof(tmp), "Content-Length: %d\r\n", clen);
		bcatcstr(newhdr, tmp);
		skip = 1;
	      } else if (!strncasecmp(hdr, "connection:", 11)) {
		skip = 1;
	      } else if (!strncasecmp(hdr, "accept-ranges:", 14)) {
		skip = 1;
	      }
	    }
	    
	    log_dbg("Resp Header [%d] %.*s%s", 
		    l, l, hdr, skip ? " [Skipped]" : "");
	    
	    if (!skip) {
	      bcatblk(newhdr, hdr, l + 2);
	    }
	    
	    hdr += l + 2;
	    if (!p) break;
	  }

	  bcatcstr(newhdr, "Connection: close\r\n");
	
	  /* process headers */
	  /* Is HTML */
	  /* Check content-encoding chunked */
	  /* Adjust content-length */
	  
	  bcatblk(newhdr, newline, 2);
	  
	  if (req->html) {
	    if (req->chunked) {
	      char tmp[56];
	      safe_snprintf(tmp, sizeof(tmp), "%x\r\n", 
			    inject->slen);
	      bcatcstr(newhdr, tmp);
	    }
	    bconcat(newhdr, inject);
	    if (req->chunked) {
	      bcatblk(newhdr, newline, 2);
	    }
	  }
	}

	bcatblk(newhdr, eoh + 4, req->hbuf->slen - header_len - 4);
	if (req->clen > 0) /* adjust clen */
	  req->clen -= (req->hbuf->slen - header_len - 4);
	redir_cli_write(req, newhdr->data, newhdr->slen);
	req->headers = 1;
	bdestroy(newhdr);
      }
    } else {
#endif

      redir_cli_write(req, bb, r);
      if (req->clen > 0)
	req->clen -= r;

#ifdef ENABLE_REDIRINJECT
    }
#endif
  }
  /*log_dbg("leaving redir_conn_read()");*/
  return 0;
}
Exemple #8
0
int Connection_read_wspacket(Connection *conn)
{
    bstring payload=NULL;

    uint8_t *dataU=NULL;
    char *data = IOBuf_start(conn->iob);
    int avail = IOBuf_avail(conn->iob);
    int64_t packet_length=-1;
    int smaller_packet_length;
    int header_length;
    char key[4];
    int i;
    int data_length;
    int tries = 0;
    int rc=0;
    int fin;
    int inprogFlags=0;
    int isControl;
    int flags;

again:
    dataU=NULL;
    data = IOBuf_start(conn->iob);
    avail = IOBuf_avail(conn->iob);
    packet_length=-1;
    smaller_packet_length=0;
    header_length=0;
    i=0;
    data_length=0;
    tries = 0;
    rc=0;
    fin=0;

    for(tries = 0; packet_length == -1 && tries < 8*CLIENT_READ_RETRIES; tries++) {
        if(avail > 0) {
            packet_length = Websocket_packet_length((uint8_t *)data, avail);
        }

        if(packet_length == -1) {
            data = IOBuf_read_some(conn->iob, &avail);
            check_debug(!IOBuf_closed(conn->iob), "Client closed during read.");
        }
    }
    check(packet_length > 0,"Error receiving websocket packet header.")

    check_debug(packet_length <= INT_MAX,"Websocket packet longer than MAXINT.");
    /* TODO properly terminate WS connection */

    smaller_packet_length = (int)packet_length;
    
    /* TODO check for maximum length */

    header_length=Websocket_header_length((uint8_t *) data, avail);
    data_length=smaller_packet_length-header_length;
    dataU = (uint8_t *)IOBuf_read_all(conn->iob,header_length,8*CLIENT_READ_RETRIES);
    memcpy(key,dataU+header_length-4,4);

    flags=dataU[0];
    if (payload==NULL) {
        inprogFlags=flags;
    }
    

    fin=(WS_fin(dataU));
    isControl=(WS_is_control(dataU));

{
    const char *error=WS_validate_packet(dataU,payload!=NULL);
    check(error==NULL,"%s",error);
}

    dataU = (uint8_t *)IOBuf_read_all(conn->iob,data_length, 8*CLIENT_READ_RETRIES);
    check(dataU != NULL, "Client closed the connection during websocket packet.");

    for(i=0;i<data_length;++i) {
        dataU[i]^=key[i%4];
    }

    if(isControl) /* Control frames get sent right-away */
    {
            Request_set(conn->req,bfromcstr("FLAGS"),bformat("0x%X",flags|0x80),1);
            rc = Connection_send_to_handler(conn, conn->handler, (void *)dataU,data_length);
            check_debug(rc == 0, "Failed to deliver to the handler.");
    }
    else {
        if(fin) {
            Request_set(conn->req,bfromcstr("FLAGS"),bformat("0x%X",inprogFlags|0x80),1);
        }
        if (payload == NULL) {
            if (fin) {
                rc = Connection_send_to_handler(conn, conn->handler, (void *)dataU,data_length);
                check_debug(rc == 0, "Failed to deliver to the handler.");
            }
            else {
                payload = blk2bstr(dataU,data_length);
                check(payload != NULL,"Allocation failed");
            }
        } else {
            check(BSTR_OK == bcatblk(payload,dataU,data_length), "Concatenation failed");
            if (fin) {
                rc = Connection_send_to_handler(conn, conn->handler, bdata(payload),blength(payload));
                check_debug(rc == 0, "Failed to deliver to the handler.");
                bdestroy(payload);
                payload=NULL;
            }
        }
    }
    if (payload != NULL) {
        goto again;
    }


    return packet_length;

error:
    bdestroy(payload);
    return -1;

}
Exemple #9
0
static size_t save_incoming_data(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    bcatblk(userdata, ptr, size * nmemb);
    return size * nmemb;
}