Ejemplo n.º 1
0
static int mpoa_egress_cache_purge_reply( uint8_t * buff ){
  int pos = 0;
  struct nhrp_fixed_h *fixed = (struct nhrp_fixed_h *)buff;
  struct nhrp_common_h *common;
  struct nhrp_cie *cie;
  struct extension_values values;
  struct k_message msg;
  memset(&values, 0, sizeof(struct extension_values));
  memset(&msg,0,sizeof(struct k_message));
  pos += sizeof(struct nhrp_fixed_h);
  common = (struct nhrp_common_h*)(buff + pos);
  if(!check_incoming(ntohl(common->request_ID), MPOA_EGRESS_CACHE_PURGE_REQUEST))
    return -1;
  pos += sizeof(struct nhrp_common_h);
  cie = (struct nhrp_cie *)(buff + pos);
  msg.ip_mask = calculate_ip_mask(cie->prefix_length);
  if(fixed->ar_extoff)
    parse_extensions(buff + ntohs(fixed->ar_extoff),&values);
  else {
    printf("mpcd: p_recogn.c: warning: ");
    printf("no extensions in MPOA Egress Cache Purge Reply\n");
    return -1;
  }
  if (values.dll_header_present == 0) {
    printf("mpcd: p_recogn.c: warning: ");
    printf("DLL Header Extension missing in MPOA Egress Cache Purge Reply\n");
    return -1;
  }
  msg.content.eg_info.cache_id = values.dll_ext.cache_id;
  msg.type = EGRESS_PURGE_RCVD;
  memcpy(msg.MPS_ctrl,mpc_control.MPS_CTRL_ATM_ADDR,ATM_ESA_LEN);
  return send_to_kernel(&msg);
}
Ejemplo n.º 2
0
static int mpoa_trigger( uint8_t * buff ){
  int pos = 0;
  struct k_message msg;
  struct nhrp_common_h *common;
  struct extension_values values;
  struct nhrp_fixed_h *fixed = (struct nhrp_fixed_h*)buff;
  memset(&values, 0, sizeof(struct extension_values));
  pos += sizeof(struct nhrp_fixed_h);
  common = (struct nhrp_common_h *)(buff + pos);
  pos += sizeof(struct nhrp_common_h);
  memset(&msg,0,sizeof(struct k_message));
  if(ntohs(fixed->ar_extoff)) {
      printf("mpcd: p_recogn.c: mpoa_trigger: ar$extoff in Fixed Header != 0\n" );
      parse_extensions(buff+ntohs(fixed->ar_extoff),&values);
  }
  if(!common->dst_proto_len){
    printf("mpcd: p_recogn.c: mpoa_trigger: no destination ip to trigger! \n");
    return -1;
  }
  if(common->src_proto_len)
    msg.content.in_info.in_dst_ip = common->dst_protocol_address;
  /* 
   * If src_proto_len == 0 dst_protocol_address is found in "place"
   * of dst_ptocol_address.
   */
  else
    msg.content.in_info.in_dst_ip = common->src_protocol_address;
  memcpy(msg.MPS_ctrl,mpc_control.MPS_CTRL_ATM_ADDR,ATM_ESA_LEN);
  msg.type = MPOA_TRIGGER_RCVD;
  send_to_kernel(&msg);
  return 1;
}
Ejemplo n.º 3
0
static int nhrp_purge_request(uint8_t *buff){
  int pos = 0;
  int cie_limit = 0;
  uint32_t ip_mask;
  uint8_t  eg_MPC_data_ATM_addr[ATM_ESA_LEN];
  uint32_t eg_MPS_ip_addr;
  uint32_t purge_ip;
  struct k_message msg;
  struct extension_values values;
  struct nhrp_common_h_no_ip *common_no_ip;
  struct nhrp_cie_no_nbma *cie_no_nbma;
  struct nhrp_cie *cie;
  struct nhrp_fixed_h *fixed = (struct nhrp_fixed_h *)buff;
  memset(&msg,0,sizeof(struct k_message));
  if(ntohs(fixed->ar_extoff)){
    cie_limit = ntohs(fixed->ar_extoff);
  }
  else{
    cie_limit = ntohs(fixed->ar_pktsz);
  }
  pos += sizeof(struct nhrp_fixed_h);
  common_no_ip = (struct nhrp_common_h_no_ip *)(buff + pos);
  memcpy(eg_MPC_data_ATM_addr, common_no_ip->src_nbma_address
	 ,ATM_ESA_LEN);
  pos += sizeof(struct nhrp_common_h_no_ip);
  if(common_no_ip->src_proto_len == PROTO_LEN_IP){
    eg_MPS_ip_addr = ntohl((uint32_t)*(buff + pos));
    pos += sizeof(eg_MPS_ip_addr);
  }
  if(common_no_ip->dst_proto_len == PROTO_LEN_IP)
    pos += sizeof(uint32_t);
  
  while(pos < cie_limit){
    cie = (struct nhrp_cie *)(buff + pos);
    if(cie->cli_addr_tl){
      purge_ip = cie->cli_protocol_address;
      ip_mask = calculate_ip_mask(cie->prefix_length);
      pos += sizeof(struct nhrp_cie);
    }
    else{
      cie_no_nbma = (struct nhrp_cie_no_nbma *)(buff + pos);
      purge_ip = cie_no_nbma->cli_protocol_address;
      ip_mask = calculate_ip_mask(cie_no_nbma->prefix_length);
      pos += sizeof(struct nhrp_cie_no_nbma);
    }
    msg.type = INGRESS_PURGE_RCVD;
    msg.ip_mask = ip_mask;
    msg.content.in_info.in_dst_ip = purge_ip;
    memcpy(msg.MPS_ctrl, mpc_control.MPS_CTRL_ATM_ADDR, ATM_ESA_LEN);
    send_to_kernel(&msg);
  }

  /* we really do not do anything with the extensions, just parse them */
  if(ntohs(fixed->ar_extoff)){
    pos += parse_extensions(buff + ntohs(fixed->ar_extoff), &values);
  }
  if(!(ntohs(common_no_ip->flags) & FLAG_N ))
    return send_purge_reply(buff);  
  return 1;
}
Ejemplo n.º 4
0
static int mpoa_resolution_reply( uint8_t * buff ){
  int pos = 0;
  struct k_message msg;
  struct extension_values values;
  struct nhrp_common_h *common;
  struct nhrp_cie *cie;
  struct nhrp_fixed_h *fixed = (struct nhrp_fixed_h*)buff;
  memset(&values, 0, sizeof(struct extension_values));
  memset(&msg,0,sizeof(struct k_message));
  pos += sizeof(struct nhrp_fixed_h);
  common = (struct nhrp_common_h*)(buff + pos);
  if(!check_incoming(ntohl(common->request_ID),MPOA_RESOLUTION_REQUEST))
    return -1;
  pos += sizeof(struct nhrp_common_h);
  cie = (struct nhrp_cie*)(buff + pos);
  if(cie->code){
    print_cie_code(cie->code);
    return -1;
  }
  msg.content.in_info.holding_time = ntohs(cie->holding_time);
  if(fixed->ar_extoff)
    pos += parse_extensions(buff + ntohs(fixed->ar_extoff), &values);
  if (values.egress_cache_tag_ext_present == 0) {
          printf("mpcd: p_recogn.c: warning: ");
          printf("received MPOA Resolution Reply ");
          printf("with no Egress Cache Tag Extension\n");
  }
  if(values.tag_present && values.tag == 0) {
          printf("mpcd: p_recogn.c: warning: ");
          printf("received MPOA Resolution Reply ");
          printf("with Egress Cache Tag Extension where tag == 0\n");
          values.tag_present = 0;
  }
  if(values.tag_present){
    msg.content.in_info.tag = values.tag;
  }
  msg.type = MPOA_RES_REPLY_RCVD;
  msg.content.in_info.in_dst_ip  = common->dst_protocol_address;
  memcpy(msg.content.in_info.eg_MPC_ATM_addr,cie->cli_nbma_address,ATM_ESA_LEN);
  memcpy(msg.MPS_ctrl,mpc_control.MPS_CTRL_ATM_ADDR, ATM_ESA_LEN);
  if(values.service_category_present)
    msg.qos.txtp.traffic_class = service_category_to_traff_class(values.service_category);
  else
    msg.qos.txtp.traffic_class = ATM_UBR;
  send_to_kernel(&msg);
  keep_alive_sm_running = 1;
  return MPOA_RESOLUTION_REPLY;
}
Ejemplo n.º 5
0
static int mpoa_cache_imposition_request( uint8_t * buff ){
  int pos = 0; 
  struct k_message msg;
  struct nhrp_fixed_h * fixed = (struct nhrp_fixed_h *)buff;
  struct nhrp_common_h * common;
  struct nhrp_cie_short * cie_short;
  struct extension_values values;
  pos += sizeof( struct nhrp_fixed_h );
  memset(&values, 0, sizeof(struct extension_values));
  memset(&msg,0,sizeof(struct k_message));
  common = (struct nhrp_common_h *)(buff + pos);
  memcpy(msg.content.eg_info.in_MPC_data_ATM_addr, 
	 common->src_nbma_address ,ATM_ESA_LEN);
  pos += sizeof(struct nhrp_common_h);
  cie_short = (struct nhrp_cie_short *)(buff + pos);
  msg.content.eg_info.holding_time = ntohs(cie_short->holding_time);
  msg.ip_mask = calculate_ip_mask(cie_short->prefix_length);
  if(ntohs(fixed->ar_extoff)){
    pos += parse_extensions(buff + ntohs(fixed->ar_extoff), &values);
  }
  if(ntohs(cie_short->holding_time)) {
      if (values.dll_header_present == 0) {
          printf("mpcd: p_recogn.c: warning: ");
          printf("holding time non-zero but MPOA DLL Header Extension missing\n");
          return 0;
      }
      keep_alive_sm_running = 1;
  }
  msg.content.eg_info.cache_id = values.dll_ext.cache_id;
  msg.content.eg_info.DH_length = values.dll_ext.dh_length;
  memcpy(msg.content.eg_info.DLL_header, values.dll_ext.dll_header, msg.content.eg_info.DH_length);
  if(common->src_proto_len)
    msg.content.eg_info.mps_ip = common->src_protocol_address;
  if(common->dst_proto_len)
    msg.content.eg_info.eg_dst_ip = common->dst_protocol_address;
  msg.content.eg_info.tag = new_tag(msg.content.eg_info.cache_id);
  memcpy(msg.MPS_ctrl, mpc_control.MPS_CTRL_ATM_ADDR, ATM_ESA_LEN);
  msg.type = CACHE_IMPOS_RCVD;
  send_to_kernel(&msg);
  return send_cache_imposition_reply( buff, msg.content.eg_info.tag,
				      0x00, 0, MTU_DEFAULT, 
				      common->src_nbma_address );
}
Ejemplo n.º 6
0
static int mpoa_keep_alive(uint8_t *buff){
  int pos = 0;
  uint32_t sequence_nmbr;
  struct nhrp_fixed_h *fixed = (struct nhrp_fixed_h *)buff;
  struct extension_values values;
  struct nhrp_common_h_no_ip *common;
  memset(&values, 0, sizeof(struct extension_values));
  pos += sizeof(struct nhrp_fixed_h);
  common = (struct nhrp_common_h_no_ip *)(buff + pos); 
  sequence_nmbr = ntohl(common->request_ID);
  if(memcmp(common->src_nbma_address,mpc_control.MPS_CTRL_ATM_ADDR,ATM_ESA_LEN)){
    printf("mpcd: p_recogn.c: new MPS! \n" );
    return -1;
  }
  if(ntohs(fixed->ar_extoff)){
    parse_extensions(buff + ntohs(fixed->ar_extoff),&values);
  }
  /* if extensions were missing sequence_nmbr == 0  => MPS Death */
  keep_alive_sm(values.keep_alive_lifetime, sequence_nmbr);
  return 1;
}
Ejemplo n.º 7
0
static int
doit(const char *filename, int mergep)
{
    krb5_error_code ret;
    FILE *f;
    char s[8192]; /* XXX should fix this properly */
    char *p;
    int line;
    int flags = O_RDWR;
    struct entry e;
    hdb_entry_ex ent;
    HDB *db = _kadm5_s_get_db(kadm_handle);

    f = fopen(filename, "r");
    if(f == NULL){
	krb5_warn(context, errno, "fopen(%s)", filename);
	return 1;
    }
    ret = kadm5_log_truncate (kadm_handle);
    if (ret) {
	fclose (f);
	krb5_warn(context, ret, "kadm5_log_truncate");
	return 1;
    }

    if(!mergep)
	flags |= O_CREAT | O_TRUNC;
    ret = db->hdb_open(context, db, flags, 0600);
    if(ret){
	krb5_warn(context, ret, "hdb_open");
	fclose(f);
	return 1;
    }
    line = 0;
    ret = 0;
    while(fgets(s, sizeof(s), f) != NULL) {
	ret = 0;
	line++;

	p = s;
	while (isspace((unsigned char)*p))
	    p++;

	e.principal = p;
	for(p = s; *p; p++){
	    if(*p == '\\')
		p++;
	    else if(isspace((unsigned char)*p)) {
		*p = 0;
		break;
	    }
	}
	p = skip_next(p);
	
	e.key = p;
	p = skip_next(p);

	e.created = p;
	p = skip_next(p);

	e.modified = p;
	p = skip_next(p);

	e.valid_start = p;
	p = skip_next(p);

	e.valid_end = p;
	p = skip_next(p);

	e.pw_end = p;
	p = skip_next(p);

	e.max_life = p;
	p = skip_next(p);

	e.max_renew = p;
	p = skip_next(p);

	e.flags = p;
	p = skip_next(p);

	e.generation = p;
	p = skip_next(p);

	e.extensions = p;
	p = skip_next(p);

	memset(&ent, 0, sizeof(ent));
	ret = krb5_parse_name(context, e.principal, &ent.entry.principal);
	if(ret) {
	    fprintf(stderr, "%s:%d:%s (%s)\n", 
		    filename, 
		    line,
		    krb5_get_err_text(context, ret),
		    e.principal);
	    continue;
	}
	
	if (parse_keys(&ent.entry, e.key)) {
	    fprintf (stderr, "%s:%d:error parsing keys (%s)\n",
		     filename, line, e.key);
	    hdb_free_entry (context, &ent);
	    continue;
	}
	
	if (parse_event(&ent.entry.created_by, e.created) == -1) {
	    fprintf (stderr, "%s:%d:error parsing created event (%s)\n",
		     filename, line, e.created);
	    hdb_free_entry (context, &ent);
	    continue;
	}
	if (parse_event_alloc (&ent.entry.modified_by, e.modified) == -1) {
	    fprintf (stderr, "%s:%d:error parsing event (%s)\n",
		     filename, line, e.modified);
	    hdb_free_entry (context, &ent);
	    continue;
	}
	if (parse_time_string_alloc (&ent.entry.valid_start, e.valid_start) == -1) {
	    fprintf (stderr, "%s:%d:error parsing time (%s)\n",
		     filename, line, e.valid_start);
	    hdb_free_entry (context, &ent);
	    continue;
	}
	if (parse_time_string_alloc (&ent.entry.valid_end,   e.valid_end) == -1) {
	    fprintf (stderr, "%s:%d:error parsing time (%s)\n",
		     filename, line, e.valid_end);
	    hdb_free_entry (context, &ent);
	    continue;
	}
	if (parse_time_string_alloc (&ent.entry.pw_end,      e.pw_end) == -1) {
	    fprintf (stderr, "%s:%d:error parsing time (%s)\n",
		     filename, line, e.pw_end);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	if (parse_integer_alloc (&ent.entry.max_life,  e.max_life) == -1) {
	    fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
		     filename, line, e.max_life);
	    hdb_free_entry (context, &ent);
	    continue;

	}
	if (parse_integer_alloc (&ent.entry.max_renew, e.max_renew) == -1) {
	    fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
		     filename, line, e.max_renew);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	if (parse_hdbflags2int (&ent.entry.flags, e.flags) != 1) {
	    fprintf (stderr, "%s:%d:error parsing flags (%s)\n",
		     filename, line, e.flags);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	if(parse_generation(e.generation, &ent.entry.generation) == -1) {
	    fprintf (stderr, "%s:%d:error parsing generation (%s)\n",
		     filename, line, e.generation);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	if(parse_extensions(e.extensions, &ent.entry.extensions) == -1) {
	    fprintf (stderr, "%s:%d:error parsing extension (%s)\n",
		     filename, line, e.extensions);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	ret = db->hdb_store(context, db, HDB_F_REPLACE, &ent);
	hdb_free_entry (context, &ent);
	if (ret) {
	    krb5_warn(context, ret, "db_store");
	    break;
	}
    }
    db->hdb_close(context, db);
    fclose(f);
    return ret != 0;
}
Ejemplo n.º 8
0
void resource_manager::process_file(int rank, FILE *fp, const char *filename,
				    FILE *outfp)
{
  // If none of these comments appear in the header section, and we are
  // just analyzing the file (ie outfp is 0), then we can return immediately.
  static const char *header_comment_table[] = {
    "DocumentNeededResources:",
    "DocumentSuppliedResources:",
    "DocumentNeededFonts:",
    "DocumentSuppliedFonts:",
    "DocumentNeededProcSets:",
    "DocumentSuppliedProcSets:",
    "DocumentNeededFiles:",
    "DocumentSuppliedFiles:",
  };
  
  const int NHEADER_COMMENTS = sizeof(header_comment_table)
			       / sizeof(header_comment_table[0]);
  struct comment_info {
    const char *name;
    int (resource_manager::*proc)(const char *, int, FILE *, FILE *);
  };

  static comment_info comment_table[] = {
    { "BeginResource:", &resource_manager::do_begin_resource },
    { "IncludeResource:", &resource_manager::do_include_resource },
    { "BeginDocument:", &resource_manager::do_begin_document },
    { "IncludeDocument:", &resource_manager::do_include_document },
    { "BeginProcSet:", &resource_manager::do_begin_procset },
    { "IncludeProcSet:", &resource_manager::do_include_procset },
    { "BeginFont:", &resource_manager::do_begin_font },
    { "IncludeFont:", &resource_manager::do_include_font },
    { "BeginFile:", &resource_manager::do_begin_file },
    { "IncludeFile:", &resource_manager::do_include_file },
    { "EndProcSet", &resource_manager::change_to_end_resource },
    { "EndFont", &resource_manager::change_to_end_resource },
    { "EndFile", &resource_manager::change_to_end_resource },
    { "BeginPreview:", &resource_manager::do_begin_preview },
    { "BeginData:", &resource_manager::do_begin_data },
    { "BeginBinary:", &resource_manager::do_begin_binary },
  };
  
  const int NCOMMENTS = sizeof(comment_table)/sizeof(comment_table[0]);
  string buf;
  int saved_lineno = current_lineno;
  const char *saved_filename = current_filename;
  current_filename = filename;
  current_lineno = 0;
  if (!ps_get_line(buf, fp)) {
    current_filename = saved_filename;
    current_lineno = saved_lineno;
    return;
  }
  if ((size_t)buf.length() < sizeof(PS_MAGIC)
      || memcmp(buf.contents(), PS_MAGIC, sizeof(PS_MAGIC) - 1) != 0) {
    if (outfp) {
      do {
	if (!(broken_flags & STRIP_PERCENT_BANG)
	    || buf[0] != '%' || buf[1] != '!')
	  fputs(buf.contents(), outfp);
      } while (ps_get_line(buf, fp));
    }
  }
  else {
    if (!(broken_flags & STRIP_PERCENT_BANG) && outfp)
      fputs(buf.contents(), outfp);
    int in_header = 1;
    int interesting = 0;
    int had_extensions_comment = 0;
    int had_language_level_comment = 0;
    for (;;) {
      if (!ps_get_line(buf, fp))
	break;
      int copy_this_line = 1;
      if (buf[0] == '%') {
	if (buf[1] == '%') {
	  const char *ptr;
	  int i;
	  for (i = 0; i < NCOMMENTS; i++)
	    if ((ptr = matches_comment(buf, comment_table[i].name))) {
	      copy_this_line
		= (this->*(comment_table[i].proc))(ptr, rank, fp, outfp);
	      break;
	    }
	  if (i >= NCOMMENTS && in_header) {
	    if ((ptr = matches_comment(buf, "EndComments")))
	      in_header = 0;
	    else if (!had_extensions_comment
		     && (ptr = matches_comment(buf, "Extensions:"))) {
	      extensions |= parse_extensions(ptr);
	      // XXX handle possibility that next line is %%+
	      had_extensions_comment = 1;
	    }
	    else if (!had_language_level_comment
		     && (ptr = matches_comment(buf, "LanguageLevel:"))) {
	      unsigned ll;
	      if (read_uint_arg(&ptr, &ll) && ll > language_level)
		language_level = ll;
	      had_language_level_comment = 1;
	    }
	    else {
	      for (i = 0; i < NHEADER_COMMENTS; i++)
		if (matches_comment(buf, header_comment_table[i])) {
		  interesting = 1;
		  break;
		}
	    }
	  }
	  if ((broken_flags & STRIP_STRUCTURE_COMMENTS)
	      && (matches_comment(buf, "EndProlog")
		  || matches_comment(buf, "Page:")
		  || matches_comment(buf, "Trailer")))
	    copy_this_line = 0;
	}
	else if (buf[1] == '!') {
	  if (broken_flags & STRIP_PERCENT_BANG)
	    copy_this_line = 0;
	}
      }
      else
	in_header = 0;
      if (!outfp && !in_header && !interesting)
	break;
      if (copy_this_line && outfp)
	fputs(buf.contents(), outfp);
    }
  }
  current_filename = saved_filename;
  current_lineno = saved_lineno;
}
Ejemplo n.º 9
0
/* Parse a TLS packet for the Server Name Indication extension in the client
 * hello handshake, returning the first servername found (pointer to static
 * array)
 *
 * Returns:
 *  >=0  - length of the hostname and updates *hostname
 *         caller is responsible for freeing *hostname
 *  -1   - Incomplete request
 *  -2   - No Host header included in this request
 *  -3   - Invalid hostname pointer
 *  -4   - malloc failure
 *  < -4 - Invalid TLS client hello
 */
static int
parse_tls_header(const char *data, size_t data_len, char **hostname) {
    char tls_content_type;
    char tls_version_major;
    char tls_version_minor;
    size_t pos = TLS_HEADER_LEN;
    size_t len;

    if (hostname == NULL)
        return -3;

    /* Check that our TCP payload is at least large enough for a TLS header */
    if (data_len < TLS_HEADER_LEN)
        return -1;

    tls_content_type = data[0];
    if (tls_content_type != TLS_HANDSHAKE_CONTENT_TYPE) {
        debug("Request did not begin with TLS handshake.");
        return -5;
    }

    tls_version_major = data[1];
    tls_version_minor = data[2];
    if (tls_version_major < 3) {
        debug("Received SSL %d.%d handshake which cannot be parsed.",
              tls_version_major, tls_version_minor);

        return -2;
    }

    /* TLS record length */
    len = ((unsigned char)data[3] << 8) +
        (unsigned char)data[4] + TLS_HEADER_LEN;
    data_len = MIN(data_len, len);

    /* Check we received entire TLS record length */
    if (data_len < len)
        return -1;

    /*
     * Handshake
     */
    if (pos + 1 > data_len) {
        return -5;
    }
    if (data[pos] != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) {
        debug("Not a client hello");

        return -5;
    }

    /* Skip past fixed length records:
       1	Handshake Type
       3	Length
       2	Version (again)
       32	Random
       to	Session ID Length
     */
    pos += 38;

    /* Session ID */
    if (pos + 1 > data_len)
        return -5;
    len = (unsigned char)data[pos];
    pos += 1 + len;

    /* Cipher Suites */
    if (pos + 2 > data_len)
        return -5;
    len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
    pos += 2 + len;

    /* Compression Methods */
    if (pos + 1 > data_len)
        return -5;
    len = (unsigned char)data[pos];
    pos += 1 + len;

    if (pos == data_len && tls_version_major == 3 && tls_version_minor == 0) {
        debug("Received SSL 3.0 handshake without extensions");
        return -2;
    }

    /* Extensions */
    if (pos + 2 > data_len)
        return -5;
    len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1];
    pos += 2;

    if (pos + len > data_len)
        return -5;
    return parse_extensions(data + pos, len, hostname);
}
Ejemplo n.º 10
0
static int
doit(const char *filename, int mergep)
{
    krb5_error_code ret = 0;
    FILE *f;
    char s[8192]; /* XXX should fix this properly */
    char *p;
    int line;
    int flags = O_RDWR;
    struct entry e;
    hdb_entry_ex ent;
    HDB *db = _kadm5_s_get_db(kadm_handle);

    f = fopen(filename, "r");
    if(f == NULL){
	krb5_warn(context, errno, "fopen(%s)", filename);
	return 1;
    }
    /*
     * We don't have a version number in the dump, so we don't know which iprop
     * log entries to keep, if any.  We throw the log away.
     *
     * We could merge the ipropd-master/slave dump/load here as an option, in
     * which case we would first load the dump.
     *
     * If we're merging, first recover unconfirmed records in the existing log.
     */
    if (mergep)
        ret = kadm5_log_init(kadm_handle);
    if (ret == 0)
        ret = kadm5_log_reinit(kadm_handle, 0);
    if (ret) {
	fclose (f);
	krb5_warn(context, ret, "kadm5_log_reinit");
	return 1;
    }

    if(!mergep)
	flags |= O_CREAT | O_TRUNC;
    ret = db->hdb_open(context, db, flags, 0600);
    if(ret){
	krb5_warn(context, ret, "hdb_open");
	fclose(f);
	return 1;
    }
    line = 0;
    ret = 0;
    while(fgets(s, sizeof(s), f) != NULL) {
	line++;

	p = s;
	while (isspace((unsigned char)*p))
	    p++;

	e.principal = p;
	for(p = s; *p; p++){
	    if(*p == '\\')
		p++;
	    else if(isspace((unsigned char)*p)) {
		*p = 0;
		break;
	    }
	}
	p = skip_next(p);

	e.key = p;
	p = skip_next(p);

	e.created = p;
	p = skip_next(p);

	e.modified = p;
	p = skip_next(p);

	e.valid_start = p;
	p = skip_next(p);

	e.valid_end = p;
	p = skip_next(p);

	e.pw_end = p;
	p = skip_next(p);

	e.max_life = p;
	p = skip_next(p);

	e.max_renew = p;
	p = skip_next(p);

	e.flags = p;
	p = skip_next(p);

	e.generation = p;
	p = skip_next(p);

	e.extensions = p;
	skip_next(p);

	memset(&ent, 0, sizeof(ent));
	ret = krb5_parse_name(context, e.principal, &ent.entry.principal);
	if(ret) {
	    const char *msg = krb5_get_error_message(context, ret);
	    fprintf(stderr, "%s:%d:%s (%s)\n",
		    filename, line, msg, e.principal);
	    krb5_free_error_message(context, msg);
	    continue;
	}

	if (parse_keys(&ent.entry, e.key)) {
	    fprintf (stderr, "%s:%d:error parsing keys (%s)\n",
		     filename, line, e.key);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	if (parse_event(&ent.entry.created_by, e.created) == -1) {
	    fprintf (stderr, "%s:%d:error parsing created event (%s)\n",
		     filename, line, e.created);
	    hdb_free_entry (context, &ent);
	    continue;
	}
	if (parse_event_alloc (&ent.entry.modified_by, e.modified) == -1) {
	    fprintf (stderr, "%s:%d:error parsing event (%s)\n",
		     filename, line, e.modified);
	    hdb_free_entry (context, &ent);
	    continue;
	}
	if (parse_time_string_alloc (&ent.entry.valid_start, e.valid_start) == -1) {
	    fprintf (stderr, "%s:%d:error parsing time (%s)\n",
		     filename, line, e.valid_start);
	    hdb_free_entry (context, &ent);
	    continue;
	}
	if (parse_time_string_alloc (&ent.entry.valid_end,   e.valid_end) == -1) {
	    fprintf (stderr, "%s:%d:error parsing time (%s)\n",
		     filename, line, e.valid_end);
	    hdb_free_entry (context, &ent);
	    continue;
	}
	if (parse_time_string_alloc (&ent.entry.pw_end,      e.pw_end) == -1) {
	    fprintf (stderr, "%s:%d:error parsing time (%s)\n",
		     filename, line, e.pw_end);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	if (parse_integer_alloc (&ent.entry.max_life,  e.max_life) == -1) {
	    fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
		     filename, line, e.max_life);
	    hdb_free_entry (context, &ent);
	    continue;

	}
	if (parse_integer_alloc (&ent.entry.max_renew, e.max_renew) == -1) {
	    fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n",
		     filename, line, e.max_renew);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	if (parse_hdbflags2int (&ent.entry.flags, e.flags) != 1) {
	    fprintf (stderr, "%s:%d:error parsing flags (%s)\n",
		     filename, line, e.flags);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	if(parse_generation(e.generation, &ent.entry.generation) == -1) {
	    fprintf (stderr, "%s:%d:error parsing generation (%s)\n",
		     filename, line, e.generation);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	if(parse_extensions(e.extensions, &ent.entry.extensions) == -1) {
	    fprintf (stderr, "%s:%d:error parsing extension (%s)\n",
		     filename, line, e.extensions);
	    hdb_free_entry (context, &ent);
	    continue;
	}

	ret = db->hdb_store(context, db, HDB_F_REPLACE, &ent);
	hdb_free_entry (context, &ent);
	if (ret) {
	    krb5_warn(context, ret, "db_store");
	    break;
	}
    }
    (void) kadm5_log_end(kadm_handle);
    db->hdb_close(context, db);
    fclose(f);
    return ret != 0;
}
Ejemplo n.º 11
0
HIDDEN int ws_start_channel(struct transaction_t *txn, const char *protocol,
                            int (*data_cb)(struct buf *inbuf, struct buf *outbuf,
                                           struct buf *logbuf, void **rock))
{
    int r;
    const char **hdr, *accept = NULL;
    wslay_event_context_ptr ev;
    struct ws_context *ctx;
    struct wslay_event_callbacks callbacks = {
        recv_cb,
        send_cb,
        NULL,
        NULL,
        NULL,
        NULL,
        on_msg_recv_cb
    };

    /* Check for supported WebSocket version */
    hdr = spool_getheader(txn->req_hdrs, "Sec-WebSocket-Version");
    if (!hdr) {
        txn->error.desc = "Missing WebSocket version";
        return HTTP_BAD_REQUEST;
    }
    else if (hdr[1]) {
        txn->error.desc = "Multiple WebSocket versions";
        return HTTP_BAD_REQUEST;
    }
    else if (strcmp(hdr[0], WS_VERSION)) {
        txn->error.desc = "Unsupported WebSocket version";
        return HTTP_UPGRADE;
    }

    if (protocol) {
        /* Check for supported WebSocket subprotocol */
        int i, found = 0;

        hdr = spool_getheader(txn->req_hdrs, "Sec-WebSocket-Protocol");
        if (!hdr) {
            txn->error.desc = "Missing WebSocket protocol";
            return HTTP_BAD_REQUEST;
        }

        for (i = 0; !found && hdr[i]; i++) {
            tok_t tok = TOK_INITIALIZER(hdr[i], ",", TOK_TRIMLEFT|TOK_TRIMRIGHT);
            char *token;

            while ((token = tok_next(&tok))) {
                if (!strcmp(token, protocol)) {
                    found = 1;
                    break;
                }
            }
            tok_fini(&tok);
        }
        if (!found) {
            txn->error.desc = "Unsupported WebSocket protocol";
            return HTTP_BAD_REQUEST;
        }
    }

    if (txn->flags.ver == VER_1_1) {
        unsigned char sha1buf[SHA1_DIGEST_LENGTH];

        /* Check for WebSocket client key */
        hdr = spool_getheader(txn->req_hdrs, "Sec-WebSocket-Key");
        if (!hdr) {
            txn->error.desc = "Missing WebSocket client key";
            return HTTP_BAD_REQUEST;
        }
        else if (hdr[1]) {
            txn->error.desc = "Multiple WebSocket client keys";
            return HTTP_BAD_REQUEST;
        }
        else if (strlen(hdr[0]) != WS_CKEY_LEN) {
            txn->error.desc = "Invalid WebSocket client key";
            return HTTP_BAD_REQUEST;
        }

        /* Create WebSocket accept key */
        buf_setcstr(&txn->buf, hdr[0]);
        buf_appendcstr(&txn->buf, WS_GUID);
        xsha1((u_char *) buf_base(&txn->buf), buf_len(&txn->buf), sha1buf);

        buf_ensure(&txn->buf, WS_AKEY_LEN+1);
        accept = buf_base(&txn->buf);

        r = sasl_encode64((char *) sha1buf, SHA1_DIGEST_LENGTH,
                          (char *) accept, WS_AKEY_LEN+1, NULL);
        if (r != SASL_OK) syslog(LOG_WARNING, "sasl_encode64: %d", r);
    }

    /* Create server context */
    r = wslay_event_context_server_init(&ev, &callbacks, txn);
    if (r) {
        syslog(LOG_WARNING,
               "wslay_event_context_init: %s", wslay_strerror(r));
        return HTTP_SERVER_ERROR;
    }

    /* Create channel context */
    ctx = xzmalloc(sizeof(struct ws_context));
    ctx->event = ev;
    ctx->accept = accept;
    ctx->protocol = protocol;
    ctx->data_cb = data_cb;
    txn->ws_ctx = ctx;

    /* Check for supported WebSocket extensions */
    parse_extensions(txn);

    /* Prepare log buffer */

    /* Add client data */
    buf_printf(&ctx->log, "%s", txn->conn->clienthost);
    if (httpd_userid) buf_printf(&ctx->log, " as \"%s\"", httpd_userid);
    if ((hdr = spool_getheader(txn->req_hdrs, "User-Agent"))) {
        buf_printf(&ctx->log, " with \"%s\"", hdr[0]);
        if ((hdr = spool_getheader(txn->req_hdrs, "X-Client")))
            buf_printf(&ctx->log, " by \"%s\"", hdr[0]);
        else if ((hdr = spool_getheader(txn->req_hdrs, "X-Requested-With")))
            buf_printf(&ctx->log, " by \"%s\"", hdr[0]);
    }

    /* Add request-line */
    buf_printf(&ctx->log, "; \"WebSocket/%s via %s\"",
               protocol ? protocol : "echo" , txn->req_line.ver);
    ctx->log_tail = buf_len(&ctx->log);

    /* Tell client that WebSocket negotiation has succeeded */
    if (txn->conn->sess_ctx) {
        /* Treat WS data as chunked response */
        txn->flags.te = TE_CHUNKED;

        response_header(HTTP_OK, txn);

        /* Force the response to the client immediately */
        prot_flush(httpd_out);
    }
    else response_header(HTTP_SWITCH_PROT, txn);

    /* Set connection as non-blocking */
    prot_NONBLOCK(txn->conn->pin);

    /* Don't do telemetry logging in prot layer */
    prot_setlog(txn->conn->pin, PROT_NO_FD);
    prot_setlog(txn->conn->pout, PROT_NO_FD);

    return 0;
}