/* give the appropriate response to the SER client */ int srv_response(struct sip_msg* msg, rd_buf_t * rb, int hftype) { int auth_hf_len=0, ret=0; char* auth_hf; switch(rb->ret_code) { case AAA_AUTHORIZED: return 1; case AAA_NOT_AUTHORIZED: send_resp(msg, 403, "Forbidden", NULL, 0); return -1; case AAA_SRVERR: send_resp(msg, 500, "Internal Server Error", NULL, 0); return -1; case AAA_CHALENGE: if(hftype==HDR_AUTHORIZATION) /* SIP server */ { auth_hf_len = WWW_AUTH_CHALLENGE_LEN+rb->chall_len; auth_hf = (char*)ad_malloc(auth_hf_len*(sizeof(char))); memset(auth_hf, 0, auth_hf_len); memcpy(auth_hf,WWW_AUTH_CHALLENGE, WWW_AUTH_CHALLENGE_LEN); memcpy(auth_hf+WWW_AUTH_CHALLENGE_LEN, rb->chall, rb->chall_len); ret = send_resp(msg, 401, MESSAGE_401, auth_hf, auth_hf_len); } else /* Proxy Server */ { auth_hf_len = PROXY_AUTH_CHALLENGE_LEN+rb->chall_len; auth_hf = (char*)ad_malloc(auth_hf_len*(sizeof(char))); memset(auth_hf, 0, auth_hf_len); memcpy(auth_hf, PROXY_AUTH_CHALLENGE, PROXY_AUTH_CHALLENGE_LEN); memcpy(auth_hf + PROXY_AUTH_CHALLENGE_LEN, rb->chall, rb->chall_len); ret = send_resp(msg, 407, MESSAGE_407, auth_hf, auth_hf_len); } if (auth_hf) pkg_free(auth_hf); if (ret == -1) { LOG(L_ERR, M_NAME":srv_response():Error while sending challenge " "to the client of SER\n"); return -1; } return -1; } // never reach this return -1; }
/* give the appropriate response to the SER client */ int srv_response(struct sip_msg* msg, rd_buf_t * rb, int hftype) { int auth_hf_len=0, ret=0; char* auth_hf; switch(rb->ret_code) { case AAA_AUTHORIZED: return 1; case AAA_NOT_AUTHORIZED: send_resp(msg, 403, &dia_403_err, NULL, 0); return -1; case AAA_SRVERR: send_resp(msg, 500, &dia_500_err, NULL, 0); return -1; case AAA_CHALENGE: if(hftype==HDR_AUTHORIZATION_T) /* SIP server */ { auth_hf_len = WWW_AUTH_CHALLENGE_LEN+rb->chall_len; auth_hf = (char*)ad_malloc(auth_hf_len*(sizeof(char))); memset(auth_hf, 0, auth_hf_len); memcpy(auth_hf,WWW_AUTH_CHALLENGE, WWW_AUTH_CHALLENGE_LEN); memcpy(auth_hf+WWW_AUTH_CHALLENGE_LEN, rb->chall, rb->chall_len); ret = send_resp(msg, 401, &dia_401_err, auth_hf, auth_hf_len); } else /* Proxy Server */ { auth_hf_len = PROXY_AUTH_CHALLENGE_LEN+rb->chall_len; auth_hf = (char*)ad_malloc(auth_hf_len*(sizeof(char))); memset(auth_hf, 0, auth_hf_len); memcpy(auth_hf, PROXY_AUTH_CHALLENGE, PROXY_AUTH_CHALLENGE_LEN); memcpy(auth_hf + PROXY_AUTH_CHALLENGE_LEN, rb->chall, rb->chall_len); ret = send_resp(msg, 407, &dia_407_err, auth_hf, auth_hf_len); } if (auth_hf) pkg_free(auth_hf); if (ret == -1) { LM_ERR("failed to send challenge to the client of SER\n"); return -1; } return -1; } // never reach this return -1; }
/* This function creates an AVP and returns a pointer to it; */ AAA_AVP* AAACreateAVP( AAA_AVPCode code, AAA_AVPFlag flags, AAAVendorId vendorId, char *data, unsigned int length, AVPDataStatus data_status) { AAA_AVP *avp; /* first check the params */ if( data==0 || length==0) { LOG(L_ERR,"ERROR:AAACreateAndAddAVPToList: NULL value received for" " param data/length !!\n"); return 0; } /* allocated a new AVP struct */ avp = 0; avp = (AAA_AVP*)ad_malloc(sizeof(AAA_AVP)); if (!avp) goto error; memset( avp, 0, sizeof(AAA_AVP) ); /* set some fields */ //avp->free_it = free_it; avp->packetType = AAA_DIAMETER; avp->code=code; avp->flags=flags; avp->vendorId=vendorId; set_avp_fields( code, avp); if ( data_status==AVP_DUPLICATE_DATA ) { /* make a duplicate for data */ avp->data.len = length; avp->data.s = (void*)ad_malloc(length); if(!avp->data.s) goto error; memcpy( avp->data.s, data, length); avp->free_it = 1; } else { avp->data.s = data; avp->data.len = length; avp->free_it = (data_status==AVP_FREE_DATA)?1:0; } return avp; error: LOG(L_ERR,"ERROR:AAACreateAVP: no more free memory!\n"); return 0; }
AAA_AVP* AAACloneAVP( AAA_AVP *avp , unsigned char clone_data) { AAA_AVP *n_avp; if (!avp || !(avp->data.s) || !(avp->data.len) ) goto error; /* clone the avp structure */ n_avp = (AAA_AVP*)ad_malloc( sizeof(AAA_AVP) ); if (!n_avp) { LM_ERR(" cannot get free pkg memory!!\n"); goto error; } memcpy( n_avp, avp, sizeof(AAA_AVP)); n_avp->next = n_avp->prev = 0; if (clone_data) { /* clone the avp data */ n_avp->data.s = (char*)ad_malloc( avp->data.len ); if (!(n_avp->data.s)) { LM_ERR("cannot get free pkg memory!!\n"); ad_free( n_avp ); goto error; } memcpy( n_avp->data.s, avp->data.s, avp->data.len); n_avp->free_it = 1; } else { /* link the clone's data to the original's data */ n_avp->data.s = avp->data.s; n_avp->data.len = avp->data.len; n_avp->free_it = 0; } return n_avp; error: return 0; }
char* ad_getDeviceName(cl_device_id dev) { cl_int status; size_t devInfoSize; char* devInfoStr = NULL; // Print the name status = clGetDeviceInfo(dev, CL_DEVICE_NAME, 0, NULL, &devInfoSize); ad_errChk(status, "Getting device name", true); devInfoStr = (char*)ad_malloc(devInfoSize); status = clGetDeviceInfo(dev, CL_DEVICE_NAME, devInfoSize, devInfoStr, NULL); ad_errChk(status, "Getting device name", true); //This will be a memory leak if not freed by caller return(devInfoStr); }
/* create a new minimal AAA message */ AAAMessage* AAAInMessage(AAACommandCode commandCode, AAAApplicationId appId) { AAAMessage *msg; /* we allocate a new AAAMessage structure and set it to 0 */ msg = (AAAMessage*)ad_malloc(sizeof(AAAMessage)); if (!msg) { ERROR("diameter_authorize(): no more free memory!\n"); return NULL; } memset(msg, 0, sizeof(AAAMessage)); /* command code */ msg->commandCode = commandCode; /* application ID */ msg->applicationId = appId; /* it's a new request -> set the flag */ msg->flags = 0x80; return msg; }
AAAMessage* AAAInMessage(AAACommandCode cmdCode, AAAApplicationId appID) { AAAMessage *msg; /* allocated a new AAAMessage structure a set it to 0 */ msg = (AAAMessage*)ad_malloc(sizeof(AAAMessage)); if (!msg) { LM_ERR("no more pkg free memory!\n"); return NULL; } memset(msg, 0, sizeof(AAAMessage)); /* command code */ msg->commandCode = cmdCode; /* application ID */ msg->applicationId = appID; /* it's a new request -> set the flag */ msg->flags = 0x80; return msg; }
/* from a AAAMessage structure, a buffer to be send is build */ AAAReturnCode AAABuildMsgBuffer( AAAMessage *msg ) { unsigned char *p; AAA_AVP *avp; AAA_AVP *mem; // group member /* first let's compute the length of the buffer */ msg->buf.len = AAA_MSG_HDR_SIZE; /* AAA message header size */ /* count and add the avps */ for(avp=msg->avpList.head;avp;avp=avp->next) { msg->buf.len += AVP_HDR_SIZE(avp->flags)+ to_32x_len( avp->data.len ); } // DBG("xxxx len=%d\n",msg->buf.len); /* allocate some memory */ msg->buf.s = (char*)ad_malloc( msg->buf.len ); if (!msg->buf.s) { ERROR("ERROR:AAABuildMsgBuffer: no more free memory!\n"); goto error; } memset(msg->buf.s, 0, msg->buf.len); /* fill in the buffer */ p = (unsigned char*)msg->buf.s; /* DIAMETER HEADER */ /* message length */ ((unsigned int*)p)[0] =htonl(msg->buf.len); /* Diameter Version */ *p = 1; p += VER_SIZE + MESSAGE_LENGTH_SIZE; /* command code */ ((unsigned int*)p)[0] = htonl(msg->commandCode); /* flags */ *p = (unsigned char)msg->flags; p += FLAGS_SIZE + COMMAND_CODE_SIZE; /* application-ID */ ((unsigned int*)p)[0] = htonl(msg->applicationId); p += APPLICATION_ID_SIZE; /* hop by hop id */ ((unsigned int*)p)[0] = msg->hopbyhopId; p += HOP_BY_HOP_IDENTIFIER_SIZE; /* end to end id */ ((unsigned int*)p)[0] = msg->endtoendId; p += END_TO_END_IDENTIFIER_SIZE; /* AVPS */ for(avp=msg->avpList.head;avp;avp=avp->next) { /* AVP HEADER */ /* avp code */ set_4bytes(p,avp->code); p +=4; /* flags */ (*p++) = (unsigned char)avp->flags; /* avp length */ set_3bytes(p, (AVP_HDR_SIZE(avp->flags)+avp->data.len) ); p += 3; /* vendor id */ if ((avp->flags&0x80)!=0) { set_4bytes(p,avp->vendorId); p +=4; } /* data */ if (!avp->groupedHead) { memcpy( p, avp->data.s, avp->data.len); p += to_32x_len( avp->data.len ); } else { // group members for(mem=avp->groupedHead;mem;mem=mem->next) p+=AAAAVPBuildBuffer(mem, p); } } if ((char*)p-msg->buf.s!=msg->buf.len) { ERROR("BUG: build_buf_from_msg: mismatch between len and buf!\n"); ad_free( msg->buf.s ); msg->buf.s = 0; msg->buf.len = 0; goto error; } // DBG("Message: %.*s\n", msg->buf.len, msg->buf.s); return AAA_ERR_SUCCESS; error: return -1; }
/* This function convert message to message structure */ AAAMessage* AAATranslateMessage( unsigned char* source, unsigned int sourceLen, int attach_buf) { unsigned char *ptr; AAAMessage *msg; unsigned char version; unsigned int msg_len; AAA_AVP *avp; unsigned int avp_code; unsigned char avp_flags; unsigned int avp_len; unsigned int avp_vendorID; unsigned int avp_data_len; /* check the params */ if( !source || !sourceLen || sourceLen<AAA_MSG_HDR_SIZE) { ERROR("ERROR:AAATranslateMessage: invalid buffered received!\n"); goto error; } /* inits */ msg = 0; avp = 0; ptr = source; /* alloc a new message structure */ msg = (AAAMessage*)ad_malloc(sizeof(AAAMessage)); if (!msg) { ERROR("ERROR:AAATranslateMessage: no more free memory!!\n"); goto error; } memset(msg,0,sizeof(AAAMessage)); /* get the version */ version = (unsigned char)*ptr; ptr += VER_SIZE; if (version!=1) { ERROR("ERROR:AAATranslateMessage: invalid version [%d]in " "AAA msg\n",version); goto error; } /* message length */ msg_len = get_3bytes( ptr ); ptr += MESSAGE_LENGTH_SIZE; if (msg_len>sourceLen) { ERROR("ERROR:AAATranslateMessage: AAA message len [%d] bigger then" " buffer len [%d]\n",msg_len,sourceLen); goto error; } /* command flags */ msg->flags = *ptr; ptr += FLAGS_SIZE; /* command code */ msg->commandCode = get_3bytes( ptr ); ptr += COMMAND_CODE_SIZE; /* application-Id */ msg->applicationId = get_4bytes( ptr ); ptr += APPLICATION_ID_SIZE; /* Hop-by-Hop-Id */ msg->hopbyhopId = *((unsigned int*)ptr); ptr += HOP_BY_HOP_IDENTIFIER_SIZE; /* End-to-End-Id */ msg->endtoendId = *((unsigned int*)ptr); ptr += END_TO_END_IDENTIFIER_SIZE; /* start decoding the AVPS */ while (ptr < source+msg_len) { if (ptr+AVP_HDR_SIZE(0x80)>source+msg_len){ ERROR("ERROR:AAATranslateMessage: source buffer to short!! " "Cannot read the whole AVP header!\n"); goto error; } /* avp code */ avp_code = get_4bytes( ptr ); ptr += AVP_CODE_SIZE; /* avp flags */ avp_flags = (unsigned char)*ptr; ptr += AVP_FLAGS_SIZE; /* avp length */ avp_len = get_3bytes( ptr ); ptr += AVP_LENGTH_SIZE; if (avp_len<1) { ERROR("ERROR:AAATranslateMessage: invalid AVP len [%d]\n", avp_len); goto error; } /* avp vendor-ID */ avp_vendorID = 0; if (avp_flags&AAA_AVP_FLAG_VENDOR_SPECIFIC) { avp_vendorID = get_4bytes( ptr ); ptr += AVP_VENDOR_ID_SIZE; } /* data length */ avp_data_len = avp_len-AVP_HDR_SIZE(avp_flags); /*check the data length */ if ( source+msg_len<ptr+avp_data_len) { ERROR("ERROR:AAATranslateMessage: source buffer to short!! " "Cannot read a whole data for AVP!\n"); goto error; } /* create the AVP */ avp = AAACreateAVP( avp_code, avp_flags, avp_vendorID, (char*)ptr, avp_data_len, AVP_DONT_FREE_DATA); if (!avp) goto error; /* link the avp into aaa message to the end */ AAAAddAVPToMessage( msg, avp, msg->avpList.tail); ptr += to_32x_len( avp_data_len ); } /* link the buffer to the message */ if (attach_buf) { msg->buf.s = (char*)source; msg->buf.len = msg_len; } //AAAPrintMessage( msg ); return msg; error: ERROR("ERROR:AAATranslateMessage: message conversion droped!!\n"); AAAFreeMessage(&msg); return 0; }
/* * This function creates and submits diameter authentication request as per * draft-srinivas-aaa-basic-digest-00.txt. * Service type of the request is Authenticate-Only. * Returns: * 1 - success * -1 - error * */ int diameter_authorize(struct hdr_field* hdr, str* p_method, struct sip_uri uri, struct sip_uri ruri, unsigned int m_id, rd_buf_t* rb) { str method, user_name; AAAMessage *req; AAA_AVP *avp, *position; int name_flag, port_flag; dig_cred_t* cred; unsigned int tmp; user_name.s=0; /* fixes gcc 4.0 warning */ if ( !p_method ) { LOG(L_ERR, M_NAME":diameter_authorize(): Invalid parameter value\n"); return -1; } if ( (req=AAAInMessage(AA_REQUEST, AAA_APP_NASREQ))==NULL) return -1; if(hdr && hdr->parsed) cred = &(((auth_body_t*)hdr->parsed)->digest); else cred = NULL; method = *p_method; if(!cred) { /* Username AVP */ user_name.len = uri.user.len + uri.host.len; if(user_name.len>0) { user_name.len += 2; user_name.s = (char*)ad_malloc(user_name.len*sizeof(char)); memset(user_name.s, 0, user_name.len); memcpy(user_name.s, uri.user.s, uri.user.len); if(uri.user.len>0) { memcpy(user_name.s+uri.user.len, "@", 1); memcpy(user_name.s+uri.user.len+1, uri.host.s, uri.host.len); } else memcpy(user_name.s, uri.host.s, uri.host.len); } if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, user_name.s, user_name.len, AVP_FREE_DATA)) == 0) { LOG(L_ERR,M_NAME":diameter_authorize(): no more free memory!\n"); if(user_name.len>0) pkg_free(user_name.s); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): avp not added \n"); goto error1; } } else /* it is a SIP message with credentials */ { /* Add Username AVP */ if (cred->username.domain.len>0) { if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, cred->username.whole.s, cred->username.whole.len, AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free " "memory!\n"); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): avp not added \n"); goto error1; } } else { user_name.len = cred->username.user.len + cred->realm.len; if(user_name.len>0) { user_name.s = ad_malloc(user_name.len); if (!user_name.s) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free " "memory\n"); goto error; } memcpy(user_name.s, cred->username.whole.s, cred->username.whole.len); if(cred->username.whole.len>0) { user_name.s[cred->username.whole.len] = '@'; memcpy(user_name.s + cred->username.whole.len + 1, cred->realm.s, cred->realm.len); } else memcpy(user_name.s, cred->realm.s, cred->realm.len); } if( (avp=AAACreateAVP(AVP_User_Name, 0, 0, user_name.s, user_name.len, AVP_FREE_DATA)) == 0) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free " "memory!\n"); if(user_name.len>0) pkg_free(user_name.s); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): avp not added \n"); goto error1; } } } /* SIP_MSGID AVP */ DBG("******* m_id=%d\n", m_id); tmp = m_id; if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&tmp), sizeof(m_id), AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): avp not added \n"); goto error1; } /* SIP Service AVP */ if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_AUTHENTICATION, SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free memory!\n"); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): avp not added \n"); goto error1; } /* Destination-Realm AVP */ if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, uri.host.s, uri.host.len, AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free memory!\n"); goto error; } #ifdef DEBUG DBG("Destination Realm: %.*s\n", uri.host.len, uri.host.s); #endif if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): avp not added \n"); goto error1; } /* Resource AVP */ user_name.len = ruri.user.len + ruri.host.len + ruri.port.len + 2; user_name.s = (char*)ad_malloc(user_name.len*sizeof(char)); memset(user_name.s, 0, user_name.len); memcpy(user_name.s, ruri.user.s, ruri.user.len); name_flag= 0; if(ruri.user.s) { name_flag = 1; memcpy(user_name.s+ruri.user.len, "@", 1); } memcpy(user_name.s+ruri.user.len+name_flag, ruri.host.s, ruri.host.len); port_flag=0; if(ruri.port.s) { port_flag = 1; memcpy(user_name.s+ruri.user.len+ruri.host.len+1, ":", 1); } memcpy(user_name.s+ruri.user.len+ruri.host.len+name_flag+port_flag, ruri.port.s, ruri.port.len); #ifdef DEBUG DBG(M_NAME": AVP_Resource=%.*s\n", user_name.len, user_name.s); #endif if( (avp=AAACreateAVP(AVP_Resource, 0, 0, user_name.s, user_name.len, AVP_FREE_DATA)) == 0) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free memory!\n"); if(user_name.s) pkg_free(user_name.s); goto error; } if( AAAAddAVPToMessage(req, avp, 0)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): avp not added \n"); goto error1; } if(cred) /* it is a SIP message with credentials */ { /* Response AVP */ if( (avp=AAACreateAVP(AVP_Response, 0, 0, hdr->body.s, hdr->body.len, AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free memory!\n"); goto error; } position = AAAGetLastAVP(&(req->avpList)); if( AAAAddAVPToMessage(req, avp, position)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): avp not added \n"); goto error1; } /* Method AVP */ if( (avp=AAACreateAVP(AVP_Method, 0, 0, p_method->s, p_method->len, AVP_DUPLICATE_DATA)) == 0) { LOG(L_ERR, M_NAME":diameter_authorize(): no more free memory!\n"); goto error; } position = AAAGetLastAVP(&(req->avpList)); if( AAAAddAVPToMessage(req, avp, position)!= AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): avp not added \n"); goto error1; } } #ifdef DEBUG AAAPrintMessage(req); #endif /* build a AAA message buffer */ if(AAABuildMsgBuffer(req) != AAA_ERR_SUCCESS) { LOG(L_ERR, M_NAME":diameter_authorize(): message buffer not created\n"); goto error; } if(sockfd==AAA_NO_CONNECTION) { sockfd = init_mytcp(diameter_client_host, diameter_client_port); if(sockfd==AAA_NO_CONNECTION) { LOG(L_ERR, M_NAME":diameter_authorize(): failed to reconnect" " to Diameter client\n"); goto error; } } /* send the message to the DIAMETER CLIENT */ switch( tcp_send_recv(sockfd, req->buf.s, req->buf.len, rb, m_id) ) { case AAA_ERROR: /* a transmission error occurred */ LOG(L_ERR, M_NAME":diameter_authorize(): message sending to the" " DIAMETER backend authorization server failed\n"); goto error; case AAA_CONN_CLOSED: LOG(L_NOTICE, M_NAME":diameter_authorize(): connection to Diameter" " client closed.It will be reopened by the next request\n"); close(sockfd); sockfd = AAA_NO_CONNECTION; goto error; case AAA_TIMEOUT: LOG(L_NOTICE,M_NAME":diameter_authorize(): no response received\n"); close(sockfd); sockfd = AAA_NO_CONNECTION; goto error; } AAAFreeMessage(&req); return 1; error1: AAAFreeAVP(&avp); error: AAAFreeMessage(&req); return -1; }