Example #1
0
/*
 *
 *      query_node_info - collect information from a batch_status and
 *                        put it in a node_info struct for easier access
 *
 *   node - a node returned from a pbs_statnode() call
 *
 * returns a node_info filled with information from node
 *
 */
node_info *query_node_info(struct batch_status *node, server_info *sinfo)
  {
  node_info *ninfo;  /* the new node_info */

  struct attrl *attrp;  /* used to cycle though attribute list */

  if ((ninfo = new_node_info()) == NULL)
    return NULL;

  attrp = node -> attribs;

  ninfo -> name = string_dup(node -> name);

  ninfo -> server = sinfo;

  while (attrp != NULL)
    {
    /* Node State... i.e. offline down free etc */
    if (!strcmp(attrp -> name, ATTR_NODE_state))
      set_node_state(ninfo, attrp -> value);

    /* properties from the servers nodes file */
    else if (!strcmp(attrp -> name, ATTR_NODE_properties))
      ninfo -> properties = break_comma_list(attrp -> value);

    /* the jobs running on the node */
    else if (!strcmp(attrp -> name, ATTR_NODE_jobs))
      ninfo -> jobs = break_comma_list(attrp -> value);

    /* the node type... i.e. timesharing or cluster */
    else if (!strcmp(attrp -> name, ATTR_NODE_ntype))
      set_node_type(ninfo, attrp -> value);

    attrp = attrp -> next;
    }

  return ninfo;
  }
