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 }
"Welcome to our mercurial repository"