Mercurial > hg > freeDiameter
comparison extensions/app_radgw/rgw_msg.c @ 516:1c2f5ee38039
Allow RADIUS Proxies with the app_radgw extension
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Fri, 27 Aug 2010 10:59:51 +0900 |
parents | e203fc0c95e3 |
children | d5383f28b96e |
comparison
equal
deleted
inserted
replaced
515:b9167b4de7dc | 516:1c2f5ee38039 |
---|---|
76 memset( &(*msg)->radius + 1, 0, sizeof(struct rgw_radius_msg_meta) - sizeof(struct radius_msg) ); | 76 memset( &(*msg)->radius + 1, 0, sizeof(struct rgw_radius_msg_meta) - sizeof(struct radius_msg) ); |
77 | 77 |
78 return 0; | 78 return 0; |
79 } | 79 } |
80 | 80 |
81 /* Check if the message has a valid authenticator, and update the meta-data accordingly */ | |
82 int rgw_msg_auth_check(struct rgw_radius_msg_meta * msg, struct rgw_client * cli, uint8_t * req_auth) | |
83 { | |
84 unsigned char * key; | |
85 size_t keylen; | |
86 int count; | |
87 | |
88 TRACE_ENTRY("%p %p %p", msg, cli, req_auth); | |
89 | |
90 CHECK_PARAMS(msg && cli); | |
91 | |
92 CHECK_FCT(rgw_clients_getkey(cli, &key, &keylen)); | |
93 | |
94 count = radius_msg_count_attr(&msg->radius, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, 0); | |
95 if (count > 1) { | |
96 TRACE_DEBUG(INFO, "Too many Message-Authenticator attributes (%d), discarding message.", count); | |
97 return EINVAL; | |
98 } | |
99 if (count == 0) { | |
100 TRACE_DEBUG(FULL, "Message does not contain a Message-Authenticator attributes."); | |
101 msg->valid_mac = 0; | |
102 } else { | |
103 if (radius_msg_verify_msg_auth( &msg->radius, key, keylen, req_auth )) { | |
104 TRACE_DEBUG(INFO, "Invalid Message-Authenticator received, discarding message."); | |
105 return EINVAL; | |
106 } | |
107 msg->valid_mac = 1; | |
108 } | |
109 | |
110 return 0; | |
111 } | |
112 | |
113 /* Dump a message (inspired from radius_msg_dump) -- can be used safely with a struct radius_msg as parameter (we don't dump the metadata) */ | 81 /* Dump a message (inspired from radius_msg_dump) -- can be used safely with a struct radius_msg as parameter (we don't dump the metadata) */ |
114 void rgw_msg_dump(struct rgw_radius_msg_meta * msg) | 82 void rgw_msg_dump(struct rgw_radius_msg_meta * msg) |
115 { | 83 { |
116 unsigned char *auth; | 84 unsigned char *auth; |
117 size_t i; | 85 size_t i; |
129 auth[8], auth[9], auth[10], auth[11], | 97 auth[8], auth[9], auth[10], auth[11], |
130 auth[12], auth[13], auth[14], auth[15]); | 98 auth[12], auth[13], auth[14], auth[15]); |
131 for (i = 0; i < msg->radius.attr_used; i++) { | 99 for (i = 0; i < msg->radius.attr_used; i++) { |
132 struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[i]); | 100 struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[i]); |
133 fd_log_debug(" - len:%3hhu, type:0x%02hhx (%s)\n", attr->length, attr->type, rgw_msg_attrtype_str(attr->type)); | 101 fd_log_debug(" - len:%3hhu, type:0x%02hhx (%s)\n", attr->length, attr->type, rgw_msg_attrtype_str(attr->type)); |
134 /* If we need to dump the value, it's better to call directly radius_msg_dump instead... */ | 102 radius_msg_dump_attr_val(attr); |
135 } | 103 } |
136 fd_log_debug("-----------------------------\n"); | 104 fd_log_debug("-----------------------------\n"); |
137 } | 105 } |
138 | 106 |
139 static struct dict_object * cache_orig_host = NULL; | |
140 static struct dict_object * cache_orig_realm = NULL; | |
141 | |
142 int rgw_msg_init(void) | |
143 { | |
144 TRACE_ENTRY(); | |
145 CHECK_FCT( fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &cache_orig_host, ENOENT) ); | |
146 CHECK_FCT( fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &cache_orig_realm, ENOENT) ); | |
147 return 0; | |
148 } | |
149 | |
150 /* Create a new Diameter msg with origin-host & realm */ | |
151 int rgw_msg_create_base(struct rgw_client * cli, struct msg ** diam) | |
152 { | |
153 char * fqdn; | |
154 char * realm; | |
155 | |
156 struct avp *avp = NULL; | |
157 union avp_value avp_val; | |
158 | |
159 TRACE_ENTRY("%p %p", cli, diam); | |
160 CHECK_PARAMS( cli && diam && (*diam == NULL) ); | |
161 | |
162 /* Get information on this peer */ | |
163 CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &realm) ); | |
164 | |
165 /* Create an empty Diameter message so that extensions can store their AVPs */ | |
166 CHECK_FCT( fd_msg_new ( NULL, MSGFL_ALLOC_ETEID, diam ) ); | |
167 | |
168 /* Add the Origin-Host as next AVP */ | |
169 CHECK_FCT( fd_msg_avp_new ( cache_orig_host, 0, &avp ) ); | |
170 memset(&avp_val, 0, sizeof(avp_val)); | |
171 avp_val.os.data = (unsigned char *)fqdn; | |
172 avp_val.os.len = strlen(fqdn); | |
173 CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) ); | |
174 CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) ); | |
175 | |
176 /* Add the Origin-Realm as next AVP */ | |
177 CHECK_FCT( fd_msg_avp_new ( cache_orig_realm, 0, &avp ) ); | |
178 memset(&avp_val, 0, sizeof(avp_val)); | |
179 avp_val.os.data = (unsigned char *)realm; | |
180 avp_val.os.len = strlen(realm); | |
181 CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) ); | |
182 CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) ); | |
183 | |
184 /* Done! */ | |
185 return 0; | |
186 } |