Example #2
0
/**
 * gnutls_priority_init:
 * @priority_cache: is a #gnutls_prioritity_t structure.
 * @priorities: is a string describing priorities
 * @err_pos: In case of an error this will have the position in the string the error occured
 *
 * Sets priorities for the ciphers, key exchange methods, macs and
 * compression methods.
 *
 * The #priorities option allows you to specify a colon
 * separated list of the cipher priorities to enable.
 * Some keywords are defined to provide quick access
 * to common preferences.
 *
 * Unless there is a special need, using "NORMAL" or "NORMAL:%COMPAT" for compatibility 
 * is recommended.
 *
 * "PERFORMANCE" means all the "secure" ciphersuites are enabled,
 * limited to 128 bit ciphers and sorted by terms of speed
 * performance.
 *
 * "NORMAL" means all "secure" ciphersuites. The 256-bit ciphers are
 * included as a fallback only.  The ciphers are sorted by security
 * margin.
 *
 * "PFS" means all "secure" ciphersuites that support perfect forward secrecy. 
 * The 256-bit ciphers are included as a fallback only.  
 * The ciphers are sorted by security margin.
 *
 * "SECURE128" means all "secure" ciphersuites of security level 128-bit
 * or more.
 *
 * "SECURE192" means all "secure" ciphersuites of security level 192-bit
 * or more.
 *
 * "SUITEB128" means all the NSA SuiteB ciphersuites with security level
 * of 128.
 *
 * "SUITEB192" means all the NSA SuiteB ciphersuites with security level
 * of 192.
 *
 * "EXPORT" means all ciphersuites are enabled, including the
 * low-security 40 bit ciphers.
 *
 * "NONE" means nothing is enabled.  This disables even protocols and
 * compression methods.
 *
 * Special keywords are "!", "-" and "+".
 * "!" or "-" appended with an algorithm will remove this algorithm.
 * "+" appended with an algorithm will add this algorithm.
 *
 * Check the GnuTLS manual section "Priority strings" for detailed
 * information.
 *
 * Examples:
 *
 * "NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
 *
 * "NORMAL:-ARCFOUR-128" means normal ciphers except for ARCFOUR-128.
 *
 * "SECURE128:-VERS-SSL3.0:+COMP-DEFLATE" means that only secure ciphers are
 * enabled, SSL3.0 is disabled, and libz compression enabled.
 *
 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1", 
 *
 * "NONE:+VERS-TLS-ALL:+AES-128-CBC:+ECDHE-RSA:+SHA1:+COMP-NULL:+SIGN-RSA-SHA1:+CURVE-SECP256R1", 
 *
 * "SECURE256:+SECURE128",
 *
 * Note that "NORMAL:%COMPAT" is the most compatible mode.
 *
 * Returns: On syntax error %GNUTLS_E_INVALID_REQUEST is returned,
 * %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_priority_init(gnutls_priority_t * priority_cache,
		     const char *priorities, const char **err_pos)
{
	char *broken_list[MAX_ELEMENTS];
	int broken_list_size = 0, i = 0, j;
	char *darg = NULL;
	unsigned ikeyword_set = 0;
	int algo;
	rmadd_func *fn;
	bulk_rmadd_func *bulk_fn;

	*priority_cache =
	    gnutls_calloc(1, sizeof(struct gnutls_priority_st));
	if (*priority_cache == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	if (err_pos)
		*err_pos = priorities;

	/* for now unsafe renegotiation is default on everyone. To be removed
	 * when we make it the default.
	 */
	(*priority_cache)->sr = SR_PARTIAL;
	(*priority_cache)->ssl3_record_version = 1;


	(*priority_cache)->max_empty_records = DEFAULT_MAX_EMPTY_RECORDS;

	if (priorities == NULL)
		priorities = LEVEL_NORMAL;

	darg = gnutls_strdup(priorities);
	if (darg == NULL) {
		gnutls_assert();
		goto error;
	}

	break_comma_list(darg, broken_list, &broken_list_size,
			 MAX_ELEMENTS, ':');
	/* This is our default set of protocol version, certificate types and
	 * compression methods.
	 */
	if (strcasecmp(broken_list[0], LEVEL_NONE) != 0) {
		_set_priority(&(*priority_cache)->protocol,
			      protocol_priority);
		_set_priority(&(*priority_cache)->compression,
			      comp_priority);
		_set_priority(&(*priority_cache)->cert_type,
			      cert_type_priority_default);
		_set_priority(&(*priority_cache)->sign_algo,
			      sign_priority_default);
		_set_priority(&(*priority_cache)->supported_ecc,
			      supported_ecc_normal);
		i = 0;
	} else {
		ikeyword_set = 1;
		i = 1;
	}

	for (; i < broken_list_size; i++) {
		if (check_level(broken_list[i], *priority_cache, ikeyword_set) != 0) {
			ikeyword_set = 1;
			continue;
		} else if (broken_list[i][0] == '!'
			   || broken_list[i][0] == '+'
			   || broken_list[i][0] == '-') {
			if (broken_list[i][0] == '+') {
				fn = prio_add;
				bulk_fn = _add_priority;
			} else {
				fn = prio_remove;
				bulk_fn = _clear_priorities;
			}

			if (broken_list[i][0] == '+'
			    && check_level(&broken_list[i][1],
					   *priority_cache, 1) != 0) {
				continue;
			} else if ((algo =
				    gnutls_mac_get_id(&broken_list[i][1]))
				   != GNUTLS_MAC_UNKNOWN)
				fn(&(*priority_cache)->mac, algo);
			else if ((algo =
				  gnutls_cipher_get_id(&broken_list[i][1]))
				 != GNUTLS_CIPHER_UNKNOWN)
				fn(&(*priority_cache)->cipher, algo);
			else if ((algo =
				  gnutls_kx_get_id(&broken_list[i][1])) !=
				 GNUTLS_KX_UNKNOWN)
				fn(&(*priority_cache)->kx, algo);
			else if (strncasecmp
				 (&broken_list[i][1], "VERS-", 5) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "VERS-TLS-ALL",
				     12) == 0) {
					bulk_fn(&(*priority_cache)->
						protocol,
						protocol_priority);
				} else
				    if (strncasecmp
					(&broken_list[i][1],
					 "VERS-DTLS-ALL", 13) == 0) {
					bulk_fn(&(*priority_cache)->
						protocol,
						dtls_protocol_priority);
				} else {
					if ((algo =
					     gnutls_protocol_get_id
					     (&broken_list[i][6])) !=
					    GNUTLS_VERSION_UNKNOWN)
						fn(&(*priority_cache)->
						   protocol, algo);
					else
						goto error;

				}
			} /* now check if the element is something like -ALGO */
			else if (strncasecmp
				 (&broken_list[i][1], "COMP-", 5) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "COMP-ALL",
				     8) == 0) {
					bulk_fn(&(*priority_cache)->
						compression,
						comp_priority);
				} else {
					if ((algo =
					     gnutls_compression_get_id
					     (&broken_list[i][6])) !=
					    GNUTLS_COMP_UNKNOWN)
						fn(&(*priority_cache)->
						   compression, algo);
					else
						goto error;
				}
			} /* now check if the element is something like -ALGO */
			else if (strncasecmp
				 (&broken_list[i][1], "CURVE-", 6) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "CURVE-ALL",
				     9) == 0) {
					bulk_fn(&(*priority_cache)->
						supported_ecc,
						supported_ecc_normal);
				} else {
					if ((algo =
					     _gnutls_ecc_curve_get_id
					     (&broken_list[i][7])) !=
					    GNUTLS_ECC_CURVE_INVALID)
						fn(&(*priority_cache)->
						   supported_ecc, algo);
					else
						goto error;
				}
			} /* now check if the element is something like -ALGO */
			else if (strncasecmp
				 (&broken_list[i][1], "CTYPE-", 6) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "CTYPE-ALL",
				     9) == 0) {
					bulk_fn(&(*priority_cache)->
						cert_type,
						cert_type_priority_all);
				} else {
					if ((algo =
					     gnutls_certificate_type_get_id
					     (&broken_list[i][7])) !=
					    GNUTLS_CRT_UNKNOWN)
						fn(&(*priority_cache)->
						   cert_type, algo);
					else
						goto error;
				}
			} /* now check if the element is something like -ALGO */
			else if (strncasecmp
				 (&broken_list[i][1], "SIGN-", 5) == 0) {
				if (strncasecmp
				    (&broken_list[i][1], "SIGN-ALL",
				     8) == 0) {
					bulk_fn(&(*priority_cache)->
						sign_algo,
						sign_priority_default);
				} else {
					if ((algo =
					     gnutls_sign_get_id
					     (&broken_list[i][6])) !=
					    GNUTLS_SIGN_UNKNOWN)
						fn(&(*priority_cache)->
						   sign_algo, algo);
					else
						goto error;
				}
			} else
			    if (strncasecmp
				(&broken_list[i][1], "MAC-ALL", 7) == 0) {
				bulk_fn(&(*priority_cache)->mac,
					mac_priority_normal);
			} else
			    if (strncasecmp
				(&broken_list[i][1], "CIPHER-ALL",
				 10) == 0) {
				bulk_fn(&(*priority_cache)->cipher,
					cipher_priority_normal);
			} else
			    if (strncasecmp
				(&broken_list[i][1], "KX-ALL", 6) == 0) {
				bulk_fn(&(*priority_cache)->kx,
					kx_priority_secure);
			} else
				goto error;
		} else if (broken_list[i][0] == '%') {
			if (strcasecmp(&broken_list[i][1], "COMPAT") == 0) {
				ENABLE_COMPAT((*priority_cache));
			} else
			  if (strcasecmp(&broken_list[i][1], "DUMBFW") == 0) {
				(*priority_cache)->dumbfw = 1;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "NO_EXTENSIONS") == 0) {
				(*priority_cache)->no_extensions = 1;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "STATELESS_COMPRESSION") == 0) {
				(*priority_cache)->stateless_compression =
				    1;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "VERIFY_ALLOW_SIGN_RSA_MD5") == 0) {
				prio_add(&(*priority_cache)->sign_algo,
					 GNUTLS_SIGN_RSA_MD5);
				(*priority_cache)->
				    additional_verify_flags |=
				    GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "VERIFY_DISABLE_CRL_CHECKS") == 0) {
				(*priority_cache)->
				    additional_verify_flags |=
				    GNUTLS_VERIFY_DISABLE_CRL_CHECKS;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "SSL3_RECORD_VERSION") == 0)
				(*priority_cache)->ssl3_record_version = 1;
			else if (strcasecmp(&broken_list[i][1],
					    "LATEST_RECORD_VERSION") == 0)
				(*priority_cache)->ssl3_record_version = 0;
			else if (strcasecmp(&broken_list[i][1],
					    "VERIFY_ALLOW_X509_V1_CA_CRT")
				 == 0)
				(*priority_cache)->
				    additional_verify_flags |=
				    GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
			else if (strcasecmp
				 (&broken_list[i][1],
				  "UNSAFE_RENEGOTIATION") == 0) {
				(*priority_cache)->sr = SR_UNSAFE;
			} else
			    if (strcasecmp
				(&broken_list[i][1],
				 "SAFE_RENEGOTIATION") == 0) {
				(*priority_cache)->sr = SR_SAFE;
			} else if (strcasecmp(&broken_list[i][1],
					      "PARTIAL_RENEGOTIATION") ==
				   0) {
				(*priority_cache)->sr = SR_PARTIAL;
			} else if (strcasecmp(&broken_list[i][1],
					      "DISABLE_SAFE_RENEGOTIATION")
				   == 0) {
				(*priority_cache)->sr = SR_DISABLED;
			} else if (strcasecmp(&broken_list[i][1],
					      "SERVER_PRECEDENCE") == 0) {
				(*priority_cache)->server_precedence = 1;
			} else if (strcasecmp(&broken_list[i][1],
					      "NEW_PADDING") == 0) {
				(*priority_cache)->new_record_padding = 1;
			} else
				goto error;
		} else
			goto error;
	}

	gnutls_free(darg);
	return 0;

      error:
	if (err_pos != NULL && i < broken_list_size) {
		*err_pos = priorities;
		for (j = 0; j < i; j++) {
			(*err_pos) += strlen(broken_list[j]) + 1;
		}
	}
	gnutls_free(darg);
	gnutls_free(*priority_cache);
	*priority_cache = NULL;

	return GNUTLS_E_INVALID_REQUEST;

}
Example #3
0
queue_info *
query_queue_info(status *policy, struct batch_status *queue, server_info *sinfo)
{
	struct attrl *attrp;		/* linked list of attributes from server */
	struct queue_info *qinfo;	/* queue_info being created */
	schd_resource *resp;		/* resource in resource qres list */
	char *endp;			/* used with strtol() */
	sch_resource_t count;		/* used to convert string -> num */

	if ((qinfo = new_queue_info(1)) == NULL)
		return NULL;

	if (qinfo->liminfo == NULL)
		return NULL;

	if ((qinfo->name = string_dup(queue->name)) == NULL) {
		free_queue_info(qinfo);
		return NULL;
	}

	attrp = queue->attribs;
	qinfo->server = sinfo;
	while (attrp != NULL) {
		if (!strcmp(attrp->name, ATTR_start)) { /* started */
			if (!strcmp(attrp->value, ATR_TRUE))
				qinfo->is_started = 1;
			else
				qinfo->is_started = 0;
		}
		else if (!strcmp(attrp->name, ATTR_HasNodes)) {
			if (!strcmp(attrp->value, ATR_TRUE)) {
				sinfo->has_nodes_assoc_queue = 1;
				qinfo->has_nodes = 1;
			}
			else
				qinfo->has_nodes = 0;
		}
		else if(!strcmp(attrp->name, ATTR_backfill_depth)) {
			qinfo->backfill_depth = strtol(attrp->value, NULL, 10);
			if(qinfo->backfill_depth > 0)
				policy->backfill = 1;
		}
		else if(!strcmp(attrp->name, ATTR_partition)) {
			if (attrp->value != NULL) {
				qinfo->partition = string_dup(attrp->value);
				if (qinfo->partition == NULL) {
					log_err(errno, __func__, MEM_ERR_MSG);
					free_queue_info(qinfo);
					return NULL;
				}
			}
		}
		else if (is_reslimattr(attrp)) {
			(void) lim_setlimits(attrp, LIM_RES, qinfo->liminfo);
			if(strstr(attrp->value, "u:") != NULL)
				sinfo->has_user_limit = 1;
			if(strstr(attrp->value, "g:") != NULL)
				sinfo->has_grp_limit = 1;
			if(strstr(attrp->value, "p:") != NULL)
				sinfo->has_proj_limit = 1;
		}
		else if (is_runlimattr(attrp)) {
			(void) lim_setlimits(attrp, LIM_RUN, qinfo->liminfo);
			if(strstr(attrp->value, "u:") != NULL)
				sinfo->has_user_limit = 1;
			if(strstr(attrp->value, "g:") != NULL)
				sinfo->has_grp_limit = 1;
			if(strstr(attrp->value, "p:") != NULL)
				sinfo->has_proj_limit = 1;

		}
		else if (is_oldlimattr(attrp)) {
			char *limname = convert_oldlim_to_new(attrp);
			(void) lim_setlimits(attrp, LIM_OLD, qinfo->liminfo);

			if(strstr(limname, "u:") != NULL)
				sinfo->has_user_limit = 1;
			if(strstr(limname, "g:") != NULL)
				sinfo->has_grp_limit = 1;
			/* no need to check for project limits because there were no old style project limits */
		}
		else if (!strcmp(attrp->name, ATTR_p)) { /* priority */
			count = strtol(attrp->value, &endp, 10);
			if (*endp != '\0')
				count = -1;
			qinfo->priority = count;
		}
		else if (!strcmp(attrp->name, ATTR_qtype)) { /* queue_type */
			if (!strcmp(attrp->value, "Execution")) {
				qinfo->is_exec = 1;
				qinfo->is_route = 0;
			}
			else if (!strcmp(attrp->value, "Route")) {
				qinfo->is_route = 1;
				qinfo->is_exec = 0;
			}
		}
		else if (!strcmp(attrp->name, ATTR_NodeGroupKey))
			qinfo->node_group_key = break_comma_list(attrp->value);
		else if (!strcmp(attrp->name, ATTR_rescavail)) { /* resources_available*/
#ifdef NAS
			/* localmod 040 */
			if (!strcmp(attrp->resource, ATTR_ignore_nodect_sort)) {
				if (!strcmp(attrp->value, ATR_TRUE))
					qinfo->ignore_nodect_sort = 1;
				else
					qinfo->ignore_nodect_sort = 0;

				resp = NULL;
			}/* localmod 038 */
			else if (!strcmp(attrp->resource, ATTR_topjob_setaside)) {
				if (!strcmp(attrp->value, ATR_TRUE))
					qinfo->is_topjob_set_aside = 1;
				else
					qinfo->is_topjob_set_aside = 0;

				resp = NULL;
			} else
#endif
				resp = find_alloc_resource_by_str(qinfo->qres, attrp->resource);
			if (resp != NULL) {
				if (qinfo->qres == NULL)
					qinfo->qres = resp;

				if (set_resource(resp, attrp->value, RF_AVAIL) == 0) {
					free_queue_info(qinfo);
					return NULL;
				}
				qinfo->has_resav_limit = 1;
			}
		} else if (!strcmp(attrp->name, ATTR_rescassn)) { /* resources_assigned */
			resp = find_alloc_resource_by_str(qinfo->qres, attrp->resource);
			if (qinfo->qres == NULL)
				qinfo->qres = resp;
			if (resp != NULL) {
				if (set_resource(resp, attrp->value, RF_ASSN) == 0) {
					free_queue_info(qinfo);
					return NULL;
				}
			}
		}
#ifdef NAS
		/* localmod 046 */
		else if (!strcmp(attrp->name, ATTR_maxstarve)) {
			time_t	starve;
			starve = site_decode_time(attrp->value);
			qinfo->max_starve = starve;
		}
		/* localmod 034 */
		else if (!strcmp(attrp->name, ATTR_maxborrow)) {
			time_t	borrow;
			borrow = site_decode_time(attrp->value);
			qinfo->max_borrow = borrow;
		}
#endif

		attrp = attrp->next;
	}

	if (has_hardlimits(qinfo->liminfo))
		qinfo->has_hard_limit = 1;
	if (has_softlimits(qinfo->liminfo))
		qinfo->has_soft_limit = 1;

	return qinfo;
}
Example #4
0
/**
  * gnutls_priority_init - Sets priorities for the cipher suites supported by gnutls.
  * @priority_cache: is a #gnutls_prioritity_t structure.
  * @priorities: is a string describing priorities
  * @err_pos: In case of an error this will have the position in the string the error occured
  *
  * Sets priorities for the ciphers, key exchange methods, macs and
  * compression methods. This is to avoid using the
  * gnutls_*_priority() functions.
  *
  * The #priorities option allows you to specify a semi-colon
  * separated list of the cipher priorities to enable.
  *
  * Unless the first keyword is "NONE" the defaults are:
  * Protocols: TLS1.1, TLS1.0, and SSL3.0.
  * Compression: NULL.
  * Certificate types: X.509, OpenPGP.
  *
  * You can also use predefined sets of ciphersuites: "PERFORMANCE"
  * all the "secure" ciphersuites are enabled, limited to 128 bit
  * ciphers and sorted by terms of speed performance.
  *
  * "NORMAL" option enables all "secure" ciphersuites. The 256-bit ciphers
  * are included as a fallback only. The ciphers are sorted by security margin.
  *
  * "SECURE128" flag enables all "secure" ciphersuites with ciphers up to 
  * 128 bits, sorted by security margin.
  *
  * "SECURE256" flag enables all "secure" ciphersuites including the 256 bit
  * ciphers, sorted by security margin.
  *
  * "EXPORT" all the ciphersuites are enabled, including the
  * low-security 40 bit ciphers.
  *
  * "NONE" nothing is enabled. This disables even protocols and
  * compression methods.
  *
  * Special keywords:
  * '!' or '-' appended with an algorithm will remove this algorithm.
  * '+' appended with an algorithm will add this algorithm.
  * '%COMPAT' will enable compatibility features for a server.
  *
  * To avoid collisions in order to specify a compression algorithm in
  * this string you have to prefix it with "COMP-", protocol versions
  * with "VERS-" and certificate types with "CTYPE-". All other
  * algorithms don't need a prefix.
  *
  * For key exchange algorithms when in NORMAL or SECURE levels the
  * perfect forward secrecy algorithms take precendence of the other
  * protocols.  In all cases all the supported key exchange algorithms
  * are enabled (except for the RSA-EXPORT which is only enabled in
  * EXPORT level).
  *
  * Note that although one can select very long key sizes (such as 256 bits) 
  * for symmetric algorithms, to actually increase security the public key
  * algorithms have to use longer key sizes as well.
  *
  * Examples: "NORMAL:!AES-128-CBC",
  * "EXPORT:!VERS-TLS1.0:+COMP-DEFLATE:+CTYPE-OPENPGP",
  * "NONE:+VERS-TLS1.0:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL", "NORMAL",
  * "NORMAL:%COMPAT".
  *
  * Returns: On syntax error GNUTLS_E_INVALID_REQUEST is returned and
  * 0 on success.
  **/
