⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alg_info.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Algorithm info parsing and creation functions * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar> * * alg_info.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * for more details. */#include <stddef.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/stat.h>#include <netinet/in.h>#include <arpa/inet.h>#include <ctype.h>#include <openswan.h>#include <openswan/ipsec_policy.h>#include <openswan/passert.h>#include <pfkeyv2.h>#include "constants.h"#include "alg_info.h"#include "oswlog.h"#include "oswalloc.h"/* abstract reference */struct oakley_group_desc;/* sadb/ESP aa attrib converters */intalg_info_esp_aa2sadb(int auth){	int sadb_aalg=0;	switch(auth) {		case AUTH_ALGORITHM_HMAC_MD5:		case AUTH_ALGORITHM_HMAC_SHA1:			sadb_aalg=auth+1;			break;		case AUTH_ALGORITHM_HMAC_SHA2_256:		case AUTH_ALGORITHM_HMAC_SHA2_384:		case AUTH_ALGORITHM_HMAC_SHA2_512:		case AUTH_ALGORITHM_HMAC_RIPEMD:			sadb_aalg=auth;			break;		default:			/* loose ... */			sadb_aalg=auth;	}	return sadb_aalg;}int /* __attribute__ ((unused)) */alg_info_esp_sadb2aa(int sadb_aalg){	int auth=0;	switch(sadb_aalg) {		case SADB_AALG_MD5HMAC:		case SADB_AALG_SHA1HMAC:			auth=sadb_aalg-1;			break;			/* since they are the same ...  :)  */		case AUTH_ALGORITHM_HMAC_SHA2_256:		case AUTH_ALGORITHM_HMAC_SHA2_384:		case AUTH_ALGORITHM_HMAC_SHA2_512:		case AUTH_ALGORITHM_HMAC_RIPEMD:			auth=sadb_aalg;			break;		default:			/* loose ... */			auth=sadb_aalg;	}	return auth;}/* * 	Search enum_name array with in prefixed uppercase */intalg_enum_search_prefix (enum_names *ed, const char *prefix, const char *str, int strlen){	char buf[64];	char *ptr;	int ret;	int len=sizeof(buf)-1;	/* reserve space for final \0 */	for (ptr=buf; *prefix; *ptr++=*prefix++, len--);	while (strlen--&&len--&&*str) *ptr++=toupper(*str++);	*ptr=0;	DBG(DBG_CRYPT, DBG_log("enum_search_prefix () "				"calling enum_search(%p, \"%s\")", ed, buf));	ret=enum_search(ed, buf);	return ret;}/* * 	Search enum_name array with in prefixed and postfixed uppercase */intalg_enum_search_ppfix (enum_names *ed, const char *prefix		   , const char *postfix, const char *str		   , int strlen){	char buf[64];	char *ptr;	int ret;	int len=sizeof(buf)-1;	/* reserve space for final \0 */	for (ptr=buf; *prefix; *ptr++=*prefix++, len--);	while (strlen--&&len--&&*str) *ptr++=toupper(*str++);	while (len--&&*postfix) *ptr++=*postfix++;	*ptr=0;	DBG(DBG_CRYPT, DBG_log("enum_search_ppfixi () "				"calling enum_search(%p, \"%s\")", ed, buf));	ret=enum_search(ed, buf);	return ret;}/* * 	Search esp_transformid_names for a match, eg: * 		"3des" <=> "ESP_3DES" */#define ESP_MAGIC_ID 0x00ffff01static intealg_getbyname_esp(const char *const str, int len){	int ret=-1;	if (!str||!*str)		goto out;	/* leave special case for eg:  "id248" string */	if (strcmp("id", str)==0)		return ESP_MAGIC_ID;	ret=alg_enum_search_prefix(&esp_transformid_names, "ESP_", str, len);out:	return ret;}/* * 	Search auth_alg_names for a match, eg: * 		"md5" <=> "AUTH_ALGORITHM_HMAC_MD5" */static intaalg_getbyname_esp(const char *const str, int len){	int ret=-1;	unsigned num;	if (!str||!*str)		goto out;	ret=alg_enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_HMAC_",str,len);	if (ret>=0) goto out;	ret=alg_enum_search_prefix(&auth_alg_names,"AUTH_ALGORITHM_",str,len);	if (ret>=0) goto out;	sscanf(str, "id%d%n", &ret, &num);	if (ret >=0 && num!=strlen(str))		ret=-1;out:	return ret;}static intmodp_getbyname_esp(const char *const str, int len){	int ret=-1;	if (!str||!*str)		goto out;	ret=alg_enum_search_prefix(&oakley_group_names,"OAKLEY_GROUP_",str,len);	if (ret>=0) goto out;	ret=alg_enum_search_ppfix(&oakley_group_names, "OAKLEY_GROUP_", " (extension)", str, len);out:	return ret;}void alg_info_free(struct alg_info *alg_info) {	pfreeany(alg_info);}/*	 *	Raw add routine: only checks for no duplicates		 */static void__alg_info_esp_add (struct alg_info_esp *alg_info		    , int ealg_id, unsigned ek_bits		    , int aalg_id, unsigned ak_bits){	struct esp_info *esp_info=alg_info->esp;	unsigned cnt=alg_info->alg_info_cnt, i;	/* 	check for overflows 	*/	passert(cnt < elemsof(alg_info->esp));	/*	dont add duplicates	*/	for (i=0;i<cnt;i++)		if (	esp_info[i].esp_ealg_id==ealg_id &&			(!ek_bits || esp_info[i].esp_ealg_keylen==ek_bits) &&			esp_info[i].esp_aalg_id==aalg_id &&			(!ak_bits || esp_info[i].esp_aalg_keylen==ak_bits))			return;	esp_info[cnt].esp_ealg_id=ealg_id;	esp_info[cnt].esp_ealg_keylen=ek_bits;	esp_info[cnt].esp_aalg_id=aalg_id;	esp_info[cnt].esp_aalg_keylen=ak_bits;	/* sadb values */	esp_info[cnt].encryptalg=ealg_id;	esp_info[cnt].authalg=alg_info_esp_aa2sadb(aalg_id);	alg_info->alg_info_cnt++;	DBG(DBG_CRYPT, DBG_log("__alg_info_esp_add() "				"ealg=%d aalg=%d cnt=%d",				ealg_id, aalg_id, alg_info->alg_info_cnt));}/*	 *	Add ESP alg info _with_ logic (policy): */static voidalg_info_esp_add (struct alg_info *alg_info,		  int ealg_id, int ek_bits,		  int aalg_id, int ak_bits,		  int modp_id, bool permit_manconn){	/*	Policy: default to 3DES */	if (ealg_id==0)		ealg_id=ESP_3DES;		if (ealg_id>0) {	    if(aalg_id > 0 ||	       (permit_manconn && aalg_id == 0))		{			__alg_info_esp_add((struct alg_info_esp *)alg_info,					ealg_id, ek_bits,					aalg_id, ak_bits);		}	    else		{			/*	Policy: default to MD5 and SHA1 */			__alg_info_esp_add((struct alg_info_esp *)alg_info,					ealg_id, ek_bits, \					AUTH_ALGORITHM_HMAC_MD5, ak_bits);			__alg_info_esp_add((struct alg_info_esp *)alg_info,					ealg_id, ek_bits, \					AUTH_ALGORITHM_HMAC_SHA1, ak_bits);		}	}}static const char *parser_state_esp_names[] = {	"ST_INI",	"ST_EA",	"ST_EA_END",		"ST_EK",	"ST_EK_END",	"ST_AA",	"ST_AA_END",	"ST_AK",	"ST_AK_END",	"ST_MOPD",	"ST_FLAG_STRICT",	"ST_END",	"ST_EOF",	"ST_ERR"};static const char *parser_state_name_esp(enum parser_state_esp state) {	return parser_state_esp_names[state];}static inline void parser_set_state(struct parser_context *p_ctx, enum parser_state_esp state) {	if (state!=p_ctx->state) {		p_ctx->old_state=p_ctx->state;		p_ctx->state=state;	}	}static int parser_machine(struct parser_context *p_ctx){	int ch=p_ctx->ch;	/* special 'absolute' cases */	p_ctx->err="No error.";	/* chars that end algo strings */	switch(ch){	case 0:		/* end-of-string */	case '!':	/* flag as strict algo list */	case ',':	/* algo string separator */	    switch(p_ctx->state) {	    case ST_EA:	    case ST_EK:	    case ST_AA:	    case ST_AK: 	    case ST_MODP:	    case ST_FLAG_STRICT:		{		    enum parser_state_esp next_state=0;		    switch(ch) {		    case 0:   next_state=ST_EOF;break;		    case ',': next_state=ST_END;break;		    case '!': next_state=ST_FLAG_STRICT;break;		    }		    /* ch? parser_set_state(p_ctx, ST_END) : parser_set_state(p_ctx, ST_EOF) ; */		    parser_set_state(p_ctx, next_state);		    goto out;		}	    default:		p_ctx->err="String ended with invalid char";		goto err;	    }	} re_eval:	switch(p_ctx->state) {	case ST_INI:	    if (isspace(ch))		break;	    if (isalnum(ch)) {		*(p_ctx->ealg_str++)=ch;		parser_set_state(p_ctx, ST_EA);		break;	    }	    p_ctx->err="No alphanum. char initially found";	    goto err;	case ST_EA:	    if (isalpha(ch) || ch == '_') {		*(p_ctx->ealg_str++)=ch;		break;	    }	    if (isdigit(ch)) {		/* bravely switch to enc keylen */		*(p_ctx->ealg_str)=0;		parser_set_state(p_ctx, ST_EK);		goto re_eval;	    }	    if (ch=='-') {		*(p_ctx->ealg_str)=0;		parser_set_state(p_ctx, ST_EA_END);		break;	    }	    p_ctx->err="No valid char found after enc alg string";	    goto err;	case ST_EA_END:	    if (isdigit(ch)) {		/* bravely switch to enc keylen */		parser_set_state(p_ctx, ST_EK);		goto re_eval;	    }	    if (isalpha(ch)) {		parser_set_state(p_ctx, ST_AA);		goto re_eval;	    }	    p_ctx->err="No alphanum char found after enc alg separator";	    goto err;	case ST_EK:	    if (ch=='-') {		parser_set_state(p_ctx, ST_EK_END);		break;	    }	    if (isdigit(ch)) {		p_ctx->eklen=p_ctx->eklen*10+ch-'0';		break;	    }	    p_ctx->err="Non digit or valid separator found while reading enc keylen";	    goto err;	case ST_EK_END:	    if (isalpha(ch)) {		parser_set_state(p_ctx, ST_AA);		goto re_eval;	    }	    p_ctx->err="Non alpha char found after enc keylen end separator";	    goto err;	case ST_AA:	    if (ch=='-') {		*(p_ctx->aalg_str++)=0;		parser_set_state(p_ctx, ST_AA_END);		break;	    }	    if (isalnum(ch) || ch=='_') {		*(p_ctx->aalg_str++)=ch;		break;	    }	    p_ctx->err="Non alphanum or valid separator found in auth string";	    goto err;	case ST_AA_END:	    if (isdigit(ch)) {		parser_set_state(p_ctx, ST_AK);		goto re_eval;	    }	    /* 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;	    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -