📄 alg_info.c
字号:
p_ctx->err="Non initial digit found for auth keylen"; goto err; case ST_AK: if (ch=='-') { parser_set_state(p_ctx, ST_AK_END); break; } if (isdigit(ch)) { p_ctx->aklen=p_ctx->aklen*10+ch-'0'; break; } p_ctx->err="Non digit found for auth keylen"; goto err; case ST_AK_END: /* Only allow modpXXXX string if we have * a modp_getbyname method */ if ((p_ctx->modp_getbyname) && isalpha(ch)) { parser_set_state(p_ctx, ST_MODP); goto re_eval; } p_ctx->err="Non alpha char found after auth keylen"; goto err; case ST_MODP: if (isalnum(ch)) { *(p_ctx->modp_str++)=ch; break; } p_ctx->err="Non alphanum char found after in modp string"; goto err; case ST_FLAG_STRICT: if (ch == 0) { parser_set_state(p_ctx, ST_END); } p_ctx->err="Flags character(s) must be at end of whole string"; goto err; /* XXX */ case ST_END: case ST_EOF: case ST_ERR: break; /* XXX */ } out: return p_ctx->state; err: parser_set_state(p_ctx, ST_ERR); return ST_ERR;}/* * Must be called for each "new" char, with new * character in ctx.ch */static voidparser_init_esp(struct parser_context *p_ctx){ memset(p_ctx, 0, sizeof (*p_ctx)); p_ctx->protoid=PROTO_IPSEC_ESP; p_ctx->ealg_str=p_ctx->ealg_buf; p_ctx->aalg_str=p_ctx->aalg_buf; p_ctx->modp_str=p_ctx->modp_buf; p_ctx->state=ST_INI; p_ctx->ealg_getbyname=ealg_getbyname_esp; p_ctx->aalg_getbyname=aalg_getbyname_esp;}static intparser_alg_info_add(struct parser_context *p_ctx , struct alg_info *alg_info , void (*alg_info_add)(struct alg_info *alg_info , int ealg_id, int ek_bits , int aalg_id, int ak_bits , int modp_id , bool permitmann) , const struct oakley_group_desc *(*lookup_group)(u_int16_t group) , bool permitike){ int ealg_id, aalg_id; int modp_id = 0; const struct oakley_group_desc *gd; ealg_id=aalg_id=0; if (*p_ctx->ealg_buf) { ealg_id=p_ctx->ealg_getbyname(p_ctx->ealg_buf, strlen(p_ctx->ealg_buf)); if (ealg_id==ESP_MAGIC_ID) { ealg_id=p_ctx->eklen; p_ctx->eklen=0; } if (ealg_id<0) { p_ctx->err="enc_alg not found"; goto out; } DBG(DBG_CRYPT, DBG_log("parser_alg_info_add() " "ealg_getbyname(\"%s\")=%d", p_ctx->ealg_buf, ealg_id)); } if (*p_ctx->aalg_buf) { aalg_id=p_ctx->aalg_getbyname(p_ctx->aalg_buf, strlen(p_ctx->aalg_buf)); if (aalg_id<0) { p_ctx->err="hash_alg not found"; goto out; } DBG(DBG_CRYPT, DBG_log("parser_alg_info_add() " "aalg_getbyname(\"%s\")=%d", p_ctx->aalg_buf, aalg_id)); } if (p_ctx->modp_getbyname && *p_ctx->modp_buf) { modp_id=p_ctx->modp_getbyname(p_ctx->modp_buf, strlen(p_ctx->modp_buf)); if (modp_id<0) { p_ctx->err="modp group not found"; goto out; } DBG(DBG_CRYPT, DBG_log("parser_alg_info_add() " "modp_getbyname(\"%s\")=%d", p_ctx->modp_buf, modp_id)); if (modp_id && !(gd=lookup_group(modp_id))) { p_ctx->err="found modp group id, but not supported"; goto out; } } (*alg_info_add)(alg_info ,ealg_id, p_ctx->eklen ,aalg_id, p_ctx->aklen ,modp_id, permitike); return 0; out: return -1;}intalg_info_parse_str (struct alg_info *alg_info , const char *alg_str , const char **err_p , void (*parser_init)(struct parser_context *p_ctx) , void (*alg_info_add)(struct alg_info *alg_info , int ealg_id, int ek_bits , int aalg_id, int ak_bits , int modp_id , bool permitmann) , const struct oakley_group_desc *(*lookup_group)(u_int16_t group) , bool permitmann){ struct parser_context ctx; int ret; const char *ptr; static char err_buf[256]; *err_buf=0; (*parser_init)(&ctx); if (err_p) *err_p=NULL; /* use default if nul esp string */ if (!*alg_str) { (*alg_info_add)(alg_info, 0, 0, 0, 0, 0, 0); } for(ret=0,ptr=alg_str;ret<ST_EOF;) { ctx.ch=*ptr++; ret= parser_machine(&ctx); switch(ret) { case ST_FLAG_STRICT: alg_info->alg_info_flags |= ALG_INFO_F_STRICT; break; case ST_END: case ST_EOF: DBG(DBG_CRYPT, DBG_log("alg_info_parse_str() " "ealg_buf=%s aalg_buf=%s" "eklen=%d aklen=%d", ctx.ealg_buf, ctx.aalg_buf, ctx.eklen, ctx.aklen)); if (parser_alg_info_add(&ctx, alg_info , alg_info_add , lookup_group , permitmann)<0) { snprintf(err_buf, sizeof(err_buf), "%s, enc_alg=\"%s\", auth_alg=\"%s\", " "modp=\"%s\"", ctx.err, ctx.ealg_buf, ctx.aalg_buf, ctx.modp_buf); goto err; } /* zero out for next run (ST_END) */ parser_init(&ctx); break; case ST_ERR: snprintf(err_buf, sizeof(err_buf), "%s, " "just after \"%.*s\"" " (old_state=%s)", ctx.err, (int)(ptr-alg_str-1), alg_str , parser_state_name_esp(ctx.old_state) ); goto err; default: if (!ctx.ch) break; } } return 0; err: if (err_p) { *err_p=err_buf; } return -1;}struct alg_info_esp *alg_info_esp_create_from_str (const char *alg_str , const char **err_p , bool permitmann){ struct alg_info_esp *alg_info_esp; char esp_buf[256]; static char err_buf[256]; char *pfs_name; int ret =0; /* * alg_info storage should be sized dynamically * but this may require 2passes to know * transform count in advance. */ alg_info_esp=alloc_thing (struct alg_info_esp, "alg_info_esp"); if (!alg_info_esp) goto out; pfs_name=index (alg_str, ';'); if (pfs_name) { memcpy(esp_buf, alg_str, pfs_name-alg_str); esp_buf[pfs_name-alg_str] = 0; alg_str=esp_buf; pfs_name++; /* if pfs strings AND first char is not '0' */ if (*pfs_name && pfs_name[0]!='0') { ret=modp_getbyname_esp(pfs_name, strlen(pfs_name)); if (ret<0) { /* Bomb if pfsgroup not found */ DBG(DBG_CRYPT, DBG_log("alg_info_esp_create_from_str(): " "pfsgroup \"%s\" not found", pfs_name)); if (*err_p) { snprintf(err_buf, sizeof(err_buf), "pfsgroup \"%s\" not found", pfs_name); *err_p=err_buf; } goto out; } alg_info_esp->esp_pfsgroup=ret; } } else alg_info_esp->esp_pfsgroup = 0; alg_info_esp->alg_info_protoid=PROTO_IPSEC_ESP; ret=alg_info_parse_str((struct alg_info *)alg_info_esp , alg_str, err_p , parser_init_esp , alg_info_esp_add , NULL , permitmann); out: if (ret<0) { pfreeany(alg_info_esp); alg_info_esp=NULL; } return alg_info_esp; }/* * alg_info struct can be shared by * several connections instances, * handle free() with ref_cnts */void alg_info_addref(struct alg_info *alg_info){ if (alg_info != NULL) { alg_info->ref_cnt++; DBG(DBG_CONTROL, DBG_log("alg_info_addref() " "alg_info->ref_cnt=%d", alg_info->ref_cnt)); }}voidalg_info_delref(struct alg_info **alg_info_p){ struct alg_info *alg_info=*alg_info_p; DBG(DBG_CONTROL, DBG_log("alg_info_delref(%p) " , alg_info)); if (alg_info != NULL) { DBG(DBG_CONTROL, DBG_log("alg_info_delref(%p) " "alg_info->ref_cnt=%d" , alg_info, alg_info->ref_cnt)); passert(alg_info->ref_cnt != 0); alg_info->ref_cnt--; if (alg_info->ref_cnt==0) { DBG(DBG_CONTROL, DBG_log("alg_info_delref(%p) " "freeing alg_info", alg_info)); alg_info_free(alg_info); } *alg_info_p=NULL; }}/* snprint already parsed transform list (alg_info) */intalg_info_snprint(char *buf, int buflen , struct alg_info *alg_info , bool permitike){ char *ptr=buf; int np=0; struct esp_info *esp_info; struct ike_info *ike_info; int cnt; ptr=buf; switch(alg_info->alg_info_protoid) { case PROTO_IPSEC_ESP: { struct alg_info_esp *alg_info_esp=(struct alg_info_esp *)alg_info; ALG_INFO_ESP_FOREACH(alg_info_esp, esp_info, cnt) { np=snprintf(ptr, buflen, "%d_%03d-%d, " , esp_info->esp_ealg_id , (int)esp_info->esp_ealg_keylen , esp_info->esp_aalg_id); ptr+=np; buflen-=np; if(buflen<0) goto out; } if (alg_info_esp->esp_pfsgroup) { np=snprintf(ptr, buflen, "; pfsgroup=%d; " , alg_info_esp->esp_pfsgroup); ptr+=np; buflen-=np; if(buflen<0) goto out; } break; } case PROTO_ISAKMP: if(permitike) { ALG_INFO_IKE_FOREACH((struct alg_info_ike *)alg_info, ike_info, cnt) { np=snprintf(ptr, buflen, "%d_%03d-%d-%d, ", ike_info->ike_ealg, (int)ike_info->ike_eklen, ike_info->ike_halg, ike_info->ike_modp); ptr+=np; buflen-=np; if(buflen<0) goto out; } break; } /* FALLTHROUGH */ default: np=snprintf(buf, buflen, "INVALID protoid=%d\n", alg_info->alg_info_protoid); ptr+=np; buflen-=np; goto out; } np=snprintf(ptr, buflen, "flags=%s", alg_info->alg_info_flags&ALG_INFO_F_STRICT? "strict":"-strict"); ptr+=np; buflen-=np; out: passert(buflen >= 0); return ptr-buf;}/* * Local Variables: * c-basic-offset:4 * c-style: pluto * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -