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

📄 rcv_info.c

📁 This a good VPN source
💻 C
字号:
/* info/policy communicating routines * Copyright (C) 2003       Michael Richardson <mcr@freeswan.org> * Copyright (C) 2004       Xelerance Corporation * 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. * * RCSID $Id: rcv_info.c,v 1.8 2004/05/13 13:38:01 ken Exp $ */#include <stdio.h>#include <stddef.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#include <netinet/in.h>#include <arpa/inet.h>#include <resolv.h>#include <arpa/nameser.h>	/* missing from <resolv.h> on old systems */#include <sys/queue.h>#include <openswan.h>#include "constants.h"#include "defs.h"#include "id.h"#ifdef XAUTH#include <security/pam_appl.h>#endif#include "connections.h"	/* needs id.h */#include "foodgroups.h"#include "whack.h"	/* needs connections.h */#include "packet.h"#include "demux.h"	/* needs packet.h */#include "state.h"#include "ipsec_doi.h"	/* needs demux.h and state.h */#include "kernel.h"	/* needs connections.h */#include "rcv_whack.h"#include "log.h"#include "keys.h"#include "adns.h"	/* needs <resolv.h> */#include "dnskey.h"	/* needs keys.h and adns.h */#include "server.h"#include "openswan/ipsec_policy.h"#include "rcv_info.h"/* global */int info_fd = -1;/** Lookup information about the hostpair, and set things like bandwidth * relative crypto strength, compression and credentials. *  * @param IPsec Policy Query * @return void */static voidinfo_lookuphostpair(struct ipsec_policy_cmd_query *ipcq){    struct connection *c;    struct state *p1st, *p2st;    /* default result: no crypto */    ipcq->strength  = IPSEC_PRIVACY_NONE;    ipcq->bandwidth = IPSEC_QOS_WIRESPEED;    ipcq->credential_count = 0;#ifdef DEBUG    {	char sstr[ADDRTOT_BUF], dstr[ADDRTOT_BUF];	addrtot(&ipcq->query_local,  0, sstr, sizeof(sstr));	addrtot(&ipcq->query_remote, 0, dstr, sizeof(dstr));	DBG_log("info request for %s -> %s", sstr, dstr);    }#endif    /* okay, look up what connection handles this ip pair */    c = find_connection_for_clients(NULL,				    &ipcq->query_local,				    &ipcq->query_remote);    if (c == NULL)    {	/* try reversing it */	c = find_connection_for_clients(NULL,					&ipcq->query_remote,					&ipcq->query_local);	if (c != NULL)	{	    ip_address tmp;	    /* If it is reversed, swap it */	    tmp = ipcq->query_local;	    ipcq->query_local = ipcq->query_remote;	    ipcq->query_remote = tmp;	}    }        if (c == NULL)    {#ifdef DEBUG	DBG_log("no connection found");#endif	return;	/* no crypto */    }    if (c->newest_ipsec_sa == SOS_NOBODY)    {	ip_subnet us, them;	DBG_log("connection %s found, no ipsec state, looking again", c->name);	addrtosubnet(&ipcq->query_local, &us);	addrtosubnet(&ipcq->query_remote, &them);	c = find_client_connection(c, &us, &them);	if (c == NULL)	    return;	/* no crypto */    }    DBG_log("connection %s[%ld] with state %u"	, c->name, c->instance_serial	, (unsigned int)c->newest_ipsec_sa);    if (c->newest_ipsec_sa == SOS_NOBODY)	return;	/* no crypto */    /* we found a connection, try to lookup the state */    p2st = state_with_serialno(c->newest_ipsec_sa);    p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);    if (p1st == NULL || p2st == NULL)    {	DBG_log("connection %s[%ld] has missing states %s %s"	    , c->name, c->instance_serial	    , (p1st ? "phase1" : "")	    , (p2st ? "phase1" : ""));	return;	/* no crypto */    }    /* if we have AH present, then record minimal info */    if (p2st->st_ah.present)    {	ipcq->strength = IPSEC_PRIVACY_INTEGRAL;	ipcq->auth_detail = p2st->st_esp.attrs.auth;    }    if (p2st->st_esp.present)    {	/*	 * XXX-mcr Please do not shout at me about relative strengths	 *         here. I'm not a cryptographer. I just diddle bits.	 */	switch (p2st->st_esp.attrs.transid)	{	case ESP_NULL:	    /* actually, do not change it if we set it from AH */	    break;	case ESP_DES:	case ESP_DES_IV64:	case ESP_DES_IV32:	case ESP_RC4:	    ipcq->strength = IPSEC_PRIVACY_ROT13;	    break;	    	case ESP_RC5:	case ESP_IDEA:	case ESP_CAST:	case ESP_BLOWFISH:	case ESP_3DES:	    ipcq->strength = IPSEC_PRIVACY_PRIVATE;	    ipcq->bandwidth = IPSEC_QOS_VOIP;	    break;	case ESP_3IDEA:	    ipcq->strength = IPSEC_PRIVACY_STRONG;	    ipcq->bandwidth = IPSEC_QOS_INTERACTIVE;	    break;	case ESP_AES:	    ipcq->strength = IPSEC_PRIVACY_STRONG;	    ipcq->bandwidth = IPSEC_QOS_FTP;	    break;	}	ipcq->esp_detail = p2st->st_esp.attrs.transid;    }    if (p2st->st_ipcomp.present)	ipcq->comp_detail = p2st->st_esp.attrs.transid;    /* now! the credentails that were used */    /* for the moment we only have 1 credential, the DNS name,     * because the DNS servers do not return the chain of SIGs yet     */    if(!c->spd.this.key_from_DNS_on_demand)    {	/* the key didn't come from the DNS in some way,	 * so it must have been loaded locally.	 */	ipcq->credential_count = 1;	ipcq->credentials[0].ii_type   = c->spd.this.id.kind;	ipcq->credentials[0].ii_format = CERT_RAW_RSA;    }	#if 0    switch (c->spd.id.kind)    {    case ID_IPV4_ADDR:    }    if (c->gw_info == NULL)    {	plog("rcv_info: connection %s had NULL gw_info.", c->name);	return    }#endif    ipcq->credential_count = 1;    /* pull credentials out of gw_info */        switch (p1st->st_peer_pubkey->dns_auth_level)    {    case DAL_UNSIGNED:    case DAL_NOTSEC:	/* these seem to be the same for this purpose */	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;	ipcq->credentials[0].ii_type   = CERT_NONE;	idtoa(&p1st->st_peer_pubkey->id	    , ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn));	break;	    case DAL_SIGNED:	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;	ipcq->credentials[0].ii_format = CERT_DNS_SIGNED_KEY;	idtoa(&p1st->st_peer_pubkey->id	    , ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn));	if (p1st->st_peer_pubkey->dns_sig != NULL)	{	    strncat(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig		, p1st->st_peer_pubkey->dns_sig		, sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig));	}	break;    case DAL_LOCAL:	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;	ipcq->credentials[0].ii_format = CERT_RAW_RSA;	idtoa(&p1st->st_peer_pubkey->id	    , ipcq->credentials[0].ii_credential.ipsec_raw_key.id_name	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_raw_key.id_name));	break;    }}/** * Handle an info/policy request.  * * For now, we close the socket after answering the request. * @param infoctlfd File Descriptor for socket communication */voidinfo_handle(int infoctlfd){	struct sockaddr_un info_client_addr;	int info_addr_len = sizeof(info_client_addr);	/* Note: actual value in n should fit in int.  To print, cast to int. */	int infofd;	err_t err;	struct ipsec_policy_cmd_query ipcq;	infofd = accept(infoctlfd, (struct sockaddr *)&info_client_addr	    , &info_addr_len);	if (infofd < 0)	{	    log_errno((e, "accept() failed in info_handle()"));	    return;	}	err = ipsec_policy_readmsg(infofd, (unsigned char *)&ipcq, sizeof(ipcq));	if (err != NULL)	{	    log_errno((e, "readmsg said: %s", err));	    close(infofd);	    return;	}	switch (ipcq.head.ipm_msg_type)	{	case IPSEC_CMD_QUERY_HOSTPAIR:	    info_lookuphostpair(&ipcq);	    write(infofd, &ipcq, ipcq.head.ipm_msg_len);	    break;	    	default:	    plog("got unimplemented msg type: %d", ipcq.head.ipm_msg_type);	    break;	}	/* for now, close the socket */	close(infofd);}

⌨️ 快捷键说明

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