int
gnutls_priority_init (gnutls_priority_t * priority_cache,
		      const char *priorities, const char **err_pos)
{
  char *broken_list[MAX_ELEMENTS];
  int broken_list_size, i, j;
  char *darg;
  int algo;
  rmadd_func *fn;

  *priority_cache = gnutls_calloc (1, sizeof (struct gnutls_priority_st));
  if (*priority_cache == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  if (priorities == NULL)
    priorities = "NORMAL";

  darg = gnutls_strdup (priorities);
  if (darg == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  break_comma_list (darg, broken_list, &broken_list_size, MAX_ELEMENTS, ':');

  /* This is our default set of protocol version, certificate types and
   * compression methods.
   */
  if (strcasecmp (broken_list[0], "NONE") != 0)
    {
      _set_priority (&(*priority_cache)->protocol, protocol_priority);
      _set_priority (&(*priority_cache)->compression, comp_priority);
      _set_priority (&(*priority_cache)->cert_type, cert_type_priority);
    }

  for (i = 0; i < broken_list_size; i++)
    {
      if (strcasecmp (broken_list[i], "PERFORMANCE") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher,
			 cipher_priority_performance);
	  _set_priority (&(*priority_cache)->kx, kx_priority_performance);
	  _set_priority (&(*priority_cache)->mac, mac_priority_performance);
	}
      else if (strcasecmp (broken_list[i], "NORMAL") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher, cipher_priority_normal);
	  _set_priority (&(*priority_cache)->kx, kx_priority_secure);
	  _set_priority (&(*priority_cache)->mac, mac_priority_secure);
	}
      else if (strcasecmp (broken_list[i], "SECURE256") == 0 || strcasecmp (broken_list[i], "SECURE") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher, cipher_priority_secure256);
	  _set_priority (&(*priority_cache)->kx, kx_priority_secure);
	  _set_priority (&(*priority_cache)->mac, mac_priority_secure);
	}
      else if (strcasecmp (broken_list[i], "SECURE128") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher, cipher_priority_secure128);
	  _set_priority (&(*priority_cache)->kx, kx_priority_secure);
	  _set_priority (&(*priority_cache)->mac, mac_priority_secure);
	}
      else if (strcasecmp (broken_list[i], "EXPORT") == 0)
	{
	  _set_priority (&(*priority_cache)->cipher, cipher_priority_export);
	  _set_priority (&(*priority_cache)->kx, kx_priority_export);
	  _set_priority (&(*priority_cache)->mac, mac_priority_secure);
	}			/* now check if the element is something like -ALGO */
      else if (broken_list[i][0] == '!' || broken_list[i][0] == '+'
	       || broken_list[i][0] == '-')
	{
	  if (broken_list[i][0] == '+')
	    fn = prio_add;
	  else
	    fn = prio_remove;

	  if ((algo =
	       gnutls_mac_get_id (&broken_list[i][1])) != GNUTLS_MAC_UNKNOWN)
	    fn (&(*priority_cache)->mac, algo);
	  else if ((algo = gnutls_cipher_get_id (&broken_list[i][1])) !=
		   GNUTLS_CIPHER_UNKNOWN)
	    fn (&(*priority_cache)->cipher, algo);
	  else if ((algo = gnutls_kx_get_id (&broken_list[i][1])) !=
		   GNUTLS_KX_UNKNOWN)
	    fn (&(*priority_cache)->kx, algo);
	  else if (strncasecmp (&broken_list[i][1], "VERS-", 5) == 0)
	    {
	      if ((algo =
		   gnutls_protocol_get_id (&broken_list[i][6])) !=
		  GNUTLS_VERSION_UNKNOWN)
		fn (&(*priority_cache)->protocol, algo);
	    }			/* now check if the element is something like -ALGO */
	  else if (strncasecmp (&broken_list[i][1], "COMP-", 5) == 0)
	    {
	      if ((algo =
		   gnutls_compression_get_id (&broken_list[i][6])) !=
		  GNUTLS_COMP_UNKNOWN)
		fn (&(*priority_cache)->compression, algo);
	    }			/* now check if the element is something like -ALGO */
	  else if (strncasecmp (&broken_list[i][1], "CTYPE-", 6) == 0)
	    {
	      if ((algo =
		   gnutls_certificate_type_get_id (&broken_list[i][7])) !=
		  GNUTLS_CRT_UNKNOWN)
		fn (&(*priority_cache)->cert_type, algo);
	    }			/* now check if the element is something like -ALGO */
	  else
	    goto error;
	}
      else if (broken_list[i][0] == '%')
	{
	  if (strcasecmp (&broken_list[i][1], "COMPAT") == 0)
	    (*priority_cache)->no_padding = 1;
	  else
	    goto error;
	}
      else
	goto error;
    }

  gnutls_free (darg);
  return 0;

error:
  if (err_pos != NULL && i < broken_list_size)
    {
      *err_pos = priorities;
      for (j = 0; j < i; j++)
	{
	  (*err_pos) += strlen (broken_list[j]) + 1;
	}
    }
  gnutls_free (darg);

  return GNUTLS_E_INVALID_REQUEST;

}