fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
5df5713f81d69c1a0797f99b13e95e220da00ef9bing zhao - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void encode_chap_password(int identifier, int chap_passwd_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesnd_radius_request(void *socket, iscsi_ipaddr_t rsvr_ip_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t rsvr_port, radius_packet_data_t *req_data)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i; /* Loop counter. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ushort_t total_length; /* Has to be 2 octets in size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *ptr; /* Pointer to RADIUS packet data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *length_ptr; /* Points to the Length field of the */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* packet. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte radius_attr_t *req_attr; /* Request attributes */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte radius_packet_t *packet; /* Outbound RADIUS packet */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Create a RADIUS packet with minimal length for now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data = kmem_zalloc(MAX_RAD_PACKET_LEN, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(req_data->authenticator, packet->authenticator,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Loop over all attributes of the request. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The packet has exceed its maximum size. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Length is 2 octets - RFC 2865 section 3 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If the attribute is CHAP-Password, encode it. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (req_attr->attr_type_code == RAD_CHAP_PASSWORD) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Identifier plus CHAP response. RFC 2865
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * section 5.3.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t encoded_chap_passwd[RAD_CHAP_PASSWD_STR_LEN +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req_attr->attr_value_len = RAD_CHAP_PASSWD_STR_LEN +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(req_attr->attr_value, ptr, req_attr->attr_value_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* Done looping over all attributes */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(&total_length, packet->length, sizeof (ushort_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Send the packet to the RADIUS server.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rsvr_ip_addr.i_insize == sizeof (in_addr_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sa_rsvr.s_in4.sin_port = htons((ushort_t)rsvr_port);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte msg.msg_name = (struct sockaddr *)&sa_rsvr.s_in4;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (rsvr_ip_addr.i_insize == sizeof (in6_addr_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* No IPv6 support for now. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Invalid IP address for RADIUS server. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortercv_radius_response(void *socket, uint8_t *shared_secret,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t shared_secret_len, uint8_t *req_authenticator,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t md5_digest[16]; /* MD5 Digest Length 16 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_data = kmem_zalloc(MAX_RAD_PACKET_LEN, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rcv_len = iscsi_net->recvmsg(socket, &msg, RAD_RCV_TIMEOUT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(rcv_rad_resp_summary, int, rcv_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE1(rcv_rad_resp_data, uint16_t, declared_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if the received packet length is within allowable range.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RFC 2865 section 3.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Check if the declared packet length is within allowable range.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RFC 2865 section 3.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Discard packet with received length shorter than declared
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * length. RFC 2865 section 3.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Authenticate the incoming packet, using the following algorithm
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (RFC 2865 section 3):
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Code = RADIUS packet code
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ID = RADIUS packet identifier
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Length = Declared length of the packet
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RequestAuth = The request authenticator
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Attributes = The response attributes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Secret = The shared secret
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MD5Update(&context, req_authenticator, RAD_AUTHENTICATOR_LEN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Include response attributes only if there is a payload */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Response Attributes */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MD5Update(&context, shared_secret, shared_secret_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(md5_digest, packet->authenticator, RAD_AUTHENTICATOR_LEN)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the received length is greater than the declared length,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * trust the declared length and shorten the packet (i.e., to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * treat the octets outside the range of the Length field as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * padding - RFC 2865 section 3).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Clear the padding data. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(tmp_data + declared_len, rcv_len - declared_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Annotate the RADIUS packet data with the data we received from
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the server.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * encode_chap_password -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Encode a CHAP-Password attribute. This function basically prepends
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the identifier in front of chap_passwd and copy the results to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteencode_chap_password(int identifier, int chap_passwd_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < chap_passwd_len; i++) {