📄 msipipsecapi.cxx
字号:
securityConfig.use_ipsec = false; return false; } //if( ka && ka->type() == KEY_AGREEMENT_TYPE_DH ){ // ((KeyAgreementDH *)*ka)->computeTgk(); //} if(initMSipIpsec()) if (start() == 0){ offered = true; return true; } return false;}//---------------------------------------------------------------------------------------------------////Remove SA and policy from kernel, -1 = errorint MsipIpsecAPI::stop(){ int notgood = 0; list <MsipIpsecRequest *>::iterator iter; for( iter = madeREQ.begin(); iter != madeREQ.end() ; iter++ ){ if((*iter)->exist) if((*iter)->remove(false) == -1) notgood = -1; } return notgood;}//---------------------------------------------------------------------------------------------------////Write SA and policy to kernel -1 == errorint MsipIpsecAPI::start(){ list <MsipIpsecRequest *>::iterator iter; for( iter = madeREQ.begin(); iter != madeREQ.end() ; iter++ ){ if(!((*iter)->exist)){ if((*iter)->set() == -1) return -1; } } return 0;}//---------------------------------------------------------------------------------------------------//bool MsipIpsecAPI::required(){ return securityConfig.use_ipsec;}//---------------------------------------------------------------------------------------------------////-MsipIpsecAPI-PRIVATE------------------------------------------------------------------------------////Get and reserve a SPI to offer. If 0 id return something went wronguint32_t MsipIpsecAPI::getOfferSPI(){ char *srcadr = "0.0.0.0"; char *dstadr = "0.0.0.0"; struct sockaddr_in src, dst; src.sin_family = AF_INET; src.sin_port = htons(0); inet_pton(AF_INET, srcadr, &(src.sin_addr)); dst.sin_family = AF_INET; dst.sin_port = htons(0); inet_pton(AF_INET, dstadr, &(dst.sin_addr)); MsipIpsecSA *sa = new MsipIpsecSA(so, SADB_SATYPE_ESP, IPSEC_MODE_TRANSPORT, reqid, seq++, (struct sockaddr *) &src, (struct sockaddr *) &dst); madeREQ.push_back((MsipIpsecRequest*) sa); //int result = sa->set(); if (sa->set() == -1) return 0; return sa->spi;}//---------------------------------------------------------------------------------------------------////Set requested SA in CS_ID_MAPvoid MsipIpsecAPI::addSAToKa(uint8_t policyNo){ ka->setCsIdMapType(HDR_CS_ID_MAP_TYPE_IPSEC4_ID); uint32_t offerspi = getOfferSPI(); massert(offerspi); ka->addIpsecSA( offerspi, 0, localIp, policyNo); /* Placeholder for the receiver to place his SPI */ ka->addIpsecSA( htonl(0), localIp, 0, policyNo);}//---------------------------------------------------------------------------------------------------////Set parameters from keyagreement Ipsec then start with start()bool MsipIpsecAPI::initMSipIpsec(){ if(ka->getCsIdMapType() == HDR_CS_ID_MAP_TYPE_IPSEC4_ID){ MikeyCsIdMapIPSEC4 *CsIdMap = (MikeyCsIdMapIPSEC4 *)(*(ka->csIdMap())); MikeyIPSEC4Cs *CsId; MsipIpsecSA *sa; int result, policylen; uint8_t policyNo; uint32_t spiDstaddr, spiSrcaddr, spi; u_int satype, mode, e_type, a_type, e_keylen, a_keylen, flags; byte_t * e_key,* a_key; char *policy; struct sockaddr_in src, dst; struct in_addr addr; int nCs = (int) ka->nCs(); if( ka && ka->type() == KEY_AGREEMENT_TYPE_DH ) ((KeyAgreementDH *)*ka)->computeTgk(); for(int i = 0 ; i < nCs ; i++){ CsId = CsIdMap->getCsIdnumber(i+1); if(!CsId){ cerr << "Invalid IPSEC CsId: " << flush << endl; return false; } policyNo = CsId->policyNo; spiDstaddr = CsId->spiDstaddr; //Network byte order if(spiDstaddr == 0){ spiDstaddr = localIp; CsId->spiDstaddr = localIp; } spiSrcaddr = CsId->spiSrcaddr; //Network byte order if(spiSrcaddr == 0){ spiSrcaddr = localIp; CsId->spiSrcaddr = localIp; } if (spiDstaddr == spiSrcaddr){ fprintf( stderr, "Same address!!\n"); return false; } spi = CsId->spi; if(spi == 0){ spi = getOfferSPI(); CsId->spi = spi; } sa = findReqSPI(spi); if(sa != NULL){ if( sa->remove(false) == -1 ) return false; } satype = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_IPSEC4, MIKEY_IPSEC_SATYPE); mode = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_IPSEC4, MIKEY_IPSEC_MODE); e_type = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_IPSEC4, MIKEY_IPSEC_EALG); a_type = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_IPSEC4, MIKEY_IPSEC_AALG); e_keylen = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_IPSEC4, MIKEY_IPSEC_EKEYL); a_keylen = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_IPSEC4, MIKEY_IPSEC_AKEYL); flags = ka->getPolicyParamTypeValue(policyNo, MIKEY_PROTO_IPSEC4, MIKEY_IPSEC_SAFLAG); e_key = new byte_t[e_keylen]; a_key = new byte_t[a_keylen]; ka->genEncr( i+1, e_key, e_keylen ); ka->genAuth( i+1, a_key, a_keylen ); //Making src and dst structs src.sin_family = AF_INET; src.sin_port = htons(0); addr.s_addr = spiSrcaddr; src.sin_addr = addr; dst.sin_family = AF_INET; dst.sin_port = htons(0); addr.s_addr = spiDstaddr; dst.sin_addr = addr; //Making a SA madeREQ.push_back(new MsipIpsecSA(so, satype, mode, reqid, seq++, (struct sockaddr *) &src, (struct sockaddr *) &dst, spi, e_type, a_type, e_keylen, a_keylen, (char*)e_key, (char*)a_key, 64, flags)); //Making a Traffic Policy. Please make it dynamic if (spiDstaddr == localIp) policy = "in ipsec esp/transport//require"; if (spiSrcaddr == localIp) policy = "out ipsec esp/transport//require"; policylen = strlen(policy); madeREQ.push_back(new MsipIpsecPolicy(so, (struct sockaddr *) &src, (struct sockaddr *) &dst, 0, policy, policylen, seq++, 32, 32 )); delete [] e_key; delete [] a_key; } return true; } else{ fprintf( stderr, "Wrong CS-id map type"); return false; }}//---------------------------------------------------------------------------------------------------////Set parameters from keyagreement and start Ipsec -1 == errorint MsipIpsecAPI::setMSipIpsec(){ if(initMSipIpsec()) return start(); return -1;}//---------------------------------------------------------------------------------------------------//// Find seq for SA with spi, 0 = don't existuint32_t MsipIpsecAPI::findSeqSPI(uint32_t spi){ list <MsipIpsecRequest *>::iterator iter; for( iter = madeREQ.begin(); iter != madeREQ.end() ; iter++ ){ if((*iter)->otype) if(((MsipIpsecSA *)(*iter))->spi == spi) return (*iter)->seq; } return 0;}//---------------------------------------------------------------------------------------------------//// Find Req for SA with spi, NULL = don't existMsipIpsecSA * MsipIpsecAPI::findReqSPI(uint32_t spi){ list <MsipIpsecRequest *>::iterator iter; for( iter = madeREQ.begin(); iter != madeREQ.end() ; iter++ ){ if((*iter)->otype) if(((MsipIpsecSA *)(*iter))->spi == spi) return (MsipIpsecSA *)(*iter); } return NULL;}//---------------------------------------------------------------------------------------------------//// Authenticate the offered messagebool MsipIpsecAPI::responderAuthenticate( string b64Message ){ bool authenticated; try{ MikeyMessage * init_mes = new MikeyMessage(b64Message); switch( init_mes->type() ){ case MIKEY_TYPE_DH_INIT: if( securityConfig.cert.isNull() ){ merr << "No certificate available" << end; securityConfig.use_ipsec = false; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; return false; } if( !securityConfig.dh_enabled ){ merr << "Cannot handle DH key agreement" << end; securityConfig.use_ipsec = false; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; return false; } if( !ka ) ka = new KeyAgreementDH( securityConfig.cert, securityConfig.cert_db, DH_GROUP_OAKLEY5 ); ka->setInitiatorData( init_mes ); if( init_mes->authenticate( ((KeyAgreementDH *)*ka) ) ){ merr << "Authentication of the DH init message failed" << end; merr << ka->authError() << end; securityConfig.use_ipsec = false; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; return false; }#ifdef DEBUG_OUTPUT merr << "Authentication successful, controling the certificate" << end;#endif if( securityConfig.check_cert ){ if( ((KeyAgreementDH *)*ka)->controlPeerCertificate() == 0){#ifdef DEBUG_OUTPUT merr << "Certificate check failed in the incoming MIKEY message" << end;#endif securityConfig.use_ipsec = false; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; return false; } } securityConfig.ka_type = KEY_MGMT_METHOD_MIKEY_DH; break; case MIKEY_TYPE_PSK_INIT: if( !securityConfig.psk_enabled ){ securityConfig.use_ipsec = false; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; return false; } ka = new KeyAgreementPSK( securityConfig.psk, securityConfig.psk_length ); ka->setInitiatorData( init_mes ); if( init_mes->authenticate( ((KeyAgreementPSK *)*ka) ) ){ securityConfig.use_ipsec = false; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; cerr << "responderAuthenticate return false" << flush << endl; return false; } securityConfig.ka_type = KEY_MGMT_METHOD_MIKEY_PSK; break; case MIKEY_TYPE_PK_INIT: securityConfig.use_ipsec = false; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; return false; default: merr << "Unexpected type of message in INVITE" << end; securityConfig.use_ipsec = false; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; return false; } securityConfig.use_ipsec = true; authenticated = true; } catch( certificate_exception & exc ){ // TODO: Tell the GUI merr << "Could not open certificate" <<end; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; securityConfig.use_ipsec = false; authenticated = false; } catch( MikeyExceptionUnacceptable & exc ){ merr << "MikeyException caught: "<<exc->message()<<end; //FIXME! send SIP Unacceptable with Mikey Error message securityConfig.ka_type = KEY_MGMT_METHOD_NULL; securityConfig.use_ipsec = false; authenticated = false; } // Authentication failed catch( MikeyExceptionAuthentication & exc ){ merr << "MikeyExceptionAuthentication caught: "<<exc->message()<<end; //FIXME! send SIP Authorization failed with Mikey Error message securityConfig.ka_type = KEY_MGMT_METHOD_NULL; securityConfig.use_ipsec = false; authenticated = false; } // Message was invalid catch( MikeyExceptionMessageContent & exc ){ MikeyMessage * error_mes; merr << "MikeyExceptionMesageContent caught: " << exc->message() << end; if( ( error_mes = exc->errorMessage() ) != NULL ){ //FIXME: send the error message! } securityConfig.ka_type = KEY_MGMT_METHOD_NULL; securityConfig.use_ipsec = false; authenticated = false; } catch( MikeyException & exc ){ merr << "MikeyException caught: " << exc->message() << end; securityConfig.ka_type = KEY_MGMT_METHOD_NULL; securityConfig.use_ipsec = false; authenticated = false; } return authenticated;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -